关于日志收集,鄙人最早接触到的是 ELK 那一套(Elasticsearch、Logstash 和 Kibana),最近我青训营的项目也是差不多的架构,但是这一套下来资源占用也太可怕了(特别是 Elasticsearch ,太重了)


go-zero 官方也说了,这一套不建议在小规模的服务上使用,而我一般的实际项目也没多大规模,根本用不上这么重的解决方案,所以我需要找一套更轻量的解决方案
翻了一圈,感觉推荐 Grafana + Loki 的不少
然后我就跑去 Loki官方文档了

这是官方文档中的快速上手的架构图,为了让你感受它的可扩展性,就把内部的读写部分拆出来运行,其实不用这么复杂,直接一个单体也可以
折腾了一圈,大概是这么个逻辑:首先是要有一个 Client(例如图中的 Promtail )去拉取运行日志喂给 Loki ,然后 Loki 去读写 Storage(例如图中的 Minio ),那日志要怎么方便地查看呢?用 Grafana ,这东西界面做的真的很好看
为了让你快速理解与上手,我简化了一下官方 Demo,docker-compose 中只包含四个服务:
-
产生日志的程序:和官方一样使用了 flog 来不停地向标准输出中放入假日志
-
Loki:用于打包日志、打标签等
-
Client:用于拉取日志交给 Loki,Loki 支持多种客户端,你可以在 Grafana Loki clients 中查看支持的所有客户端
我知道有一个 Docker Driver ,但是这东西要给 Docker 装插件,感觉有点麻烦,还是和官方例子一样使用了 Promtail
-
Storage:用于保存日志,你可以在 Storage 中查看所有支持的存储介质,甚至存储为本地文件都行
这里和官方例子一样使用了兼容亚马逊 S3协议的 minio 作为存储介质
-
Grafana:用于提供一个好看的可视化界面
先新建一个文件夹,进去创建三个文件:
1 2 3 4
| . |-- docker-compose.yaml |-- loki-config.yaml `-- promtail-config.yaml
|
docker-compose.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| version: "3"
networks: loki:
services: loki: image: grafana/loki:2.7.1 container_name: loki ports: - 3100:3100 volumes: - ./loki-config.yaml:/etc/loki/local-config.yaml command: -config.file=/etc/loki/local-config.yaml depends_on: - minio networks: - loki
promtail: image: grafana/promtail:2.7.1 container_name: promtail volumes: - ./promtail-config.yaml:/etc/promtail/promtail-config.yaml - /var/run/docker.sock:/var/run/docker.sock command: -config.file=/etc/promtail/promtail-config.yaml networks: - loki
grafana: image: grafana/grafana:latest container_name: grafana environment: - GF_PATHS_PROVISIONING=/etc/grafana/provisioning - GF_AUTH_ANONYMOUS_ENABLED=true - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin ports: - 3000:3000 command: -config /etc/grafana/grafana.ini networks: - loki
minio: image: minio/minio container_name: minio entrypoint: - sh - -euc - | mkdir -p /data/loki-data && \ mkdir -p /data/loki-ruler && \ minio server /data environment: - MINIO_ACCESS_KEY=loki - MINIO_SECRET_KEY=supersecret - MINIO_PROMETHEUS_AUTH_TYPE=public - MINIO_UPDATE=off ports: - 9000 volumes: - ./.data/minio:/data networks: - loki
flog: image: mingrammer/flog container_name: flog command: -f json -d 1s -l networks: - loki
|
loki-config.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| --- auth_enabled: false server: http_listen_port: 3100 memberlist: join_members: - loki:7946 schema_config: configs: - from: 2021-08-01 store: boltdb-shipper object_store: s3 schema: v11 index: prefix: index_ period: 24h common: path_prefix: /loki replication_factor: 1 storage: s3: endpoint: http://minio:9000 insecure: true bucketnames: loki-data access_key_id: loki secret_access_key: supersecret s3forcepathstyle: true ring: kvstore: store: memberlist ruler: storage: s3: bucketnames: loki-ruler
|
promtail-config.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| server: http_listen_port: 9080 grpc_listen_port: 0
positions: filename: /tmp/positions.yaml
clients: - url: http://loki:3100/loki/api/v1/push tenant_id: tenant1
scrape_configs: - job_name: flog_scrape docker_sd_configs: - host: unix:///var/run/docker.sock refresh_interval: 5s relabel_configs: - source_labels: ['__meta_docker_container_name'] regex: '/(.*)' target_label: 'container'
|
准备好了之后,运行 docker-compose 文件
然后来到 127.0.0.1:3000 进入Grafana

点击左下角添加数据源,选择 Loki

URL填写为 http://loki:3100

再来到 Explore,选择要看的容器为 flog

它居然会自动提示你添加 JSON 解析

然后你就可以根据字段添加检索条件了,比方说状态码限定为 200

我只能说简直不要太舒服了
接下来你就可以把这一套放在你的项目里面了,你可以监听某个容器,或者监听某个日志文件,又或者监听某个卡夫卡队列,都可以,随便你折腾了
(PS:你的容器不能启用 tty
https://github.com/grafana/loki/issues/5950#issuecomment-1223979118 )

最后来看看资源占用,内存 200MB 左右,相对来说轻量了不少