Skip to content

Add Inferred spans extension - #47

Merged
JonasKunz merged 21 commits into
elastic:mainfrom
JonasKunz:inferred-spans
Jan 9, 2024
Merged

Add Inferred spans extension#47
JonasKunz merged 21 commits into
elastic:mainfrom
JonasKunz:inferred-spans

Conversation

@JonasKunz

Copy link
Copy Markdown
Contributor

Adds the inferred spans feature from the previous elastic-apm-agent as a standalone OTel-extension.
Closes #23. Autoconfiguration and a README.md as documentation will be added with #29 .

The initial commit of this PR is an unchanged copy of all the files from the original profiling plugin, reformatted with spotless. This should allow you to ignore this commit when reviewing to focus on the more relevant remainign diff.

Below is a sample application on how this extension can be used and tested.
I've also used this example application to manually verify that the backup diagnostic files feature works and the diagnostic files can be replayed.

Sample app
public class InferredSpansTestApp {

    public static void main(String[] args) {
        InferredSpansProcessor profiler = InferredSpansProcessor.builder()
                .samplingInterval(Duration.ofMillis(10))
                //.backupDiagnosticFiles(true)
                .build();
        SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
                .setResource(Resource.builder()
                        .put(ResourceAttributes.SERVICE_NAME, "Inferred Spans Otel Test")
                        .build())
                .addSpanProcessor(profiler)
                .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
                                .setEndpoint("https://XXXXXX.apm.europe-west3.gcp.cloud.es.io:443")
                                .addHeader("Authorization", "Bearer XXXXX")
                                .build()
                        )
                        .build())
                .build();
        profiler.setTracerProvider(tracerProvider);

        try (OpenTelemetrySdk sdk = OpenTelemetrySdk.builder()
                .setTracerProvider(tracerProvider)
                .build()) {
            while (true) {
                doTracing(sdk.getTracer("my-manual-tracer"));
            }
        }
    }

    private static void doTracing(Tracer tracer) {
        Span span = tracer.spanBuilder("my-root").startSpan();
        try (var scope = span.makeCurrent()) {
            doSleep(100);
            inferMeParent(tracer);
        } finally {
            span.end();
        }
    }

    private static void inferMeParent(Tracer tracer) {
        inferMe(tracer);
    }

    private static void inferMe(Tracer tracer) {
        child1(tracer);
        inferMeToo();
        child2(tracer);
    }

    private static void child1(Tracer tracer) {
        Span span1 = tracer.spanBuilder("child-1").startSpan();
        try (var scope = span1.makeCurrent()) {
            doSleep(200);
        } finally {
            span1.end();
        }
    }

    private static void child2(Tracer tracer) {
        Span span2 = tracer.spanBuilder("child-2").startSpan();
        try (var scope = span2.makeCurrent()) {
            doSleep(400);
        } finally {
            span2.end();
        }
    }


    private static void inferMeToo() {
        doSleep(300);
    }

    private static void doSleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

@@ -0,0 +1,396 @@
/*

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.

This file has also been copied unchaged.


void clear();

public static <T extends Recyclable> ObjectPool<T> createRecyclable(

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.

This method was the only change/addition in the pooling package, all other classes have been copied unchanged.

import java.security.NoSuchAlgorithmException;
import java.util.EnumSet;

public class ResourceExtractionUtil {

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.

This class also has been copied unchanged from the elastic apm agent

@JonasKunz

Copy link
Copy Markdown
Contributor Author

Related apm-data PR: apm-data/pull/185

Comment thread inferred-spans-otel/build.gradle.kts
Comment thread inferred-spans/src/main/java/co/elastic/apm/otel/profiler/NanoClock.java Outdated
Comment thread inferred-spans/src/main/java/co/elastic/apm/otel/profiler/StackFrame.java Outdated
Comment thread gradle/libs.versions.toml
result.fail();
}
});
// TODO: Replace with co.elastic.otel.util.ExecutorUtils

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.

[minor] why not do the change right now ?

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.

ExecutorUtils is not yet visible from here, because it is in the custom subproject. We'll need to move ExecutorUtils to a common project first.

JonasKunz and others added 5 commits January 9, 2024 12:08
Co-authored-by: SylvainJuge <763082+SylvainJuge@users.noreply.github.com>
@JonasKunz
JonasKunz merged commit b119f5e into elastic:main Jan 9, 2024
@JonasKunz
JonasKunz deleted the inferred-spans branch January 9, 2024 11:41
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.

Create standalone inferred spans extension

2 participants