Skip to content

Commit

Permalink
HttpLogOptions -> HttpInstrumentationOptions, docs and logging cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
lmolkova committed Jan 14, 2025
1 parent cd5ec3a commit d3630d8
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 42 deletions.
1 change: 0 additions & 1 deletion sdk/clientcore/core/checkstyle-suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
<suppress files="io.clientcore.core.http.client.DefaultHttpClientBuilder.java" checks="com.azure.tools.checkstyle.checks.ServiceClientBuilderCheck" />
<suppress files="io.clientcore.core.http.client.implementation.InputStreamTimeoutResponseSubscriber.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="io.clientcore.core.http.pipeline.HttpInstrumentationPolicy.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="io.clientcore.core.http.pipeline.HttpLoggingPolicy.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="io.clientcore.core.implementation.MethodHandleReflectiveInvoker.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="io.clientcore.core.implementation.http.rest.LengthValidatingInputStream.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
<suppress files="io.clientcore.core.serialization.json.JsonReader.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
Expand Down
4 changes: 0 additions & 4 deletions sdk/clientcore/core/spotbugs-exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@
<Bug pattern="DB_DUPLICATE_SWITCH_CLAUSES" />
<Class name="io.clientcore.core.serialization.xml.implementation.aalto.out.CharXmlWriter" />
</Match>
<Match>
<Bug pattern="DCN_NULLPOINTER_EXCEPTION" />
<Class name="io.clientcore.core.http.pipeline.HttpLoggingPolicy" />
</Match>
<Match>
<Bug pattern="DLS_DEAD_LOCAL_STORE" />
<Or>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,71 @@
import java.util.Set;

