Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
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
Prev Previous commit
Next Next commit
observability -> telemetry
  • Loading branch information
Liudmila Molkova committed Jan 6, 2025
commit 85c187ef7be00edb3754b4e4bd0e8aded388c0da
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,6 @@
<suppress checks="com.azure.tools.checkstyle.checks.ServiceClientBuilderCheck" files="io.clientcore.http.okhttp3.OkHttpHttpClientBuilder" />
<suppress checks="ExternalDependencyExposed" files=".*[/\\]http-stress[/\\].*\.java"/>
<suppress checks="IllegalImport" files="io.clientcore.http.*.stress"/>
<suppress checks="IllegalImport" files="io.clientcore.core.observability.*Tests"/>
<suppress checks="IllegalImport" files="io.clientcore.core.telemetry.*Tests"/>
<suppress checks="IllegalImport" files="io.clientcore.core.http.pipeline.InstrumentationPolicyTests"/>
</suppressions>
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,44 @@
import io.clientcore.core.http.models.HttpRequest;
import io.clientcore.core.http.models.Response;
import io.clientcore.core.implementation.http.HttpRequestAccessHelper;
import io.clientcore.core.observability.LibraryObservabilityOptions;
import io.clientcore.core.observability.ObservabilityOptions;
import io.clientcore.core.observability.ObservabilityProvider;
import io.clientcore.core.observability.Scope;
import io.clientcore.core.observability.tracing.Span;
import io.clientcore.core.observability.tracing.SpanContext;
import io.clientcore.core.observability.tracing.SpanKind;
import io.clientcore.core.observability.tracing.Tracer;
import io.clientcore.core.telemetry.LibraryTelemetryOptions;
import io.clientcore.core.telemetry.TelemetryOptions;
import io.clientcore.core.telemetry.TelemetryProvider;
import io.clientcore.core.telemetry.Scope;
import io.clientcore.core.telemetry.tracing.Span;
import io.clientcore.core.telemetry.tracing.SpanContext;
import io.clientcore.core.telemetry.tracing.SpanKind;
import io.clientcore.core.telemetry.tracing.Tracer;
import io.clientcore.core.util.ClientLogger;
import io.clientcore.core.util.Context;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

import static io.clientcore.core.observability.ObservabilityProvider.DISABLE_TRACING_KEY;
import static io.clientcore.core.telemetry.TelemetryProvider.DISABLE_TRACING_KEY;

