Skip to content

Commit

Permalink
๐Ÿš€ ้‡‡้›†้€ป่พ‘้‡ๆž„
Browse files Browse the repository at this point in the history
  • Loading branch information
Cairry committed Dec 27, 2024
1 parent 14a4701 commit 23f0b71
Show file tree
Hide file tree
Showing 32 changed files with 1,001 additions and 1,443 deletions.
24 changes: 8 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM registry.js.design/base/golang:1.18-alpine3.16 AS build
FROM registry.cn-hangzhou.aliyuncs.com/opsre/golang:1.21.9-alpine3.19 AS build

ENV GO111MODULE=on \
CGO_ENABLED=0 \
Expand All @@ -11,29 +11,21 @@ COPY . /workspace
WORKDIR /workspace

RUN go mod tidy && \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o point ./main.go && \
chmod 777 point
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o watchlog ./main.go && \
chmod 777 watchlog

FROM elastic/filebeat:7.17.10
FROM registry.js.design/library/filebeat:7.17.10_python2

USER root
COPY --from=build /workspace/watchlog /usr/share/filebeat/watchlog/watchlog

COPY --from=build /workspace/point /usr/share/filebeat/point/point
COPY assets/entrypoint assets/filebeat/ assets/healthz /usr/share/filebeat/watchlog/

COPY assets/entrypoint assets/filebeat/ assets/healthz /usr/share/filebeat/point/

RUN apt-get update && \
apt-get -y install python2 && \
/usr/bin/chmod +x /usr/share/filebeat/point/point /usr/share/filebeat/point/healthz /usr/share/filebeat/point/config.filebeat
RUN /usr/bin/chmod +x /usr/share/filebeat/watchlog/watchlog /usr/share/filebeat/watchlog/healthz /usr/share/filebeat/watchlog/config.filebeat

HEALTHCHECK CMD /usr/share/filebeat/healthz

VOLUME /var/log/filebeat

VOLUME /var/lib/filebeat

WORKDIR /usr/share/filebeat/

ENV PILOT_TYPE=filebeat

ENTRYPOINT ["python2", "/usr/share/filebeat/point/entrypoint"]
ENTRYPOINT ["python2", "/usr/share/filebeat/watchlog/entrypoint"]
29 changes: 0 additions & 29 deletions README.md

This file was deleted.

6 changes: 3 additions & 3 deletions assets/entrypoint
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ def cleanup():
def run():
pilot_type = os.environ.get(ENV_PILOT_TYPE)
if pilot_filebeat == pilot_type:
tpl_config = "/usr/share/filebeat/point/filebeat.tpl"
tpl_config = "/usr/share/filebeat/watchlog/filebeat.tpl"

