4、日志查询与分析:Kibana可视化查询、Lucene查询语法、聚合分析、告警规则配置
日志这东西,平时没人看,一出事全盯着它。我在金融科技这行干了快十年,见过太多因为日志查不明白,导致故障定位花了几个小时的案例。说白了,日志就是系统的黑匣子,但前提是你得会读。
这一章,我带你搞定Kibana的可视化查询、Lucene查询语法、聚合分析,还有告警规则配置。嗯,这些都是实战中每天都要用的东西。
4.1 Kibana可视化查询:从入门到熟练
Kibana的界面,第一次看可能觉得眼花。但别慌,核心就三个区域:左侧导航、顶部搜索栏、中间数据展示区。
我个人习惯,先看数据有没有进来。在Discover页面,选好索引模式(比如fintech-logs-*),然后设置时间范围。时间范围这个坑,我踩过——有一次查了半天没数据,结果是时间范围选错了,默认只显示最近15分钟。
Ctrl + / 可以快速调出快捷键列表。我常用的快捷键是 t 切换时间选择器。
Kibana的查询分两种:KQL(Kibana Query Language)和Lucene。默认是KQL,但我建议你切到Lucene,因为后面告警规则里用的也是Lucene语法。
怎么切?在搜索框左侧有个下拉菜单,点一下选「Lucene」就行。
4.2 Lucene查询语法:金融日志的精准定位
Lucene语法,说白了就是一套关键词匹配规则。我把它拆成三个层次:基础查询、字段查询、布尔组合。
4.2.1 基础查询
直接输入关键词,比如:
ERROR
timeout
transaction_failed
这会匹配所有包含这些词的日志。但问题来了——金融日志里字段很多,你搜ERROR可能把error_code、error_message都搜出来,不够精确。
4.2.2 字段查询
指定字段名,用冒号分隔:
level:ERROR
service_name:payment-gateway
transaction_id:TX20240315001
我在项目中遇到过,有个同事查支付超时,直接搜timeout,结果把connection_timeout和read_timeout混在一起了。后来我让他改成:
message:"connection timeout" AND level:WARN
这样精准多了。
4.2.3 布尔组合
用AND、OR、NOT组合条件:
level:ERROR AND (service_name:payment OR service_name:settlement)
level:ERROR NOT service_name:health-check
注意,AND、OR、NOT必须大写。这个坑我见过好几次,小写的话Lucene会当成普通关键词处理。
4.2.4 通配符与正则
有时候字段值记不全,可以用通配符:
transaction_id:TX*
message:timeout?
?匹配单个字符,*匹配任意多个。但性能上要注意——通配符查询很慢,尤其是前缀通配符(比如*timeout)。我建议尽量用前缀匹配,少用后缀。
4.3 聚合分析:从日志里挖出金矿
聚合分析,说白了就是分组统计。Kibana里聚合分三种:Metric、Bucket、Pipeline。
4.3.1 Metric聚合:算数
最常用的就是count、avg、sum、max、min。比如统计过去1小时的平均响应时间:
{
"aggs": {
"avg_response_time": {
"avg": {
"field": "response_time_ms"
}
}
}
}
在Kibana可视化里,选「Metric」类型,字段选response_time_ms,聚合方式选「Average」就行。
4.3.2 Bucket聚合:分组
Bucket聚合才是真正的分组利器。比如按服务名分组统计错误数:
{
"aggs": {
"by_service": {
"terms": {
"field": "service_name.keyword",
"size": 10
},
"aggs": {
"error_count": {
"filter": {
"term": { "level": "ERROR" }
}
}
}
}
}
}
这个查询会返回错误数最多的前10个服务。我在排查生产问题时,经常用这个快速定位「哪个服务在报错」。
常用的Bucket类型还有:
- Date Histogram:按时间分组,比如每分钟的请求数
- Range:按数值范围分组,比如响应时间0-100ms、100-200ms
- Filter:按过滤条件分组
4.3.3 Pipeline聚合:链式处理
Pipeline聚合,说白了就是对聚合结果再做一次聚合。比如计算「每分钟错误数的移动平均值」:
{
"aggs": {
"errors_per_minute": {
"date_histogram": {
"field": "@timestamp",
"interval": "1m"
},
"aggs": {
"error_count": {
"filter": { "term": { "level": "ERROR" } }
},
"moving_avg": {
"moving_avg": {
"buckets_path": "error_count._count",
"window": 5
}
}
}
}
}
}
这个在监控告警里很有用。直接看原始值可能波动大,但移动平均能看出趋势。我曾经用这个发现了一个缓慢增长的内存泄漏——原始值看不出来,但移动平均曲线一直在往上走。
4.4 告警规则配置:让系统替你盯着
日志分析的最后一步,就是告警。你不可能24小时盯着Kibana看,得让系统帮你盯着。
Kibana的告警在Stack Management → Alerts and Insights → Rules里配置。我常用的规则类型有两种:
4.4.1 阈值告警
最简单的,比如「过去5分钟ERROR日志超过10条就告警」:
| 配置项 | 值 |
|---|---|
| Rule type | Threshold |
| Index | fintech-logs-* |
| Query | level:ERROR |
| Time window | 5 minutes |
| Threshold | IS ABOVE 10 |
这里有个细节:Time window不要设太短。我见过有人设1分钟,结果网络抖动一下,告警刷屏了。建议至少5分钟。
4.4.2 异常检测告警
阈值告警有个问题——你不知道阈值设多少合适。设高了漏报,设低了误报。
这时候可以用异常检测。Kibana内置了机器学习功能,可以自动学习日志的「正常模式」,然后检测异常。比如支付接口的调用量,平时是1000 QPS,突然降到100 QPS,这就是异常。
4.4.3 告警动作
告警触发后,得有人知道。Kibana支持多种动作:
- Slack:发消息到运维群
- Email:发邮件
- Webhook:调用外部API,比如对接PagerDuty
- Index:把告警事件写回Elasticsearch,方便后续分析
我个人习惯,核心告警用Slack+Webhook双通道。Slack通知人,Webhook触发自动化处理脚本(比如自动重启服务)。
4.5 实战:一个完整的查询到告警流程
我拿一个真实场景举例。假设你负责支付网关,最近发现偶尔有交易超时。你想做三件事:
- 查清楚超时集中在哪些服务
- 看超时的时间分布规律
- 设置告警,下次超时增多时自动通知
第一步:查询
在Discover页面,用Lucene语法:
message:"timeout" AND service_name:payment*
时间范围选「Last 7 days」。
第二步:聚合分析
在Visualize Library里,新建一个「Vertical Bar」图表:
- Bucket: Date Histogram,按
@timestamp,间隔1小时 - Sub-Bucket: Terms,按
service_name.keyword,size 5 - Metric: Count
这样就能看到每个服务每小时超时次数的柱状图。
第三步:设置告警
新建一个Threshold规则:
- Query:
message:"timeout" AND service_name:payment-gateway - Time window: 5 minutes
- Threshold: IS ABOVE 5
- Action: Slack通知到#payment-alerts频道
搞定。以后只要支付网关5分钟内超时超过5次,你手机就会收到Slack通知。
- Lucene查询:字段名+冒号+值,布尔操作符大写
- 聚合分析:Metric算数,Bucket分组,Pipeline链式处理
- 告警配置:阈值设合理,时间窗口别太短,动作双通道
嗯,这一章的内容就这些。日志查询和分析,说白了就是「先查得准,再看得懂,最后自动盯」。你把这套流程跑通了,生产环境出问题,你至少能比别人快10分钟定位到根因。
公众号:蓝海资料掘金营,微信deep3321