Telegraf配置inputs.tail.multiline解析MySQL多行慢日志对接Prometheus
Telegraf 解析MySQL慢日志配置修正方案
当前配置存在两处关键问题,导致无法完整解析慢日志条目:
- 多行日志合并规则逻辑颠倒,无法将同一条慢日志的5行内容拼接为单条待解析字符串
- grok 提取规则仅匹配慢日志第一行内容,未覆盖完整字段范围
Telegraf 的tail插件默认是逐行读取日志文件的,不经过multiline合并的话,只会读到第一行# Time: ...的内容就直接传给grok解析,后续4行内容会被判定为独立的无效日志行,完全无法进入提取流程。
1. 修正多行合并逻辑
MySQL慢日志的条目边界固定清晰:每条慢日志的起始行必然以# Time:开头,其余4行附属内容都不会使用该标记开头。
合并规则需要调整为:只有当读取到的行不匹配# Time:起始标记时,自动将该行追加到上一条已读取的日志块中;直到读取到下一条以# Time:开头的新行时,才将之前拼接完成的完整日志块传递给grok解析。
对应multiline模块的配置参数要求:
- 匹配规则
pattern设置为条目前缀标记:^# Time: - 合并方向
match_which_line设置为"next" - 开启反向匹配 match_negative = true:表示不匹配上述pattern的行,全部和前一行合并
- 删除原本无效的全匹配规则
^%{GREEDYDATA:logmessage},该规则会让所有行都被判定为独立新条目,永远不会触发合并动作 - 可选配置合并超时时间
multiline_timeout = "5s":避免日志文件写入异常时,日志块迟迟不被传递,5秒的默认阈值完全满足慢日志写入节奏
2. 修正grok提取规则
等multiline模块将5行内容拼接为连续字符串(行与行之间自动保留换行连接符)后,就可以对完整日志块做全字段提取。之前仅匹配第一行的grok规则需要替换为完整覆盖5行结构的提取逻辑,同时为每个核心字段加上命名与类型声明,方便后续直接作为Prometheus指标使用。
可直接使用的grok规则示例:
"^# Time: %{TIMESTAMP_ISO8601:slow_log_time}\n" + "# User@Host: %{DATA:db_user}\\[%{DATA:db_schema}\\] @ %{HOSTNAME:client_host} \\[%{IPORHOST:client_ip}\\]\\s*Id:\\s*%{INT:connection_id}\n" + "# Query_time: %{BASE16FLOAT:query_time:float}\\s*Lock_time: %{BASE16FLOAT:lock_time:float}\\s*Rows_sent: %{INT:rows_sent:int}\\s*Rows_examined: %{INT:rows_examined:int}\n" + "SET timestamp=%{BASE10NUM:query_start_ts};\n" + "%{GREEDYDATA:query_statement}"
3. 完整可运行的配置示例
[[inputs.tail]] files = ["/var/log/mysql/mysql-slow.log"] from_beginning = true watch_method = "inotify" max_undelivered_lines = 1000 character_encoding = "utf-8" name_override = "mysql_slow_log" data_format = "grok" grok_patterns = [ "^# Time: %{TIMESTAMP_ISO8601:slow_log_time}\n" + "# User@Host: %{DATA:db_user}\\[%{DATA:db_schema}\\] @ %{HOSTNAME:client_host} \\[%{IPORHOST:client_ip}\\]\\s*Id:\\s*%{INT:connection_id}\n" + "# Query_time: %{BASE16FLOAT:query_time:float}\\s*Lock_time: %{BASE16FLOAT:lock_time:float}\\s*Rows_sent: %{INT:rows_sent:int}\\s*Rows_examined: %{INT:rows_examined:int}\n" + "SET timestamp=%{BASE10NUM:query_start_ts};\n" + "%{GREEDYDATA:query_statement}" ] [inputs.tail.multiline] pattern = "^# Time:" match_which_line = "next" match_negative = true multiline_timeout = "5s"
配置生效后的解析效果
调整完成后,单条慢日志会被完整解析为包含以下字段的指标:
- 日志生成时间
slow_log_time - 数据库用户名、访问来源主机、连接ID等维度标签
- 查询耗时
query_time、锁等待耗时lock_time、返回行数、扫描行数等核心监控指标 - 实际执行的SQL语句
query_statement
内容的提问来源于stack exchange,提问作者Alex Konkin
相关产品推荐
相关产品推荐

