Skip to content

Commit

Permalink
[3.x] - Make Jaeger Tracer OpenTelemetry Agent aware. (#6537)
Browse files Browse the repository at this point in the history
* Refactor Java Agent detector.

* Remove redundant AgentDetection class

* Detector aligned with 4.x. Package name in tests fixed.

* Utility class

* Formatting

* Formatting

* Formatting

* fix style

* fix style
  • Loading branch information
dalexandrov authored Jun 2, 2023
1 parent 4d768ae commit 3da80ae
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public class JaegerTracerBuilder implements TracerBuilder<JaegerTracerBuilder> {
private byte[] certificate;
private byte[] trustedCertificates;
private String path;
private Config config;

/**
* Default constructor, does not modify any state.
Expand Down Expand Up @@ -253,6 +254,7 @@ public JaegerTracerBuilder addTracerTag(String key, boolean value) {

@Override
public JaegerTracerBuilder config(Config config) {
this.config = config;
config.get("enabled").asBoolean().ifPresent(this::enabled);
config.get("service").asString().ifPresent(this::serviceName);
config.get("protocol").asString().ifPresent(this::collectorProtocol);
Expand Down Expand Up @@ -419,6 +421,12 @@ public JaegerTracerBuilder addPropagation(PropagationFormat propagationFormat) {
public Tracer build() {
Tracer result;

if (HelidonOpenTelemetry.AgentDetector.isAgentPresent(config)) {
return HelidonOpenTelemetry.create(GlobalOpenTelemetry.get(),
GlobalOpenTelemetry.getTracer(this.serviceName),
tags);
}

if (enabled) {
if (serviceName == null) {
throw new IllegalArgumentException(
Expand Down Expand Up @@ -449,10 +457,10 @@ public Tracer build() {
Resource serviceName = Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, this.serviceName));
OpenTelemetry ot = OpenTelemetrySdk.builder()
.setTracerProvider(SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(exporter))
.setSampler(sampler)
.setResource(serviceName)
.build())
.addSpanProcessor(SimpleSpanProcessor.create(exporter))
.setSampler(sampler)
.setResource(serviceName)
.build())
.setPropagators(ContextPropagators.create(TextMapPropagator.composite(createPropagators())))
.build();

Expand Down
10 changes: 10 additions & 0 deletions tracing/opentelemetry/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,15 @@
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.microprofile.tests</groupId>
<artifactId>helidon-microprofile-tests-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.microprofile.server</groupId>
<artifactId>helidon-microprofile-server</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,9 @@


import java.util.Map;
import java.util.Optional;

import io.helidon.config.Config;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
Expand All @@ -26,6 +29,10 @@
* Open Telemetry factory methods to create wrappers for Open Telemetry types.
*/
public final class HelidonOpenTelemetry {

private static final System.Logger LOGGER = System.getLogger(HelidonOpenTelemetry.class.getName());
static final String OTEL_AGENT_PRESENT_PROPERTY = "otel.agent.present";
static final String IO_OPENTELEMETRY_JAVAAGENT = "io.opentelemetry.javaagent";
private HelidonOpenTelemetry() {
}
/**
Expand All @@ -49,4 +56,55 @@ public static OpenTelemetryTracer create(OpenTelemetry telemetry, Tracer tracer,
public static io.helidon.tracing.Span create(Span span) {
return new OpenTelemetrySpan(span);
}


/**
* Check if OpenTelemetry is present by indirect properties.
* This class does best explicit check if OTEL_AGENT_PRESENT_PROPERTY config property is set and uses its
* value to set the behaviour of OpenTelemetry producer.
*
* If the value is not explicitly set, the detector does best effort to estimate indirect means if the agent is present.
* This detector may stop working if OTEL changes the indirect indicators.
*/
public static final class AgentDetector {

//Private constructor for a utility class.
private AgentDetector() {
}

/**
* Check if the OTEL Agent is present.
*
* @param config Configuration
* @return boolean
*/
public static boolean isAgentPresent(Config config) {

//Explicitly check if agent property is set
if (config != null) {
Optional<Boolean> agentPresent = config.get(OTEL_AGENT_PRESENT_PROPERTY).asBoolean().asOptional();
if (agentPresent.isPresent()) {
return agentPresent.get();
}
}

if (checkContext() || checkSystemProperties()) {
if (LOGGER.isLoggable(System.Logger.Level.INFO)) {
LOGGER.log(System.Logger.Level.INFO, "OpenTelemetry Agent detected");
}
return true;
}
return false;
}

private static boolean checkSystemProperties() {
return System.getProperties().stringPropertyNames()
.stream()
.anyMatch(property -> property.contains(IO_OPENTELEMETRY_JAVAAGENT));
}

private static boolean checkContext() {
return io.opentelemetry.context.Context.current().getClass().getName().contains("agent");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed 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 io.helidon.tracing.opentelemetry;

import io.helidon.config.Config;
import io.helidon.microprofile.server.ServerCdiExtension;
import io.helidon.microprofile.tests.junit5.AddConfig;
import io.helidon.microprofile.tests.junit5.AddExtension;
import io.helidon.microprofile.tests.junit5.HelidonTest;
import jakarta.enterprise.inject.spi.CDI;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;


/**
* Check Agent Detector working correctly.
*/
@HelidonTest(resetPerTest = true)
@AddExtension(ServerCdiExtension.class)
class AgentDetectorTest {

@Test
@AddConfig(key = HelidonOpenTelemetry.OTEL_AGENT_PRESENT_PROPERTY, value = "true")
void shouldBeNoOpTelemetry() {
Config config = CDI.current().select(Config.class).get();
boolean present = HelidonOpenTelemetry.AgentDetector.isAgentPresent(config);
assertThat(present, is(true));
}

@Test
@AddConfig(key = HelidonOpenTelemetry.OTEL_AGENT_PRESENT_PROPERTY, value = "false")
void shouldNotBeNoOpTelemetry() {
Config config = CDI.current().select(Config.class).get();
boolean present = HelidonOpenTelemetry.AgentDetector.isAgentPresent(config);
assertThat(present, is(false));
}

@Test
void checkEnvVariable() {
System.setProperty(HelidonOpenTelemetry.IO_OPENTELEMETRY_JAVAAGENT, "true");
Config config = CDI.current().select(Config.class).get();
boolean present = HelidonOpenTelemetry.AgentDetector.isAgentPresent(config);
assertThat(present, is(true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package io.helidon.tracing.opentelemetery;
package io.helidon.tracing.opentelemetry;

import java.util.Optional;

Expand All @@ -37,7 +37,7 @@ class BaggageTest {
private final Tracer tracer = TracerBuilder.create("test-service").registerGlobal(false).build();

@Test
void testBaggage(){
void testBaggage() {
Span span = tracer.spanBuilder("test-span").start();
Span spanWithBaggage = span.baggage("key", "value");
Optional<String> result = spanWithBaggage.baggage("key");
Expand All @@ -47,7 +47,7 @@ void testBaggage(){
}

@Test
void testBadBaggage(){
void testBadBaggage() {
Span span = tracer.spanBuilder("test-bad-span").start();
assertThrows(NullPointerException.class, () -> span.baggage(null, "value"));
assertThrows(NullPointerException.class, () -> span.baggage("key", null));
Expand Down

0 comments on commit 3da80ae

Please sign in to comment.