Skip to content
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

RootIds generated by TelemetryCorrelationUtils can be < 32 characters #910

Closed
raedur opened this issue Apr 16, 2019 · 8 comments
Closed
Assignees
Milestone

Comments

@raedur
Copy link

raedur commented Apr 16, 2019

Expected behavior

Traceparent.validate doesn't throw an exception on generated traceIds

Actual behavior

Traceparent.validate sometimes throws an exception on generated traceIds if they are not 32 characters long

Traceparent.validate requires traceIds to be 32 characters long, however those created by TelemetryCorrelationUtils are not guaranteed to be 32 characters long, the current code is as follows:

private static String generateRootId() {
    UUID guid = UUID.randomUUID();
    long least = guid.getLeastSignificantBits();
    long most = guid.getMostSignificantBits();
    return Long.toHexString(most) + Long.toHexString(least);
}

This generates 32 char ids most of the time, (e.g. for UUIDs of "bb1141ac-f798-4a6c-1234-76774462e31f") but if the generated UUID contains multiple 0s in a row (e.g. bb1141ac-f798-4a6c-0000-76774462e31f) it omits the 0s in the generated id (i.e. it generates bb1141acf7984a6c76774462e31f) which is only 28 characters long which subsequently throws the exception in Traceparent.validate

Maybe the generateRootId should be:

private static String generateRootId() {
    return UUID.randomUUID().toString().replace("-", "");
}
@dhaval24
Copy link
Contributor

@raedur thanks for opening the issue. I am curious when do you see this behavior. Have you turned on W3C for both agent and sdk?

@raedur
Copy link
Author

raedur commented Apr 24, 2019

This is not using the javaagent, just the sdk. I'll have to double check if W3C is on, but the function should probably be fixed anyway, for now in my code I have created an interceptor that generates the root Id instead of letting application insights do it.

@vlev
Copy link

vlev commented Jul 26, 2019

We hit the same bug with 2.4.0 version.

Also, with AI agent instrumenting Apache Http Client, this bug prevents some of the outgoing http requests from executing:

AI: TRACE 26-07-2019 12:23:39.272+0000, 2171(hystrix-CaseHub-31): Stack trace generated is java.lang.IllegalArgumentException: invalid traceId
	at com.microsoft.applicationinsights.web.internal.correlation.tracecontext.Traceparent.validate(Traceparent.java:86)
	at com.microsoft.applicationinsights.web.internal.correlation.tracecontext.Traceparent.<init>(Traceparent.java:39)
	at com.microsoft.applicationinsights.web.internal.correlation.tracecontext.Traceparent.<init>(Traceparent.java:52)
	at com.microsoft.applicationinsights.web.internal.correlation.TraceContextCorrelation.generateChildDependencyTraceparent(TraceContextCorrelation.java:477)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at feign.httpclient.ApacheHttpClient.execute(ApacheHttpClient.java:85)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:108)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
	at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:106)

In this particular case, traceId was 31 symbols long.

ThreadContext.getRequestTelemetryContext()
                .getHttpRequestTelemetry().getContext().getOperation().getId();

@vlev
Copy link

vlev commented Jul 26, 2019

This is pretty significant issue for the users of AI agent.
I could provide a fix proposed by @raedur. Will it be possible to create dedicated release 2.4.1?

@trask
Copy link
Member

trask commented Jul 26, 2019

Hi @vlev, yes, a PR would be great. As far as releasing dedicated 2.4.1 for this, it looks like this exception is caught and logged by TraceContextCorrelation.java, so it should not prevent the outgoing http request from executing, can you confirm what you are seeing?

@vlev
Copy link

vlev commented Jul 29, 2019

Hi @trask,
Here is the place where the call fails:

RxError: null
java.lang.NullPointerException: null
	at com.microsoft.applicationinsights.web.internal.correlation.TraceContextCorrelation.createChildIdFromTraceparentString(TraceContextCorrelation.java:498)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at feign.httpclient.ApacheHttpClient.execute(ApacheHttpClient.java:85)

It seems, that createChildIdFromTraceparentString() won't work with null value.

    public static String createChildIdFromTraceparentString(String traceparent) {
        assert traceparent != null;

        String[] traceparentArr = traceparent.split("-");
        assert traceparentArr.length == 4;

        return "|" + traceparentArr[1] + "." + traceparentArr[2] + ".";

This method is called thru cryptic asm instrumentation:

 // generate child Traceparent
            mv.visitMethodInsn(INVOKESTATIC, "com/microsoft/applicationinsights/web/internal/correlation/TraceContextCorrelation",
                "generateChildDependencyTraceparent", "()Ljava/lang/String;", false);
            traceparent = this.newLocal(Type.getType(Object.class));
            mv.visitVarInsn(ASTORE, traceparent);

            mv.visitVarInsn(ALOAD, traceparent);
            mv.visitMethodInsn(INVOKESTATIC, "com/microsoft/applicationinsights/web/internal/correlation/TraceContextCorrelation",
                "createChildIdFromTraceparentString", "(Ljava/lang/String;)Ljava/lang/String;", false);
            childIdLocal = this.newLocal(Type.getType(Object.class));
            mv.visitVarInsn(ASTORE, childIdLocal);

@trask trask assigned trask and littleaj and unassigned trask Jul 31, 2019
vlev pushed a commit to vlev/ApplicationInsights-Java that referenced this issue Jul 31, 2019
@littleaj littleaj added this to the 2.4.1 milestone Jul 31, 2019
@littleaj
Copy link
Contributor

Fixed in version 2.4.1, releasing this week.

@trask
Copy link
Member

trask commented Aug 5, 2019

Thanks @vlev !

trask added a commit that referenced this issue Sep 21, 2020
* Add document describing current problem with context propagation

* Update docs/contributing/inter-thread-context-propagation.md

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>

* Update docs/contributing/inter-thread-context-propagation.md

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>

* More clarifications

* More clarifications

* Better example

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
@ghost ghost locked as resolved and limited conversation to collaborators Jul 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants