使用JSON日志器重定向至Docker日志时的格式异常问题
问题分析与解决
你的日志未按JSON格式输出的核心原因是bash函数中jq的参数行末尾缺少续行反斜杠,导致后续参数被当作独立命令,JSON格式化脚本__JQ_LOGGER_SCRIPT根本没传递给jq,最终jq只是默认处理原始输入,直接输出带引号的字符串。
从Docker日志的set -x输出也能佐证:最后jq的参数是两个空字符串'' '',说明本该传递的__JQ_LOGGER_SCRIPT丢失了。
修正后的完整脚本
#!/bin/bash set -x # Json logger IFS= read -r -d '' __JQ_LOGGER_SCRIPT <<'JQSCRIPT' { "type": "log", "host": $host, "level": $level, "systemid": $systemid, "system": "connect-manager", "time": $time, "timezone": $timezone, "log": . } JQSCRIPT json_logger() { jq \ --raw-input \ --compact-output \ --arg level "$1" \ --arg systemid "app-manager-$(cat /etc/machine-id)" \ --arg host "$(hostname).${MY_POD_NAMESPACE}" \ --arg time "$(date '+%Y-%m-%dT%H:%M:%S.%3NZ')" \ --arg timezone "$(date +%Z)" \ "$__JQ_LOGGER_SCRIPT" } echo "Starting App manager" | json_logger INFO > /proc/1/fd/1 # 注意:此处子shell的$?是子shell自身的退出码,若要捕获主进程信号需调整逻辑 ( # 替换为你的实际进程命令 sleep 60 echo "App manager terminated due to signal $?" | json_logger INFO > /proc/1/fd/1 )&
关键修改点
- 给
json_logger函数中jq的每一行参数末尾添加续行反斜杠\(最后一行"$__JQ_LOGGER_SCRIPT"除外),确保所有参数被正确传递给jq。 - 将反引号
`替换为$(),这是bash中执行子shell命令的推荐写法,可读性更强且避免嵌套问题。 - 给
--arg host的参数添加双引号,避免当MY_POD_NAMESPACE为空或包含特殊字符时出现格式错误。
额外说明
你尝试的第二个参数传入方式是错误的,json_logger函数只接收一个参数(日志级别),日志内容是通过管道输入传递给jq的--raw-input,无需额外传入。
内容的提问来源于stack exchange,提问作者swamoch
相关产品推荐
相关产品推荐

