promtail+loki+grafana搭建日志上报及告警服务

使用 promtail+loki+grafana/Nightingale夜莺搭建日志上报和统计分析系统,当然,这些组件也适用于其他日志上报。

前文

内容来自一次失败的尝试,本文记录了其中有用的部分。

某游戏服务端没有信息查询接口,只能从打印的日志看玩家加入、退出及状态信息。为了做一个状态通知机器人,遂各处寻找日志上报分析的解决方案。

尝试过程中,日志上报和统计分析已经打通,但我的需求是把新日志当作即时消息推送至处理模块进行语义分析及告警,而使用的成品软件侧重于某时间段内的总体分析及告警,因此不能开箱即用,需要二次开发。

问题根源是 LogQL 侧重于聚合查询(eg:X 分钟内出现次数/比例/分组),并不具备完整的 SQL 查询能力。

本人还有其他事情要忙,遂二次开发暂时搁置。

不过,搭建日志文件上报分析系统的过程还是有用的,遂写在这里,期望能帮助到其他人。

软件角色

这次搭建涉及三(四)个软件:

  1. promtail:客户机上的日志收集及上报工具
  2. Loki:日志聚合系统,接收 promtail 日志上报并聚合存储,提供 LogQL 查询接口
  3. Grafana/Nightingale夜莺:统一观测平台,具备日志分析/告警等多种功能

数据流向

本文以读取 Docker 容器日志文件为例。

提醒:不建议直接读取 Docker Container 日志文件,本文仅为读取文件 log 示例;建议通过 Docker API 或logspoutilogtail等工具进行 Docker Container 日志的读取。

读取 Docker 日志文件仅为 loki 读文件 log 的示例,不推荐这种做法;
对于文件日志,请合理配置 log rotation(Docker 请合理设置 log max-size 与 max-file);
log rotation 对 loki 的影响见:
https://grafana.com/docs/loki/latest/send-data/promtail/logrotation/

数据流向如下:

搭建的几个点

能搜到此文的各位都不是小白,因此我就不班门弄斧讲什么从零到一部署了,只说说我所修改的内容。

再次提醒:不建议直接读取 Docker Container 日志文件,本文仅为读取文件 log 示例;建议通过 Docker API 或logspout``ilogtail等工具进行 Docker Container 日志的读取。

Docker 日志添加直观的 tag

默认情况下,日志文件中没有容器名等信息,日式收集后靠文件名或 ID 区分不同容器,且日志文件名是全长的容器 ID。

为了使结果方便检索,且更加直观,可以让 Docker 在日志中追加一些 tag 参数:

文档见:https://docs.docker.com/config/containers/logging/log_tags/

  1. Docker run 容器时(对本容器有效):
    docker run --log-driver json-file --log-opt tag="{{.Name}}" XXX
    
  2. 追加到 Docker daemon.json(对在此之后 run 的容器有效):
    "log-opts": {
        // …… 前略
        "tag": "{{.ImageName}}"
    }
    

反映到日志中,就是:

{
    "log":"xxxx",
    "stream":"stdout ",
    "attrs":{
        "tag":"test-container-1"
    },
    "time":"2024-01-28T13:31:05.824003795Z"
}

LOKI 添加 Label(s)

文档:https://grafana.com/docs/loki/latest/get-started/labels/

简单看了两眼,也没深入研究,直接照猫画虎拷贝:

pipeline_stages:
  - json:
      expressions:
        output: log
        stream: stream
        attrs:
  - json:
      expressions:
        tag:
      source: attrs
  - regex:
      expression: (?P<container_name>(?:[^|]*[^|]))
      source: tag
  - timestamp:
      format: RFC3339Nano
      source: time
  - labels:
      stream:
      container_name:
  - output:
      source: output

这样,当你在 grafana 或夜莺中使用 LogQL 查询时,即可使用定义的 label 作为关键字:

{container_name="test-container-1"}

关于告警

进行某些数据分析后,执行某些脚本,完成告警。

不管是夜莺还是 Grafana,都支持图形化界面配置及用户自定义告警模板。结合 LogSQL,做一个X 分钟内 404 状态码超过阈值的告警很简单。

最后

各大公司都有自己内部的 Metrics 系统,其功能丰富度比开源的这些强不少(虽然大部分也是基于开源的修改)。

术业有专攻,如果想在功能丰富度上追齐某些商业公司内部的 Metrics 系统,那工作量不是一两个外行随便看两天就能搞定的;如果想在性能上追齐,那更不可能了。

梓喵出没博客(azimiao.com)版权所有,转载请注明链接:https://www.azimiao.com/10264.html
欢迎加入梓喵出没博客交流群:313732000

我来吐槽

*

*