跳到主要内容

error-log-logger

error-log-logger 插件会将 APISIX 和 API7 网关错误日志(error.log)分批发送到 TCP、Apache SkyWalking、Apache Kafka 或 ClickHouse 服务器。配置严重级别阈值后,插件会发送该级别及所有更严重级别的日志。

该插件默认禁用。一旦启用,它将自动开始将错误日志推送到远程服务器。你应该仅在 插件元数据 中配置远程服务器详细信息,而不是在路由等其他资源上配置。

示例​

下面的示例展示了如何在不同场景下配置 error-log-logger 插件。

APISIX 和 API7 网关运行时配置默认不会加载 error-log-logger。配置插件元数据前,请先在网关静态配置中启用该插件。

保留 config.yaml 中现有插件列表,并加入 error-log-logger:

config.yaml
plugins:
# 保留当前网关使用的完整插件列表。
- error-log-logger

重新加载网关以使更改生效。

发送日志到 TCP 服务器​

以下示例将网关错误日志发送到 TCP 服务器。

在端口 19000 上启动一个示例 TCP 接收器:

设置正在运行的 APISIX 或 API7 网关容器名称:

export GATEWAY_CONTAINER=replace-with-gateway-container-name

创建专用网络:

docker network create gateway-error-log-net

将网关连接到该网络:

docker network connect gateway-error-log-net "$GATEWAY_CONTAINER"

在网络中启动固定版本的 TCP 接收器:

docker run -d \
--name error-log-tcp \
--network gateway-error-log-net \
alpine/socat:1.8.1.3 \
-u TCP-LISTEN:19000,fork,reuseaddr STDOUT

在 error-log-logger 的插件元数据中配置 TCP 目标。Admin API 和 ADC 示例使用 Docker 接收器主机名 error-log-tcp;如果网关运行在 Kubernetes 中,请改为 tcp-server.aic.svc。Ingress Controller 示例已经使用 Kubernetes 主机名。

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/error-log-logger" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"tcp": {
"host": "error-log-tcp",
"port": 19000
},
"level": "WARN",
"batch_max_size": 1
}'

❶ 配置网关可访问的接收器主机名。Docker 使用 error-log-tcp,Kubernetes 使用 tcp-server.aic.svc。

❷ 配置接收器的 TCP 监听端口。

❸ 转发 warning、error、critical、alert 和 emergency 级别的日志。

示例将 batch_max_size 设为 1,以便立即转发每条符合条件的错误日志,方便验证。

以下确定性验证使用 Docker,并假定 Admin API 和代理可通过 127.0.0.1 访问。如果网关运行在 Kubernetes 中,请通过部署的常规路由工作流生成 warning 或更严重的错误,再使用下方 Kubernetes 日志命令。

在 Docker 环境中,创建一条 upstream 指向关闭端口的路由:

curl "http://127.0.0.1:9180/apisix/admin/routes/error-log-tcp-source" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/error-log-tcp",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1": 1
}
}
}'

发送请求以触发 upstream 连接错误:

curl -i "http://127.0.0.1:9080/error-log-tcp"

你应该收到 HTTP/1.1 502 Bad Gateway 响应。

查看转发的错误:

docker logs error-log-tcp

接收器中应出现类似以下的日志条目:

2026/09/21 12:02:40 [error] 358#358: *5675628 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.155.1, server: _, request: "GET /error-log-tcp HTTP/1.1", upstream: "http://127.0.0.1:1/error-log-tcp", host: "127.0.0.1:9080", request_id: "0e772dc645823636907d5b3be972c42f"

发送日志到 SkyWalking​

以下示例配置 error-log-logger 插件,将网关错误日志发送到 SkyWalking OAP 11.0.0,并搭配 BanyanDB 0.11.0 和 Horizon 1.0.0。

设置 SkyWalking OAP 服务器:

创建 SkyWalking 容器所使用的网络:

docker network create gateway-skywalking-net

如果网关也在 Docker 中运行,请设置 GATEWAY_CONTAINER 并将其连接到该网络。如果网关安装在宿主机上,请跳过此步骤:

export GATEWAY_CONTAINER=replace-with-gateway-container-name
docker network connect gateway-skywalking-net "$GATEWAY_CONTAINER"

创建以下 Docker Compose 文件:

skywalking-compose.yaml
services:
banyandb:
image: apache/skywalking-banyandb:0.11.0
command: standalone
networks:
- skywalking

oap:
image: apache/skywalking-oap-server:11.0.0
environment:
SW_STORAGE: banyandb
SW_STORAGE_BANYANDB_TARGETS: banyandb:17912
ports:
- "127.0.0.1:12800:12800"
depends_on:
- banyandb
networks:
skywalking:
aliases:
- skywalking-oap

horizon:
image: apache/skywalking-ui:horizon-1.0.0
environment:
HORIZON_OAP_QUERY_URL: http://skywalking-oap:12800
HORIZON_OAP_ADMIN_URL: http://skywalking-oap:17128
HORIZON_AUTH_LOCAL_USERS: '[{"username":"admin","passwordHash":"$$argon2id$$v=19$$m=65536,t=3,p=4$$eemqy1r72oSXR58y8VpRqw$$Bn/dULrmJTHEi3263KfgWDEwQmUsqNLi3xwyv/DekHM","roles":["admin"]}]'
ports:
- "127.0.0.1:8081:8081"
depends_on:
- oap
networks:
- skywalking

networks:
skywalking:
name: gateway-skywalking-net
external: true

启动服务:

docker compose -f skywalking-compose.yaml up -d

通过 http://localhost:8081 访问 Horizon。使用用户名 admin 和密码 admin 登录。

警告

本示例中的本地用户使用公开的演示凭据。请仅在可信的本地评估环境中使用这些凭据。将 Horizon 暴露到本地环境之外前,请配置身份提供商或生成唯一的密码哈希。

下面的 Admin API 和 ADC 示例使用 Docker 网络地址 http://skywalking-oap:12800/v3/logs。如果网关安装在宿主机上,请改用 http://127.0.0.1:12800/v3/logs。如果网关通过 Kubernetes 访问 OAP,请使用 http://skywalking-oap.skywalking.svc.cluster.local:12800/v3/logs。Ingress Controller 示例已使用 Kubernetes Service 地址。

在 error-log-logger 的插件元数据中配置 SkyWalking 目标:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/error-log-logger" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"skywalking": {
"endpoint_addr": "http://skywalking-oap:12800/v3/logs"
},
"level": "INFO"
}'

❶ 将端点地址配置为 SkyWalking 服务器地址。

❷ 将严重级别配置为 INFO,以便发送大多数日志,方便验证。

要进行验证,可以通过重新加载 APISIX 手动生成一条 warn 级别的日志。

在 Horizon 中,导航到 General Service → Logs,选择 APISIX 服务并运行查询。你应该会看到生成的告警日志:

2025/01/27 07:40:06 [warn] 211#211: *35552 [lua] plugin.lua:205: load(): new plugins: {"cas-auth":true,"real-ip":true,"ai":true,"client-control":true,"proxy-control":true,"request-id":true,"zipkin":true,"ext-plugin-pre-req":true,"fault-injection":true,"mocking":true,"serverless-pre-function":true,"cors":true,"ip-restriction":true,"ua-restriction":true,"referer-restriction":true,"csrf":true,"uri-blocker":true,"request-validation":true,"chaitin-waf":true,"multi-auth":true,"openid-connect":true,"authz-casbin":true,"authz-casdoor":true,"wolf-rbac":true,"ldap-auth":true,"hmac-auth":true,"basic-auth":true,"jwt-auth":true,"redirect":true,"key-auth":true,"consumer-restriction":true,"attach-consumer-label":true,"authz-keycloak":true,"proxy-cache":true,"body-transformer":true,"ai-prompt-template":true,"ai-prompt-decorator":true,"proxy-mirror":true,"proxy-rewrite":true,"workflow":true,"api-breaker":true,"ai-proxy":true,"limit-conn":true,"limit-count":true,"limit-req":true,"gzip":true,"server-info":true,"traffic-split":true,"response-rewrite":true,"degraphql":true,"kafka-proxy":true,"grpc-transcode":true,"grpc-web":true,"http-dubbo":true,"public-api":true,"prometheus":true,"datadog":true,"loki-logger":true,"elasticsearch-logger":true,"echo":true,"loggly":true,"http-logger":true,"splunk-hec-logging":true,"skywalking-logger":true,"google-cloud-logging":true,"sls-logger":true,"tcp-logger":true,"kafka-logger":true,"rocketmq-logger":true,"syslog":true,"udp-logger":true,"file-logger":true,"clickhouse-logger":true,"tencent-cloud-cls":true,"inspect":true,"example-plugin":true,"aws-lambda":true,"azure-functions":true,"openwhisk":true,"openfunction":true,"error-log-logger":true,"ext-plugin-post-req":true,"ext-plugin-post-resp":true,"serverless-post-function":true,"opa":true,"forward-auth":true,"jwe-decrypt":true}, context: init_worker_by_lua*

时间戳、Worker 标识符和已加载的插件集合会因部署而异。

当生成其他严重级别(如 error、emerg 和 info)的日志时,你也应该观察到它们。

通过 TLS 将日志发送到 Kafka​

以下示例会将网关的 error 级别日志发送到启用了 TLS 的 Kafka Broker。请先按照 Kafka Logger 的“将日志发送到启用 TLS 的 Broker”章节完成受信任 CA 配置,再设置 Broker 地址和主题:

export KAFKA_TLS_HOST="kafka-tls"
export KAFKA_TLS_PORT="9093"
export KAFKA_ERROR_TOPIC="apisix-error-logs"

创建专用的错误日志主题:

