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

First POC for external extension loading #2881

Merged
merged 25 commits into from
May 18, 2021
Merged
Show file tree
Hide file tree
Changes from 16 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
51 changes: 51 additions & 0 deletions examples/extension/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
group 'io.opentelemetry.example'
version '1.0-SNAPSHOT'

subprojects {
version = rootProject.version

apply plugin: "java"

ext {
versions = [
opentelemetry : "1.1.0",
opentelemetryJavaagent: "1.2.0-SNAPSHOT",
bytebuddy : "1.10.18",
guava : "30.1-jre"
]
versions.opentelemetryAlpha = "${versions.opentelemetry}-alpha"
versions.opentelemetryJavaagentAlpha = "1.2.0-alpha-SNAPSHOT"

deps = [
bytebuddy : dependencies.create(group: 'net.bytebuddy', name: 'byte-buddy', version: versions.bytebuddy),
bytebuddyagent : dependencies.create(group: 'net.bytebuddy', name: 'byte-buddy-agent', version: versions.bytebuddy),
autoservice : [
dependencies.create(group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc7'),
dependencies.create(group: 'com.google.auto', name: 'auto-common', version: '0.8'),
dependencies.create(group: 'com.google.guava', name: 'guava', version: "${versions.guava}"),
],
autoValueAnnotations: "com.google.auto.value:auto-value-annotations:${versions.autoValue}",
]
}

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
testImplementation("org.mockito:mockito-core:3.3.3")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.2")
}

tasks {
test {
useJUnitPlatform()
}

compileJava {
options.release.set(11)
}
}
}
20 changes: 20 additions & 0 deletions examples/extension/custom/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
plugins {
id "java"
}

