From 7048f661fe7d4bf8bfed0c566d0f1ac0eafc86b3 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 3 Oct 2023 10:51:03 -0500 Subject: [PATCH] Demonstrate file based configuration of RuleBasedRoutingSampler --- build.gradle | 1 + file-configuration/build.gradle | 15 +++-- file-configuration/otel-sdk-config.yaml | 23 +++---- .../examples/fileconfig/Application.java | 67 ++++++++----------- .../examples/fileconfig/Controller.java | 52 ++++++++++++++ 5 files changed, 104 insertions(+), 54 deletions(-) create mode 100644 file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Controller.java diff --git a/build.gradle b/build.gradle index a18409bb00..bb8a6dd5e9 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ subprojects { repositories { mavenCentral() + mavenLocal() } dependencies { diff --git a/file-configuration/build.gradle b/file-configuration/build.gradle index 53478b6700..0fd0ebddfb 100644 --- a/file-configuration/build.gradle +++ b/file-configuration/build.gradle @@ -1,18 +1,25 @@ plugins { id 'java' - id 'application' + id 'org.springframework.boot' version '2.7.16' + id 'io.spring.dependency-management' version '1.1.3' } description = 'OpenTelemetry Example for File Configuration' ext.moduleName = "io.opentelemetry.examples.fileconfig" dependencies { + //spring modules + implementation("org.springframework.boot:spring-boot-starter-web") + implementation 'org.springframework.boot:spring-boot-starter-actuator' + + implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.31.0-alpha-SNAPSHOT') implementation("io.opentelemetry:opentelemetry-api") implementation("io.opentelemetry:opentelemetry-sdk") implementation("io.opentelemetry:opentelemetry-exporter-logging") implementation("io.opentelemetry:opentelemetry-sdk-extension-incubator") -} -application { - mainClass = 'io.opentelemetry.examples.fileconfig.Application' + implementation "io.opentelemetry.contrib:opentelemetry-samplers:1.31.0-alpha-SNAPSHOT" + + implementation platform('io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:1.29.0-alpha') + implementation 'io.opentelemetry.instrumentation:opentelemetry-spring-webmvc-5.3' } diff --git a/file-configuration/otel-sdk-config.yaml b/file-configuration/otel-sdk-config.yaml index deff810f21..d751549773 100644 --- a/file-configuration/otel-sdk-config.yaml +++ b/file-configuration/otel-sdk-config.yaml @@ -10,17 +10,16 @@ tracer_provider: - batch: exporter: console: {} - -meter_provider: - readers: - - periodic: - exporter: - console: {} - views: - - selector: - instrument_type: histogram - stream: - aggregation: - drop: {} + sampler: + parent_based: + root: + rule_based_routing_sampler: + fallback: always_on + span_kind: SERVER + drop_rules: + - attribute: http.target + pattern: "/actuator.*" + - attribute: http.target + pattern: "/foo" propagators: [tracecontext, baggage] diff --git a/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Application.java b/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Application.java index 24a469eddd..6b2c005a9e 100644 --- a/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Application.java +++ b/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Application.java @@ -5,55 +5,46 @@ package io.opentelemetry.examples.fileconfig; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.LongHistogram; -import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.spring.webmvc.v5_3.SpringWebMvcTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.extension.incubator.fileconfig.ConfigurationFactory; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.concurrent.TimeUnit; +import javax.servlet.Filter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; /** Example code for setting up the SDK using file based configuration */ -public final class Application { +@SpringBootApplication +public class Application { + + private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); + + private static OpenTelemetrySdk openTelemetrySdk; public static void main(String[] args) throws InterruptedException, IOException { // it is important to initialize your SDK as early as possible in your application's lifecycle InputStream is = Files.newInputStream(Paths.get(System.getenv("OTEL_CONFIG_FILE"))); - OpenTelemetrySdk openTelemetrySdk = ConfigurationFactory.parseAndInterpret(is); - - Tracer tracer = openTelemetrySdk.getTracer("io.opentelemetry.example"); - Meter meter = openTelemetrySdk.getMeter("io.opentelemetry.example"); - LongCounter counter = meter.counterBuilder("example_counter").build(); - // Filter out histogram with view defined in otel-sdk-config.yaml - LongHistogram histogram = meter.histogramBuilder("super_timer").ofLongs().setUnit("ms").build(); - - for (int i = 0; i < 100; i++) { - long startTime = System.currentTimeMillis(); - Span exampleSpan = tracer.spanBuilder("exampleSpan").startSpan(); - Context exampleContext = Context.current().with(exampleSpan); - try (Scope scope = exampleContext.makeCurrent()) { - counter.add(1); - exampleSpan.setAttribute("good", true); - exampleSpan.setAttribute("exampleNumber", i); - Thread.sleep(100); - } finally { - histogram.record( - System.currentTimeMillis() - startTime, Attributes.empty(), exampleContext); - exampleSpan.end(); - } - } - - // shutdown to ensure data is flusehdd - openTelemetrySdk.shutdown().join(10, TimeUnit.SECONDS); - - System.out.println("Bye"); + openTelemetrySdk = ConfigurationFactory.parseAndInterpret(is); + + LOGGER.info("SDK config: " + openTelemetrySdk.toString()); + + SpringApplication.run(Application.class, args); + } + + @Bean + public OpenTelemetry openTelemetry() { + return openTelemetrySdk; + } + + @Bean + public Filter webMvcTracingFilter(OpenTelemetry openTelemetry) { + return SpringWebMvcTelemetry.create(openTelemetry).createServletFilter(); } } diff --git a/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Controller.java b/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Controller.java new file mode 100644 index 0000000000..9b3274b20a --- /dev/null +++ b/file-configuration/src/main/java/io/opentelemetry/examples/fileconfig/Controller.java @@ -0,0 +1,52 @@ +package io.opentelemetry.examples.fileconfig; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; +import java.util.Random; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class Controller { + + private static final Logger LOGGER = LogManager.getLogger(Controller.class); + private final AttributeKey ATTR_METHOD = AttributeKey.stringKey("method"); + + private final Random random = new Random(); + private final Tracer tracer; + private final LongHistogram doWorkHistogram; + + @Autowired + Controller(OpenTelemetry openTelemetry) { + tracer = openTelemetry.getTracer(Application.class.getName()); + Meter meter = openTelemetry.getMeter(Application.class.getName()); + doWorkHistogram = meter.histogramBuilder("do-work").ofLongs().build(); + } + + @GetMapping("/ping") + public String ping() throws InterruptedException { + int sleepTime = random.nextInt(200); + doWork(sleepTime); + doWorkHistogram.record(sleepTime, Attributes.of(ATTR_METHOD, "ping")); + return "pong"; + } + + private void doWork(int sleepTime) throws InterruptedException { + Span span = tracer.spanBuilder("doWork").startSpan(); + try (Scope ignored = span.makeCurrent()) { + Thread.sleep(sleepTime); + LOGGER.info("A sample log message!"); + } finally { + span.end(); + } + } +}