docker exec kafka-tls /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafka-tls:9093 \
--command-config /etc/kafka/secrets/client.properties \
--create \
--if-not-exists \
--topic "${KAFKA_ERROR_TOPIC}" \
--partitions 1 \
--replication-factor 1

配置插件元数据:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/error-log-logger" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
--data-binary @- <<EOF
{
"kafka": {
"brokers": [
{
"host": "${KAFKA_TLS_HOST}",
"port": ${KAFKA_TLS_PORT}
}
],
"kafka_topic": "${KAFKA_ERROR_TOPIC}",
"tls": {
"verify": true
}
},
"level": "ERROR",
"inactive_timeout": 1
}
EOF

要生成一条用于验证的错误日志,请创建上游端口关闭的路由,然后发送请求:

curl "http://127.0.0.1:9180/apisix/admin/routes/trigger-error-log" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"uri": "/trigger-error-log",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1": 1
}
}
}'

curl -i "http://127.0.0.1:9080/trigger-error-log"

请求应返回 502 Bad Gateway。等待一秒批处理超时后,从专用主题消费一条记录:

docker exec kafka-tls /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server kafka-tls:9093 \
--topic "${KAFKA_ERROR_TOPIC}" \
--consumer.config /etc/kafka/secrets/client.properties \
--from-beginning \
--max-messages 1

该记录应包含类似以下内容的错误条目:

connect() failed (111: Connection refused) while connecting to upstream

插件写入自身日志的 Kafka Broker 信息只包含主机和端口;SASL 密码会被遮蔽。

发送日志到 ClickHouse​

以下示例配置 error-log-logger,将网关错误日志发送到 ClickHouse。

本地评估凭据

示例使用 HTTP 连接和固定的本地密码。生产环境中,请使用安全的 ClickHouse 端点,并按照网关部署的凭据管理策略保护插件元数据及其加密密钥。

使用专用数据库和用户启动 ClickHouse:

将 GATEWAY_CONTAINER 设置为正在运行的 APISIX 或 API7 网关容器。创建专用网络并将网关连接到该网络:

export GATEWAY_CONTAINER=replace-with-gateway-container-name

docker network create gateway-error-log-clickhouse-net
docker network connect gateway-error-log-clickhouse-net "$GATEWAY_CONTAINER"

在同一网络中启动 ClickHouse:

docker run -d \
--name error-log-clickhouse \
--network gateway-error-log-clickhouse-net \
-p 127.0.0.1:8123:8123 \
-e CLICKHOUSE_DB=apisix_logs \
-e CLICKHOUSE_USER=apisix_logger \
-e CLICKHOUSE_PASSWORD=apisix-logger-pass \
-e CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 \
--ulimit nofile=262144:262144 \
clickhouse/clickhouse-server:26.8.5.13

等待 ClickHouse 就绪:

until curl -fsS -u "apisix_logger:apisix-logger-pass" \
"http://127.0.0.1:8123/ping" | grep -q "Ok"; do
sleep 2
done

创建 error_logs 表。插件会将每条错误日志写入该表的 data 列:

curl "http://127.0.0.1:8123" \
-u "apisix_logger:apisix-logger-pass" \
-d '
CREATE TABLE apisix_logs.error_logs (
data String,
PRIMARY KEY(`data`)
)
ENGINE = MergeTree()
'

在 error-log-logger 的插件元数据中配置 ClickHouse 目标:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/error-log-logger" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"clickhouse": {
"endpoint_addr": "http://error-log-clickhouse:8123",
"user": "apisix_logger",
"password": "apisix-logger-pass",
"database": "apisix_logs",
"logtable": "error_logs"
},
"level": "INFO",
"batch_max_size": 1
}'

Docker 端点使用专用网络中的容器名称;Kubernetes 端点使用 ClickHouse Service 的 DNS 名称。level: INFO 会捕获 info 级别及所有更严重级别的消息,batch_max_size: 1 则会在本次验证中立即发送每条日志。

创建一个上游不可用的路由,使网关写入可预测的错误日志条目:

curl "http://127.0.0.1:9180/apisix/admin/routes/clickhouse-error-source" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"uri": "/clickhouse-error",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1": 1
}
}
}'

发送请求。不可用的上游应返回 HTTP/1.1 502 Bad Gateway 响应并生成错误日志条目:

curl -i "http://127.0.0.1:9080/clickhouse-error"

发送请求到 ClickHouse 以查看日志条目:

echo "SELECT substring(data, 1, 220) AS data FROM apisix_logs.error_logs WHERE position(data, 'clickhouse-error') > 0 ORDER BY data DESC LIMIT 1 FORMAT JSONEachRow" | \
curl "http://127.0.0.1:8123/?" \
-u "apisix_logger:apisix-logger-pass" \
--data-binary @-

你应该看到类似于以下的日志条目:

{"data":"2026/09/16 12:26:17 [error] ... connect() failed (111: Connection refused) while connecting to upstream ... request: \"GET /clickhouse-error HTTP/1.1\" ..."}