linux运维脚本通过json格式结构化记录错误,统一写入/var/log/scripts/errors.jsonl,字段含timestamp、level、source、code、message等,配合trap自动捕获并联动logrotate与prometheus实现可统计告警。

Linux运维脚本实现错误信息的结构化存储,核心是把“发生了什么错”变成“可提取、可统计、可告警”的数据,而不是堆在日志里等人翻。关键不在于记录多全,而在于字段清晰、格式统一、路径可控。
用标准字段定义错误结构
每次出错时,脚本应主动输出固定字段,推荐 JSON 格式(易解析、兼容性强):
-
timestamp:用
$(date -u +%Y-%m-%dT%H:%M:%SZ),确保时区一致 -
level:限定为
ERROR、WARN、FATAL,避免自由填写 -
source:脚本名或模块名,如
"backup-mysql"或"disk-check" -
code:自定义错误码,如
ERR_CONN_REFUSED、ERR_DISK_FULL,比 exit code 更具业务含义 - message:一句话说明原因,不含换行和控制字符
-
context(可选):附加键值对,如
{"device":"/dev/sda1","used_pct":"98"}
写入位置要统一且可采集
不要分散写进多个文件或 stdout/stderr,而是集中落盘并暴露给监控链路:
- 写入专用目录,如
/var/log/scripts/errors.jsonl(每行一个 JSON 对象,即 JSON Lines 格式) - 权限设为
644,属主为root:syslog,确保 logrotate 和 prometheus_exporter 可读 - 配合
logrotate按大小轮转(如 10MB),保留最近 7 天,防止撑爆磁盘 - 若已接入 Prometheus,可用
prometheus-json-exporter直接将 JSONL 转为指标,例如把code统计为script_error_total{code="ERR_DISK_FULL"}
错误发生时自动触发结构化记录
别靠人工加 echo,用 trap + 函数封装成通用逻辑:
- 在脚本开头定义
log_error()函数,内部组装 JSON 并echo >> /var/log/scripts/errors.jsonl - 用
trap 'log_error "$LINENO" "$?"' ERR捕获所有未处理错误 - 对关键检查点(如备份后校验失败、curl 返回非200)显式调用
log_error,传入具体上下文 - 示例片段:
log_error() {<br> local line=$1 code=$2 msg=${3:-"unknown error"}<br> printf '{"timestamp":"%s","level":"ERROR","source":"%s","code":"%s","message":"%s","line":%s}\n' \<br> "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$0" "$code" "$msg" "$line" \<br> >> /var/log/scripts/errors.jsonl<br>}
与日志系统联动,避免重复造轮子
已有 syslog 架构的环境,可直接走 logger 命令,利用其结构化能力:
- 使用 RFC5424 格式发送,带 structured-data 字段:
logger -t "backup-mysql" -p local0.err -s '1 $(date -u +%Y-%m-%dT%H:%M:%SZ) $(hostname) backup-mysql - - [error@12345 code="ERR_NO_DUMP_FILE"] Backup failed: no SQL file generated' - rsyslog 配置中启用
imjournal或imfile,配合mmjsonparse插件提取code、error@12345等字段,再写入 Elasticsearch 或转发至告警平台 - 优势是复用系统级日志管道,无需额外维护文件路径和轮转逻辑











