Skip to content

Commit

Permalink
Merge branch 'main' into external-plugin-application-class-loader
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiasstadler authored Jan 27, 2022
2 parents 8384c32 + c4d6148 commit e255dca
Show file tree
Hide file tree
Showing 39 changed files with 445 additions and 100 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ endif::[]
* Adding agent logging capabilities to our SDK, making it available for external plugins - {pull}2390[#2390]
* When the `MANIFEST.MF` of the main jar contains the `Implementation-Title` attribute, it is used as the default service name - {pull}1921[#1921]
Note: this may change your service names if you relied on the auto-discovery that uses the name of the jar file. If that jar file also contains an `Implementation-Title` attribute in the `MANIFEST.MF` file, the latter will take precedence.
* When the MANIFEST.MF of the main jar contains the Implementation-Version attribute, it is used as the default service version (except for application servers) - {pull}1922[#1922]
* When the `MANIFEST.MF` of the main jar contains the `Implementation-Version` attribute, it is used as the default service version (except for application servers) - {pull}1922[#1922]
* Added support for overwritting the service version per classloader - {pull}1726[#1726]
* Added support for setting the application class loader when starting a transaction via the public api - {pull}2369[#2369]
[float]
Expand All @@ -45,6 +46,7 @@ paths. The BCI warmup is on by default and may be disabled through the internal
** Dubbo transaction will should be created at the provider side
** APM headers conversion issue within dubbo transaction
* Fix External plugins automatic setting of span outcome - {pull}2376[#2376]
* Avoid early initialization of JMX on Weblogic - {pull}2420[#2420]
[[release-notes-1.x]]
=== Java Agent version 1.x
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
public class ElasticApmTracer implements Tracer {
private static final Logger logger = LoggerFactory.getLogger(ElasticApmTracer.class);

private static final WeakMap<ClassLoader, String> serviceNameByClassLoader = WeakConcurrent.buildMap();
private static final WeakMap<ClassLoader, ServiceInfo> serviceInfoByClassLoader = WeakConcurrent.buildMap();

private final ConfigurationRegistry configurationRegistry;
private final StacktraceConfiguration stacktraceConfiguration;
Expand Down Expand Up @@ -230,9 +230,10 @@ private void afterTransactionStart(@Nullable ClassLoader initiatingClassLoader,
new RuntimeException("this exception is just used to record where the transaction has been started from"));
}
}
final String serviceName = getServiceName(initiatingClassLoader);
if (serviceName != null) {
transaction.getTraceContext().setServiceName(serviceName);
final ServiceInfo serviceInfo = getServiceInfo(initiatingClassLoader);
if (serviceInfo != null) {
transaction.getTraceContext().setServiceName(serviceInfo.getServiceName());
transaction.getTraceContext().setServiceVersion(serviceInfo.getServiceVersion());
}
}

Expand Down Expand Up @@ -342,7 +343,11 @@ private ErrorCapture captureException(long epochMicros, @Nullable Throwable e, @
parent.setNonDiscardable();
} else {
error.getTraceContext().getId().setToRandomValue();
error.getTraceContext().setServiceName(getServiceName(initiatingClassLoader));
ServiceInfo serviceInfo = getServiceInfo(initiatingClassLoader);
if (serviceInfo != null) {
error.getTraceContext().setServiceName(serviceInfo.getServiceName());
error.getTraceContext().setServiceVersion(serviceInfo.getServiceVersion());
}
}
return error;
}
Expand Down Expand Up @@ -734,17 +739,22 @@ public MetricRegistry getMetricRegistry() {
return metricRegistry;
}

public List<String> getServiceNameOverrides() {
List<String> serviceNames = new ArrayList<>(serviceNameByClassLoader.approximateSize());
for (Map.Entry<ClassLoader, String> entry : serviceNameByClassLoader) {
serviceNames.add(entry.getValue());
public List<ServiceInfo> getServiceInfoOverrides() {
List<ServiceInfo> serviceInfos = new ArrayList<>(serviceInfoByClassLoader.approximateSize());
for (Map.Entry<ClassLoader, ServiceInfo> entry : serviceInfoByClassLoader) {
serviceInfos.add(entry.getValue());
}
return serviceNames;
return serviceInfos;
}

@Override
public void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName) {
overrideServiceInfoForClassLoader(classLoader, serviceName, null);
}

@Override
public void overrideServiceNameForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName) {
// overriding the service name for the bootstrap class loader is not an actual use-case
public void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName, @Nullable String serviceVersion) {
// overriding the service name/version for the bootstrap class loader is not an actual use-case
// null may also mean we don't know about the initiating class loader
if (classLoader == null
|| serviceName == null || serviceName.isEmpty()
Expand All @@ -753,23 +763,23 @@ public void overrideServiceNameForClassLoader(@Nullable ClassLoader classLoader,
return;
}

String sanitizedServiceName = ServiceInfo.replaceDisallowedServiceNameChars(serviceName);
logger.debug("Using `{}` as the service name for class loader [{}]", sanitizedServiceName, classLoader);
if (!serviceNameByClassLoader.containsKey(classLoader)) {
serviceNameByClassLoader.putIfAbsent(classLoader, sanitizedServiceName);
ServiceInfo serviceInfo = new ServiceInfo(serviceName, serviceVersion);
logger.debug("Using `{}` as the service name and `{}` as the service version for class loader [{}]", serviceInfo.getServiceName(), serviceInfo.getServiceVersion(), classLoader);
if (!serviceInfoByClassLoader.containsKey(classLoader)) {
serviceInfoByClassLoader.putIfAbsent(classLoader, new ServiceInfo(serviceName, serviceVersion));
}
}

@Nullable
private String getServiceName(@Nullable ClassLoader initiatingClassLoader) {
private ServiceInfo getServiceInfo(@Nullable ClassLoader initiatingClassLoader) {
if (initiatingClassLoader == null) {
return null;
}
return serviceNameByClassLoader.get(initiatingClassLoader);
return serviceInfoByClassLoader.get(initiatingClassLoader);
}

public void resetServiceNameOverrides() {
serviceNameByClassLoader.clear();
public void resetServiceInfoOverrides() {
serviceInfoByClassLoader.clear();
}

public ApmServerClient getApmServerClient() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,13 @@ public TracerState getState() {
}

@Override
public void overrideServiceNameForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName) {
tracer.overrideServiceNameForClassLoader(classLoader, serviceName);
public void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName) {
tracer.overrideServiceInfoForClassLoader(classLoader, serviceName);
}

@Override
public void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName, @Nullable String serviceVersion) {
tracer.overrideServiceInfoForClassLoader(classLoader, serviceName, serviceVersion);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ public TracerState getState() {
}

@Override
public void overrideServiceNameForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName) {
public void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName) {
}

@Override
public void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName, @Nullable String serviceVersion) {
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,20 @@ <C> Transaction startChildTransaction(@Nullable C headerCarrier, BinaryHeaderGet
* @param classLoader the class loader which corresponds to a particular service
* @param serviceName the service name for this class loader
*/
void overrideServiceNameForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName);
void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName);

/**
* Overrides the service name and version for all {@link Transaction}s,
* {@link Span}s and {@link ErrorCapture}s which are created by the service which corresponds to the provided {@link ClassLoader}.
* <p>
* The main use case is being able to differentiate between multiple services deployed to the same application server.
* </p>
*
* @param classLoader the class loader which corresponds to a particular service
* @param serviceName the service name for this class loader
* @param serviceVersion the service version for this class loader
*/
void overrideServiceInfoForClassLoader(@Nullable ClassLoader classLoader, @Nullable String serviceName, @Nullable String serviceVersion);

/**
* Called when the container shuts down.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ public static <S, D> void copyTraceContextTextHeaders(S source, TextHeaderGetter
@Nullable
private String serviceName;

@Nullable
private String serviceVersion;

private TraceContext(ElasticApmTracer tracer, Id id) {
coreConfiguration = tracer.getConfig(CoreConfiguration.class);
traceState = new TraceState();
Expand Down Expand Up @@ -436,6 +439,7 @@ public void asChildOf(TraceContext parent) {
id.setToRandomValue();
clock.init(parent.clock);
serviceName = parent.serviceName;
serviceVersion = parent.serviceVersion;
applicationClassLoader = parent.applicationClassLoader;
traceState.copyFrom(parent.traceState);
onMutation();
Expand All @@ -452,6 +456,7 @@ public void resetState() {
discardable = true;
clock.resetState();
serviceName = null;
serviceVersion = null;
applicationClassLoader = null;
traceState.resetState();
traceState.setSizeLimit(coreConfiguration.getTracestateSizeLimit());
Expand Down Expand Up @@ -652,6 +657,7 @@ public void copyFrom(TraceContext other) {
discardable = other.discardable;
clock.init(other.clock);
serviceName = other.serviceName;
serviceVersion = other.serviceVersion;
applicationClassLoader = other.applicationClassLoader;
traceState.copyFrom(other.traceState);
onMutation();
Expand Down Expand Up @@ -684,6 +690,20 @@ public void setServiceName(@Nullable String serviceName) {
this.serviceName = serviceName;
}

@Nullable
public String getServiceVersion() {
return serviceVersion;
}

/**
* Overrides the {@code co.elastic.apm.agent.impl.payload.Service#version} property sent via the meta data Intake V2 event.
*
* @param serviceVersion the service version for this event
*/
public void setServiceVersion(@Nullable String serviceVersion) {
this.serviceVersion = serviceVersion;
}

public Span createSpan() {
return tracer.startSpan(fromParentContext(), this);
}
Expand Down Expand Up @@ -753,7 +773,7 @@ public void serialize(byte[] buffer) {
ByteUtils.putLong(buffer, offset, clock.getOffset());
}

private void asChildOf(byte[] buffer, @Nullable String serviceName) {
private void asChildOf(byte[] buffer, @Nullable String serviceName, @Nullable String serviceVersion) {
int offset = 0;
offset += traceId.fromBytes(buffer, offset);
offset += parentId.fromBytes(buffer, offset);
Expand All @@ -763,10 +783,11 @@ private void asChildOf(byte[] buffer, @Nullable String serviceName) {
discardable = buffer[offset++] == (byte) 1;
clock.init(ByteUtils.getLong(buffer, offset));
this.serviceName = serviceName;
this.serviceVersion = serviceVersion;
onMutation();
}

public void deserialize(byte[] buffer, @Nullable String serviceName) {
public void deserialize(byte[] buffer, @Nullable String serviceName, @Nullable String serviceVersion) {
int offset = 0;
offset += traceId.fromBytes(buffer, offset);
offset += id.fromBytes(buffer, offset);
Expand All @@ -775,6 +796,7 @@ public void deserialize(byte[] buffer, @Nullable String serviceName) {
discardable = buffer[offset++] == (byte) 1;
clock.init(ByteUtils.getLong(buffer, offset));
this.serviceName = serviceName;
this.serviceVersion = serviceVersion;
onMutation();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,10 @@ private void trackMetrics() {
}
final Labels.Mutable labels = labelsThreadLocal.get();
labels.resetState();
labels.serviceName(getTraceContext().getServiceName()).transactionName(name).transactionType(type);
labels.serviceName(getTraceContext().getServiceName())
.serviceVersion(getTraceContext().getServiceVersion())
.transactionName(name)
.transactionType(type);
final MetricRegistry metricRegistry = tracer.getMetricRegistry();
long criticalValueAtEnter = metricRegistry.writerCriticalSectionEnter();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public interface Labels {
@Nullable
String getServiceName();

@Nullable
String getServiceVersion();

@Nullable
CharSequence getTransactionName();

Expand Down Expand Up @@ -92,7 +95,7 @@ public List<CharSequence> getValues() {
}

public boolean isEmpty() {
return keys.isEmpty() && getServiceName() == null && getTransactionName() == null && getTransactionType() == null && getSpanType() == null;
return keys.isEmpty() && getServiceName() == null && getServiceVersion() == null && getTransactionName() == null && getTransactionType() == null && getSpanType() == null;
}

public int size() {
Expand All @@ -117,6 +120,7 @@ public boolean equals(Object o) {
Objects.equals(getTransactionType(), labels.getTransactionType()) &&
contentEquals(getTransactionName(), labels.getTransactionName()) &&
Objects.equals(getServiceName(), labels.getServiceName()) &&
Objects.equals(getServiceVersion(), labels.getServiceVersion()) &&
keys.equals(labels.keys) &&
isEqual(values, labels.values);
}
Expand All @@ -128,6 +132,7 @@ public int hashCode() {
h = 31 * h + hashEntryAt(i);
}
h = 31 * h + hash(getServiceName());
h = 31 * h + hash(getServiceVersion());
h = 31 * h + hash(getTransactionName());
h = 31 * h + (getTransactionType() != null ? getTransactionType().hashCode() : 0);
h = 31 * h + (getSpanType() != null ? getSpanType().hashCode() : 0);
Expand Down Expand Up @@ -205,6 +210,8 @@ class Mutable extends AbstractBase implements Recyclable {
@Nullable
private String serviceName;
@Nullable
private String serviceVersion;
@Nullable
private CharSequence transactionName;
@Nullable
private String transactionType;
Expand Down Expand Up @@ -246,6 +253,11 @@ public Labels.Mutable serviceName(@Nullable String serviceName) {
return this;
}

public Labels.Mutable serviceVersion(@Nullable String serviceVersion) {
this.serviceVersion = serviceVersion;
return this;
}

public Labels.Mutable transactionName(@Nullable CharSequence transactionName) {
this.transactionName = transactionName;
return this;
Expand All @@ -271,6 +283,11 @@ public String getServiceName() {
return serviceName;
}

@Nullable
public String getServiceVersion() {
return serviceVersion;
}

@Nullable
public CharSequence getTransactionName() {
return transactionName;
Expand Down Expand Up @@ -301,6 +318,7 @@ public void resetState() {
keys.clear();
values.clear();
serviceName = null;
serviceVersion = null;
transactionName = null;
transactionType = null;
spanType = null;
Expand All @@ -323,6 +341,8 @@ class Immutable extends AbstractBase {
@Nullable
private final String serviceName;
@Nullable
private final String serviceVersion;
@Nullable
private final String transactionName;
@Nullable
private final String transactionType;
Expand All @@ -334,6 +354,7 @@ class Immutable extends AbstractBase {
public Immutable(Labels labels) {
super(new ArrayList<>(labels.getKeys()), copy(labels.getValues()));
this.serviceName = labels.getServiceName();
this.serviceVersion = labels.getServiceVersion();
final CharSequence transactionName = labels.getTransactionName();
this.transactionName = transactionName != null ? transactionName.toString() : null;
this.transactionType = labels.getTransactionType();
Expand Down Expand Up @@ -365,6 +386,12 @@ public String getServiceName() {
return serviceName;
}

@Nullable
@Override
public String getServiceVersion() {
return serviceVersion;
}

@Nullable
@Override
public String getTransactionName() {
Expand Down
Loading

0 comments on commit e255dca

Please sign in to comment.