-
Notifications
You must be signed in to change notification settings - Fork 24
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
HPCC-586 Add Otel Tracing support #714
Conversation
@@ -164,6 +202,89 @@ private String getTargetHPCCBuildVersionString() throws Exception | |||
|
|||
} | |||
|
|||
public SpanBuilder getSpanBuilder(String spanName) | |||
{ | |||
Tracer tracer = getTracer(INSTRUMENTED_LIBRARY_NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use member tracer instead.
})).build(); | ||
*/ | ||
} | ||
tracer = GlobalOpenTelemetry.getTracer(tracerName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tracer should be static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's preferred to track opentelemetry singleton and fetch tracer from it
if (options != null) | ||
{ | ||
if (currentSpan != null && currentSpan.getSpanContext().isValid()) | ||
W3CTraceContextPropagator.getInstance().inject(Context.current(), options, Options::setProperty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we propagate the Context.current(), or the currentSpan.getContext() passed in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use currentSpan.getContext() for consistency. We could also have an override of injectTraceParentHeader() that doesn't require any input and grabs the current span via Span.current()
{ | ||
((WsWorkunitsStub) stub).ping(request); | ||
verifyStub(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass in span
Ping request = new Ping(); | ||
|
||
try | ||
Span span = getSpanBuilder("WsWUClient_Ping").startSpan(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how to disable if tracing not desirable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rpastrana look good, I don't see any major issues, but do have a few questions / comments
if (options != null) | ||
{ | ||
if (currentSpan != null && currentSpan.getSpanContext().isValid()) | ||
W3CTraceContextPropagator.getInstance().inject(Context.current(), options, Options::setProperty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use currentSpan.getContext() for consistency. We could also have an override of injectTraceParentHeader() that doesn't require any input and grabs the current span via Span.current()
{ | ||
Map<String, String> carrier = new HashMap<>(); | ||
TextMapSetter<Map<String, String>> setter = Map::put; | ||
W3CTraceContextPropagator.getInstance().inject(Context.current(), carrier, setter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be using currentSpawn.getContext() here as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inject actually takes a Context rather than SpanContext
@@ -582,6 +726,10 @@ static public Stub setStubOptions(Stub thestub, Connection connection) throws Ax | |||
|
|||
opt.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE); | |||
|
|||
//only do this if tracing enabled? | |||
//injectCurrentSpanTraceParentHeader(opt); | |||
//opt.setProperty("traceparent", getTraceParentHeader()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need these comments?
@@ -240,7 +279,16 @@ public boolean verify(String hostname,javax.net.ssl.SSLSession sslSession) | |||
// Run the generate-datasets.ecl script if present in the project resources | |||
try | |||
{ | |||
executeECLScript("generate-datasets.ecl"); | |||
//Span eclscriptspan = tracer.spanBuilder("generate-datasets.ecl").startSpan(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it could be interesting to add tracing into our tests. This could be a good way to better understanding how the tracing works in practice, and it could help us track down issues. So, I think lets keep this trace code
fb5e881
to
ad53e15
Compare
@jpmcmu please review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rpastrana looks good
pom.xml
Outdated
</dependency> | ||
<dependency> | ||
<groupId>io.opentelemetry</groupId> | ||
<artifactId>opentelemetry-exporter-otlp</artifactId> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rpastrana Based on our discussion it probably makes sense to trim these dependencies. We can probably rely on the downstream client applications to provide the exporter jars they need / use.
// -D.otel.logs.exporter=none | ||
// -Dotel.java.global-autoconfigure.enabled=true | ||
|
||
globalOTel = GlobalOpenTelemetry.get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we handle defaults here? Should we check if defaults have been set and if not default to no-op and / or logging exporter?
15cce48
to
f763fda
Compare
@jpmcmu see latest commit |
.spanBuilder(method.toUpperCase() + " " + url.toExternalForm()) | ||
.setAttribute(ServerAttributes.SERVER_ADDRESS, getHost()) | ||
.setAttribute(ServerAttributes.SERVER_PORT, Long.getLong(getPort())) | ||
.setAttribute(HttpAttributes.HTTP_REQUEST_METHOD, HttpAttributes.HttpRequestMethodValues.GET) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this won't always be an http get
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments and I would also be curious to see what the trace output looks like from the ESP logging perspective.
* WARNING: Due to the inherent complications around initialization order involving this classand its single global instance, we strongly recommend *not* using GlobalOpenTelemetry unless youhave a use-case that absolutely requires it. Please favor using instances of OpenTelemetrywherever possible. | ||
* If you are using the OpenTelemetry javaagent, it is generally best to only callGlobalOpenTelemetry.get() once, and then pass the resulting reference where you need to use it. | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on our conversation lets remove this documentation about default config. Maybe also add a comment specifying what happens if the client application hasn't setup Otel.
} | ||
catch (Exception e) | ||
{ | ||
System.out.println("OpenTelemetry autoconfiguration failed: " + e.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will globalOTel be null if we get an exception here?
int responseCode = httpURLConnection.getResponseCode(); //throws IOException | ||
try (Scope scope = sendHTTPReqSpan.makeCurrent()) | ||
{ | ||
Span currentSpan = Span.current(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use sendHTTPReqSpan here since currentSpan should always be sendHTTPReqSpan. Otherwise it is unclear why we would be expecting a different span.
Map<String, String> carrier = new HashMap<>(); | ||
TextMapSetter<Map<String, String>> setter = Map::put; | ||
W3CTraceContextPropagator.getInstance().inject(Context.current(), carrier, setter); | ||
String traceparent = carrier.getOrDefault("traceparent", "00-" + currentSpan.getSpanContext().getTraceId() + "-" + currentSpan.getSpanContext().getSpanId() + "-00"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this make sense to move this functionality to create trace into a utility so that dfsclient can use this as well?
Sample trace output via console/log trace exporter:
Followed by corresponding ESP log output including server trace output:
|
Sample JVM arguments used to autoconfigure Junit tests and/or platformtester
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rpastrana looks good
- Injects trace context in traceparent http header - Integrates autoconfigure otel SDK - Adds manual WsWUClient.ping span - Adds manual WsWUClientTest.ping span - Adds manual span around getHPCCver and getHPCCContainerizedMode - Adds manual http span on Utils.Connection.sendHTTPRequest - Injects traceparent http header on outgoing Utils.Connection.sendHTTPRequest - Only attempts to autoconfig remotetest if otel.java.global-autoconfig enabled - Adds root span around platform tester Signed-off-by: Rodrigo Pastrana <[email protected]>
@drealeed please take a look and let's discuss how your projects are/will be using OTEL for tracing etc. |
Type of change:
Checklist:
Testing: