Skip to content

Add instrumentation for thrift#18405

Merged
trask merged 24 commits into
open-telemetry:mainfrom
laurit:thrift
May 16, 2026
Merged

Add instrumentation for thrift#18405
trask merged 24 commits into
open-telemetry:mainfrom
laurit:thrift

Conversation

@laurit
Copy link
Copy Markdown
Contributor

@laurit laurit commented Apr 29, 2026

Resolves #1573
While reviewing #13784 noticed that it is significantly more complicated than https://github.com/opentracing-contrib/java-thrift Here is my attempt at building a simpler instrumentation.
It is possible that some of the complexity in #13784 is because of supporting 0.9.1 vs 0.13.0 in the opentracing. Could also be that it handles some cases better. I didn't get around to trying the tests from #13784 with my instrumentation. The tests in this PR are based on the opentracing tests.
cc @YaoYingLong

@otelbot-java-instrumentation otelbot-java-instrumentation Bot added the test native This label can be applied to PRs to trigger them to run native tests label Apr 29, 2026
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
// limit support to 0.13.0 since we don't test with earlier versions
// added in 0.13.0
return hasClassesNamed("org.apache.thrift.protocol.ShortStack");
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the library instrumentation requires 0.13.0 the agent instrumentation could work with older versions. We are limiting the version here because we don't test on older versions.

@laurit laurit marked this pull request as ready for review April 29, 2026 19:52
@laurit laurit requested a review from a team as a code owner April 29, 2026 19:52
Copy link
Copy Markdown
Member

@trask trask left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated CI review from #17889 incoming...

Review of the new Apache Thrift instrumentation. Main findings:

  • SocketAccessor has a copy/paste bug: FRAMED_TRANSPORT and FAST_FRAMED_TRANSPORT both resolve to TFastFramedTransport, so TFramedTransport-wrapped transports never reach the framed-transport branch and their socket is not unwrapped.
  • ContextPropagationUtil.readHeaders corrupts the protocol stream when the entry count exceeds MAX_CONTEXT_ENTRIES — it returns without skipping the unread map entries, while the size-limit branch correctly skips remaining entries.
  • library/README.md looks copy-pasted from gRPC: wrong title, wrong central.sonatype.com artifact link, undefined telemetry variable in the snippets, wrong return type on wrapClientProtocolFactory.
  • Minor style: this.getClass().getName() in transform() should be getClass().getName() (per javaagent-module-patterns.md); duplicate AutoCleanupExtension field in the library ThriftTest (the abstract base already declares one).

Comment thread instrumentation/thrift-0.13/library/README.md Outdated
Comment thread instrumentation/thrift-0.13/library/README.md Outdated
Comment thread instrumentation/thrift-0.13/library/README.md Outdated
@trask
Copy link
Copy Markdown
Member

trask commented May 4, 2026

I sent a few optional suggestions in laurit#410

@github-actions github-actions Bot mentioned this pull request May 5, 2026
@laurit laurit modified the milestone: v3.0.0 May 7, 2026
@trask trask requested a review from Copilot May 10, 2026 00:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces Apache Thrift 0.13+ instrumentation to the OpenTelemetry Java Instrumentation project, providing both a standalone library wrapper (ThriftTelemetry) and Javaagent auto-instrumentation, along with a dedicated testing module and documentation/metadata updates.

Changes:

  • Added new Thrift 0.13 modules: library, javaagent, and testing, including client/server span + metric coverage and context propagation.
  • Implemented Thrift client/server wrappers for library users and ByteBuddy instrumentations for javaagent users.
  • Added Thrift test coverage (sync, async, transports), plus repo metadata/docs updates and latest-deps tracking.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