/**
* Configuration options for HTTP logging and tracing.
* Configuration options for HTTP instrumentation.
* <p>
* The instrumentation emits distributed traces following <a href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md">OpenTelemetry HTTP semantic conventions</a>
* and, when enabled, detailed HTTP logs.
* <p>
* The following information is recorded on distributed traces:
* <ul>
* <li>Request method, URI. The URI is sanitized based on allowed query parameters configurable with {@link #setAllowedQueryParamNames(Set)} and {@link #addAllowedQueryParamName(String)}</li>
* <li>Response status code</li>
* <li>Error details if the request fails</li>
* <li>Time it takes to receive response</li>
* <li>Correlation identifiers</li>
* </ul>
*
* @param <T> The type of the instrumentation provider.
The following information is recorded on detailed HTTP logs:
* <ul>
* <li>Request method, URI, and body size. URI is sanitized based on allowed query parameters configurable with {@link #setAllowedQueryParamNames(Set)} and {@link #addAllowedQueryParamName(String)}</li>
* <li>Response status code and body size</li>
* <li>Request and response headers from allow-list configured via {@link #setAllowedHeaderNames(Set)} and {@link #addAllowedHeaderName(HttpHeaderName)}.</li>
* <li>Error details if the request fails</li>
* <li>Time it takes to receive response</li>
* <li>Correlation identifiers</li>
* <li>When content logging is enabled via {@link #setContentLoggingEnabled(boolean)}: request and response body, and time-to-last-byte</li>
* </ul>
*
* Client libraries auto-discover global OpenTelemetry SDK instance configured by the java agent or
* in the application code. Just create a client instance as usual as shown in the following code snippet:
*
* <p><strong>Clients auto-discover global OpenTelemetry</strong></p>
*
* <!-- src_embed io.clientcore.core.telemetry.useglobalopentelemetry -->
* <pre>
*
* AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;;
*
* SampleClient client = new SampleClientBuilder&#40;&#41;.build&#40;&#41;;
*
* &#47;&#47; this call will be traced using OpenTelemetry SDK initialized globally
* client.clientCall&#40;&#41;;
*
* </pre>
* <!-- end io.clientcore.core.telemetry.useglobalopentelemetry -->
* <p>
*
* Alternatively, application developers can pass OpenTelemetry SDK instance explicitly to the client libraries.
*
* <p><strong>Pass configured OpenTelemetry instance explicitly</strong></p>
*
* <!-- src_embed io.clientcore.core.telemetry.useexplicitopentelemetry -->
* <pre>
*
* OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;.getOpenTelemetrySdk&#40;&#41;;
* HttpInstrumentationOptions&lt;OpenTelemetry&gt; instrumentationOptions = new HttpInstrumentationOptions&lt;OpenTelemetry&gt;&#40;&#41;
* .setProvider&#40;openTelemetry&#41;;
*
* SampleClient client = new SampleClientBuilder&#40;&#41;.instrumentationOptions&#40;instrumentationOptions&#41;.build&#40;&#41;;
*
* &#47;&#47; this call will be traced using OpenTelemetry SDK provided explicitly
* client.clientCall&#40;&#41;;
*
* </pre>
* <!-- end io.clientcore.core.telemetry.useexplicitopentelemetry -->
*
* @param <T> The type of the instrumentation provider. When using OpenTelemetry, this is {@code io.opentelemetry.api.OpenTelemetry}. If not provided
* the {@code io.opentelemetry.api.GlobalOpenTelemetry} instance is used.
*/
public final class HttpInstrumentationOptions<T> extends InstrumentationOptions<T> {
private boolean isHttpLoggingEnabled;
Expand Down Expand Up @@ -47,7 +109,11 @@ public final class HttpInstrumentationOptions<T> extends InstrumentationOptions<
= Configuration.getGlobalConfiguration().get(HTTP_LOGGING_ENABLED);

/**
* Creates a new instance that does not log any information about HTTP requests or responses.
* Creates a new instance using default options:
* <ul>
* <li>Detailed HTTP logging is disabled.</li>
* <li>Distributed tracing is enabled.</li>
* </ul>
*/
public HttpInstrumentationOptions() {
super();
Expand All @@ -59,11 +125,11 @@ public HttpInstrumentationOptions() {
}

/**
* Flag indicating whether HTTP request and response logging is enabled.
* Flag indicating whether detailed HTTP request and response logging is enabled.
* False by default.
* <p>
* When HTTP logging is disabled, basic information about the request and response is still recorded
* via distributed tracing.
* on distributed tracing spans.
*
* @return True if logging is enabled, false otherwise.
*/
Expand Down Expand Up @@ -99,12 +165,8 @@ public boolean isRedactedHeaderNamesLoggingEnabled() {
* Flag indicating whether HTTP request and response body is logged.
* False by default.
* <p>
* Note: even when content logging is explicitly enabled, it's not logged in the
* following cases:
* <ul>
* <li>When the content length is not known.</li>
* <li>When the content length is greater than 16KB.</li>
* </ul>
* Note: even when content logging is explicitly enabled, content is not logged
* for requests and responses where the content length is not known or greater than 16KB.
*
* @return True if content logging is enabled, false otherwise.
*/
Expand All @@ -119,7 +181,7 @@ public boolean isContentLoggingEnabled() {
* When HTTP logging is disabled, basic information about the request and response is still recorded
* via distributed tracing.
*
* @param isHttpLoggingEnabled True to enable HTTP logging, false otherwise.
* @param isHttpLoggingEnabled True to enable detailed HTTP logging, false otherwise.
* @return The updated {@link HttpInstrumentationOptions} object.
*/
public HttpInstrumentationOptions<T> setHttpLoggingEnabled(boolean isHttpLoggingEnabled) {
Expand All @@ -128,15 +190,11 @@ public HttpInstrumentationOptions<T> setHttpLoggingEnabled(boolean isHttpLogging
}

/**
* Enables or disables logging of HTTP request and response body.
* False by default.
* Enables or disables logging of HTTP request and response body. False by default.
* Enabling content logging also enables HTTP logging in general.
* <p>
* Note: even when content logging is explicitly enabled, it's not logged in the
* following cases:
* <ul>
* <li>When the content length is not known.</li>
* <li>When the content length is greater than 16KB.</li>
* </ul>
* Note: even when content logging is explicitly enabled, content is not logged for requests and responses where the
* content length is not known or greater than 16KB.
*
* @param isContentLoggingEnabled True to enable content logging, false otherwise.
* @return The updated {@link HttpInstrumentationOptions} object.
Expand All @@ -148,7 +206,7 @@ public HttpInstrumentationOptions<T> setContentLoggingEnabled(boolean isContentL
}

/**
* Gets the allowed headers that should be logged.
* Gets the allowed headers that should be logged when they appear on the request or response.
*
* @return The list of allowed headers.
*/
Expand Down Expand Up @@ -178,7 +236,7 @@ public HttpInstrumentationOptions<T> setAllowedHeaderNames(final Set<HttpHeaderN
}

/**
* Sets the given allowed header to the default header set that should be logged.
* Sets the given allowed header to the default header set that should be logged when they appear on the request or response.
* <p>
* Note: headers are not recorded on traces.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ public InstrumentationOptions<T> setTracingEnabled(boolean isTracingEnabled) {
* <!-- src_embed io.clientcore.core.telemetry.useexplicitopentelemetry -->
* <pre>
*
* OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;.getOpenTelemetrySdk&#40;&#41;;
* OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;.getOpenTelemetrySdk&#40;&#41;;
* HttpInstrumentationOptions&lt;OpenTelemetry&gt; instrumentationOptions = new HttpInstrumentationOptions&lt;OpenTelemetry&gt;&#40;&#41;
* .setProvider&#40;openTelemetry&#41;;
*
* SampleClient client = new SampleClientBuilder&#40;&#41;.instrumentationOptions&#40;instrumentationOptions&#41;.build&#40;&#41;;
*
* &#47;&#47; this call will be traced using OpenTelemetry SDK provided explicitly
* client.clientCall&#40;&#41;;
*
* </pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
* AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;;
*
* SampleClient client = new SampleClientBuilder&#40;&#41;.build&#40;&#41;;
*
* &#47;&#47; this call will be traced using OpenTelemetry SDK initialized globally
* client.clientCall&#40;&#41;;
*
* </pre>
Expand All @@ -40,11 +42,13 @@
* <!-- src_embed io.clientcore.core.telemetry.useexplicitopentelemetry -->
* <pre>
*
* OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;.getOpenTelemetrySdk&#40;&#41;;
* OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize&#40;&#41;.getOpenTelemetrySdk&#40;&#41;;
* HttpInstrumentationOptions&lt;OpenTelemetry&gt; instrumentationOptions = new HttpInstrumentationOptions&lt;OpenTelemetry&gt;&#40;&#41;
* .setProvider&#40;openTelemetry&#41;;
*
* SampleClient client = new SampleClientBuilder&#40;&#41;.instrumentationOptions&#40;instrumentationOptions&#41;.build&#40;&#41;;
*
* &#47;&#47; this call will be traced using OpenTelemetry SDK provided explicitly
* client.clientCall&#40;&#41;;
*
* </pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,21 @@ public interface HttpTrait<T extends HttpTrait<T>> {
T httpRetryOptions(HttpRetryOptions retryOptions);

/**
* Sets the {@link HttpInstrumentationOptions instrumentation configuration} to use when sending and receiving requests to and from the
* service. If not provided, HTTP logging is disabled by default. Basic HTTP request/response information may be available
* through distributed tracing. TODO: update it all
* Sets the {@link HttpInstrumentationOptions instrumentation configuration} to use when recording telemetry about HTTP
* requests sent to the service and responses received from it.
* <p>
* By default, when instrumentation options are not provided (explicitly or via environment variables), the following
* defaults are used:
* <ul>
* <li>Detailed HTTP logging about requests and responses is disabled</li>
* <li>Distributed tracing is enabled. If OpenTelemetry is found on the classpath, HTTP requests are
* captured as OpenTelemetry spans.
* If OpenTelemetry is not found on the classpath, the same information is captured in logs.
* HTTP request spans contain basic information about the request, such as the HTTP method, URL, status code and
* duration.
* See {@link io.clientcore.core.http.pipeline.HttpInstrumentationPolicy} for
* the details.</li>
* </ul>
*
* <p><strong>Note:</strong> It is important to understand the precedence order of the {@link HttpTrait} APIs. In
* particular, if a {@link HttpPipeline} is specified, this takes precedence over all other APIs in the trait, and
Expand All @@ -117,8 +129,8 @@ public interface HttpTrait<T extends HttpTrait<T>> {
* trait that are also ignored if an {@link HttpPipeline} is specified, so please be sure to refer to the
* documentation of types that implement this trait to understand the full set of implications.</p>
*
* @param instrumentationOptions The {@link HttpInstrumentationOptions logging configuration} to use when sending and receiving requests to
* and from the service.
* @param instrumentationOptions The {@link HttpInstrumentationOptions configuration} to use when recording telemetry about HTTP
* requests sent to the service and responses received from it.
*
* @return Returns the same concrete type with the appropriate properties updated, to allow for fluent chaining of
* operations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ Args=\
org.slf4j.MDC,\
org.slf4j.LoggerFactory,\
org.slf4j.impl.StaticLoggerBinder,\
io.clientcore.core.util.ClientLogger.LogLevel,\
io.clientcore.core.util.Configuration,\
io.clientcore.core.util.implementation.ImplUtils,\
io.clientcore.core.util.ClientLogger.LoggingEvent,\
io.clientcore.core.instrumentation.logging.ClientLogger.LogLevel,\
io.clientcore.core.instrumentation.logging.ClientLogger.LoggingEvent,\



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ private HttpRequest createRequest() {
}

private HttpPipelineBuilder getPipelineBuilder() {
HttpPipelineBuilder builder
= new HttpPipelineBuilder().policies(new HttpRetryPolicy(), new HttpInstrumentationPolicy(new HttpInstrumentationOptions<>().setHttpLoggingEnabled(true)));
HttpPipelineBuilder builder = new HttpPipelineBuilder().policies(new HttpRetryPolicy(),
new HttpInstrumentationPolicy(new HttpInstrumentationOptions<>().setHttpLoggingEnabled(true)));

if (options.getHttpClient() == PerfStressOptions.HttpClientType.OKHTTP) {
builder.httpClient(new OkHttpHttpClientProvider().getSharedInstance());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public void useGlobalOpenTelemetry() {
AutoConfiguredOpenTelemetrySdk.initialize();

SampleClient client = new SampleClientBuilder().build();

// this call will be traced using OpenTelemetry SDK initialized globally
client.clientCall();

// END: io.clientcore.core.telemetry.useglobalopentelemetry
Expand All @@ -71,11 +73,13 @@ public void useGlobalOpenTelemetry() {
public void useExplicitOpenTelemetry() {
// BEGIN: io.clientcore.core.telemetry.useexplicitopentelemetry

OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
HttpInstrumentationOptions<OpenTelemetry> instrumentationOptions = new HttpInstrumentationOptions<OpenTelemetry>()
.setProvider(openTelemetry);

SampleClient client = new SampleClientBuilder().instrumentationOptions(instrumentationOptions).build();

// this call will be traced using OpenTelemetry SDK provided explicitly
client.clientCall();

// END: io.clientcore.core.telemetry.useexplicitopentelemetry
Expand Down
2 changes: 1 addition & 1 deletion sdk/clientcore/tools/annotation-processor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<dependency>
<groupId>io.clientcore</groupId>
<artifactId>core</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;io.clientcore:core;dependency} -->
<version>1.0.0-beta.2</version> <!-- {x-version-update;io.clientcore:core;current} -->
<scope>compile</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class JavaPoetTemplateProcessor implements TemplateProcessor {
private TypeSpec.Builder classBuilder;
final ClassName HTTP_PIPELINE = ClassName.get("io.clientcore.core.http.pipeline", "HttpPipeline");
static ClassName SERVICE_VERSION_TYPE;
final ClassName CLIENTLOGGER_NAME = ClassName.get("io.clientcore.core.util", "ClientLogger");
final ClassName CLIENTLOGGER_NAME = ClassName.get("io.clientcore.core.instrumentation.logging", "ClientLogger");

@Override
public void process(TemplateInput templateInput, ProcessingEnvironment processingEnv) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,6 @@ public void testLoggerFieldGeneration() {
loggerField.modifiers);
assertEquals(processor.CLIENTLOGGER_NAME, loggerField.type);
assertEquals("LOGGER", loggerField.name);
assertTrue(loggerField.initializer.toString().contains("new io.clientcore.core.util.ClientLogger(com.example.ExampleClientServiceImpl.class)"));
assertTrue(loggerField.initializer.toString().contains("new io.clientcore.core.instrumentation.logging.ClientLogger(com.example.ExampleClientServiceImpl.class)"));
}
}

0 comments on commit d3630d8

Please sign in to comment.