/**
* The instrumentation policy is responsible for instrumenting the HTTP request and response with distributed tracing
* and (in the future) metrics.
*/
public class InstrumentationPolicy implements HttpPipelinePolicy {
private static final ClientLogger LOGGER = new ClientLogger(InstrumentationPolicy.class);
private static final String LIBRARY_NAME;
private static final String LIBRARY_VERSION;

static {
Map<String, String> properties = getProperties("core.properties");
LIBRARY_NAME = properties.getOrDefault("name", "unknown");
LIBRARY_VERSION = properties.getOrDefault("version", "unknown");
}

// TODO (lmolkova) read from properties
private static final LibraryObservabilityOptions LIBRARY_OPTIONS
= new LibraryObservabilityOptions("clientcore").setLibraryVersion("1.0.0")
private static final LibraryTelemetryOptions LIBRARY_OPTIONS
= new LibraryTelemetryOptions(LIBRARY_NAME).setLibraryVersion(LIBRARY_VERSION)
.setSchemaUrl("https://opentelemetry.io/schemas/1.29.0");

private static final String HTTP_REQUEST_METHOD = "http.request.method";
Expand All @@ -48,22 +62,22 @@ public class InstrumentationPolicy implements HttpPipelinePolicy {
/**
* Creates a new instrumentation policy.
*
* @param options The observability options.
* @param options Application telemetry options.
*/
public InstrumentationPolicy(ObservabilityOptions<?> options) {
public InstrumentationPolicy(TelemetryOptions<?> options) {
this(options, null, null);
}

/**
* Creates a new instrumentation policy with the ability to capture request and response headers.
*
* @param options The observability options.
* @param options Application telemetry options.
* @param requestHeaders The request headers to capture.
* @param responseHeaders The response headers to capture.
*/
public InstrumentationPolicy(ObservabilityOptions<?> options, Map<HttpHeaderName, String> requestHeaders,
public InstrumentationPolicy(TelemetryOptions<?> options, Map<HttpHeaderName, String> requestHeaders,
Map<HttpHeaderName, String> responseHeaders) {
this.tracer = ObservabilityProvider.getInstance().getTracer(options, LIBRARY_OPTIONS);
this.tracer = TelemetryProvider.getInstance().getTracer(options, LIBRARY_OPTIONS);
this.requestHeaders = requestHeaders;
this.responseHeaders = responseHeaders;
}
Expand Down Expand Up @@ -175,4 +189,23 @@ private void addRequestHeaders(HttpRequest httpRequest, Span span) {
}
}
}

private static Map<String, String> getProperties(String propertiesFileName) {
try (InputStream inputStream
= InstrumentationPolicy.class.getClassLoader().getResourceAsStream(propertiesFileName)) {
if (inputStream != null) {
Properties properties = new Properties();
properties.load(inputStream);
return Collections.unmodifiableMap(properties.entrySet()
.stream()
.collect(Collectors.toMap(entry -> (String) entry.getKey(), entry -> (String) entry.getValue())));
}
} catch (IOException ex) {
LOGGER.atWarning()
.addKeyValue("propertiesFileName", propertiesFileName)
.log("Failed to read properties.", ex);
}

return Collections.emptyMap();
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel;
package io.clientcore.core.implementation.telemetry.otel;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.util.ClientLogger;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.ATTRIBUTE_KEY_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.ATTRIBUTE_KEY_CLASS;

public class OTelAttributeKey {
private static final ClientLogger LOGGER = new ClientLogger(OTelAttributeKey.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel;
package io.clientcore.core.implementation.telemetry.otel;

import io.clientcore.core.util.ClientLogger;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel;
package io.clientcore.core.implementation.telemetry.otel;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.implementation.observability.otel.tracing.OTelTracer;
import io.clientcore.core.implementation.observability.otel.tracing.OTelTracerBuilder;
import io.clientcore.core.observability.LibraryObservabilityOptions;
import io.clientcore.core.observability.ObservabilityOptions;
import io.clientcore.core.observability.ObservabilityProvider;
import io.clientcore.core.observability.tracing.Tracer;
import io.clientcore.core.implementation.telemetry.otel.tracing.OTelTracer;
import io.clientcore.core.implementation.telemetry.otel.tracing.OTelTracerBuilder;
import io.clientcore.core.telemetry.LibraryTelemetryOptions;
import io.clientcore.core.telemetry.TelemetryOptions;
import io.clientcore.core.telemetry.TelemetryProvider;
import io.clientcore.core.telemetry.tracing.Tracer;
import io.clientcore.core.util.ClientLogger;

import java.util.Objects;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.GLOBAL_OTEL_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.OTEL_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.TRACER_PROVIDER_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.GLOBAL_OTEL_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.OTEL_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.TRACER_PROVIDER_CLASS;

public class OTelObservabilityProvider implements ObservabilityProvider {
public static final ObservabilityProvider INSTANCE = new OTelObservabilityProvider();
public class OTelTelemetryProvider implements TelemetryProvider {
public static final TelemetryProvider INSTANCE = new OTelTelemetryProvider();
private static final ReflectiveInvoker GET_PROVIDER_INVOKER;
private static final ReflectiveInvoker GET_GLOBAL_PROVIDER_INVOKER;
private static final ReflectiveInvoker GET_TRACER_BUILDER_INVOKER;

private static final Object NOOP_PROVIDER;
private static final ClientLogger LOGGER = new ClientLogger(OTelObservabilityProvider.class);
private static final ClientLogger LOGGER = new ClientLogger(OTelTelemetryProvider.class);
static {
ReflectiveInvoker getProviderInvoker = null;
ReflectiveInvoker getGlobalProviderInvoker = null;
Expand Down Expand Up @@ -59,7 +59,7 @@ public class OTelObservabilityProvider implements ObservabilityProvider {
}

@Override
public Tracer getTracer(ObservabilityOptions<?> applicationOptions, LibraryObservabilityOptions libraryOptions) {
public Tracer getTracer(TelemetryOptions<?> applicationOptions, LibraryTelemetryOptions libraryOptions) {
Objects.requireNonNull(libraryOptions, "'libraryOptions' cannot be null");

if (!OTelInitializer.INSTANCE.isInitialized()
Expand All @@ -83,12 +83,12 @@ public Tracer getTracer(ObservabilityOptions<?> applicationOptions, LibraryObser
private Object getTracerProvider(Object otel) {
if (otel != null && !OTEL_CLASS.isInstance(otel)) {
IllegalArgumentException error
= new IllegalArgumentException("Observability provider is not an instance of " + OTEL_CLASS.getName());
= new IllegalArgumentException("Telemetry provider is not an instance of " + OTEL_CLASS.getName());

throw LOGGER.atError()
.addKeyValue("expectedProvider", OTEL_CLASS.getName())
.addKeyValue("actualProvider", otel.getClass().getName())
.log("Unexpected observability provider type.", error);
.log("Unexpected telemetry provider type.", error);
}

if (OTelInitializer.INSTANCE.isInitialized()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel.tracing;
package io.clientcore.core.implementation.telemetry.otel.tracing;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.implementation.observability.otel.OTelAttributeKey;
import io.clientcore.core.implementation.observability.otel.OTelInitializer;
import io.clientcore.core.observability.Scope;
import io.clientcore.core.observability.tracing.Span;
import io.clientcore.core.observability.tracing.SpanContext;
import io.clientcore.core.implementation.telemetry.otel.OTelAttributeKey;
import io.clientcore.core.implementation.telemetry.otel.OTelInitializer;
import io.clientcore.core.telemetry.Scope;
import io.clientcore.core.telemetry.tracing.Span;
import io.clientcore.core.telemetry.tracing.SpanContext;
import io.clientcore.core.util.ClientLogger;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.ATTRIBUTE_KEY_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.SPAN_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.STATUS_CODE_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.ATTRIBUTE_KEY_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.SPAN_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.STATUS_CODE_CLASS;

public class OTelSpan implements Span {
private static final ClientLogger LOGGER = new ClientLogger(OTelSpan.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel.tracing;
package io.clientcore.core.implementation.telemetry.otel.tracing;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.implementation.observability.otel.OTelAttributeKey;
import io.clientcore.core.implementation.observability.otel.OTelInitializer;
import io.clientcore.core.observability.ObservabilityProvider;
import io.clientcore.core.observability.tracing.Span;
import io.clientcore.core.observability.tracing.SpanBuilder;
import io.clientcore.core.observability.tracing.SpanKind;
import io.clientcore.core.implementation.telemetry.otel.OTelAttributeKey;
import io.clientcore.core.implementation.telemetry.otel.OTelInitializer;
import io.clientcore.core.telemetry.TelemetryProvider;
import io.clientcore.core.telemetry.tracing.Span;
import io.clientcore.core.telemetry.tracing.SpanBuilder;
import io.clientcore.core.telemetry.tracing.SpanKind;
import io.clientcore.core.util.ClientLogger;
import io.clientcore.core.util.Context;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.ATTRIBUTE_KEY_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.CONTEXT_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.SPAN_BUILDER_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.SPAN_KIND_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.ATTRIBUTE_KEY_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.CONTEXT_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.SPAN_BUILDER_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.SPAN_KIND_CLASS;

public class OTelSpanBuilder implements SpanBuilder {
static final OTelSpanBuilder NOOP = new OTelSpanBuilder(null);
Expand Down Expand Up @@ -89,7 +89,7 @@ public class OTelSpanBuilder implements SpanBuilder {
@Override
public SpanBuilder setParent(Context context) {
if (OTelInitializer.INSTANCE.isInitialized() && otelSpanBuilder != null) {
Object otelContext = context.get(ObservabilityProvider.TRACE_CONTEXT_KEY);
Object otelContext = context.get(TelemetryProvider.TRACE_CONTEXT_KEY);
if (!CONTEXT_CLASS.isInstance(otelContext)) {
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel.tracing;
package io.clientcore.core.implementation.telemetry.otel.tracing;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.implementation.observability.otel.OTelInitializer;
import io.clientcore.core.observability.tracing.SpanContext;
import io.clientcore.core.implementation.telemetry.otel.OTelInitializer;
import io.clientcore.core.telemetry.tracing.SpanContext;
import io.clientcore.core.util.ClientLogger;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.SPAN_CONTEXT_CLASS;
import static io.clientcore.core.implementation.observability.otel.OTelInitializer.TRACE_FLAGS_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.SPAN_CONTEXT_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.TRACE_FLAGS_CLASS;

public class OTelSpanContext implements SpanContext {
private static final OTelSpanContext INVALID;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel.tracing;
package io.clientcore.core.implementation.telemetry.otel.tracing;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.implementation.observability.otel.OTelInitializer;
import io.clientcore.core.observability.tracing.SpanBuilder;
import io.clientcore.core.observability.tracing.Tracer;
import io.clientcore.core.implementation.telemetry.otel.OTelInitializer;
import io.clientcore.core.telemetry.tracing.SpanBuilder;
import io.clientcore.core.telemetry.tracing.Tracer;
import io.clientcore.core.util.ClientLogger;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.TRACER_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.TRACER_CLASS;

public class OTelTracer implements Tracer {
public static final OTelTracer NOOP = new OTelTracer(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package io.clientcore.core.implementation.observability.otel.tracing;
package io.clientcore.core.implementation.telemetry.otel.tracing;

import io.clientcore.core.implementation.ReflectionUtils;
import io.clientcore.core.implementation.ReflectiveInvoker;
import io.clientcore.core.implementation.observability.otel.OTelInitializer;
import io.clientcore.core.implementation.telemetry.otel.OTelInitializer;
import io.clientcore.core.util.ClientLogger;

import static io.clientcore.core.implementation.observability.otel.OTelInitializer.TRACER_BUILDER_CLASS;
import static io.clientcore.core.implementation.telemetry.otel.OTelInitializer.TRACER_BUILDER_CLASS;

public class OTelTracerBuilder {
private static final ClientLogger LOGGER = new ClientLogger(OTelTracerBuilder.class);
Expand Down
Loading