使用 grok_exporter 从日志中提取指标(日志监控)

秦晓辉@快猫星云 2022年12月18日

这篇文章翻译自 easyaslinux,讲解如何使用 grok_exporter 从非结构化日志数据中提取结构化的 Prometheus 指标,原文内容稍显陈旧,本文根据新版本 grok_exporter 做了调整。

use-grok-exporter-to-create-prometheus-metrics-from-unstructured-logs

在 ELK 生态中,Grok 是非常流行的。感谢 Fabian Stäber,基于 Grok 技术开发了 grok_exporter。就是下面这位仁兄,大家认识一下:

1. 安装 grok_exporter

首先要下载 grok_exporter 的 zip 包。

  1. github releases 页面可以找到作者编译好的发布包,选择最新版本就好(当前最新版本是:v1.0.0.RC5)
  2. 下载与你的操作系统匹配的发布包,我的是 64 位 Linux,所以我的下载命令是:
wget https://github.com/fstab/grok_exporter/releases/download/v1.0.0.RC5/grok_exporter-1.0.0.RC5.linux-amd64.zip
  1. 使用 unzip 解包,进入新解出的目录
  2. 然后运行下面的命令启动 grok_exporter
[root@fc-demo-02 grok_exporter-1.0.0.RC5.linux-amd64]# ./grok_exporter -config example/config.yml.bak
Starting server on http://fc-demo-02:9144/metrics

提示我们访问上面的地址,把 fc-demo-02 换成你的机器 IP 即可,不用非得按照他的提示访问机器名,机器名如果没有加入 DNS 反而访问不了。

2. 处理一些自定义日志

下面我们使用 Grok exporter 处理一些样例日志,下面是我做的一些随机日志。请保存为 login.log,放到刚才解压缩的 grok_exporter 的 example 目录。

30.07.2016 04:33:03 10.3.4.1 user=Nijil message="logged in"
30.07.2016 06:47:03 10.3.4.2 user=Alex message="logged failed"
30.07.2016 06:55:03 10.3.4.2 user=Alex message="logged in"
30.07.2016 07:03:03 10.3.4.3 user=Alan message="logged in"
30.07.2016 07:37:03 10.3.4.1 user=Nijil message="logged out"
30.07.2016 08:47:03 10.3.4.2 user=Alex message="logged out"
30.07.2016 14:34:03 10.3.4.3 user=Alan message="logged out"

如你所想,这些日志展示了哪些人登录登出过机器。现在我就要基于这些内容产生 Prometheus metrics。启动命令中传入了 config.yml 配置文件,我们要把 config.yml 调整为以下内容:

global:
  config_version: 3
input:
  type: file
  path: ./example/login.log
  readall: true # Read from the beginning of the file? False means we start at the end of the file and read only new lines.
imports:
- type: grok_patterns
  dir: ./patterns
metrics:
- type: counter
  name: user_activity
  help: Counter metric example with labels.
  match: '%{DATE} %{TIME} %{HOSTNAME:instance} user=%{USER:user} message="%{GREEDYDATA:data}"'
  labels:
    user: '{{.user}}'
    logfile: '{{base .logfile}}'
server:
  protocol: http
  port: 9144

上面这个配置文件是基于以下配置框架做的修改:

global:
    # 配置版本,当前最新版本是 3
input:
    # 如何读取日志内容,比如是从文件读取呢还是从标准输入读取
imports:
    # 导入一些 pattern,也就是预定义的正则片段
metrics:
    # 定义一些 mapping 规则,从 Grok 字段映射为 Prometheus metrics
server:
    # 启动 HTTP Server 的相关配置

3. 调整 grok_exporter 的核心配置

上面的配置中最有意思的是 metrics 部分,这部分配置描述了日志内容怎么映射成 Prometheus metrics.

metrics:
- type: counter
  name: user_activity
  help: Counter metric example with labels.
  match: '%{DATE} %{TIME} %{HOSTNAME:instance} user=%{USER:user} message="%{GREEDYDATA:data}"'
  labels:
    user: '{{.user}}'
    logfile: '{{base .logfile}}'

Grok pattern 的语法是 %{SYNTAX:SEMANTIC} ,其中 SYNTAX 是 pattern 的 name,上面用到的 DATE TIME HOSTNAME USER 等实际都是预定义的 pattern,也就是一些预定义的正则片段。SEMANTIC 则是字段名,对于匹配到的内容,会赋值给 SEMANTIC 指定的字段。

%{HOSTNAME:instance} 为例,HOSTNAME 是 grok pattern,也就是一段正则,这段正则用于匹配日志中的机器名部分,对于匹配到的机器名会被存入 instance 变量中,当然,这里你也可以不叫 instance,叫个别的名字也完全 OK,后面你就可以用这些变量了,比如在 labels 中使用。

想知道 HOSTNAME、DATE、TIME 等这些 pattern 具体是对应什么正则么?看到解压缩之后的 patterns 目录了么,使用下面的命令搜一下就知道了(以搜索 HOSTNAME 为例):

# grep -P "^HOSTNAME" -r patterns
patterns/grok-patterns:HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)

你可以使用 labels 配置来指定要生成的指标带有哪些标签。从上面的例子可以看出,我们指定了两个标签,一个是 user,从日志中提取的,一个是 logfile,是使用了内置的日志文件名,注意在引用字段名的时候要使用 SEMANTIC 部分指定的字符串。这个指标通过 type 字段指定为 counter 类型,也就是统计各个 user 登录登出的总次数,当然,你可以使用 gauge、histogram 等其他类型,更多信息请参考GrokExporter官网

下面我们来测试一下,启动 grok_exporter,然后请求其 /metrics 接口:

[root@fc-demo-02 grok_exporter-1.0.0.RC5.linux-amd64]# nohup ./grok_exporter -config example/config.yml &> stdout.log &
[1] 15817

[root@fc-demo-02 grok_exporter-1.0.0.RC5.linux-amd64]# ps aux|grep grok
root     15817  0.0  0.0 895116  7948 pts/58   Sl   18:09   0:00 ./grok_exporter -config example/config.yml
root     15838  0.0  0.0 112812   980 pts/58   S+   18:09   0:00 grep --color=auto grok

[root@fc-demo-02 grok_exporter-1.0.0.RC5.linux-amd64]# curl -s 10.100.0.7:9144/metrics | grep user_activity
grok_exporter_line_processing_errors_total{metric="user_activity"} 0
grok_exporter_lines_matching_total{metric="user_activity"} 7
grok_exporter_lines_processing_time_microseconds_total{metric="user_activity"} 177
# HELP user_activity Counter metric example with labels.
# TYPE user_activity counter
user_activity{logfile="login.log",user="Alan"} 2
user_activity{logfile="login.log",user="Alex"} 3
user_activity{logfile="login.log",user="Nijil"} 2

至于如何抓取这些监控数据进入 Prometheus,如何使用 Grafana 绘图,已经超出了本讲的内容,在 Prometheus 里配置抓取规则就好了,相信难不到你。

关于译者

本文译者秦晓辉Flashcat合伙人,文章内容是Flashcat技术团队共同沉淀的结晶,作者做了编辑整理,我们会持续输出监控、稳定性保障相关的技术文章,文章可转载,转载请注明出处,尊重技术人员的成果。

开源版
Flashcat
Flashduty