PrintBody allows the sidecar proxy to intercept and parse the body of HTTP requests and responses. Combined with the custom access log feature for the Service Mesh (ASM) data plane, PrintBody can print the request and response bodies in the sidecar access log.
This plug-in needs to be used with access logs. You need to add an access log variable with the value %DYNAMIC_METADATA(envoy.lua)% (You can specify the variable name based on your needs) in the access log format to view the HTTP message body in the access log.
Prerequisites
An ingress gateway is deployed. For more information, see Create an ingress gateway.
The httpbin service is already deployed in the data plane cluster. For more information, see Deploy the httpbin application.
Configuration fields
Name | Data type | Required | Default value | Description |
port_number | string | Yes | - | The container port of the pod corresponding to the service that is used to parse and respond to the request and response bodies. |
Configuration example
Configure the
PrintBodyplug-in.
Enable the PrintBody plug-in and configure the plug-in parameters as follows:
port_number: "80"
This example will configure the access log to print the request and response bodies received by the httpbin service. The container port for the httpbin service is 80, so the port_number parameter is set to 80. Set the plug-in scope to Global.
See the steps in Customize data plane access logs to customize the access log format and add the following new access log field:
http_body: %DYNAMIC_METADATA(envoy.lua)%
Test the request by sending a POST request with a request body
{"msg":"OK!"}to the httpbin service.
$ curl -H "Content-Type: application/json" -X POST -d '{"msg":"OK!"}' {gateway IP address}/post
{
"args": {},
"data": "{\"msg\":\"OK!\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "13",
"Content-Type": "application/json",
"Host": "*******",
"User-Agent": "curl/7.79.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-Internal": "true",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=3f512ea654ce60e2d80f91f8896033db8**********;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"
},
"json": {
"msg": "OK!"
},
"origin": "*******",
"url": "http://*******/post"
}
View the sidecar access log in the httpbin pod:
kc logs httpbin-669******-tx*** -c istio-proxy|grep msg
You can get the following log content:
{"downstream_local_address":"172.17.80.6:80","upstream_cluster":"inbound|80||","start_time":"2022-**-**T12:01:*.533Z","bytes_sent":673,"response_flags":"-","response_code":200,"x_forwarded_for":"10.0.0.130","http_body":{"responseBody":"{\n \"args\": {}, \n \"data\": \"{\\\"msg\\\":\\\"OK!\\\"}\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Accept\": \"*/*\", \n \"Content-Length\": \"13\", \n \"Content-Type\": \"application/json\", \n \"Host\": \"121.40.183.72\", \n \"User-Agent\": \"curl/7.79.1\", \n \"X-Envoy-Attempt-Count\": \"1\", \n \"X-Envoy-Internal\": \"true\", \n \"X-Forwarded-Client-Cert\": \"By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=3f512ea654ce60e2d80f91f8896033db8b0f**********;Subject=\\\"\\\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account\"\n }, \n \"json\": {\n \"msg\": \"OK!\"\n }, \n \"origin\": \"********\", \n \"url\": \"http://********/post\"\n}\n","requestBody":"{\"msg\":\"OK!\"}"},"downstream_remote_address":"10.0.0.130:0","method":"POST","bytes_received":13,"upstream_host":"172.17.80.6:80","upstream_service_time":"1","upstream_local_address":"127.0.0.6:48862","protocol":"HTTP/1.1","user_agent":"curl/7.79.1","trace_id":null,"route_name":"default","request_id":"0ca6ac34-7141-46b3-85c3-f98b087ea674","upstream_transport_failure_reason":null,"path":"/post","duration":2,"authority":"121.40.183.72","istio_policy_status":null,"authority_for":"121.40.183.72","requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local"}
You can see that the http_body field is displayed in the access log. The request body is displayed in the requestBody subfield, while the response body is displayed in the responseBody subfield.