os.execve('/usr/share/filebeat/point/point', ['/usr/share/filebeat/point/point', '-template', tpl_config, '-base', base, '-log-level', 'debug'],
os.execve('/usr/share/filebeat/watchlog/watchlog', ['/usr/share/filebeat/watchlog/watchlog', '-template', tpl_config],
os.environ)


def config():
pilot_type = os.environ.get(ENV_PILOT_TYPE)
if pilot_filebeat == pilot_type:
print "start log-pilot:", pilot_filebeat
subprocess.check_call(['/usr/share/filebeat/point/config.filebeat'])
subprocess.check_call(['/usr/share/filebeat/watchlog/config.filebeat'])


if __name__ == '__main__':
Expand Down
7 changes: 0 additions & 7 deletions assets/filebeat/filebeat.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,16 @@
json.keys_under_root: true
{{end}}
fields:
{{range $key, $value := .CustomFields}}
{{ $key }}: {{ $value }}
{{end}}
{{range $key, $value := .Tags}}
{{ $key }}: {{ $value }}
{{end}}
{{range $key, $value := $.container}}
{{ $key }}: {{ $value }}
{{end}}
{{range $key, $value := .CustomConfigs}}
{{ $key }}: {{ $value }}
{{end}}
tail_files: false
close_inactive: 2h
close_eof: false
close_removed: true
clean_removed: true
close_renamed: false

{{end}}
168 changes: 168 additions & 0 deletions controller/containerd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package controller

import (
"context"
"encoding/json"
"fmt"
"github.com/containerd/containerd"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci"
"github.com/zeromicro/go-zero/core/logc"
"io"
"regexp"
"strings"
"watchlog/pkg/ctx"
"watchlog/pkg/runtime"
)

var (
create = "containerd.events.ContainerCreate"
delete = "containerd.events.ContainerDelete"
)

type Containerd struct {
ctx *ctx.Context
}

func NewContainerInterface(ctx *ctx.Context) InterRuntime {
return &Containerd{
ctx: ctx,
}
}

func (c Containerd) ProcessContainers() error {
c.ctx.Lock()
defer c.ctx.Unlock()

containerCtx := namespaces.WithNamespace(c.ctx.Context, "k8s.io")
c.watchEvent(c.ctx, containerCtx)

containers, err := c.ctx.ContainerdCli.Containers(containerCtx)
if err != nil {
logc.Errorf(context.Background(), fmt.Sprintf("get containers failed, %s", err.Error()))
return err
}

for _, container := range containers {
if err := c.processContainer(containerCtx, container); err != nil {
logc.Errorf(context.Background(), "process container failed: %v", err)
}
}

return nil
}

func (c Containerd) processContainer(containerCtx context.Context, container containerd.Container) error {
meta, err := container.Info(containerCtx)
if err != nil {
return fmt.Errorf("get container meta info failed: %s", err.Error())
}

spec, err := container.Spec(containerCtx)
if err != nil {
return fmt.Errorf("get container spec failed: %s", err.Error())
}

return processCollectFile(c.ctx, spec.Process.Env, meta)
}

func (c Containerd) watchEvent(ctx *ctx.Context, containerCtx context.Context) {
msgs, errs := c.ctx.ContainerdCli.EventService().Subscribe(containerCtx, "")

go func() {
defer logc.Info(context.Background(), "finish to watch containerd event")
logc.Infof(context.Background(), "begin to watch containerd event")

for {
select {
case msg := <-msgs:
if err := c.processEvent(ctx, containerCtx, msg); err != nil {
logc.Errorf(context.Background(), "process event failed: %v", err)
}
case err := <-errs:
if err == io.EOF || err == io.ErrUnexpectedEOF {
return
}
logc.Errorf(context.Background(), "event subscription error: %v", err)
}
}
}()
}

func (c Containerd) processEvent(ctx *ctx.Context, containerCtx context.Context, msg *events.Envelope) error {
v := string(msg.Event.GetValue())
s := strings.TrimPrefix(v, "\n@")
containerId := removeSpecialChars(s)
containerId = strings.Split(containerId, "-")[0]

t := msg.Event.GetTypeUrl()
switch t {
case create:
if Exists(ctx, containerId) {
return nil
}

_, err := ctx.ContainerdCli.LoadContainer(containerCtx, containerId)
if err != nil {
if errdefs.IsNotFound(err) {
_, err = ctx.ContainerdCli.LoadContainer(containerCtx, containerId)
}

return err
}

meta, err := ctx.ContainerdCli.ContainerService().Get(containerCtx, containerId)
if err != nil {
return err
}

var spec oci.Spec
err = json.Unmarshal(meta.Spec.GetValue(), &spec)
if err != nil {
return err
}

err = processCollectFile(ctx, spec.Process.Env, meta)
if err != nil {
return err
}

return err

case delete:
logc.Infof(context.Background(), "Process container destroy event: %s", containerId)

err := DelContainerLogFile(ctx, containerId)
if err != nil {
logc.Errorf(context.Background(), fmt.Sprintf("Process container destroy event error: %s, %s", containerId, err.Error()))
}
}
return nil
}

func processCollectFile(c *ctx.Context, envs []string, meta containers.Container) error {
// ็ฌฆๅˆๆกไปถ็š„ Env
var logEnvs []string
for _, envVar := range envs {
// LogPrefix: aliyun_logs_tencent-prod-hermione=stdout ,envVar: aliyun_logs
if strings.HasPrefix(envVar, c.LogPrefix) {
logEnvs = append(logEnvs, envVar)
}
}

fields := CollectFields{
Id: meta.ID,
Env: logEnvs,
Labels: meta.Labels,
LogPath: fmt.Sprintf("%s_%s_*/%s/*.log", meta.Labels[runtime.KubernetesContainerNamespace], meta.Labels[runtime.KubernetesPodName], meta.Labels[runtime.KubernetesContainerName]),
}
return NewCollectFile(c, fields)
}

func removeSpecialChars(str string) string {
re := regexp.MustCompile(`[^a-zA-Z0-9]+`)
return re.ReplaceAllString(str, "-")
}
Loading

0 comments on commit 23f0b71

Please sign in to comment.