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

Add api usage snippets #498

Merged
merged 5 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
12 changes: 12 additions & 0 deletions doc-snippets/api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
plugins {
id("java")
}

val moduleName by extra { "io.opentelemetry.examples.docs.configuration" }

dependencies {
implementation("io.opentelemetry:opentelemetry-api")

implementation("io.opentelemetry.semconv:opentelemetry-semconv")
implementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.26.0-alpha")
}
50 changes: 50 additions & 0 deletions doc-snippets/api/src/main/java/otel/AsyncCounterUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package otel;

import static otel.Util.WIDGET_COLOR;
import static otel.Util.WIDGET_SHAPE;
import static otel.Util.computeWidgetColor;
import static otel.Util.computeWidgetShape;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongCounter;
import java.util.concurrent.atomic.AtomicLong;

public class AsyncCounterUsage {
// Pre-allocate attributes whenever possible
private static final Attributes WIDGET_RED_CIRCLE = Util.WIDGET_RED_CIRCLE;

public static void asyncCounterUsage(Meter meter) {
AtomicLong widgetCount = new AtomicLong();

// Construct an async counter to observe an existing counter in a callback
ObservableLongCounter asyncCounter =
meter
.counterBuilder("fully.qualified.counter")
.setDescription("A count of produced widgets")
.setUnit("{widget}")
// Uncomment to optionally change the type to double
// .ofDoubles()
.buildWithCallback(
// the callback is invoked a MetricReader reads metrics
observableMeasurement -> {
long currentWidgetCount = widgetCount.get();

// Record a measurement with no attributes.
// Attributes defaults to Attributes.empty().
observableMeasurement.record(currentWidgetCount);

// Record a measurement with attributes, using pre-allocated attributes whenever
// possible.
observableMeasurement.record(currentWidgetCount, WIDGET_RED_CIRCLE);
// Sometimes, attributes must be computed using application context.
observableMeasurement.record(
currentWidgetCount,
Attributes.of(
WIDGET_SHAPE, computeWidgetShape(), WIDGET_COLOR, computeWidgetColor()));
});

// Optionally close the counter to unregister the callback when required
asyncCounter.close();
}
}
49 changes: 49 additions & 0 deletions doc-snippets/api/src/main/java/otel/AsyncGaugeUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package otel;

import static otel.Util.WIDGET_COLOR;
import static otel.Util.WIDGET_SHAPE;
import static otel.Util.computeWidgetColor;
import static otel.Util.computeWidgetShape;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableDoubleGauge;
import java.util.concurrent.atomic.AtomicReference;

