PostgreSQL学徒

轻量、零配置、极速: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 console
Usage:  pgweasel [command]
Available Commands:  completion  Generate the autocompletion script for the specified shell  connections Show connections summary  errors      Shows WARNING and higher entries by default  grep        Show matching log entries only, e.g.: pgweasel grep 'Seq Scan.*tblX' mylogfile.log  help        Help about any command  locks       Only show locking related entries  peaks       Identify periods where most log entries are emitted, per severity level  slow        Show queries above user set threshold, e.g.: pgweasel slow 1s mylogfile.log  stats       Summary of log events  system      Show messages by Postgres internal processes
Flags:      --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 chat
Use "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 ms  0.90 quantile: 6927.41 ms  0.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