Skip to content

Commit

Permalink
Introduce minimal, zero-dependency tracer API within isolated module.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Mar 1, 2023
1 parent 5301136 commit 652b540
Show file tree
Hide file tree
Showing 171 changed files with 1,820 additions and 601 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ endif::[]
////
=== Unreleased
* Introduce *apm-agent-tracer* module that contains a minimal, zero-dependency `Tracer` API.
[[release-notes-1.37.0]]
==== 1.37.0 - YYYY/MM/DD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*/
package co.elastic.apm.agent.objectpool.impl;

import co.elastic.apm.agent.objectpool.Allocator;
import co.elastic.apm.agent.objectpool.Recyclable;
import co.elastic.apm.agent.objectpool.Resetter;
import co.elastic.apm.agent.tracer.pooling.Allocator;
import co.elastic.apm.agent.tracer.pooling.Recyclable;

import javax.annotation.Nullable;

Expand Down
5 changes: 5 additions & 0 deletions apm-agent-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
<artifactId>apm-agent-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>apm-agent-tracer</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>apm-agent-cached-lookup-key</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@
import co.elastic.apm.agent.impl.sampling.Sampler;
import co.elastic.apm.agent.impl.stacktrace.StacktraceConfiguration;
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
import co.elastic.apm.agent.impl.transaction.BinaryHeaderGetter;
import co.elastic.apm.agent.impl.transaction.ElasticContext;
import co.elastic.apm.agent.impl.transaction.Span;
import co.elastic.apm.agent.impl.transaction.TextHeaderGetter;
import co.elastic.apm.agent.impl.transaction.TraceContext;
import co.elastic.apm.agent.impl.transaction.Transaction;
import co.elastic.apm.agent.logging.LoggingConfiguration;
Expand All @@ -50,6 +48,9 @@
import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap;
import co.elastic.apm.agent.util.DependencyInjectingServiceLoader;
import co.elastic.apm.agent.util.ExecutorUtils;
import co.elastic.apm.agent.tracer.Scope;
import co.elastic.apm.agent.tracer.dispatch.BinaryHeaderGetter;
import co.elastic.apm.agent.tracer.dispatch.TextHeaderGetter;
import org.stagemonitor.configuration.ConfigurationOption;
import org.stagemonitor.configuration.ConfigurationOptionProvider;
import org.stagemonitor.configuration.ConfigurationRegistry;
Expand Down Expand Up @@ -290,7 +291,7 @@ public Span startSpan(AbstractSpan<?> parent, long epochMicros) {
* @param parentContext the trace context of the parent
* @param epochMicros the start timestamp of the span in microseconds after epoch
* @return a new started span
* @see #startSpan(TraceContext.ChildContextCreator, Object)
* @see #startSpan(ChildContextCreator, Object)
*/
public <T> Span startSpan(TraceContext.ChildContextCreator<T> childContextCreator, T parentContext, long epochMicros) {
return createSpan().start(childContextCreator, parentContext, epochMicros);
Expand Down Expand Up @@ -374,8 +375,14 @@ public ConfigurationRegistry getConfigurationRegistry() {
return configurationRegistry;
}

public <T extends ConfigurationOptionProvider> T getConfig(Class<T> configProvider) {
return configurationRegistry.getConfig(configProvider);
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> T getConfig(Class<T> configProvider) {
if (ConfigurationOptionProvider.class.isAssignableFrom(configProvider)) {
return (T) configurationRegistry.getConfig((Class) configProvider);
} else {
return null;
}
}

public void endTransaction(Transaction transaction) {
Expand Down Expand Up @@ -516,6 +523,7 @@ public Sampler getSampler() {
return sampler;
}

@Override
public ObjectPoolFactory getObjectPoolFactory() {
return objectPoolFactory;
}
Expand Down Expand Up @@ -756,7 +764,7 @@ public void activate(ElasticContext<?> context) {
public Scope activateInScope(final ElasticContext<?> context) {
// already in scope
if (currentContext() == context) {
return Scope.NoopScope.INSTANCE;
return NoopScope.INSTANCE;
}
context.activate();

Expand Down Expand Up @@ -837,4 +845,23 @@ public ScheduledThreadPoolExecutor getSharedSingleThreadedPool() {
public void addShutdownHook(Closeable closeable) {
lifecycleListeners.add(ClosableLifecycleListenerAdapter.of(closeable));
}

@Nullable
@Override
public <T extends co.elastic.apm.agent.tracer.Tracer> T probe(Class<T> type) {
if (type.isInstance(this)) {
return type.cast(this);
} else {
return null;
}
}

@Override
public <T extends co.elastic.apm.agent.tracer.Tracer> T require(Class<T> type) {
T cast = probe(type);
if (cast == null) {
throw new IllegalStateException(this + " does not implement " + type.getName());
}
return cast;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
import co.elastic.apm.agent.impl.error.ErrorCapture;
import co.elastic.apm.agent.impl.sampling.Sampler;
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
import co.elastic.apm.agent.impl.transaction.BinaryHeaderGetter;
import co.elastic.apm.agent.impl.transaction.Span;
import co.elastic.apm.agent.impl.transaction.TextHeaderGetter;
import co.elastic.apm.agent.impl.transaction.Transaction;
import co.elastic.apm.agent.util.PrivilegedActionUtils;
import co.elastic.apm.agent.util.VersionUtils;
import co.elastic.apm.agent.tracer.dispatch.BinaryHeaderGetter;
import co.elastic.apm.agent.tracer.dispatch.TextHeaderGetter;
import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory;

import javax.annotation.Nullable;
import java.io.File;
Expand Down Expand Up @@ -231,4 +232,25 @@ public boolean isRunning() {
public Span createExitChildSpan() {
return tracer.createExitChildSpan();
}

@Nullable
@Override
public <T extends co.elastic.apm.agent.tracer.Tracer> T probe(Class<T> type) {
return tracer.probe(type);
}

@Override
public <T extends co.elastic.apm.agent.tracer.Tracer> T require(Class<T> type) {
return tracer.require(type);
}

@Override
public <T> T getConfig(Class<T> configuration) {
return tracer.getConfig(configuration);
}

@Override
public ObjectPoolFactory getObjectPoolFactory() {
return tracer.getObjectPoolFactory();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package co.elastic.apm.agent.impl;

import co.elastic.apm.agent.tracer.Scope;

public class NoopScope implements Scope {

public static final Scope INSTANCE = new NoopScope();

private NoopScope() {
}

@Override
public void close() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
import co.elastic.apm.agent.impl.error.ErrorCapture;
import co.elastic.apm.agent.impl.sampling.Sampler;
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
import co.elastic.apm.agent.impl.transaction.BinaryHeaderGetter;
import co.elastic.apm.agent.impl.transaction.Span;
import co.elastic.apm.agent.impl.transaction.TextHeaderGetter;
import co.elastic.apm.agent.impl.transaction.Transaction;
import co.elastic.apm.agent.objectpool.ObjectPoolFactory;
import co.elastic.apm.agent.tracer.dispatch.BinaryHeaderGetter;
import co.elastic.apm.agent.tracer.dispatch.TextHeaderGetter;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -154,4 +155,25 @@ public boolean isRunning() {
public Span createExitChildSpan() {
return null;
}

@Nullable
@Override
public <T extends co.elastic.apm.agent.tracer.Tracer> T probe(Class<T> type) {
return null;
}

@Override
public <T extends co.elastic.apm.agent.tracer.Tracer> T require(Class<T> type) {
throw new IllegalStateException();
}

@Override
public <T> T getConfig(Class<T> configuration) {
return null;
}

@Override
public co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory getObjectPoolFactory() {
return new ObjectPoolFactory();
}
}
43 changes: 10 additions & 33 deletions apm-agent-core/src/main/java/co/elastic/apm/agent/impl/Tracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,18 @@
import co.elastic.apm.agent.impl.error.ErrorCapture;
import co.elastic.apm.agent.impl.sampling.Sampler;
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
import co.elastic.apm.agent.impl.transaction.BinaryHeaderGetter;
import co.elastic.apm.agent.impl.transaction.HeaderGetter;
import co.elastic.apm.agent.impl.transaction.Span;
import co.elastic.apm.agent.impl.transaction.TextHeaderGetter;
import co.elastic.apm.agent.impl.transaction.Transaction;
import co.elastic.apm.agent.tracer.dispatch.BinaryHeaderGetter;
import co.elastic.apm.agent.tracer.dispatch.HeaderGetter;
import co.elastic.apm.agent.tracer.dispatch.TextHeaderGetter;

import javax.annotation.Nullable;

public interface Tracer {
public interface Tracer extends co.elastic.apm.agent.tracer.Tracer {

/**
* Starts a trace-root transaction
*
* @param initiatingClassLoader the class loader corresponding to the service which initiated the creation of the transaction.
* Used to determine the service name.
* @return a transaction that will be the root of the current trace if the agent is currently RUNNING; null otherwise
*/
@Nullable
@Override
Transaction startRootTransaction(@Nullable ClassLoader initiatingClassLoader);

@Nullable
Expand All @@ -58,17 +52,7 @@ public interface Tracer {
@Nullable
Transaction startRootTransaction(Sampler sampler, long epochMicros, @Nullable ClassLoader initiatingClassLoader);

/**
* Starts a transaction as a child of the context headers obtained through the provided {@link HeaderGetter}.
* If the created transaction cannot be started as a child transaction (for example - if no parent context header is
* available), then it will be started as the root transaction of the trace.
*
* @param headerCarrier the Object from which context headers can be obtained, typically a request or a message
* @param textHeadersGetter provides the trace context headers required in order to create a child transaction
* @param initiatingClassLoader the class loader corresponding to the service which initiated the creation of the transaction.
* Used to determine the service name.
* @return a transaction which is a child of the provided parent if the agent is currently RUNNING; null otherwise
*/
@Override
@Nullable
<C> Transaction startChildTransaction(@Nullable C headerCarrier, TextHeaderGetter<C> textHeadersGetter, @Nullable ClassLoader initiatingClassLoader);

Expand All @@ -93,17 +77,7 @@ public interface Tracer {
<C> Transaction startChildTransaction(@Nullable C headerCarrier, TextHeaderGetter<C> textHeadersGetter, Sampler sampler,
long epochMicros, @Nullable ClassLoader initiatingClassLoader);

/**
* Starts a transaction as a child of the context headers obtained through the provided {@link HeaderGetter}.
* If the created transaction cannot be started as a child transaction (for example - if no parent context header is
* available), then it will be started as the root transaction of the trace.
*
* @param headerCarrier the Object from which context headers can be obtained, typically a request or a message
* @param binaryHeadersGetter provides the trace context headers required in order to create a child transaction
* @param initiatingClassLoader the class loader corresponding to the service which initiated the creation of the transaction.
* Used to determine the service name.
* @return a transaction which is a child of the provided parent if the agent is currently RUNNING; null otherwise
*/
@Override
@Nullable
<C> Transaction startChildTransaction(@Nullable C headerCarrier, BinaryHeaderGetter<C> binaryHeadersGetter, @Nullable ClassLoader initiatingClassLoader);

Expand All @@ -125,9 +99,11 @@ <C> Transaction startChildTransaction(@Nullable C headerCarrier, TextHeaderGette
<C> Transaction startChildTransaction(@Nullable C headerCarrier, BinaryHeaderGetter<C> binaryHeadersGetter,
Sampler sampler, long epochMicros, @Nullable ClassLoader initiatingClassLoader);

@Override
@Nullable
Transaction currentTransaction();

@Override
@Nullable
AbstractSpan<?> getActive();

Expand Down Expand Up @@ -174,6 +150,7 @@ <C> Transaction startChildTransaction(@Nullable C headerCarrier, BinaryHeaderGet
*/
void stop();

@Override
boolean isRunning();

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
*/
package co.elastic.apm.agent.impl.context;

import co.elastic.apm.agent.objectpool.Recyclable;
import co.elastic.apm.agent.tracer.pooling.Recyclable;

import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractContext implements Recyclable {
public abstract class AbstractContext implements Recyclable, co.elastic.apm.agent.tracer.AbstractContext {

public static final String REDACTED_CONTEXT_STRING = "[REDACTED]";

Expand Down Expand Up @@ -72,6 +72,7 @@ public boolean hasLabels() {
return !labels.isEmpty();
}

@Override
public Message getMessage() {
return message;
}
Expand Down
Loading

0 comments on commit 652b540

Please sign in to comment.