mtail是谷歌开源的一款从应用日志提取 metrics 的工具,它会实时读取应用程序的日志,然后通过自己编写的脚本分析日志,最终生成时间序列的指标,项目地址是:https://github.com/google/mtail。
夜莺的Categraf对日志指标的收集也是采用的 mtail,不过做了一些优化,具体优化了什么我们慢慢道来。
现在,我们先从谷歌的mtail开始聊起,再慢慢聊到夜莺的 mtail 插件。
mtail 的安装
前面已经对mtail做了简短的介绍,其实那就是全部。
所以,我们直接从安装开始。
从https://github.com/google/mtail/releases下载需要的版本,操作如下:
mtail 参数详解
安装完mtail之后,如果对mtail的参数一无所知的话,也就不知道如何下手了,本小节就带大家来了解一下 mtail 有哪些参数。
我们可以通过mtail -h来查看mtail支持的参数列表,下面我对这些参数加一些中文注释,应该能够帮助你了解它们的意思了。
配置参数非常多,一般情况下我们使用的也就那几个,如下:
指定 mtail 脚本以及日志目录即可。
mtail 脚本语法
在https://github.com/google/mtail/blob/main/docs/Programming-Guide.md处对脚本语法有相应的介绍,这里做一个简单的介绍。
脚本标准的格式如下:
其中COND是一个条件表达式,可以是正则表达式,也可以是 boolean 类型的条件语句,如下:
COND表达式可用的运算符如下:
- 关系运算符:< , <= , > , >= , == , != , =~ , !~ , || , && , !
- 算术运算符:| , & , ^ , + , - , * , /, << , >> , **
另外,ACTION是具体的操作,如下表示从日志中匹配到 foo 字段,就给相应的指标 foo_total 的值就加 1:
对于指标,可以用= , += , ++ , –等运算符进行操作。
mtail的目的是从日志中提取信息并将其传递到监控系统。因此,必须导出指标变量并命名,命名可以使用counter、histogram、gauge指标类型,并且命名的变量必须在COND脚本之前。
- Counter(计数器):用于记录单调递增的值,例如请求数、错误数等。
- Gauge(仪表):用于记录可增可减的值,例如 CPU 使用率、内存使用量等。
- Histogram(直方图):用于记录数据的分布情况,例如请求延迟、响应大小等。
我们知道,拿 Prometheus 来说,除了上面的三种指标类型之外还有一个Summary的指标类型,为什么 mtail 没有呢?
因为在 Prometheus 中,summary 指标类型用于记录数据的分布情况,并计算出更多的统计信息,例如平均值、中位数、标准差等。但是,由于 mtail 是从日志文件中提取指标,而不是直接从应用程序中提取指标,因此没有必要使用 summary 指标类型。
高阶用法
变量定义
对于在一个脚本中需要重复使用的表达式,可以将其定义为一个变量,后续可以直接使用变量。
这是开发中常用的手段。
解析时间戳
mtail 会为每一个日志事件都赋予一个时间戳,如果日志里没有时间戳,mtail 会为本次日志事件赋予一个当前的日志时间。
除此之外,如果日志里的时间戳不是标准时间或者其他情况,可以使用 strptime 对其进行解析,如下:
条件判断
/pattern/ { action }是 mtail 程序中正常的条件控制流结构。
如果模式匹配,那么该块中的动作就会被执行。如果模式不匹配,则跳过该块。
else关键字允许程序在模式不匹配的情况下执行动作。
除此之外,还可以使用 otherwise 来处理没有匹配到的规则,如下:
这种语法类似于switch case default语法。
精准匹配
上面的/pattern/ { _action_ }形式隐含地匹配了当前的输入日志行。
如果想与另一个字符串变量匹配,可以使用=~操作符,或者用!~来否定匹配,像这样:
解析非数字类型的数字字段
有时候遇到的日志里输出的数字是字符串,而非数字,mtail 可以对其进行解析,如下:
解析带有额外字符的数字
一些日志包含除了包含数字,还包含分隔符,我们可以用 subst 函数删除它们:
过滤操作
如果你想过滤一些不必要的日志被mtail采集,你可以使用stop,如下:
重写操作
一些日志,如网络服务器日志,描述了一些常见的元素,其中有独特的标识符,如果不加处理,会导致大量的度量衡键,而没有有用的计数。要重写这些捕获组,可以使用 subst(),将模式作为第一个参数:
这里我们把$url中/后面的任何数字部分替换为字面字符串/:num,所以我们最终只计算 URL 路由的静态部分。
mtail 实操
说一千,道一万,不如真正来一遍。
当然,我这里也不会把上面说的都来一次。
为了方便阐述,我把本次操作的脚本都放到~/Desktop/mtail目录中。
单日志采集
多日志采集
如果多日志在同一个文件夹里,这时候采集的指标就可能混淆。
可以看到能正常收集指标,但是如果我们向 a.log 也写入 bar 日志,指标会增加吗?
可以看到指标依然会增加。其实我们的期望是prog1.mtail只收集a.log的日志指标,prog2.mtail只收集b.log的指标,不要相互影响。
如果要解决这个问题,就需要启动不同的mtail才行。换句话说有多少日志文件,如果想分开收集,则要启动多少个mtail,可以想想这是一个非常恐怖的事情。
鉴于此,Categraf 对 mtail 插件做了一些优化,优化后的 mtail 插件可以做到一个 Categraf 进程同时解析多个服务的日志,改造后的示例图如下:
Categraf 操作
在前面的夜莺监控系列中,对 Categraf 基本都有一个印象。默认情况下它的配置都在 conf 目录下,其中插件都在以 input 开头的文件夹里。
我们进入input.mtail文件夹,编辑mtail.toml并增加如下配置:
然后添加需要的目录以及脚本:
启动 categraf:
然后往a.log写入foo日志。
然后看到指标增加了:
再往b.log写入bar日志。
bar_count的指标也相应增加了。
那如果我们向a.log增加bar的日志,bar_count会增加么?我们来测试一下:
通过观察bar_count指标不会增加。
Categraf 就完美解决了不同日志指标错乱的问题。
除了正常的处理指标,如果想给不同的instance指定label,也是可以的,如下:
重启 Categraf 就可以看到指标多了一个 label。
其他的脚本语法和原生的 mtail 一致,这里不再追溯了。
总结
相比于谷歌的mtail,categraf对mtail做了一些优化,可以更好的处理多日志的问题。而且 categraf 本身集成了很多插件,都可以统一使用它实现。
另外,还是相同的问题,假设插件开启比较多,categraf 的具体性能如何以及会不会影响主机的整体性能,这还有待研究。