syslog
syslog 插件将请求和响应日志作为 JSON 对象分批推送到 syslog 服务器,并支持自定义日志格式。
示例
以下示例展示了如何在不同场景下配置 syslog 插件。
要跟随示例操作,你应该有一个运行中的 syslog 服务器,或者在 Docker 中启动一个示例 rsyslog 服务器:
- Docker
- Kubernetes
docker run -d -p 514:514/tcp --name example-rsyslog-server rsyslog/syslog_appliance_alpine
查看服务器收到的日志:
docker logs -f example-rsyslog-server
为示例 TCP syslog 接收器创建 Kubernetes 清单:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: example-rsyslog-server
spec:
replicas: 1
selector:
matchLabels:
app: example-rsyslog-server
template:
metadata:
labels:
app: example-rsyslog-server
spec:
containers:
- name: tcp-syslog
image: alpine/socat
args:
- -v
- TCP-LISTEN:514,reuseaddr,fork
- STDOUT
ports:
- containerPort: 514
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: example-rsyslog-server
spec:
selector:
app: example-rsyslog-server
ports:
- name: tcp-syslog
port: 514
targetPort: 514
protocol: TCP
type: ClusterIP
应用清单:
kubectl apply -f syslog-server.yaml
查看服务器收到的日志:
kubectl logs -n aic deploy/example-rsyslog-server -f
推送日志到 Syslog 服务器
以下示例展示了如何在路由上启用 syslog 插件,该插件记录客户端对路由的请求并将日志推送到 syslog 服务器。
创建一个路由并在其上启用 syslog:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "syslog-route",
"uri": "/anything",
"plugins": {
"syslog": {
"host": "127.0.0.1",
"port": 514,
"flush_limit": 1
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}'
services:
- name: httpbin
routes:
- name: syslog-route
uris:
- /anything
plugins:
syslog:
host: 127.0.0.1
port: 514
flush_limit: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: syslog-plugin-config
spec:
plugins:
- name: syslog
config:
host: example-rsyslog-server.aic.svc.cluster.local
port: 514
flush_limit: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: syslog-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: syslog-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: syslog-route
spec:
ingressClassName: apisix
http:
- name: syslog-route
match:
paths:
- /anything
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: syslog
enable: true
config:
host: example-rsyslog-server.aic.svc.cluster.local
port: 514
flush_limit: 1
应用配置:
kubectl apply -f syslog-ic.yaml
❶ host:替换为 syslog 服务器的地址。对于 Kubernetes,请使用集群内 Service 地址,例如 example-rsyslog-server.aic.svc.cluster.local。
❷ port: 替换为你的 syslog 服务器端口。
❸ flush_limit:设置为 1,以便立即将日志推送到 syslog 服务器。
发送一个请求到该路由:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 200 OK 响应。
在 syslog 服务器中,你应该看到类似以下的日志条目:
{
"response": {
"status": 200,
"headers": {
"access-control-allow-credentials": "true",
"connection": "close",
"date": "Fri, 17 Apr 2026 05:39:46 GMT",
"access-control-allow-origin": "*",
"server": "APISIX/3.16.0",
"content-type": "application/json",
"content-length": "387"
},
"size": 614
},
"service_id": "",
"client_ip": "172.19.0.1",
"server": {
"hostname": "eff61bf7be4d",
"version": "3.16.0"
},
"upstream": "35.171.123.176:80",
"apisix_latency": 13.999900817871,
"request": {
"method": "GET",
"url": "http://127.0.0.1:9080/anything",
"querystring": {},
"size": 86,
"uri": "/anything",
"headers": {
"host": "127.0.0.1:9080",
"accept": "*/*",
"user-agent": "curl/7.29.0"
}
},
"route_id": "syslog-route",
"upstream_latency": 165,
"latency": 178.99990081787,
"start_time": 1709334859598
}
使用插件元数据自定义日志格式
以下示例展示了如何使用插件元数据自定义日志格式。在插件元数据中配置的日志格式将应用于所有 syslog 插件实例。
创建一个启用 syslog 插件的路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "syslog-route",
"uri": "/anything",
"plugins": {
"syslog": {
"host": "127.0.0.1",
"port": 514,
"flush_limit": 1
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}'
services:
- name: httpbin
routes:
- name: syslog-route
uris:
- /anything
plugins:
syslog:
host: 127.0.0.1
port: 514
flush_limit: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: syslog-plugin-config
spec:
plugins:
- name: syslog
config:
host: example-rsyslog-server.aic.svc.cluster.local
port: 514
flush_limit: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: syslog-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: syslog-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: syslog-route
spec:
ingressClassName: apisix
http:
- name: syslog-route
match:
paths:
- /anything
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: syslog
enable: true
config:
host: example-rsyslog-server.aic.svc.cluster.local
port: 514
flush_limit: 1
应用配置:
kubectl apply -f syslog-ic.yaml
配置 syslog 的插件元数据:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/syslog" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"log_format": {
"host": "$host",
"@timestamp": "$time_iso8601",
"route_id": "$route_id",
"client_ip": "$remote_addr",
"resp_content_type": "$sent_http_Content_Type"
}
}'
plugin_metadata:
- name: syslog
log_format:
host: "$host"
"@timestamp": "$time_iso8601"
route_id: "$route_id"
client_ip: "$remote_addr"
resp_content_type: "$sent_http_Content_Type"
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
namespace: aic
name: apisix-config
spec:
provider:
type: ControlPlane
controlPlane:
# ...
# 控制面连接配置
pluginMetadata:
syslog:
log_format:
host: "$host"
"@timestamp": "$time_iso8601"
route_id: "$route_id"
client_ip: "$remote_addr"
resp_content_type: "$sent_http_Content_Type"
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
namespace: aic
name: apisix-config
spec:
provider:
type: ControlPlane
controlPlane:
# ...
# 控制面连接配置
pluginMetadata:
syslog:
log_format:
host: "$host"
"@timestamp": "$time_iso8601"
route_id: "$route_id"
client_ip: "$remote_addr"
resp_content_type: "$sent_http_Content_Type"
应用配置:
kubectl apply -f gatewayproxy.yaml
发送一个请求到该路由:
curl -i "http://127.0.0.1:9080/anything"
在 syslog 服务器中,你应该看到类似以下的日志条目:
{
"@timestamp": "2026-04-17T05:39:46+00:00",
"resp_content_type": "application/json",
"host": "127.0.0.1",
"route_id": "syslog-route",
"client_ip": "172.19.0.1"
}
有条件地记录请求体
以下示例展示了如何有条件地记录请求体。
创建一个启用 syslog 插件的路由如下:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "syslog-route",
"uri": "/anything",
"plugins": {
"syslog": {
"host": "127.0.0.1",
"port": 514,
"flush_limit": 1,
"include_req_body": true,
"include_req_body_expr": [["arg_log_body", "==", "yes"]]
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}'
services:
- name: httpbin
routes:
- name: syslog-route
uris:
- /anything
plugins:
syslog:
host: 127.0.0.1
port: 514
flush_limit: 1
include_req_body: true
include_req_body_expr:
- - arg_log_body
- ==
- "yes"
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: syslog-plugin-config
spec:
plugins:
- name: syslog
config:
host: example-rsyslog-server.aic.svc.cluster.local
port: 514
flush_limit: 1
include_req_body: true
include_req_body_expr:
- - arg_log_body
- ==
- "yes"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: syslog-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: syslog-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: syslog-route
spec:
ingressClassName: apisix
http:
- name: syslog-route
match:
paths:
- /anything
methods:
- POST
upstreams:
- name: httpbin-external-domain
plugins:
- name: syslog
enable: true
config:
host: example-rsyslog-server.aic.svc.cluster.local
port: 514
flush_limit: 1
include_req_body: true
include_req_body_expr:
- - arg_log_body
- ==
- "yes"
应用配置:
kubectl apply -f syslog-ic.yaml
❶ include_req_body:设置为 true 以包含请求体。
❷ include_req_body_expr:仅当 URL 查询字符串 log_body 为 yes 时包含请求体。在基于 YAML 的配置中,请用引号括起 "yes",以避免 YAML 将其转换为布尔值。
发送一个满足条件的请求到该路由:
curl -i "http://127.0.0.1:9080/anything?log_body=yes" -X POST \
-H "Content-Type: application/json" \
-d '{"env":"dev"}'
你应该看到请求体被记录:
{
"response": {
"status": 200,
"headers": {
"connection": "close",
"server": "APISIX/3.16.0",
"date": "Fri, 17 Apr 2026 05:55:06 GMT",
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true",
"content-type": "application/json",
"content-length": "531"
},
"size": 759
},
"service_id": "",
"client_ip": "172.19.0.1",
"server": {
"hostname": "eff61bf7be4d",
"version": "3.16.0"
},
"upstream": "35.171.123.176:80",
"apisix_latency": 0,
"request": {
"method": "POST",
"url": "http://127.0.0.1:9080/anything?log_body=yes",
"querystring": {
"log_body": "yes"
},
"size": 164,
"body": "{\"env\":\"dev\"}",
"uri": "/anything?log_body=yes",
"headers": {
"accept": "*/*",
"user-agent": "curl/7.29.0",
"host": "127.0.0.1:9080",
"content-type": "application/json",
"content-length": "13"
}
},
"route_id": "syslog-route",
"upstream_latency": 892,
"latency": 1011.0001564026,
"start_time": 1709340364390
}
发送一个不带 URL 查询字符串的请求到该路由:
curl -i "http://127.0.0.1:9080/anything" -X POST \
-H "Content-Type: application/json" \
-d '{"env":"dev"}'
你不应该在日志中看到请求体。
如果你在设置 include_req_body 或 include_resp_body 为 true 的同时自定义了 log_format,插件将不会在日志中包含这些内容。
作为变通方法,你可以在日志格式中使用 NGINX 变量 $request_body,例如:
{
"syslog": {
...,
"log_format": {"body": "$request_body"}
}
}