In an environment receiving large volume of requests, it is always handy to have some pseudo-unique identification so it is easy to track where the request was routed to.
APISIX has a built-in request-id plugin that does exactly that: gives each request a unique request ID but it also tags the response with it. If the specific header is present in the
request, the plugin will not modify it.
curl http://127.0.0.1:9180/apisix/admin/global_rules/1 -H "X-API-KEY: $APISIX_ADMIN_TOKEN" -X PUT -d '
{
"plugins": {
"request-id": {
"include_in_response": true,
"header_name": "message-id",
"generator": "none",
"disable": false
}
}
}'
Modify access logs to display message tag as below in values.yaml and redeploy APISIX.
accessLogFormat: '$remote_addr - $remote_user [$time_local] $http_host \"$request\" $status $body_bytes_sent $request_time \"$http_referer\" \"$http_user_agent\" $upstream_addr $upstream_status $upstream_response_time \"$upstream_scheme://$upstream_host$upstream_uri\" $sent_http_message_id'
Example letting APISIX tag message:
dalen@Dalens-MBP ~ % curl -X POST http://localhost:9080/deck-api/deck/create -H 'Content-Type: application/json' -v -d '{
"deckType": "standard52"
}'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Host localhost:9080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:9080...
* Connected to localhost (::1) port 9080
> POST /deck-api/deck/create HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 28
>
* upload completely sent off: 28 bytes
< HTTP/1.1 200
< Content-Type: application/json
< Content-Length: 132
< Connection: keep-alive
< Date: Thu, 16 Oct 2025 14:20:04 GMT
< Server: APISIX
< message-id: f93e00bc-b8fe-456f-ad1d-babc60adbcc5
<
* Connection #0 to host localhost left intact
{"deckState":"rO0ABXcUAApzdGFuZGFyZDUyAAAANAAAAAB1cgACW0p4IAS1ErF1kwIAAHhwAAAAAHVxAH4AAAAAAAEAD////////w==","deckType":"standard52"}%
Example passing original message-id:
dalen@Dalens-MBP ~ % curl -X POST http://localhost:9080/deck-api/deck/create -H 'Content-Type: application/json' -H 'message-id: surprise' -v -d '{
"deckType": "standard52"
}'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Host localhost:9080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:9080...
* Connected to localhost (::1) port 9080
> POST /deck-api/deck/create HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Type: application/json
> message-id: surprise
> Content-Length: 28
>
* upload completely sent off: 28 bytes
< HTTP/1.1 200
< Content-Type: application/json
< Content-Length: 132
< Connection: keep-alive
< Date: Thu, 16 Oct 2025 14:21:05 GMT
< Server: APISIX
< message-id: surprise
<
* Connection #0 to host localhost left intact
{"deckState":"rO0ABXcUAApzdGFuZGFyZDUyAAAANAAAAAB1cgACW0p4IAS1ErF1kwIAAHhwAAAAAHVxAH4AAAAAAAEAD////////w==","deckType":"standard52"}%
Code changes
We also modified codebase to serialise, with each request, message-id - see
modifications for ramblings here.
Then running a search over logging messages in api gateway and application namespace should provide full tracking e.g.
{namespace=~"apisix|ramblings"} | json