dependencies {
compileOnly("io.opentelemetry:opentelemetry-sdk:${versions.opentelemetry}")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:${versions.opentelemetryAlpha}")

compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-spi:${versions.opentelemetryJavaagentAlpha}")
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-api:${versions.opentelemetryJavaagentAlpha}")
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:${versions.opentelemetryJavaagentAlpha}")

compileOnly deps.bytebuddy
compileOnly deps.bytebuddyagent
annotationProcessor deps.autoservice
compileOnly deps.autoservice

compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.javaagent;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.trace.IdGenerator;
import java.util.concurrent.atomic.AtomicLong;

/**
* Custom {@link IdGenerator} which provides span and trace ids.
*
* @see io.opentelemetry.sdk.trace.SdkTracerProvider
* @see DemoSdkTracerProviderConfigurer
*/
public class DemoIdGenerator implements IdGenerator {
private static final AtomicLong traceId = new AtomicLong(0);
private static final AtomicLong spanId = new AtomicLong(0);

@Override
public String generateSpanId() {
return String.format("%016d", spanId.incrementAndGet());
}

@Override
public String generateTraceId() {
return String.format("%032d", traceId.incrementAndGet());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.javaagent;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.context.propagation.TextMapSetter;
import java.util.Collections;
import java.util.List;

/**
* See <a href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/context/api-propagators.md">
* OpenTelemetry Specification</a> for more information about Propagators.
*
* @see DemoPropagatorProvider
*/
public class DemoPropagator implements TextMapPropagator {
private static final String FIELD = "X-demo-field";
private static final ContextKey<Long> PROPAGATION_START_KEY = ContextKey.named("propagation.start");

@Override
public List<String> fields() {
return Collections.singletonList(FIELD);
}

@Override
public <C> void inject(Context context, C carrier, TextMapSetter<C> setter) {
Long propagationStart = context.get(PROPAGATION_START_KEY);
if (propagationStart == null) {
propagationStart = System.currentTimeMillis();
}
setter.set(carrier, FIELD, String.valueOf(propagationStart));
}

@Override
public <C> Context extract(Context context, C carrier, TextMapGetter<C> getter) {
String propagationStart = getter.get(carrier, FIELD);
if (propagationStart != null) {
return context.with(PROPAGATION_START_KEY, Long.valueOf(propagationStart));
} else {
return context;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.javaagent;

import com.google.auto.service.AutoService;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider;

/**
* Registers the custom propagator used by this example.
*
* @see ConfigurablePropagatorProvider
* @see DemoPropagator
*/
@AutoService(ConfigurablePropagatorProvider.class)
public class DemoPropagatorProvider implements ConfigurablePropagatorProvider {
@Override
public TextMapPropagator getPropagator() {
return new DemoPropagator();
}

@Override
public String getName() {
return "demo";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.javaagent;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.spi.config.PropertySource;
import java.util.Map;

/**
* {@link PropertySource} is an SPI provided by OpenTelemetry Java instrumentation agent.
* By implementing it custom distributions can supply their own default configuration.
* The configuration priority, from highest to lowest is:
* system properties -> environment variables -> configuration file -> PropertySource SPI -> hard-coded defaults
*/
@AutoService(PropertySource.class)
public class DemoPropertySource implements PropertySource {

@Override
public Map<String, String> getProperties() {
return Map.of(
"otel.exporter.otlp.endpoint", "http://collector:55680",
"otel.exporter.otlp.insecure", "true",
"otel.config.max.attrs", "16"
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.javaagent;

import com.google.auto.service.AutoService;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;

@AutoService(ResourceProvider.class)
public class DemoResourceProvider implements ResourceProvider {
@Override
public Resource createResource(ConfigProperties config) {
Attributes attributes = Attributes.builder().put("custom.resource", "demo").build();
return Resource.create(attributes);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.javaagent;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
import java.util.List;

/**
* This demo sampler filters out all internal spans whose name contains string "greeting".
* <p>
* See <a href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#sampling">
* OpenTelemetry Specification</a> for more information about span sampling.
*
* @see DemoSdkTracerProviderConfigurer
*/
public class DemoSampler implements Sampler {
@Override
public SamplingResult shouldSample(Context parentContext, String traceId, String name,
SpanKind spanKind, Attributes attributes, List<LinkData> parentLinks) {
if (spanKind == SpanKind.INTERNAL && name.contains("greeting")) {
return SamplingResult.create(SamplingDecision.DROP);
} else {
return SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE);
}
}

@Override
public String getDescription() {
return "DemoSampler";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.javaagent;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.SdkTracerProviderConfigurer;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;

/**
* This is one of the main entry points for Instrumentation Agent's customizations.
* It allows configuring {@link SdkTracerProviderBuilder}.
* See the {@link #configure(SdkTracerProviderBuilder)} method below.
* <p>
* Also see https://github.com/open-telemetry/opentelemetry-java/issues/2022
*
* @see SdkTracerProviderConfigurer
* @see DemoPropagatorProvider
*/
@AutoService(SdkTracerProviderConfigurer.class)
public class DemoSdkTracerProviderConfigurer implements SdkTracerProviderConfigurer {
@Override
public void configure(SdkTracerProviderBuilder tracerProvider) {
tracerProvider
.setIdGenerator(new DemoIdGenerator())
.setSpanLimits(SpanLimits.builder().setMaxNumberOfAttributes(1024).build())
.setSampler(new DemoSampler())
.addSpanProcessor(new DemoSpanProcessor())
.addSpanProcessor(SimpleSpanProcessor.create(new DemoSpanExporter()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.javaagent;

import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.Collection;

/**
* See <a href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#span-exporter">
* OpenTelemetry Specification</a> for more information about {@link SpanExporter}.
*
* @see DemoSdkTracerProviderConfigurer
*/
public class DemoSpanExporter implements SpanExporter {
@Override
public CompletableResultCode export(Collection<SpanData> spans) {
System.out.printf("%d spans exported%n", spans.size());
return CompletableResultCode.ofSuccess();
}

@Override
public CompletableResultCode flush() {
return CompletableResultCode.ofSuccess();
}

@Override
public CompletableResultCode shutdown() {
return CompletableResultCode.ofSuccess();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.example.javaagent;

import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.SpanProcessor;

/**
* See <a href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#span-processor">
* OpenTelemetry Specification</a> for more information about {@link SpanProcessor}.
*
* @see DemoSdkTracerProviderConfigurer
*/
public class DemoSpanProcessor implements SpanProcessor {
@Override
public void onStart(Context parentContext, ReadWriteSpan span) {
span.setAttribute("custom", "demo");
}

@Override
public boolean isStartRequired() {
return true;
}

@Override
public void onEnd(ReadableSpan span) {

}

@Override
public boolean isEndRequired() {
return false;
}

@Override
public CompletableResultCode shutdown() {
return CompletableResultCode.ofSuccess();
}

@Override
public CompletableResultCode forceFlush() {
return CompletableResultCode.ofSuccess();
}
}
Loading