如何通过Journalctl -O short --precise在Linux中查看精确到微秒的业务逻辑耗时记录?
- 内容介绍
- 文章标签
- 相关推荐
本文共计845个文字,预计阅读时间需要4分钟。
bashjournalctl -o short-precise本身体现不支持显示微秒级时间戳,只能精确到微秒(µs)单位,但实际上输出默认只显示到毫秒(ms)。格式是固定的、不可编程扩展的。Linux systemd journal 的日志时间戳底层实际上支持微秒精度(`CLOCK_REALTIME` + `struct timespec`),但 `short-precise` 输出格式仅保留毫秒部分(保留三位小数),截断了后续微秒数字。
要真正获取微秒级精度的业务耗时日志,需从日志生成端 + 查询端协同实现:
✅ 正确做法:在业务代码中主动打点并写入微秒级时间戳
journalctl 只是读取日志,不负责计时。真正的耗时分析必须由业务逻辑自己完成:
- 在关键路径开始前,调用
clock_gettime(CLOCK_MONOTONIC, &ts)获取纳秒级起始时间; - 执行业务逻辑;
- 结束后再次获取时间,计算差值(单位:纳秒或微秒);
- 将耗时(如
duration_us=12487)和上下文(trace_id、func、status 等)作为结构化字段,通过sd_journal_print()或printf写入 journal。
#include <sys/time.h> #include <systemd/sd-journal.h> struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); // ... your business logic ... clock_gettime(CLOCK_MONOTONIC, &end); long us = (end.tv_sec - start.tv_sec) * 1000000L + (end.tv_nsec - start.tv_nsec) / 1000L; sd_journal_print(LOG_INFO, "MESSAGE=HTTP request processed; " "duration_us=%ld; " "path=/api/order; " "status=200", us);
✅ 查看时按微秒字段筛选与排序(非时间戳,而是业务耗时字段)
journalctl 不支持按数值字段排序,但可通过组合命令提取分析:
# 提取所有含 duration_us 的日志,并按耗时降序排列(单位:微秒) journalctl -o json | jq -r 'select(.duration_us) | "\(.duration_us | tonumber) \(.MESSAGE)"' | sort -nr | head -20 # 或导出为 CSV 分析 journalctl -o json | jq -r 'select(.duration_us) | [.timestamp, .duration_us, .path, .status] | @csv' > trace.csv
❌ journalctl -o short-precise 的真实表现(验证即可)
运行以下命令观察:
echo "test" | systemd-cat -t microtest journalctl -n1 -o short-precise -t microtest
输出类似:
May 22 14:30:45.123 hostname microtest[12345]: test
→ .123 是毫秒,不是微秒;你无法从中还原 123456。
而用 -o json 查看同一日志:
journalctl -n1 -o json -t microtest | jq -r .__REALTIME_TIMESTAMP # 输出:1716388245123456 ← 单位是微秒(自 UNIX epoch 起)
✅ 这个数字 1716388245123456 就是真实微秒级时间戳(最后 6 位 123456 = 微秒部分)。
✅ 快速提取高精度时间戳(供脚本处理)
# 获取最近一条日志的完整微秒时间戳(整数) journalctl -n1 -o json | jq -r '.__REALTIME_TIMESTAMP' # 转为可读格式(含微秒) journalctl -n1 -o json | jq -r '.__REALTIME_TIMESTAMP | (. / 1000000 | floor | strftime("%Y-%m-%d %H:%M:%S")) + "." + (.%1000000 | tostring | rpad(6;"0"))' # → 2024-05-22 14:30:45.123456
不复杂但容易忽略:short-precise 是给人眼快速扫读用的简化格式,不是精度工具。真要分析微秒级耗时,得靠业务埋点 + 结构化日志 + JSON/字段提取。
本文共计845个文字,预计阅读时间需要4分钟。
bashjournalctl -o short-precise本身体现不支持显示微秒级时间戳,只能精确到微秒(µs)单位,但实际上输出默认只显示到毫秒(ms)。格式是固定的、不可编程扩展的。Linux systemd journal 的日志时间戳底层实际上支持微秒精度(`CLOCK_REALTIME` + `struct timespec`),但 `short-precise` 输出格式仅保留毫秒部分(保留三位小数),截断了后续微秒数字。
要真正获取微秒级精度的业务耗时日志,需从日志生成端 + 查询端协同实现:
✅ 正确做法:在业务代码中主动打点并写入微秒级时间戳
journalctl 只是读取日志,不负责计时。真正的耗时分析必须由业务逻辑自己完成:
- 在关键路径开始前,调用
clock_gettime(CLOCK_MONOTONIC, &ts)获取纳秒级起始时间; - 执行业务逻辑;
- 结束后再次获取时间,计算差值(单位:纳秒或微秒);
- 将耗时(如
duration_us=12487)和上下文(trace_id、func、status 等)作为结构化字段,通过sd_journal_print()或printf写入 journal。
#include <sys/time.h> #include <systemd/sd-journal.h> struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); // ... your business logic ... clock_gettime(CLOCK_MONOTONIC, &end); long us = (end.tv_sec - start.tv_sec) * 1000000L + (end.tv_nsec - start.tv_nsec) / 1000L; sd_journal_print(LOG_INFO, "MESSAGE=HTTP request processed; " "duration_us=%ld; " "path=/api/order; " "status=200", us);
✅ 查看时按微秒字段筛选与排序(非时间戳,而是业务耗时字段)
journalctl 不支持按数值字段排序,但可通过组合命令提取分析:
# 提取所有含 duration_us 的日志,并按耗时降序排列(单位:微秒) journalctl -o json | jq -r 'select(.duration_us) | "\(.duration_us | tonumber) \(.MESSAGE)"' | sort -nr | head -20 # 或导出为 CSV 分析 journalctl -o json | jq -r 'select(.duration_us) | [.timestamp, .duration_us, .path, .status] | @csv' > trace.csv
❌ journalctl -o short-precise 的真实表现(验证即可)
运行以下命令观察:
echo "test" | systemd-cat -t microtest journalctl -n1 -o short-precise -t microtest
输出类似:
May 22 14:30:45.123 hostname microtest[12345]: test
→ .123 是毫秒,不是微秒;你无法从中还原 123456。
而用 -o json 查看同一日志:
journalctl -n1 -o json -t microtest | jq -r .__REALTIME_TIMESTAMP # 输出:1716388245123456 ← 单位是微秒(自 UNIX epoch 起)
✅ 这个数字 1716388245123456 就是真实微秒级时间戳(最后 6 位 123456 = 微秒部分)。
✅ 快速提取高精度时间戳(供脚本处理)
# 获取最近一条日志的完整微秒时间戳(整数) journalctl -n1 -o json | jq -r '.__REALTIME_TIMESTAMP' # 转为可读格式(含微秒) journalctl -n1 -o json | jq -r '.__REALTIME_TIMESTAMP | (. / 1000000 | floor | strftime("%Y-%m-%d %H:%M:%S")) + "." + (.%1000000 | tostring | rpad(6;"0"))' # → 2024-05-22 14:30:45.123456
不复杂但容易忽略:short-precise 是给人眼快速扫读用的简化格式,不是精度工具。真要分析微秒级耗时,得靠业务埋点 + 结构化日志 + JSON/字段提取。

