hypertrace / javaagent

Hypertrace OpenTelemetry Java agent with payload/body and headers data capture.
Apache License 2.0
30 stars 15 forks source link

✨ Capture HTTP bodies on Undertow #321

Closed ryandens closed 3 years ago

ryandens commented 3 years ago

✨ Capture request bodies on Undertow

Background

Overview

Testing

Checklist:

Documentation

No new documentation is required, as we broadly claim Java Servlet support of which this undertow use-case is an implementation. This just happens to be a corner case.

ryandens commented 3 years ago

Undertow support should be added to the readme.

I'm avoiding adding undertow support to the readme because we specifically only will only fully work on Undertow servlets. Due to the implementation details of APIs like io.undertow.servlet.spec.HttpServletRequestImpl.getParameterMap(), we know that the request body won't always be accessed via the standard servlet body access APIs getReader and getInputStream() so we add this as a way to support servlets running on Undertow, but it does not mean that we support running on a raw Undertow HTTP server ( we don't).

Should this instrumentation capture headers as well?

Theoretically, we could add that over time, but the goal of this PR is to solve the request bodies missing when running undertow with Servlets, one of our supported use cases. Right now, adding full-out undertow support isn't our top priority

This is the first servlet container instrumentation in this project. Could the payloads be captured twice? E.g. first in Undertow and then in the servlet instrumentation?

I'm really glad you asked this! This was indeed happening when you brought this up. The solution I came up with was to add some lightweight instrumentation to undertow-servlet to mark and store in the instrumentation context whether or not an HttpServerExchange should be instrumented with undertow specific body-capturing.

ryandens commented 3 years ago

Hey @pavolloffay, thanks for taking the time to review these changes! Do you have any further comments/concerns about this PR?

ryandens commented 3 years ago

Why there are 3 gradle modules? Any real justification?

There is:

* common

* undertow

* undertow-servlet

Does the undertow instrumentation work without servlet? I guess the servlet depends on the core so if the core is not reused I would merge them together.

Yes, the common module is depend on by both the undertow module and the undertow-servlet module. The undertow module works without the servlet module because we can't count on undertow-servlet always being used. The undertow-servlet insrumentation module serves to add instrumentation to undertow-servlet APIs in a way that can be detected by our undertow-core instrumentation. This allows us to intelligently avoid capturing the reqeust body twice depeneidng on on what APIs are used to access it/in what context.