splunk-hec-logging
splunk-hec-logging 插件采用 Splunk 事件数据格式,将 APISIX 和 API7 网关的请求及响应日志发送到 Splunk HTTP Event Collector (HEC)。该插件会批量发送日志,并支持自定义日志格式。
示例
以下示例展示如何把网关请求日志发送到 Splunk,以及如何通过插件元数据自定义日志内容。
要跟随示例操作,请完成以下步骤以设置 Splunk:
- Docker
- Kubernetes
官方 Splunk 镜像目前仅发布 amd64 版本。设置网关容器名称和本地评估凭据:
export GATEWAY_CONTAINER=replace-with-gateway-container-name
export SPLUNK_PASSWORD=Splunk-local-password-1234
export SPLUNK_HEC_TOKEN=apisix-hec-token
创建专用网络:
docker network create gateway-splunk-net
将网关连接到该网络:
docker network connect gateway-splunk-net "$GATEWAY_CONTAINER"
启动已启用 HEC 的 Splunk Enterprise。所需标志表示接受 Splunk 通用条款:
docker run -d \
--platform linux/amd64 \
--name splunk-hec \
--network gateway-splunk-net \
-p 127.0.0.1:8000:8000 \
-p 127.0.0.1:8088:8088 \
-e SPLUNK_START_ARGS=--accept-license \
-e SPLUNK_GENERAL_TERMS=--accept-sgt-current-at-splunk-com \
-e SPLUNK_PASSWORD \
-e SPLUNK_HEC_TOKEN \
splunk/splunk:10.4.3-rhel9
容器启动后,验证 HEC 健康状态:
curl -k "https://127.0.0.1:8088/services/collector/health"
你应该收到 {"text":"HEC is healthy","code":17}。如果命令报告连接错误,请等待几秒后重试。
设置 Admin API 和 ADC 示例使用的 HEC 端点:
export SPLUNK_HEC_ENDPOINT=https://splunk-hec:8088/services/collector/event
Splunk Web 位于 http://localhost:8000;使用用户名 admin 和 SPLUNK_PASSWORD 的值登录。
创建 Kubernetes 清单以部署启用了 HEC 的 Splunk:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: aic
name: splunk-defaults
data:
default.yml: |
splunk:
hec:
enable: True
ssl: False
token: apisix-hec-token
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: splunk
spec:
replicas: 1
selector:
matchLabels:
app: splunk
template:
metadata:
labels:
app: splunk
spec:
enableServiceLinks: false
nodeSelector:
kubernetes.io/arch: amd64
containers:
- name: splunk
image: splunk/splunk:10.4.3-rhel9
env:
- name: SPLUNK_START_ARGS
value: "--accept-license"
# 接受 Splunk 通用条款:https://www.splunk.com/en_us/legal/splunk-general-terms.html
- name: SPLUNK_GENERAL_TERMS
value: "--accept-sgt-current-at-splunk-com"
- name: SPLUNK_PASSWORD
value: "Splunk@1234"
ports:
- name: hec
containerPort: 8088
- name: web
containerPort: 8000
volumeMounts:
- name: defaults
mountPath: /tmp/defaults
readinessProbe:
httpGet:
path: /services/collector/health
port: hec
initialDelaySeconds: 60
periodSeconds: 10
failureThreshold: 10
volumes:
- name: defaults
configMap:
name: splunk-defaults
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: splunk-hec
spec:
selector:
app: splunk
ports:
- name: hec
port: 8088
targetPort: hec
- name: web
port: 8000
targetPort: web
应用清单:
kubectl apply -f splunk-hec-server.yaml
等待 Splunk 就绪:
kubectl rollout status -n aic deployment/splunk
设置 Admin API 和 ADC 示例使用的 HEC 端点:
export SPLUNK_HEC_ENDPOINT=http://splunk-hec.aic.svc.cluster.local:8088/services/collector/event
将 Splunk Web 端口转发到本机:
kubectl port-forward -n aic svc/splunk-hec 8000:8000
然后打开 http://localhost:8000,使用用户名 admin 和密码 Splunk@1234 登录。
这些示例中的密码和 HEC Token 仅用于可信的评估环境。生产环境应使用组织的密钥管理系统和 TLS 信任配置。
将日志发送到 Splunk
以下示例将一条路由的请求日志发送到 Splunk HEC。
创建一个路由如下:
- 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 @- <<EOF
{
"id": "splunk-route",
"uri": "/anything",
"plugins": {
"splunk-hec-logging": {
"endpoint": {
"uri": "$SPLUNK_HEC_ENDPOINT",
"token": "apisix-hec-token"
},
"ssl_verify": false,
"batch_max_size": 1
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}
EOF
services:
- name: httpbin
labels:
docs-example: splunk-hec-logging
routes:
- name: splunk-route
uris:
- /anything
plugins:
splunk-hec-logging:
endpoint:
uri: "${SPLUNK_HEC_ENDPOINT}"
token: apisix-hec-token
ssl_verify: false
batch_max_size: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
预览带有示例标签的服务变更:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=splunk-hec-logging
同步已审查的变更:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=splunk-hec-logging
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: splunk-hec-logging-plugin-config
spec:
plugins:
- name: splunk-hec-logging
config:
endpoint:
uri: http://splunk-hec.aic.svc.cluster.local:8088/services/collector/event
token: apisix-hec-token
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: splunk-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: splunk-hec-logging-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: splunk-route
spec:
ingressClassName: apisix
http:
- name: splunk-route
match:
paths:
- /anything
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: splunk-hec-logging
enable: true
config:
endpoint:
uri: http://splunk-hec.aic.svc.cluster.local:8088/services/collector/event
token: apisix-hec-token
应用配置:
kubectl apply -f splunk-hec-logging-ic.yaml
Admin API 和 ADC 示例将 batch_max_size 设为 1,以便验证时立即发送每个事件。省略此字段可保留默认的批处理行为。对于 Docker HTTPS 端点,ssl_verify: false 会接受 Splunk 的自签名评估证书。生产环境应配置可信证书,并保留默认的证书验证。
发送一些请求到该路由:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 200 OK 响应。
在 Splunk Web 中打开 Search & Reporting。搜索 source="apache-apisix-splunk-hec-logging",查找来自网关的事件。
使用插件元数据记录请求和响应头
以下示例使用插件元数据,为未自行定义 log_format 的 splunk-hec-logging 实例添加选定的请求头和响应头。元数据值引用内置变量,因此一份配置可以在多条路由和服务上应用相同的日志字段。
创建一个路由如下:
- 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 @- <<EOF
{
"id": "splunk-route",
"uri": "/anything",
"plugins": {
"splunk-hec-logging": {
"endpoint": {
"uri": "$SPLUNK_HEC_ENDPOINT",
"token": "apisix-hec-token"
},
"ssl_verify": false,
"batch_max_size": 1
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}
EOF
services:
- name: httpbin
labels:
docs-example: splunk-hec-logging
routes:
- name: splunk-route
uris:
- /anything
plugins:
splunk-hec-logging:
endpoint:
uri: "${SPLUNK_HEC_ENDPOINT}"
token: apisix-hec-token
ssl_verify: false
batch_max_size: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
预览带有示例标签的服务变更:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=splunk-hec-logging
同步已审查的变更:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=splunk-hec-logging
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: splunk-hec-logging-plugin-config
spec:
plugins:
- name: splunk-hec-logging
config:
endpoint:
uri: http://splunk-hec.aic.svc.cluster.local:8088/services/collector/event
token: apisix-hec-token
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: splunk-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: splunk-hec-logging-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: splunk-route
spec:
ingressClassName: apisix
http:
- name: splunk-route
match:
paths:
- /anything
methods:
- GET
upstreams:
- name: httpbin-external-domain
plugins:
- name: splunk-hec-logging
enable: true
config:
endpoint:
uri: http://splunk-hec.aic.svc.cluster.local:8088/services/collector/event
token: apisix-hec-token
应用 配置:
kubectl apply -f splunk-hec-logging-ic.yaml
配置 splunk-hec-logging 的插件元数据:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/splunk-hec-logging" -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",
"env": "$http_env",
"resp_content_type": "$sent_http_Content_Type"
}
}'
插件元数据是全局集合,无法通过标签选择器隔离。修改该条目前,请先导出完整集合:
adc dump -o adc-metadata.yaml --with-id \
--include-resource-type plugin_metadata
在保留 adc-metadata.yaml 中所有其他条目的同时,添加或更新 splunk-hec-logging 条目:
plugin_metadata:
# 保留导出文件中的所有其他插件元数据条目。
splunk-hec-logging:
log_format:
host: "$host"
"@timestamp": "$time_iso8601"
route_id: "$route_id"
client_ip: "$remote_addr"
env: "$http_env"
resp_content_type: "$sent_http_Content_Type"
预览完整的元数据变更,并确认其中没有非预期的更新或删除:
adc diff -f adc-metadata.yaml \
--include-resource-type plugin_metadata
同步已审查的插件元数据集合:
adc sync -f adc-metadata.yaml \
--include-resource-type plugin_metadata
在部署使用的完整 GatewayProxy 清单的 spec.pluginMetadata 下添加以下条目:
splunk-hec-logging:
log_format:
host: "$host"
"@timestamp": "$time_iso8601"
route_id: "$route_id"
client_ip: "$remote_addr"
env: "$http_env"
resp_content_type: "$sent_http_Content_Type"
通过该部署常规的 Kubernetes 或 GitOps 工作流应用更新后的完整清单。
❶ 记录自定义请求头 env。
❷ 记录响应头 Content-Type。
发送带有 env 头的请求到该路由:
curl -i "http://127.0.0.1:9080/anything" -H "env: dev"
在 Splunk Web 中打开 Search & Reporting,搜索 source="apache-apisix-splunk-hec-logging"。