🤔 Introducing APISIX AI Gateway – Built for LLMs and AI workloads. Learn More

syslog

描述

syslog 插件将请求和响应日志以 JSON 对象批量推送到 syslog 服务器,并支持自定义日志格式。

属性

名称类型必选项默认值有效值描述
hoststringTruesyslog 服务器的 IP 地址或主机名。
portintegerTruesyslog 服务器的目标端口。
timeoutintegerFalse3000大于 0向上游发送数据的超时时间(毫秒)。
tlsbooleanFalsefalse若为 true,则验证 TLS。
flush_limitintegerFalse4096大于 0推送日志到 syslog 服务器前,缓冲区和当前消息的最大大小(字节,B)。
drop_limitintegerFalse1048576大于 0丢弃日志前,缓冲区和当前消息允许的最大大小(字节,B)。
sock_typestringFalsetcptcpudp使用的传输层协议。
pool_sizeintegerFalse5大于等于 5sock:keepalive 使用的连接池大小。
log_formatobjectFalse以 JSON 键值对形式声明的自定义日志格式,值可以引用 NGINX 变量。也可以通过插件元数据在全局范围内配置日志格式,将应用于所有 syslog 插件实例。如果插件实例的日志格式与插件元数据的日志格式不同,插件实例的日志格式优先生效。
include_req_bodybooleanFalsefalse若为 true,则在日志中包含请求体。注意:若请求体太大而无法保存在内存中,由于 NGINX 的限制,将无法记录。
include_req_body_exprarrayFalselua-resty-expr 表达式数组。当 include_req_body 为 true 时使用,仅当此处表达式求值为 true 时才记录请求体。
include_resp_bodybooleanFalsefalse若为 true,则在日志中包含响应体。
include_resp_body_exprarrayFalselua-resty-expr 表达式数组。当 include_resp_body 为 true 时使用,仅当此处表达式求值为 true 时才记录响应体。
max_req_body_bytesintegerFalse524288大于等于 1日志中记录的最大请求体字节数。超出该值的请求体将被截断。在 APISIX 3.16.0 版本中可用。
max_resp_body_bytesintegerFalse524288大于等于 1日志中记录的最大响应体字节数。超出该值的响应体将被截断。在 APISIX 3.16.0 版本中可用。
namestringFalsesys logger批处理器中插件的唯一标识符。若使用 Prometheus 监控 APISIX 指标,该名称将以 apisix_batch_process_entries 导出。
batch_max_sizeintegerFalse1000大于 0每批次允许的最大日志条目数。达到该值后,批次将被发送至日志服务。设置为 1 表示立即处理。
inactive_timeoutintegerFalse5大于 0在将批次发送至日志服务前等待新日志的最长时间(秒)。该值应小于 buffer_duration
buffer_durationintegerFalse60大于 0发送批次前允许最早条目存在的最长时间(秒)。
retry_delayintegerFalse1大于等于 0批次发送失败后重试的时间间隔(秒)。
max_retry_countintegerFalse0大于等于 0丢弃日志条目前允许的最大重试次数。

NOTE

该插件支持使用批处理器来聚合并批量处理条目(日志/数据),避免频繁提交数据。默认情况下,批处理器每 5 秒或队列数据达到 1000 条时提交数据。详情请参考批处理器

插件元数据

也可以通过配置插件元数据来设置日志格式,可用配置如下:

名称类型必选项描述
log_formatobjectFalse以 JSON 键值对形式声明的自定义日志格式,值可以引用 NGINX 变量

IMPORTANT

插件元数据的配置为全局范围生效,将作用于所有使用 syslog 插件的路由和服务。

使用示例

以下示例演示如何在不同场景下配置 syslog 插件。

请先在 Docker 中启动一个示例 rsyslog 服务器:

docker run -d -p 514:514 --name example-rsyslog-server rsyslog/syslog_appliance_alpine

NOTE

您可以通过以下命令从 config.yaml 中获取 admin_key 并存入环境变量:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

推送日志到 Syslog 服务器

以下示例演示如何在路由上启用 syslog 插件,记录客户端请求并推送日志到 syslog 服务器。

创建带 syslog 的路由,将 hostport 替换为您 syslog 服务器的地址和端口,并将 flush_limit 设为 1 以立即推送日志:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "syslog-route",
    "uri": "/anything",
    "plugins": {
      "syslog": {
        "host" : "172.0.0.1",
        "port" : 514,
        "flush_limit" : 1
      }
    },
    "upstream": {
      "nodes": {
        "httpbin.org:80": 1
      },
      "type": "roundrobin"
    }
  }'

向路由发送请求:

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": "Sat, 02 Mar 2024 00:14:19 GMT",
      "access-control-allow-origin": "*",
      "server": "APISIX/3.8.0",
      "content-type": "application/json",
      "content-length": "387"
    },
    "size": 614
  },
  "service_id": "",
  "client_ip": "172.19.0.1",
  "server": {
    "hostname": "eff61bf7be4d",
    "version": "3.8.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 插件的路由:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "syslog-route",
    "uri": "/anything",
    "plugins": {
      "syslog": {
        "host" : "172.0.0.1",
        "port" : 514,
        "flush_limit" : 1
      }
    },
    "upstream": {
      "nodes": {
        "httpbin.org:80": 1
      },
      "type": "roundrobin"
    }
  }'

syslog 配置插件元数据:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/syslog" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "log_format": {
      "host": "$host",
      "@timestamp": "$time_iso8601",
      "route_id": "$route_id",
      "client_ip": "$remote_addr",
      "resp_content_type": "$sent_http_Content_Type"
    }
  }'

向路由发送请求:

curl -i "http://127.0.0.1:9080/anything"

在 syslog 服务器中,您应看到类似如下的日志条目:

{
  "@timestamp": "2024-03-02T00:00:31+00:00",
  "resp_content_type": "application/json",
  "host": "127.0.0.1",
  "route_id": "syslog-route",
  "client_ip": "172.19.0.1"
}

按条件记录请求体

以下示例演示如何按条件记录请求体。

创建如下带 syslog 插件的路由,仅当 URL 查询参数 log_bodyyes 时才记录请求体:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "syslog-route",
    "uri": "/anything",
    "plugins": {
      "syslog": {
        "host" : "172.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"
    }
  }'

发送满足条件的带 URL 查询参数的请求:

curl -i "http://127.0.0.1:9080/anything?log_body=yes" -X POST -d '{"env": "dev"}'

您应看到日志中包含请求体:

{
  "request": {
    "method": "POST",
    "url": "http://127.0.0.1:9080/anything?log_body=yes",
    "querystring": {
      "log_body": "yes"
    },
    "size": 183,
    "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/x-www-form-urlencoded",
      "content-length": "14"
    }
  }
}

不带 URL 查询参数发送请求:

curl -i "http://127.0.0.1:9080/anything" -X POST -d '{"env": "dev"}'

此时日志中将不包含请求体。

NOTE

若在将 include_req_bodyinclude_resp_body 设为 true 的同时自定义了 log_format,插件将不会在日志中包含请求体或响应体。

解决方法是在日志格式中使用 NGINX 变量 $request_body,例如:

{
  "syslog": {
    "log_format": {"body": "$request_body"}
  }
}