settings.gradle.kts Registers the new Thrift 0.13 modules in the Gradle build.
instrumentation/thrift-0.13/testing/src/main/thrift/custom.thrift Defines the Thrift IDL used to generate test client/server artifacts.
instrumentation/thrift-0.13/testing/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/CustomHandler.java Implements the Thrift service used by tests.
instrumentation/thrift-0.13/testing/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/AbstractThriftTest.java Shared test suite validating spans/metrics and behavior across server/client modes.
instrumentation/thrift-0.13/testing/build.gradle.kts Adds the testing module dependencies and Thrift source generation step.
instrumentation/thrift-0.13/metadata.yaml Declares instrumentation metadata (semantic conventions, description, link).
instrumentation/thrift-0.13/library/src/test/java/io/opentelemetry/instrumentation/thrift/v0_13/ThriftTest.java Library-instrumentation test coverage using ThriftTelemetry wrappers.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/ThriftTelemetryBuilder.java Builder API to customize extractors and span naming for Thrift telemetry.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/ThriftTelemetry.java Public entrypoint providing wrappers for Thrift processors/protocols/clients.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/ThriftResponse.java Response type used for instrumenter end/status decisions.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/ThriftRequest.java Request carrier for RPC + network attributes and propagation headers.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ThriftServerNetworkAttributesGetter.java Extracts server-side network/server attributes from ThriftRequest.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ThriftRpcAttributesGetter.java Provides RPC semantic convention attributes (system/service/method/error).
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ThriftRequestGetter.java TextMapGetter for extracting propagation headers from ThriftRequest.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ThriftInstrumenterFactory.java Builds client/server instrumenters and wires RPC/network extractors + metrics.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ThriftClientNetworkAttributesGetter.java Extracts client-side server/network attributes from ThriftRequest.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/SocketAccessor.java Retrieves socket/socket address details across Thrift transport variants.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ServerProcessorDecorator.java Wraps server processor to apply protocol decorators and end spans correctly.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ServerOutProtocolDecorator.java Detects server-side exception responses when writing messages.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ServerInProtocolDecorator.java Reads propagation field, starts server span, and scopes context for handlers.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ServerCallContext.java ThreadLocal context to expose transport for nonblocking server socket discovery.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ContextPropagationUtil.java Writes/reads propagation payload in Thrift maps with safety limits.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ClientProtocolDecorator.java Injects propagation headers into outbound Thrift message fields.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/ClientCallContext.java ThreadLocal call context to coordinate injection and client span lifecycle.
instrumentation/thrift-0.13/library/src/main/java/io/opentelemetry/instrumentation/thrift/v0_13/internal/AsyncMethodCallbackUtil.java Wraps async callbacks to end spans and restore parent context for callback code.
instrumentation/thrift-0.13/library/README.md Documents how to use the standalone Thrift library instrumentation.
instrumentation/thrift-0.13/library/build.gradle.kts Declares library instrumentation build/test tasks (including semconv variants).
instrumentation/thrift-0.13/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftTest.java Javaagent test coverage via AbstractThriftTest.
instrumentation/thrift-0.13/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftTBaseProcessorInstrumentation.java Instruments server processing entrypoint for blocking servers.
instrumentation/thrift-0.13/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftSingletons.java Provides global client/server instrumenters and propagators for the agent.
instrumentation/thrift-0.13/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftServiceClientInstrumentation.java Instruments generated Thrift sync clients and wraps protocols for propagation.
instrumentation/thrift-0.13/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftInstrumentationModule.java Registers the Thrift agent instrumentation module and its type instrumentations.
instrumentation/thrift-0.13/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftFrameBufferInstrumentation.java Adds transport exposure for nonblocking server processing via ThreadLocal context.
instrumentation/thrift-0.13/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/thrift/v0_13/ThriftAsyncClientInstrumentation.java Instruments generated Thrift async clients, wrapping callbacks for span end.
instrumentation/thrift-0.13/javaagent/build.gradle.kts Configures agent module dependencies, muzzle, and semconv-variant test tasks.
docs/supported-libraries.md Adds Thrift to the supported libraries list.
.github/config/latest-dep-versions.json Adds org.apache.thrift:libthrift latest version for dependency update tooling.
.fossa.yml Adds new Thrift gradle targets for license scanning.

Comment thread docs/supported-libraries.md Outdated
Comment thread instrumentation/thrift-0.13/testing/build.gradle.kts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

Comment thread docs/supported-libraries.md Outdated
Comment thread instrumentation/thrift-0.13/library/README.md
Comment on lines +49 to +75
transformer.applyAdviceToMethod(
isConstructor().and(takesArgument(0, named("org.apache.thrift.protocol.TProtocolFactory"))),
getClass().getName() + "$ConstructorAdvice");

transformer.applyAdviceToMethod(
isMethod()
.and(
target -> {
ParameterList<?> parameterList = target.getParameters();
if (!parameterList.isEmpty()) {
String lastParameter =
parameterList.get(parameterList.size() - 1).getType().asErasure().getName();
return "org.apache.thrift.async.AsyncMethodCallback".equals(lastParameter);
}
return false;
}),
getClass().getName() + "$MethodAdvice");
}

@SuppressWarnings("unused")
public static class ConstructorAdvice {
@Advice.AssignReturned.ToArguments(@ToArgument(0))
@Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
public static TProtocolFactory onEnter(
@Advice.Argument(0) TProtocolFactory protocolFactory,
@Advice.Argument(2) TNonblockingTransport transport) {
return new ClientProtocolDecorator.Factory(protocolFactory, getPropagators());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fa3f3bc — tightened the matcher with takesArguments(3) and takesArgument(2, TNonblockingTransport), and dropped the unused transport advice binding.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: amended in 951e709 — kept just the original takesArgument(0, TProtocolFactory) matcher and only removed the unused @Advice.Argument(2) TNonblockingTransport binding. takesArguments(3) would have over-tightened (Thrift's generator emits both 3-arg and 4-arg subclass ctors via super(...), so both should be instrumented to wrap the protocol factory).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

@laurit
Copy link
Copy Markdown
Contributor Author

laurit commented May 11, 2026

@copilot apply changes based on the comments in this thread

@laurit laurit added this to the v2.28.0 milestone May 12, 2026
@laurit laurit requested a review from Copilot May 12, 2026 08:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

Comment on lines +22 to +31
private UnaryOperator<SpanNameExtractor<ThriftRequest>> clientSpanNameExtractorCustomizer =
UnaryOperator.identity();
private UnaryOperator<SpanNameExtractor<ThriftRequest>> serverSpanNameExtractorCustomizer =
UnaryOperator.identity();
private final List<AttributesExtractor<ThriftRequest, ThriftResponse>> additionalExtractors =
new ArrayList<>();
private final List<AttributesExtractor<ThriftRequest, ThriftResponse>>
additionalClientExtractors = new ArrayList<>();
private final List<AttributesExtractor<ThriftRequest, ThriftResponse>>
additionalServerExtractors = new ArrayList<>();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We removed the complex generics from http instrumentations, should we also do it elsewhere for 3.0?

@trask trask merged commit e3d5372 into open-telemetry:main May 16, 2026
96 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test native This label can be applied to PRs to trigger them to run native tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for thrift

3 participants