public class AsyncGaugeUsage {
private static final Attributes WIDGET_RED_CIRCLE = Util.WIDGET_RED_CIRCLE;

public static void asyncGaugeUsage(Meter meter) {
AtomicReference<Double> processingLineTemp = new AtomicReference<>(273.0);

// Construct an async counter to observe an existing counter in a callback
ObservableDoubleGauge asyncGauge =
meter
.gaugeBuilder("fully.qualified.gauge")
.setDescription("The current temperature of the widget processing line")
.setUnit("K")
// Uncomment to optionally change the type to long
// .ofLongs()
.buildWithCallback(
// the callback is invoked a MetricReader reads metrics
observableMeasurement -> {
double currentWidgetCount = processingLineTemp.get();

// Record a measurement with no attributes.
// Attributes defaults to Attributes.empty().
observableMeasurement.record(currentWidgetCount);

// Record a measurement with attributes, using pre-allocated attributes whenever
// possible.
observableMeasurement.record(currentWidgetCount, WIDGET_RED_CIRCLE);
// Sometimes, attributes must be computed using application context.
observableMeasurement.record(
currentWidgetCount,
Attributes.of(
WIDGET_SHAPE, computeWidgetShape(), WIDGET_COLOR, computeWidgetColor()));
});

// Optionally close the gauge to unregister the callback when required
asyncGauge.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package otel;

import static otel.Util.WIDGET_COLOR;
import static otel.Util.WIDGET_SHAPE;
import static otel.Util.computeWidgetColor;
import static otel.Util.computeWidgetShape;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongUpDownCounter;
import java.util.concurrent.atomic.AtomicLong;

public class AsyncUpDownCounterUsage {
private static final Attributes WIDGET_RED_CIRCLE = Util.WIDGET_RED_CIRCLE;

public static void asyncUpDownCounterUsage(Meter meter) {
AtomicLong queueLength = new AtomicLong();

// Construct an async updowncounter to observe an existing up down counter in a callback
ObservableLongUpDownCounter asyncUpDownCounter =
meter
.upDownCounterBuilder("fully.qualified.updowncounter")
.setDescription("Current length of widget processing queue")
.setUnit("{widget}")
// Uncomment to optionally change the type to double
// .ofDoubles()
.buildWithCallback(
// the callback is invoked a MetricReader reads metrics
observableMeasurement -> {
long currentWidgetCount = queueLength.get();

// Record a measurement with no attributes.
// Attributes defaults to Attributes.empty().
observableMeasurement.record(currentWidgetCount);

// Record a measurement with attributes, using pre-allocated attributes whenever
// possible.
observableMeasurement.record(currentWidgetCount, WIDGET_RED_CIRCLE);
// Sometimes, attributes must be computed using application context.
observableMeasurement.record(
currentWidgetCount,
Attributes.of(
WIDGET_SHAPE, computeWidgetShape(), WIDGET_COLOR, computeWidgetColor()));
});

// Optionally close the counter to unregister the callback when required
asyncUpDownCounter.close();
}
}
79 changes: 79 additions & 0 deletions doc-snippets/api/src/main/java/otel/AttributesUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package otel;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import java.util.Map;

public class AttributesUsage {
// Establish static constant for attribute keys and reuse to avoid allocations
private static final AttributeKey<String> SHOP_ID = AttributeKey.stringKey("com.acme.shop.id");
private static final AttributeKey<String> SHOP_NAME =
AttributeKey.stringKey("com.acme.shop.name");
private static final AttributeKey<Long> CUSTOMER_ID =
AttributeKey.longKey("com.acme.customer.id");
private static final AttributeKey<String> CUSTOMER_NAME =
AttributeKey.stringKey("com.acme.customer.name");

public static void attributesUsage() {
// Use a varargs initializer and pre-allocated attribute keys. This is the most efficient way to
// create attributes.
Attributes attributes =
Attributes.of(
SHOP_ID,
"abc123",
SHOP_NAME,
"opentelemetry-demo",
CUSTOMER_ID,
123L,
CUSTOMER_NAME,
"Jack");

// ...or use a builder.
attributes =
Attributes.builder()
.put(SHOP_ID, "abc123")
.put(SHOP_NAME, "opentelemetry-demo")
.put(CUSTOMER_ID, 123)
.put(CUSTOMER_NAME, "Jack")
// Optionally initialize attribute keys on the fly
.put(AttributeKey.stringKey("com.acme.string-key"), "value")
.put(AttributeKey.booleanKey("com.acme.bool-key"), true)
.put(AttributeKey.longKey("com.acme.long-key"), 1L)
.put(AttributeKey.doubleKey("com.acme.double-key"), 1.1)
.put(AttributeKey.stringArrayKey("com.acme.string-array-key"), "value1", "value2")
.put(AttributeKey.booleanArrayKey("come.acme.bool-array-key"), true, false)
.put(AttributeKey.longArrayKey("come.acme.long-array-key"), 1L, 2L)
.put(AttributeKey.doubleArrayKey("come.acme.double-array-key"), 1.1, 2.2)
// Optionally omit initializing AttributeKey
.put("com.acme.string-key", "value")
.put("com.acme.bool-key", true)
.put("come.acme.long-key", 1L)
.put("come.acme.double-key", 1.1)
.put("come.acme.string-array-key", "value1", "value2")
.put("come.acme.bool-array-key", true, false)
.put("come.acme.long-array-key", 1L, 2L)
.put("come.acme.double-array-key", 1.1, 2.2)
.build();

// Attributes has a variety of methods for manipulating and reading data.
// Read an attribute key:
String shopIdValue = attributes.get(SHOP_ID);
// Inspect size:
int size = attributes.size();
boolean isEmpty = attributes.isEmpty();
// Convert to a map representation:
Map<AttributeKey<?>, Object> map = attributes.asMap();
// Iterate through entries, printing each to the template: <key> (<type>): <value>\n
attributes.forEach(
(attributeKey, value) ->
System.out.printf(
"%s (%s): %s%n", attributeKey.getKey(), attributeKey.getType(), value));
// Convert to a builder, remove the com.acme.customer.id and any entry whose key starts with
// com.acme.shop, and build a new instance:
AttributesBuilder builder = attributes.toBuilder();
builder.remove(CUSTOMER_ID);
builder.removeIf(attributeKey -> attributeKey.getKey().startsWith("com.acme.shop"));
Attributes trimmedAttributes = builder.build();
}
}
74 changes: 74 additions & 0 deletions doc-snippets/api/src/main/java/otel/BaggageUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package otel;

import static io.opentelemetry.context.Context.current;

import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageEntry;
import io.opentelemetry.api.baggage.BaggageEntryMetadata;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Scope;
import java.util.Map;
import java.util.stream.Collectors;

public class BaggageUsage {
private static final Attributes WIDGET_RED_CIRCLE = Util.WIDGET_RED_CIRCLE;

public static void baggageUsage() {
// Access current baggage with Baggage.current()
// output => context baggage: {}
Baggage currentBaggage = Baggage.current();
System.out.println("current baggage: " + asString(currentBaggage));
// ...or from a Context
currentBaggage = Baggage.fromContext(current());

// Baggage has a variety of methods for manipulating and reading data.
// Convert to builder and add entries:
Baggage newBaggage =
Baggage.current().toBuilder()
.put("shopId", "abc123")
.put("shopName", "opentelemetry-demo", BaggageEntryMetadata.create("metadata"))
.build();
// ...or uncomment to start from empty
// newBaggage = Baggage.empty().toBuilder().put("shopId", "abc123").build();
// output => new baggage: {shopId=abc123(), shopName=opentelemetry-demo(metadata)}
System.out.println("new baggage: " + asString(newBaggage));
// Read an entry:
String shopIdValue = newBaggage.getEntryValue("shopId");
// Inspect size:
int size = newBaggage.size();
boolean isEmpty = newBaggage.isEmpty();
// Convert to map representation:
Map<String, BaggageEntry> map = newBaggage.asMap();
// Iterate through entries:
newBaggage.forEach((s, baggageEntry) -> {});

// The current baggage still doesn't contain the new entries
// output => context baggage: {}
System.out.println("current baggage: " + asString(Baggage.current()));

// Calling Baggage.makeCurrent() sets Baggage.current() to the baggage until the scope is
// closed, upon which Baggage.current() is restored to the state prior to when
// Baggage.makeCurrent() was called.
try (Scope scope = newBaggage.makeCurrent()) {
// The current baggage now contains the added value
// output => context baggage: {shopId=abc123(), shopName=opentelemetry-demo(metadata)}
System.out.println("current baggage: " + asString(Baggage.current()));
}

// The current baggage no longer contains the new entries:
// output => context baggage: {}
System.out.println("current baggage: " + asString(Baggage.current()));
}

private static String asString(Baggage baggage) {
return baggage.asMap().entrySet().stream()
.map(
entry ->
String.format(
"%s=%s(%s)",
entry.getKey(),
entry.getValue().getValue(),
entry.getValue().getMetadata().getValue()))
.collect(Collectors.joining(", ", "{", "}"));
}
}
Loading
Loading