从应用日志中提取监控 metrics - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GoRuby
V2EX    开源软件

从应用日志中提取监控 metrics

  •  
  •   GoRuby 2022-11-05 16:38:16 +08:00 1519 次点击
    这是一个创建于 1120 天前的主题,其中的信息可能已经有所发展或是发生改变。

    mtail 是谷歌开源的一款从应用日志中提取 metrics 的工具。categraf 将 mtail 作为一个插件集成了进来,并且兼容 mtail 的语法,简化了部署。原本 mtail 和日志文件之间是一对一的关系,即一般都是一个 mtail 进程处理一类日志,但是对于很配的物理机,上面会部署很多不同的服务,每个服务进程都对应一个 mtail ,此时机器上会出现特别多的 mtail 进程,较难维护。把 mtail 集成到 categraf 之后,复用 categraf 的多实例插件机制,可以做到一台机器上只有一个 categraf 进程即可读取解析多个服务的日志。示例图如下:

    mtail

    下面来看如何使用这个插件从日志中提取 metrics 。

    插件简介

    插件启动

    编辑 mtail.toml 文件, 注意每个 instance 需要指定不同的 progs 参数(不同的 progs 文件或者目录)

    输入

    logs 参数指定要处理的日志源, 支持模糊匹配, 支持多个 log 文件。

    处理规则

    progs指定具体的规则文件目录(或文件)

    处理规则与语法

    处理流程

    for line in lines: for regex in regexes: if match: do something 

    语法

    exported variable pattern { action statements } def decorator { pattern and action statements } 

    定义指标名称

    前面也提过,指标仅支持 counter gauge histogram 三种类型。举一个

    counter lines /INFO.*/ { lines++ } 

    注意,定义的名称只支持 C 类型的命名方式(字母 /数字 /下划线),如果想使用"-" 要使用"as"导出别名。例如,

    counter lines_total as "line-count" 

    这样获取到的就是 line-count 这个指标名称了

    匹配与计算(pattern/action)

    PATTERN { ACTION } // examples: /foo/ { ACTION1 } variable > 0 { ACTION2 } /foo/ && variable > 0 { ACTION3 } 

    支持 RE2 正则匹配

    const PREFIX /^\w+\W+\d+ / PREFIX { ACTION1 } PREFIX + /foo/ { ACTION2 } 

    这样,ACTION1 是匹配以小写字符+大写字符+数字+空格的行,ACTION2 是匹配小写字符+大写字符+数字+空格+foo 开头的行。

    关系运算符

    • < 小于 <= 小于等于
    • > 大于 >= 大于等于
    • == 相等 != 不等
    • =~ 匹配(模糊) !~ 不匹配(模糊)
    • || 逻辑或 && 逻辑与 ! 逻辑非

    数学运算符

    • | 按位或
    • & 按位与
    • ^ 按位异或
    • + - * / 四则运算
    • << 按位左移
    • >> 按位右移
    • ** 指数运算
    • = 赋值
    • ++ 自增运算
    • -- 自减运算
    • += 加且赋值

    支持 else 与 otherwise

    /foo/ { ACTION1 } else { ACTION2 } 

    支持嵌套

    /foo/ { /foo1/ { ACTION1 } /foo2/ { ACTION2 } otherwise { ACTION3 } } 

    支持命名与非命名提取

    /(?P<operation>\S+) (\S+) \[\S+\] (\S+) \(\S*\) \S+ (?P<bytes>\d+)/ { bytes_total[$operation][$3] += $bytes } 

    增加常量 label

    # test.mtail # 定义常量 label env hidden text env # 给 label 赋值 这样定义是 global 范围; # 局部添加,则在对应的 condition 中添加 env="production" counter line_total by logfile,env /^(?P<date>\w+\s+\d+\s+\d+:\d+:\d+)/ { line_total[getfilename()][env]++ } 

    获取到的 metrics 中会添加上env=production的 label 如下:

    # metrics line_total{env="production",logfile="/path/to/xxxx.log",prog="test.mtail"} 4 1661165941788 

    如果要给 metrics 增加变量 label ,必须要使用命名提取。例如

    # 日志内容 192.168.0.1 GET /foo 192.168.0.2 GET /bar 192.168.0.1 POST /bar 
    # test.mtail counter my_http_requests_total by log_file, verb /^/ + /(?P<host>[0-9A-Za-z\.:-]+) / + /(?P<verb>[A-Z]+) / + /(?P<URI>\S+).*/ + /$/ { my_http_requests_total[getfilename()][$verb]++ } 
    # metrics my_http_requests_total{logfile="xxx.log",verb="GET",prog="test.mtail"} 4242 my_http_requests_total{logfile="xxx.log",verb="POST",prog="test.mtail"} 42 

    命名提取的变量可以在条件中使用

    /(?P<x>\d+)/ && $x > 1 { nonzero_positives++ } 

    时间处理

    不显示处理,则默认使用系统时间

    默认 emit_metric_timestamp="false"(注意是字符串)

    http_latency_bucket{prog="histo.mtail",le="1"} 0 http_latency_bucket{prog="histo.mtail",le="2"} 0 http_latency_bucket{prog="histo.mtail",le="4"} 0 http_latency_bucket{prog="histo.mtail",le="8"} 0 http_latency_bucket{prog="histo.mtail",le="+Inf"} 0 http_latency_sum{prog="histo.mtail"} 0 http_latency_count{prog="histo.mtail"} 0 

    参数 emit_metric_timestamp="true"(注意是字符串)

    http_latency_bucket{prog="histo.mtail",le="1"} 1 1661152917471 http_latency_bucket{prog="histo.mtail",le="2"} 2 1661152917471 http_latency_bucket{prog="histo.mtail",le="4"} 2 1661152917471 http_latency_bucket{prog="histo.mtail",le="8"} 2 1661152917471 http_latency_bucket{prog="histo.mtail",le="+Inf"} 2 1661152917471 http_latency_sum{prog="histo.mtail"} 3 1661152917471 http_latency_count{prog="histo.mtail"} 4 1661152917471 

    使用日志的时间

    Aug 22 15:28:32 GET /api/v1/pods latency=2s code=200 Aug 22 15:28:32 GET /api/v1/pods latency=1s code=200 Aug 22 15:28:32 GET /api/v1/pods latency=0s code=200 
    histogram http_latency buckets 1, 2, 4, 8 /^(?P<date>\w+\s+\d+\s+\d+:\d+:\d+)/ { strptime($date, "Jan 02 15:04:05") /latency=(?P<latency>\d+)/ { http_latency=$latency } } 

    日志提取的时间,一定要注意时区问题,有一个参数 override_timezone 可以控制时区选择,否则默认使用 UTC 转换。 比如我启动时指定 override_timezOne=Asia/Shanghai, 这个时候日志提取的时间会当做东八区时间 转换为 timestamp , 然后再从 timestamp 转换为各时区时间时 就没有问题了,如图:

    timestamp

    如果不带 override_timezOne=Asia/Shanghai, 则默认将Aug 22 15:34:32 当做 UTC 时间,转换为 timestamp 。 这样再转换为本地时间时,会多了 8 个小时, 如图:

    timestamp

    其他日志处理方案

    本文介绍的日志处理方案相对简单,就像一把瑞士军刀,小巧锋利,如果你已经把日志都收集到 ElasticSearch 中了,想对 ElasticSearch 中的日志做告警,这就需要另一个方案了,请参考《ElasticSearch 日志告警

    关于作者

    本文作者孔飞,快猫星云工程师,文章内容是快猫技术团队共同沉淀的结晶。我们会持续输出监控、稳定性保障相关的技术文章,文章可转载,转载请注明出处,尊重技术人员的成果。

    本文转载自:https://flashcat.cloud/blog/log-monitoring-mtail/

    1 条回复    2022-11-05 21:11:18 +08:00
    byte404
       1
    byte404  
       2022-11-05 21:11:18 +08:00 via Android
    我的 es 中存的日志就是写了个 exporter 收集关键标签来告警。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2502 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 04:33 PVG 12:33 LAX 20:33 JFK 23:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86