Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ lmax-disruptor = "com.lmax:disruptor:3.4.4"
jctools = "org.jctools:jctools-core:4.0.3"
github-api = "org.kohsuke:github-api:1.321"
apachecommons-compress = "org.apache.commons:commons-compress:1.26.1"
asyncprofiler = "tools.profiler:async-profiler:1.8.3"
asyncprofiler = "tools.profiler:async-profiler:3.0"

freemarker = "org.freemarker:freemarker:2.3.32"

Expand Down
4 changes: 2 additions & 2 deletions inferred-spans/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ dependencies {
compileOnly(libs.findbugs.jsr305)
implementation(libs.lmax.disruptor)
implementation(libs.jctools)
implementation(project(":common"))
implementation(libs.asyncprofiler)
implementation(libs.bundles.semconv)
implementation(project(":common"))

testAnnotationProcessor(libs.autoservice.processor)
testCompileOnly(libs.autoservice.annotations)
Expand All @@ -25,7 +26,6 @@ dependencies {
testImplementation(libs.awaitility)
testImplementation(libs.github.api)
testImplementation(libs.apachecommons.compress)
testImplementation(libs.asyncprofiler)
testImplementation(libs.bundles.semconv)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

import co.elastic.otel.common.config.WildcardMatcher;
import co.elastic.otel.common.util.ExecutorUtils;
import co.elastic.otel.profiler.asyncprofiler.AsyncProfiler;
import co.elastic.otel.profiler.asyncprofiler.JfrParser;
import co.elastic.otel.profiler.collections.Long2ObjectHashMap;
import co.elastic.otel.profiler.pooling.Allocator;
Expand Down Expand Up @@ -60,6 +59,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import one.profiler.AsyncProfiler;

/**
* Correlates {@link ActivationEvent}s with {@link StackFrame}s which are recorded by {@link
Expand Down Expand Up @@ -112,6 +112,8 @@
*/
class SamplingProfiler implements Runnable {

private static final String LIB_DIR_PROPERTY_NAME = "one.profiler.extractPath";

private static final Logger logger = Logger.getLogger(SamplingProfiler.class.getName());
private static final int ACTIVATION_EVENTS_IN_FILE = 1_000_000;
private static final int MAX_STACK_DEPTH = 256;
Expand Down Expand Up @@ -179,6 +181,8 @@ public void translateTo(

private final Supplier<Tracer> tracerProvider;

private final AsyncProfiler profiler;

/**
* Creates a sampling profiler, optionally relying on existing files.
*
Expand Down Expand Up @@ -230,9 +234,21 @@ public CallTree.Root createInstance() {
this.jfrFile = jfrFile;
activationEventsBuffer = ByteBuffer.allocateDirect(ACTIVATION_EVENTS_BUFFER_SIZE);
this.activationEventsFile = activationEventsFile;
profiler = loadProfiler();
activationListener = ProfilingActivationListener.register(this);
}

private AsyncProfiler loadProfiler() {
String libDir = config.getProfilerLibDirectory();
try {
Files.createDirectories(Paths.get(libDir));
} catch (IOException e) {
throw new RuntimeException("Failed to create directory to extract lib to", e);
}
System.setProperty(LIB_DIR_PROPERTY_NAME, libDir);
return AsyncProfiler.getInstance();
}

/**
* For testing only! This method must only be called in tests and some period after activation /
* deactivation events, as otherwise it is racy.
Expand Down Expand Up @@ -309,9 +325,7 @@ public ActivationEvent newInstance() {
public boolean onActivation(Span activeSpan, @Nullable Span previouslyActive) {
if (profilingSessionOngoing) {
if (previouslyActive == null) {
AsyncProfiler.getInstance(
config.getProfilerLibDirectory(), config.getAsyncProfilerSafeMode())
.enableProfilingCurrentThread();
profiler.addThread(Thread.currentThread());
}
boolean success =
eventBuffer.tryPublishEvent(ACTIVATION_EVENT_TRANSLATOR, activeSpan, previouslyActive);
Expand All @@ -337,9 +351,7 @@ public boolean onActivation(Span activeSpan, @Nullable Span previouslyActive) {
public boolean onDeactivation(Span activeSpan, @Nullable Span previouslyActive) {
if (profilingSessionOngoing) {
if (previouslyActive == null) {
AsyncProfiler.getInstance(
config.getProfilerLibDirectory(), config.getAsyncProfilerSafeMode())
.disableProfilingCurrentThread();
profiler.removeThread(Thread.currentThread());
}
boolean success =
eventBuffer.tryPublishEvent(DEACTIVATION_EVENT_TRANSLATOR, activeSpan, previouslyActive);
Expand Down Expand Up @@ -393,15 +405,12 @@ public void run() {
}

private void profile(Duration profilingDuration) throws Exception {
AsyncProfiler asyncProfiler =
AsyncProfiler.getInstance(
config.getProfilerLibDirectory(), config.getAsyncProfilerSafeMode());
try {
String startCommand = createStartCommand();
String startMessage = asyncProfiler.execute(startCommand);
String startMessage = profiler.execute(startCommand);
logger.fine(startMessage);
if (!profiledThreads.isEmpty()) {
restoreFilterState(asyncProfiler);
restoreFilterState(profiler);
}
// Doesn't need to be atomic as this field is being updated only by a single thread
//noinspection NonAtomicOperationOnVolatileField
Expand All @@ -414,7 +423,7 @@ private void profile(Duration profilingDuration) throws Exception {
// residual activation events if post-processing is disabled dynamically
consumeActivationEventsFromRingBufferAndWriteToFile(profilingDuration);

String stopMessage = asyncProfiler.execute("stop");
String stopMessage = profiler.execute("stop");
logger.fine(stopMessage);

// When post-processing is disabled, jfr file will not be parsed and the heavy processing will
Expand All @@ -423,7 +432,7 @@ private void profile(Duration profilingDuration) throws Exception {
processTraces();
} catch (InterruptedException | ClosedByInterruptException e) {
try {
asyncProfiler.stop();
profiler.stop();
} catch (IllegalStateException ignore) {
}
Thread.currentThread().interrupt();
Expand All @@ -439,7 +448,7 @@ String createStartCommand() {
.append(",safemode=")
.append(config.getAsyncProfilerSafeMode());
if (!config.isProfilingLoggingEnabled()) {
startCommand.append(",log=none");
startCommand.append(",loglevel=none");
}
return startCommand.toString();
}
Expand All @@ -460,7 +469,7 @@ public boolean test(Thread thread, Long2ObjectHashMap<?>.KeySet profiledThreads)
new ThreadMatcher.NonCapturingConsumer<Thread, AsyncProfiler>() {
@Override
public void accept(Thread thread, AsyncProfiler asyncProfiler) {
asyncProfiler.enableProfilingThread(thread);
asyncProfiler.addThread(thread);
}
},
asyncProfiler);
Expand Down Expand Up @@ -531,7 +540,7 @@ public void processTraces() throws IOException {
processActivationEventsUpTo(stackTrace.nanoTime, event, eof);
CallTree.Root root = profiledThreads.get(stackTrace.threadId);
if (root != null) {
jfrParser.resolveStackTrace(stackTrace.stackTraceId, true, stackFrames, MAX_STACK_DEPTH);
jfrParser.resolveStackTrace(stackTrace.stackTraceId, stackFrames, MAX_STACK_DEPTH);
if (stackFrames.size() == MAX_STACK_DEPTH) {
logger.fine(
"Max stack depth reached. Set profiling_included_classes or profiling_excluded_classes.");
Expand Down

This file was deleted.

Loading