Updating Trace Context headers implementation#1024
Updating Trace Context headers implementation#1024felixbarny merged 21 commits intoelastic:masterfrom
Conversation
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java
Outdated
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/HeaderGetter.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContext.java
Outdated
Show resolved
Hide resolved
| } | ||
| byte[] buffer = headerSetter.getFixedLengthByteArray(TRACE_PARENT_BINARY_HEADER_NAME, BINARY_FORMAT_EXPECTED_LENGTH); | ||
| if (buffer == null || buffer.length != BINARY_FORMAT_EXPECTED_LENGTH) { | ||
| logger.warn("Header setter {} failed to provide a byte buffer with the proper length. Allocating a buffer for each header.", |
There was a problem hiding this comment.
There's a chance that this will be logged very frequently. Do any of the existing implementations return null?
There was a problem hiding this comment.
There is a single implementation (Kafka) that returns null if the current assumption (of same thread setting and serializing the headers) becomes invalid. If and when that happens, I don't mind the first user encountering it will get lots of errors. I made it so that distributed tracing will continue to work, but will start allocating more than before, so it can be easily overlooked if not logged clearly.
There was a problem hiding this comment.
We should track https://issues.apache.org/jira/browse/KAFKA-3539
Codecov Report
@@ Coverage Diff @@
## master #1024 +/- ##
=========================================
Coverage ? 61.69%
Complexity ? 85
=========================================
Files ? 288
Lines ? 11298
Branches ? 1499
=========================================
Hits ? 6970
Misses ? 3881
Partials ? 447
Continue to review full report at Codecov.
|
Improvements - MethodHandles are not @nullable - Both getFirstHeader and getAllHeaders method handles are used in HeadersExtractorBridge
Allows for internal iteration which can be more efficient - No forced Iterator allocations - No conversion from Header to String/byte[] necessary - Consumer is stateless and can be re-used, due to state method argument
felixbarny
left a comment
There was a problem hiding this comment.
I made some suggestions in eyalkoren#1
See also the messages of the individual commits.
Codecov Report
@@ Coverage Diff @@
## master #1024 +/- ##
=========================================
Coverage 62.30% 62.30%
Complexity 85 85
=========================================
Files 290 290
Lines 11375 11375
Branches 1514 1514
=========================================
Hits 7087 7087
Misses 3840 3840
Partials 448 448 Continue to review full report at Codecov.
|
apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/HeaderGetter.java
Show resolved
Hide resolved
| } | ||
| byte[] buffer = headerSetter.getFixedLengthByteArray(TRACE_PARENT_BINARY_HEADER_NAME, BINARY_FORMAT_EXPECTED_LENGTH); | ||
| if (buffer == null || buffer.length != BINARY_FORMAT_EXPECTED_LENGTH) { | ||
| logger.warn("Header setter {} failed to provide a byte buffer with the proper length. Allocating a buffer for each header.", |
There was a problem hiding this comment.
We should track https://issues.apache.org/jira/browse/KAFKA-3539
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TextTracestateAppender.java
Outdated
Show resolved
Hide resolved
apm-agent-core/src/test/java/co/elastic/apm/agent/impl/BinaryHeaderMapAccessor.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContext.java
Show resolved
Hide resolved
| private Extractor() {} | ||
|
|
||
| private HeadersExtractorBridge() { | ||
| public static Extractor of(@Nullable Object headerExtractor, Object headersExtractor) { |
There was a problem hiding this comment.
This does not work, unfortunately. There can be multiple implementations passed to the API. Even for the same technology, the headerExtractor will be specific to a particular instance of a request object.
There was a problem hiding this comment.
Of course 🤦♂
I can make it ThreadLocal, or cache per extractor. Since it's our API implementation, I want to make sure it is in accordance to the rest of the stuff we do
There was a problem hiding this comment.
let's just allocate in this case. There will be allocations anyway for a capturing lambda (like request::getHeaders) and the header iterator. Allocations are fine and inevitable in the public API.
What does this PR do?
Implementing
Implementing elastic/apm#71. Since this logic touches LOTs of plugins for both server and client sides of the tracing, it starts with a refactor that adds new APIs so that all plugins are indifferent to the logic of headers additions/reads/removal.
Checklist
Author's Checklist
Related issues
Closes #923
Use cases
Screenshots