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

JIT exporter metrics #4993

Merged
merged 5 commits into from
Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterProvider;
import java.util.function.Supplier;
import javax.annotation.Nullable;

/**
* Helper for recording metrics from exporters.
Expand All @@ -25,45 +27,77 @@ public class ExporterMetrics {
private static final AttributeKey<String> ATTRIBUTE_KEY_TYPE = stringKey("type");
private static final AttributeKey<Boolean> ATTRIBUTE_KEY_SUCCESS = booleanKey("success");

private final LongCounter seen;
private final LongCounter exported;

private final Supplier<MeterProvider> meterProviderSupplier;
private final String exporterName;
private final String transportName;
private final Attributes seenAttrs;
private final Attributes successAttrs;
private final Attributes failedAttrs;

/** Access via {@link #seen()}. */
@Nullable private volatile LongCounter seen;

/** Access via {@link #exported()} . */
@Nullable private volatile LongCounter exported;

private ExporterMetrics(
MeterProvider meterProvider, String exporterName, String type, String transportName) {
Meter meter =
meterProvider.get("io.opentelemetry.exporters." + exporterName + "-" + transportName);
seenAttrs = Attributes.builder().put(ATTRIBUTE_KEY_TYPE, type).build();
seen = meter.counterBuilder(exporterName + ".exporter.seen").build();
exported = meter.counterBuilder(exporterName + ".exporter.exported").build();
successAttrs = seenAttrs.toBuilder().put(ATTRIBUTE_KEY_SUCCESS, true).build();
failedAttrs = seenAttrs.toBuilder().put(ATTRIBUTE_KEY_SUCCESS, false).build();
Supplier<MeterProvider> meterProviderSupplier,
String exporterName,
String type,
String transportName) {
this.meterProviderSupplier = meterProviderSupplier;
this.exporterName = exporterName;
this.transportName = transportName;
this.seenAttrs = Attributes.builder().put(ATTRIBUTE_KEY_TYPE, type).build();
this.successAttrs = this.seenAttrs.toBuilder().put(ATTRIBUTE_KEY_SUCCESS, true).build();
this.failedAttrs = this.seenAttrs.toBuilder().put(ATTRIBUTE_KEY_SUCCESS, false).build();
}

/** Record number of records seen. */
public void addSeen(long value) {
seen.add(value, seenAttrs);
seen().add(value, seenAttrs);
}

/** Record number of records which successfully exported. */
public void addSuccess(long value) {
exported.add(value, successAttrs);
exported().add(value, successAttrs);
}

/** Record number of records which failed to export. */
public void addFailed(long value) {
exported.add(value, failedAttrs);
exported().add(value, failedAttrs);
}

private LongCounter seen() {
LongCounter seen = this.seen;
if (seen == null) {
seen = meter().counterBuilder(exporterName + ".exporter.seen").build();
this.seen = seen;
}
return seen;
}

private LongCounter exported() {
LongCounter exported = this.exported;
if (exported == null) {
exported = meter().counterBuilder(exporterName + ".exporter.exported").build();
this.exported = exported;
}
return exported;
}
Comment on lines +71 to +87
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not clear to me if this initialization should be synchronized or not, but I think it's ok either way for now and will get cleaned up by #5021 since then there will be post-init method that can be used for initialization

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't need to be synchronized. It looks a bit weird, but if two threads call exported() at the same time, both will initialize a counter and set this.exported, but this isn't a problem.


private Meter meter() {
return meterProviderSupplier
.get()
.get("io.opentelemetry.exporters." + exporterName + "-" + transportName);
}

/**
* Create an instance for recording exporter metrics under the meter {@code
* "io.opentelemetry.exporters." + exporterName + "-grpc}".
*/
public static ExporterMetrics createGrpc(
String exporterName, String type, MeterProvider meterProvider) {
String exporterName, String type, Supplier<MeterProvider> meterProvider) {
return new ExporterMetrics(meterProvider, exporterName, type, "grpc");
}

