在AWS/Fargate中启动syslog-ng遇KW_BODY语法错误求助
问题详情
将syslog-ng作为Fargate服务搭建日志转发器时,本地笔记本可正常启动,但在AWS/Fargate中启动失败,报错如下:
20 Error parsing within destination, syntax error, unexpected KW_BODY, expecting ')' in /etc/syslog-ng/syslog-ng.conf:26:7-26:11:
21 destination d_datadog {
22 http(
23 url("https://http-intake.logs.datadoghq.com/api/v2/logs?ddsource=DD_SOURCE&ddtags=test:test}")
24 method("POST")
25 headers("Content-Type: application/json", "Accept: application/json", "DD-API-KEY:DD_API_KEY")
26----> body("<${PRI}>1 ${ISODATE} ${HOST:--} ${PROGRAM:--} ${PID:--} ${MSGID:--} ${SDATA:--} $MSG
")
26----> ^^^^
27 );
28 };
完整配置文件:
@version: 4.8 @include "scl.conf" source s_network { tcp(ip(0.0.0.0) port(601)); }; source s_local { internal(); }; destination d_stdout { file("/dev/stdout"); }; destination d_local { file("/var/log/messages"); file("/var/log/messages-kv.log" template("$ISODATE $HOST $(format-welf --scope all-nv-pairs) ") frac-digits(3)); }; destination d_datadog { http( url("https://http-intake.logs.datadoghq.com/api/v2/logs?ddsource=`DD_SOURCE`&ddtags=test:test") method("POST") headers("Content-Type: application/json", "Accept: application/json", "DD-API-KEY: `DD_API_KEY`") body("<${PRI}>1 ${ISODATE} ${HOST:--} ${PROGRAM:--} ${PID:--} ${MSGID:--} ${SDATA:--} $MSG ") ); }; log { source(s_network); source(s_local); destination(d_local); destination(d_stdout); destination(d_datadog); };
解决方案
1. 统一syslog-ng版本
报错核心是http()目的地不识别body参数,大概率是Fargate容器内的syslog-ng版本与本地4.8版本不一致。body参数是syslog-ng 4.x版本新增特性,若容器内版本低于4.0,会触发语法错误。
- 解决方式:确保Fargate使用的镜像中syslog-ng版本为4.8,可在Dockerfile中指定安装:
FROM alpine:latest RUN apk add --no-cache syslog-ng=4.8-r0
2. 修正环境变量引用语法
配置中用反引号`DD_SOURCE`引用环境变量是shell语法,syslog-ng不支持,需改用其原生语法${env:VAR_NAME}:
修改d_datadog中的url和headers参数:
url("https://http-intake.logs.datadoghq.com/api/v2/logs?ddsource=${env:DD_SOURCE}&ddtags=test:test") headers("Content-Type: application/json", "Accept: application/json", "DD-API-KEY: ${env:DD_API_KEY}")
3. 调整模板格式与换行
- 原
body参数内的字符串包含换行,易导致解析异常,建议将模板合并为一行。 - Datadog v2日志接口要求JSON格式,原
body为syslog格式,需调整为JSON模板适配接口:
修改后的d_datadog配置示例:
destination d_datadog { http( url("https://http-intake.logs.datadoghq.com/api/v2/logs?ddsource=${env:DD_SOURCE}&ddtags=test:test") method("POST") headers("Content-Type: application/json", "Accept: application/json", "DD-API-KEY: ${env:DD_API_KEY}") body("{\"message\": \"$MSG\", \"hostname\": \"${HOST:--}\", \"timestamp\": \"${ISODATE}\", \"priority\": \"${PRI}\"}") ); };
4. 额外检查
- 确认报错信息中url末尾的多余
}是输入笔误,实际配置中需移除(完整配置已正确,可忽略)。 - 确保Fargate容器已正确传递
DD_SOURCE和DD_API_KEY环境变量。
内容的提问来源于stack exchange,提问作者Pavel Chernikov

