Skip to content

Add NATS instrumentation #13999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

AlixBa
Copy link
Contributor

@AlixBa AlixBa commented Jun 8, 2025

First, sorry for the review of 5000 rows, that's not very nice.

This PR aims at instrumenting NATS for both library and java agent, using the messaging conventions.

I identified three blocks, publish, subscribe and request. The two first ones are classic pub-sub operations. The latter is a request-reply pattern, out of the box using NATS. It basically combines publish and subscribe over a unique and temporary subject(topic).

Few things:

  • I left out JetStreams from the instrumentation for now (as I don't have a particular interest and I have never used)
  • I didn't implement any messaging metrics. I'll take a look after this PR I think.
  • Not sure how to instrument the request. I used a CLIENT instrumenter and played with the Context to group the publish/subscribe under the same trace. Ideally, for my usage at work, I'd like everything to be in the same trace. I guess we could control this with an option.
  • I feel like the java agent advices are very verbose. If there is a better way of doing it, I'll gladly modify what I wrote.

What it looks like (only tested the library part):

Publish & Subscribe

Two different traces. subscribe follows_from publish with a reference/link
Screenshot 2025-06-08 at 15 56 15
Screenshot 2025-06-08 at 15 55 38

Request

Unique trace. subscribe child_of publish as the code calls for request
Screenshot 2025-06-08 at 15 56 45

@AlixBa AlixBa requested a review from a team as a code owner June 8, 2025 19:10
@otelbot-java-instrumentation
Copy link
Contributor

🔧 The result from spotlessApply was committed to the PR branch.

@AlixBa
Copy link
Contributor Author

AlixBa commented Jun 9, 2025

@laurit is it you I should ask a review from?

Copy link
Contributor

@laurit laurit left a comment

Choose a reason for hiding this comment

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

Currently there is a build failure, and a test failure.

@AlixBa AlixBa force-pushed the nats-instrumentation branch from fcb32fb to 487dffb Compare June 21, 2025 14:05
import io.opentelemetry.instrumentation.api.internal.Timer;
import io.opentelemetry.instrumentation.nats.v2_21.internal.NatsRequest;

final class OpenTelemetryMessageHandler implements MessageHandler {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the only one class I didn't proxy as it's a single method interface and it should be pretty stable

@AlixBa AlixBa force-pushed the nats-instrumentation branch from 40e1913 to 7d1b355 Compare June 22, 2025 09:53
@AlixBa AlixBa force-pushed the nats-instrumentation branch from 89cd845 to 360a21f Compare June 22, 2025 10:40
@@ -29,6 +29,9 @@ for dir in $(find instrumentation -name "*.java" | grep library/src/main/java |
if [[ "$dir" == "instrumentation/lettuce/lettuce-5.1/library/src/main/java/io/lettuce/core/protocol" ]]; then
continue
fi
if [[ "$dir" == "instrumentation/nats/nats-2.21/library/src/main/java/io/nats/client/impl" ]]; then
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need to put OpenTelemetryDispatcherFactory in this package because it relies on NatsConnection and NatsDispatcher which are package scoped. See this comment

}

/** Returns a {@link Options.Builder} with instrumented {@link DispatcherFactory}. */
public Options.Builder wrap(Options.Builder options) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not really sure about this, as I have to rely on a build. I think it would be better to let users do options.dispatcherFactory(...) as OpenTelemetryDispatcherFactory is now exposed

@AlixBa
Copy link
Contributor Author

AlixBa commented Jun 22, 2025

hey @laurit

could you have a second look at this one when you have the time?
Took all the comments and followed (I hope) a very close implementation from other messaging instrumentations.

muzzle passes locally and on previous builds, so I guess the error is transient.

@@ -691,6 +691,12 @@ targets:
- type: gradle
path: ./
target: ':instrumentation:mongo:mongo-async-3.3:javaagent'
- type: gradle
path: ./
target: ':instrumentation:nats:nats-2.21:javaagent'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

since it passes for 2.17.2+, should I change 2.21 to 2.17.2 everywhere? (library included)

@AlixBa
Copy link
Contributor Author

AlixBa commented Jun 27, 2025

might be worth checking if this needs to be applied before merging

@AlixBa AlixBa requested a review from laurit July 1, 2025 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants