Java apm agent doesn't capture text or json body

Kibana version: 8.6

Elasticsearch version:8.6

APM Server version: 8.6

APM Agent language and version: Java 1.35.0

Browser version: Chrome

Original install method (e.g. download page, yum, deb, from source, etc.) and version: Download page

Fresh install or upgraded from other version?: Fresh

Is there anything special in your setup?: Spring boot 2.7.4 application

Description of the problem including expected versus actual behavior. Please include screenshots (if relevant):
Apm agent doesnt register plain text request body. It does register application/x-www-form-urlencoded.
Using trace logging I can see that the information that the agent sends doesnt include the body.
Debugging with the agent I cant find where the bodyBuffer is assigned with the request data

Steps to reproduce:

  1. Set java option elastic.apm.capture_body=all
  2. Make a POST request with content-type: text/plain

Could anyone refer me to where in the code is the apm request body copied from the servlet request body?

Hi @mrodal ,

Could you please provide us Debug Logs (via GH gists) of a run from your application which includes both the startup of the application as well as a POST request with content-type text/plain. The debug logs should usually report why a body is not being captured.

Hi @Jonas_Kunz ,
Heres a trace log so it captures the serialized information sent to the apm agent:

https://gist.githubusercontent.com/mrodal/7acff287bc31bb592df437d513b388e2/raw/eb82498c17046452ff15ee92ed34f0ad615cdbe0

If you search for "123456" you can find where the transaction begins and searching for "text/plain" you can find the serialized data

Please let me know if I can provide any more useful information

Ok, the logs do not indicate any reason why the agent is actively not capturing the body.

Does your application consume the incoming request body? E.g. does your spring controller have something like a @RequestBody String content parameter?

The agent decides on whether or not to capture the body here. Based on that decision the ServletRequest's getInputStream is wrapped here with a stream which copies the data to the transaction. So if your application does not consume the input stream, no data will be recorded on the transaction.

If you are already debugging yourself with the agent source code, these two code locations might allow you to locate the issue.

To my knowledge, the application doesnt consume the incoming request body. Actually the controller method was a GET and I changed it to a POST to test this.

The first line you mention (request.withBodyBuffer()) gets hit. For the second one, I cant get the debugger to stop there. Where is afterGetInputStream supposed to get called from?

Following the code from onEnterServletService and onExitServletService here I cant find where afterGetInputStream gets called

Thanks

afterGetInputStream is invoked whenever any implementation of ServletRequest.getInputStream is called. This very likely never happens because your application doesn't consume the request body. Making your application consume the body should hopefully fix the issue for you.

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.