轻量、零配置、极速:pgweasel 带来的日志分析新体验
前言
PostgreSQL 的统计系统虽然强大,但覆盖面远远不够。想要真正理解系统发生了什么,“server log” 是唯一可靠的信息源。日志能为我们提供:
•完整的报错信息(ERROR / FATAL / PANIC)•慢查询详情(参数化、执行计划、auto_explain 输出)•未认证访问 / 暴力破解尝试•autovacuum / background worker 行为•锁等待信息•临时文件行为•后端崩溃、OOM•各类扩展的日志输出
日志是黑匣子,是故障排查的第一手材料。
日志处理方式
日志处理方式大体分成 4 大类:
•临时分析,各种小脚本和 shell 命令,比如 grep / egrep / ripgrep,awk 等,简单粗暴,高频使用,但是碰到一些苛刻要求时比较棘手•持续分析,将日志持续导入某种系统:Filebeat → ELK;Syslog → ELK 等•直接挂钩 Postgres,比如 Redislog•直接导入数据库中,结合 file_fdw
对于一些云厂商和 SaaS 的日志工具,比如 Datadog、AppDynamics、Pganalyze、Loggly、BetterStack 等,需要遵循厂商给的 log_line_prefix,分析功能不一定符合 Postgres 生态。
另外我们可能很熟悉 pgbadger,能够自动出 HTML 报表,也支持并行,但是功能较复杂,要上手需要一堆繁琐的配置。
pgBadger 是好工具,但有时“太重”,并不适合快速 CLI 分析。
pgweasel
对于 DBA 来说,笔者尤甚,尤其钟爱于 CLI,一款简洁高效的 CLI 可以大幅提升我们的效率,这不 pgweasel 来了,一款补足 pgBadger 的新工具。pgweasel 的优势在于
•零配置(不依赖 log_line_prefix)•命令 + 子命令结构(类似 kubectl)•Golang 编写,速度极快•自动多核心并行•自动检测日志文件位置•友好:支持相对时间、别名、智能选取日志•单一二进制,特别适合容器 / K8s
目标定位不是替代 pgBadger,而是给 DBA 提供一个在服务器上直接解析日志的简洁 CLI 工具,安装很简单,让我们小试牛刀一下:
[postgres@mypg pgweasel]$ ./pgweasel --helpA simplistic PostgreSQL log parser for the consoleUsage:pgweasel [command]Available Commands:completion Generate the autocompletion script for the specified shellconnections Show connections summaryerrors Shows WARNING and higher entries by defaultgrep Show matching log entries only, e.g.: pgweasel grep 'Seq Scan.*tblX' mylogfile.loghelp Help about any commandlocks Only show locking related entriespeaks Identify periods where most log entries are emitted, per severity levelslow Show queries above user set threshold, e.g.: pgweasel slow 1s mylogfile.logstats Summary of log eventssystem Show messages by Postgres internal processesFlags:--csv Specify that input file or stdin is actually CSV regardless of file extension-f, --filter stringArray Add extra line match conditions (regex)--from string Log entries from $time, e.g.: -1h-h, --help help for pgweasel-1, --oneline Compact multiline entries--to string Log entries up to $time-v, --verbose More chatUse "pgweasel [command] --help" for more information about a command.
比如我手动构造一个死锁,然后使用 ./pgweasel locks 即可检测到锁
2025-11-22 11:29:32.868 CST,"postgres","postgres",27418,"[local]",69212e09.6b1a,1,"UPDATE",2025-11-22 11:29:13 CST,9/2,121819,ERROR,40P01,"deadlock detected","Process 27418 waits for ShareLock on transaction 121818; blocked by process 27364.Process 27364 waits for ShareLock on transaction 121819; blocked by process 27418.Process 27418: update test_lock set id = 99 where id = 1;Process 27364: update test_lock set id = 100 where id = 2;","See server log for query details.",,,"while updating tuple (0,1) in relation ""test_lock""","update test_lock set id = 99 where id = 1;",,,"psql","client backend",,02025-11-22 11:29:32.868 CST,"postgres","postgres",27418,"[local]",69212e09.6b1a,1,"UPDATE",2025-11-22 11:29:13 CST,9/2,121819,ERROR,40P01,"deadlock detected","Process 27418 waits for ShareLock on transaction 121818; blocked by process 27364.Process 27364 waits for ShareLock on transaction 121819; blocked by process 27418.Process 27418: update test_lock set id = 99 where id = 1;Process 27364: update test_lock set id = 100 where id = 2;","See server log for query details.",,,"while updating tuple (0,1) in relation ""test_lock""","update test_lock set id = 99 where id = 1;",,,"psql","client backend",,0
查看系统状态
[postgres@mypg pgweasel]$ ./pgweasel stats /home/postgres/pgdata/log/Total events: 882 (0.03 events/minute)ERROR events: 512 (58.0%)LOG events: 336 (38.1%)FATAL events: 34 (3.9%)First event time: 2025-11-03 19:23:36.745 +0800 CSTLast event time: 2025-11-22 11:29:32.868 +0800 CSTTotal connections: 0 (0.00 connections/minute)Total disconnections: 0Query times histogram:0.50 quantile: 6927.41 ms0.90 quantile: 6927.41 ms0.99 quantile: 6927.41 msQuery durations records: 2 (0.00 slow queries/minute)Checkpoints timed: 30Checkpoints forced: 28Longest checkpoint duration: 810.0 sAutovacuums: 0Longest autovacuum duration: 0.0 s (on table "")Autoanalyzes: 0Longest autoanalyze duration: 0.0 s (on table "")
统计日志情况:
[postgres@mypg pgweasel]$ ./pgweasel peaks /home/postgres/pgdata/log/Most events per 10m:LOG : 62 (2025-11-17 16:00:00 +0800 CST, e.g.: 2025-11-17 16:02:38.952 CST)FATAL : 26 (2025-11-03 19:30:00 +0800 CST, e.g.: 2025-11-03 19:31:27.116 CST)ERROR : 442 (2025-11-19 16:30:00 +0800 CST, e.g.: 2025-11-19 16:34:06.828 CST)LOCKS : 2 (2025-11-22 11:20:00 +0800 CST, e.g.: 2025-11-22 11:25:27.802 CST)CONNECTS : 0 (0001-01-01 00:00:00 +0000 UTC, e.g: )
统计慢 SQL
[postgres@mypg pgweasel]$ ./pgweasel slow 500ms /home/postgres/pgdata/log/ 2025-11-22 11:29:32.868 CST,"postgres","postgres",27364,"[local]",69212dee.6ae4,1,"UPDATE",2025-11-22 11:28:46 CST,8/6,121818,LOG,00000,"duration: 6927.409 ms statement: update test_lock set id = 100 where id = 2;",,,,,,,,,"psql","client backend",,02025-11-22 11:29:32.868 CST,"postgres","postgres",27364,"[local]",69212dee.6ae4,1,"UPDATE",2025-11-22 11:28:46 CST,8/6,121818,LOG,00000,"duration: 6927.409 ms statement: update test_lock set id = 100 where id = 2;",,,,,,,,,"psql","client backend",,0
十分好用 ~ 👍🏻
小结
pgBadger 侧重分析,而 pgweasel 则适合于排查临时问题与自动化和脚本继承,它代表了一种新的趋势:不拼功能,而回归日志分析的核心:速度、可靠、简洁。
参考
Parsing Postgres Logs the non-pgBadger Way
https://github.com/kmoppel/pgweasel