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

Add Inferred spans extension #47

Merged
merged 21 commits into from
Jan 9, 2024
Merged

Add Inferred spans extension #47

merged 21 commits into from
Jan 9, 2024

Conversation

JonasKunz
Copy link
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
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
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
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
Contributor Author

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

gradle/libs.versions.toml Outdated Show resolved Hide resolved
result.fail();
}
});
// TODO: Replace with co.elastic.otel.util.ExecutorUtils
Copy link
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
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 JonasKunz merged commit b119f5e into elastic:main Jan 9, 2024
2 checks passed
@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