Expand All @@ -72,7 +106,7 @@ public static ExporterMetrics createGrpc(
* "io.opentelemetry.exporters." + exporterName + "-grpc-okhttp}".
*/
public static ExporterMetrics createGrpcOkHttp(
String exporterName, String type, MeterProvider meterProvider) {
String exporterName, String type, Supplier<MeterProvider> meterProvider) {
return new ExporterMetrics(meterProvider, exporterName, type, "grpc-okhttp");
}

Expand All @@ -81,7 +115,7 @@ public static ExporterMetrics createGrpcOkHttp(
* "io.opentelemetry.exporters." + exporterName + "-http}".
*/
public static ExporterMetrics createHttpProtobuf(
String exporterName, String type, MeterProvider meterProvider) {
String exporterName, String type, Supplier<MeterProvider> meterProvider) {
return new ExporterMetrics(meterProvider, exporterName, type, "http");
}

Expand All @@ -90,7 +124,7 @@ public static ExporterMetrics createHttpProtobuf(
* "io.opentelemetry.exporters." + exporterName + "-http-json}".
*/
public static ExporterMetrics createHttpJson(
String exporterName, String type, MeterProvider meterProvider) {
String exporterName, String type, Supplier<MeterProvider> meterProvider) {
return new ExporterMetrics(meterProvider, exporterName, type, "http-json");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.grpc.ManagedChannel;
import io.grpc.Metadata;
import io.grpc.stub.MetadataUtils;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.ExporterBuilderUtil;
import io.opentelemetry.exporter.internal.TlsUtil;
Expand Down Expand Up @@ -58,7 +59,7 @@ public class GrpcExporterBuilder<T extends Marshaler> {
@Nullable private byte[] privateKeyPem;
@Nullable private byte[] certificatePem;
@Nullable private RetryPolicy retryPolicy;
private MeterProvider meterProvider = MeterProvider.noop();
private Supplier<MeterProvider> meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider;

// Use Object type since gRPC may not be on the classpath.
@Nullable private Object grpcChannel;
Expand Down Expand Up @@ -124,7 +125,7 @@ public GrpcExporterBuilder<T> setRetryPolicy(RetryPolicy retryPolicy) {
}

public GrpcExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
this.meterProvider = meterProvider;
this.meterProviderSupplier = () -> meterProvider;
return this;
}

Expand Down Expand Up @@ -177,7 +178,7 @@ public GrpcExporter<T> build() {
exporterName,
type,
clientBuilder.build(),
meterProvider,
meterProviderSupplier,
endpoint,
headers.build(),
compressionEnabled);
Expand Down Expand Up @@ -209,7 +210,8 @@ private GrpcExporter<T> buildWithChannel(Channel channel) {
.get()
.apply(channel, authorityOverride)
.withCompression(codec.getMessageEncoding());
return new UpstreamGrpcExporter<>(exporterName, type, stub, meterProvider, timeoutNanos);
return new UpstreamGrpcExporter<>(
exporterName, type, stub, meterProviderSupplier, timeoutNanos);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -75,12 +76,13 @@ public final class OkHttpGrpcExporter<T extends Marshaler> implements GrpcExport
String exporterName,
String type,
OkHttpClient client,
MeterProvider meterProvider,
Supplier<MeterProvider> meterProviderSupplier,
String endpoint,
Headers headers,
boolean compressionEnabled) {
this.type = type;
this.exporterMetrics = ExporterMetrics.createGrpcOkHttp(exporterName, type, meterProvider);
this.exporterMetrics =
ExporterMetrics.createGrpcOkHttp(exporterName, type, meterProviderSupplier);
this.client = client;
this.url = HttpUrl.get(endpoint);
this.headers = headers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.opentelemetry.sdk.internal.ThrottlingLogger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand Down Expand Up @@ -46,10 +47,10 @@ public final class UpstreamGrpcExporter<T extends Marshaler> implements GrpcExpo
String exporterName,
String type,
MarshalerServiceStub<T, ?, ?> stub,
MeterProvider meterProvider,
Supplier<MeterProvider> meterProviderSupplier,
long timeoutNanos) {
this.type = type;
this.exporterMetrics = ExporterMetrics.createGrpc(exporterName, type, meterProvider);
this.exporterMetrics = ExporterMetrics.createGrpc(exporterName, type, meterProviderSupplier);
this.timeoutNanos = timeoutNanos;
this.stub = stub;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.opentelemetry.sdk.internal.ThrottlingLogger;
import java.io.IOException;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -57,7 +58,7 @@ public final class OkHttpExporter<T extends Marshaler> {
String exporterName,
String type,
OkHttpClient client,
MeterProvider meterProvider,
Supplier<MeterProvider> meterProviderSupplier,
String endpoint,
@Nullable Headers headers,
boolean compressionEnabled,
Expand All @@ -70,8 +71,8 @@ public final class OkHttpExporter<T extends Marshaler> {
this.requestBodyCreator = exportAsJson ? JsonRequestBody::new : ProtoRequestBody::new;
this.exporterMetrics =
exportAsJson
? ExporterMetrics.createHttpJson(exporterName, type, meterProvider)
: ExporterMetrics.createHttpProtobuf(exporterName, type, meterProvider);
? ExporterMetrics.createHttpJson(exporterName, type, meterProviderSupplier)
: ExporterMetrics.createHttpProtobuf(exporterName, type, meterProviderSupplier);
}

public CompletableResultCode export(T exportRequest, int numItems) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.exporter.internal.okhttp;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.ExporterBuilderUtil;
import io.opentelemetry.exporter.internal.TlsUtil;
Expand All @@ -15,6 +16,7 @@
import java.net.URI;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.net.ssl.SSLException;
import javax.net.ssl.X509KeyManager;
Expand Down Expand Up @@ -46,7 +48,7 @@ public final class OkHttpExporterBuilder<T extends Marshaler> {
@Nullable private byte[] privateKeyPem;
@Nullable private byte[] certificatePem;
@Nullable private RetryPolicy retryPolicy;
private MeterProvider meterProvider = MeterProvider.noop();
private Supplier<MeterProvider> meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider;
@Nullable private Authenticator authenticator;

public OkHttpExporterBuilder(String exporterName, String type, String defaultEndpoint) {
Expand Down Expand Up @@ -101,7 +103,7 @@ public OkHttpExporterBuilder<T> setClientTls(byte[] privateKeyPem, byte[] certif
}

public OkHttpExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
this.meterProvider = meterProvider;
this.meterProviderSupplier = () -> meterProvider;
return this;
}

Expand Down Expand Up @@ -158,7 +160,7 @@ public OkHttpExporter<T> build() {
exporterName,
type,
clientBuilder.build(),
meterProvider,
meterProviderSupplier,
endpoint,
headers,
compressionEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static java.util.Objects.requireNonNull;

import io.grpc.ManagedChannel;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.grpc.GrpcExporter;
import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder;
Expand Down Expand Up @@ -119,8 +120,8 @@ public JaegerGrpcSpanExporterBuilder setClientTls(byte[] privateKeyPem, byte[] c
}

/**
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, metrics
* will not be collected.
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses
* {@link GlobalOpenTelemetry#getMeterProvider()}.
*
* @since 1.15.0
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static io.opentelemetry.api.internal.Utils.checkArgument;
import static java.util.Objects.requireNonNull;

import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.okhttp.OkHttpExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent;
import io.opentelemetry.exporter.internal.otlp.metrics.MetricsRequestMarshaler;
Expand Down Expand Up @@ -39,6 +40,7 @@ public final class OtlpHttpMetricExporterBuilder {

OtlpHttpMetricExporterBuilder() {
delegate = new OkHttpExporterBuilder<>("otlp", "metric", DEFAULT_ENDPOINT);
delegate.setMeterProvider(MeterProvider.noop());
trask marked this conversation as resolved.
Show resolved Hide resolved
OtlpUserAgent.addUserAgentHeader(delegate::addHeader);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static io.opentelemetry.api.internal.Utils.checkArgument;
import static java.util.Objects.requireNonNull;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.okhttp.OkHttpExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent;
Expand Down Expand Up @@ -100,8 +101,8 @@ public OtlpHttpSpanExporterBuilder setClientTls(byte[] privateKeyPem, byte[] cer
}

/**
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, metrics
* will not be collected.
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses
* {@link GlobalOpenTelemetry#getMeterProvider()}.
*/
public OtlpHttpSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
requireNonNull(meterProvider, "meterProvider");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static java.util.Objects.requireNonNull;

import io.grpc.ManagedChannel;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.grpc.GrpcExporter;
import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent;
Expand Down Expand Up @@ -57,6 +58,7 @@ public final class OtlpGrpcMetricExporterBuilder {
DEFAULT_ENDPOINT,
() -> MarshalerMetricsServiceGrpc::newFutureStub,
GRPC_ENDPOINT_PATH);
delegate.setMeterProvider(MeterProvider.noop());
trask marked this conversation as resolved.
Show resolved Hide resolved
OtlpUserAgent.addUserAgentHeader(delegate::addHeader);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static java.util.Objects.requireNonNull;

import io.grpc.ManagedChannel;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.grpc.GrpcExporter;
import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder;
Expand Down Expand Up @@ -141,8 +142,8 @@ public OtlpGrpcSpanExporterBuilder addHeader(String key, String value) {
}

/**
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, metrics
* will not be collected.
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses
* {@link GlobalOpenTelemetry#getMeterProvider()}.
*/
public OtlpGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
requireNonNull(meterProvider, "meterProvider");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static io.opentelemetry.api.internal.Utils.checkArgument;
import static java.util.Objects.requireNonNull;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.okhttp.OkHttpExporterBuilder;
import io.opentelemetry.exporter.internal.otlp.OtlpUserAgent;
Expand Down Expand Up @@ -97,8 +98,8 @@ public OtlpHttpLogRecordExporterBuilder setClientTls(
}

/**
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, metrics
* will not be collected.
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, uses
* {@link GlobalOpenTelemetry#getMeterProvider()}.
*/
public OtlpHttpLogRecordExporterBuilder setMeterProvider(MeterProvider meterProvider) {
requireNonNull(meterProvider, "meterProvider");
Expand Down
Loading