Skip to content

Commit

Permalink
Add APIs to determine if tracer, logger, instruments are enabled (#6502)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg authored Jul 3, 2024
1 parent 9fd6bca commit 1f7d6a5
Show file tree
Hide file tree
Showing 37 changed files with 773 additions and 81 deletions.
3 changes: 3 additions & 0 deletions api/incubator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ See [EventApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/events/Ev

Features:

* Check if logger is enabled before emitting logs to avoid uneccessary computation
* Set AnyValue log record body with arbitrarily complex data

See [ExtendedLogsBridgeApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java).
Expand All @@ -30,6 +31,7 @@ See [ExtendedMetricsApiUsageTest](./src/test/java/io/opentelemetry/api/incubator

Features:

* Check if instrument is enabled before recording measurements to avoid uneccessary computation
* Simplified injection / extraction of context

See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/incubator/propagation/ExtendedContextPropagatorsUsageTest.java).
Expand All @@ -38,6 +40,7 @@ See [ExtendedContextPropagatorsUsageTest](./src/test/java/io/opentelemetry/api/i

Features:

* Check if tracer is enabled before starting spans to avoid uneccessary computation
* Utility methods to reduce boilerplace using span API, including extracting context, and wrapping runnables / callables with spans

See [ExtendedTraceApiUsageTest](./src/test/java/io/opentelemetry/api/incubator/trace/ExtendedTraceApiUsageTest.java).
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.logs;

import io.opentelemetry.api.logs.Logger;

/** Extended {@link Logger} with experimental APIs. */
public interface ExtendedLogger extends Logger {

/**
* Returns {@code true} if the logger is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #logRecordBuilder()}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleCounter;
import io.opentelemetry.context.Context;

/** Extended {@link DoubleCounter} with experimental APIs. */
public interface ExtendedDoubleCounter extends DoubleCounter {

/**
* Returns {@code true} if the counter is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #add(double)}, {@link #add(double, Attributes)}, or {@link #add(double,
* Attributes, Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleGauge;
import io.opentelemetry.context.Context;

/** Extended {@link DoubleGauge} with experimental APIs. */
public interface ExtendedDoubleGauge extends DoubleGauge {

/**
* Returns {@code true} if the gauge is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #set(double)}, {@link #set(double, Attributes)}, or {@link #set(double,
* Attributes, Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.context.Context;

/** Extended {@link DoubleHistogram} with experimental APIs. */
public interface ExtendedDoubleHistogram extends DoubleHistogram {

/**
* Returns {@code true} if the histogram is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #record(double)}, {@link #record(double, Attributes)}, or {@link #record(double,
* Attributes, Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleUpDownCounter;
import io.opentelemetry.context.Context;

/** Extended {@link DoubleUpDownCounter} with experimental APIs. */
public interface ExtendedDoubleUpDownCounter extends DoubleUpDownCounter {

/**
* Returns {@code true} if the up down counter is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #add(double)}, {@link #add(double, Attributes)}, or {@link #add(double,
* Attributes, Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleCounter;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.context.Context;

/** Extended {@link DoubleCounter} with experimental APIs. */
public interface ExtendedLongCounter extends LongCounter {

/**
* Returns {@code true} if the counter is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #add(long)}, {@link #add(long, Attributes)}, or {@link #add(long, Attributes,
* Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongGauge;
import io.opentelemetry.context.Context;

/** Extended {@link LongGauge} with experimental APIs. */
public interface ExtendedLongGauge extends LongGauge {

/**
* Returns {@code true} if the gauge is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #set(long)}, {@link #set(long, Attributes)}, or {@link #set(long, Attributes,
* Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.context.Context;

/** Extended {@link LongHistogram} with experimental APIs. */
public interface ExtendedLongHistogram extends LongHistogram {

/**
* Returns {@code true} if the histogram is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #record(long)}, {@link #record(long, Attributes)}, or {@link #record(long,
* Attributes, Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.metrics;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongUpDownCounter;
import io.opentelemetry.context.Context;

/** Extended {@link LongUpDownCounter} with experimental APIs. */
public interface ExtendedLongUpDownCounter extends LongUpDownCounter {

/**
* Returns {@code true} if the up down counter is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #add(long)}, {@link #add(long, Attributes)}, or {@link #add(long, Attributes,
* Context)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.incubator.trace;

import io.opentelemetry.api.trace.Tracer;

/** Extended {@link Tracer} with experimental APIs. */
public interface ExtendedTracer extends Tracer {

/**
* Returns {@code true} if the tracer is enabled.
*
* <p>This allows callers to avoid unnecessary compute when nothing is consuming the data. Because
* the response is subject to change over the application, callers should call this before each
* call to {@link #spanBuilder(String)}.
*/
default boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,82 @@

package io.opentelemetry.api.incubator.logs;

import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals;
import static io.opentelemetry.sdk.logs.internal.LoggerConfig.disabled;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;

import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.logs.internal.AnyValueBody;
import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;

/** Demonstrating usage of extended Logs Bridge API. */
class ExtendedLogsBridgeApiUsageTest {

@Test
void loggerEnabled() {
// Setup SdkLoggerProvider
InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create();
SdkLoggerProviderBuilder loggerProviderBuilder =
SdkLoggerProvider.builder()
// Default resource used for demonstration purposes
.setResource(Resource.getDefault())
// In-memory exporter used for demonstration purposes
.addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter));
// Disable loggerB
SdkLoggerProviderUtil.addLoggerConfiguratorCondition(
loggerProviderBuilder, nameEquals("loggerB"), disabled());
SdkLoggerProvider loggerProvider = loggerProviderBuilder.build();

// Create loggerA and loggerB
ExtendedLogger loggerA = (ExtendedLogger) loggerProvider.get("loggerA");
ExtendedLogger loggerB = (ExtendedLogger) loggerProvider.get("loggerB");

// Check if logger is enabled before emitting log and avoid unnecessary computation
if (loggerA.isEnabled()) {
loggerA
.logRecordBuilder()
.setBody("hello world!")
.setAllAttributes(Attributes.builder().put("result", flipCoin()).build())
.emit();
}
if (loggerB.isEnabled()) {
loggerB
.logRecordBuilder()
.setBody("hello world!")
.setAllAttributes(Attributes.builder().put("result", flipCoin()).build())
.emit();
}

// loggerA is enabled, loggerB is disabled
assertThat(loggerA.isEnabled()).isTrue();
assertThat(loggerB.isEnabled()).isFalse();

// Collected data only consists of logs from loggerA. Note, loggerB's logs would be
// omitted from the results even if logs were emitted. The check if enabled simply avoids
// unnecessary computation.
assertThat(exporter.getFinishedLogRecordItems())
.allSatisfy(
logRecordData ->
assertThat(logRecordData.getInstrumentationScopeInfo().getName())
.isEqualTo("loggerA"));
}

private static final Random random = new Random();

private static String flipCoin() {
return random.nextBoolean() ? "heads" : "tails";
}

@Test
void extendedLogRecordBuilderUsage() {
// Setup SdkLoggerProvider
Expand Down
Loading

0 comments on commit 1f7d6a5

Please sign in to comment.