KEMBAR78
chore: refactor otel tracing of Storage to be a decorator rather than in method modification by BenWhitehead · Pull Request #2856 · googleapis/java-storage · GitHub
Skip to content

Conversation

@BenWhitehead
Copy link
Collaborator

Refactor com.google.cloud.storage.Storage otel tracing to be based on a decorating instance of Storage rather than modifying the implementations of StorageImpl and GrpcStorageImpl directly.

This simplifies things by ensuring any otel tracing for c.g.c.s.Storage is implemented for both http and grpc at the same time and with the same metadata.

As a side effect, the previous com.google.cloud.storage.otel package has been removed.

The number of lines appears daunting, however a high level overview of the actual modifications:

  1. Remove otel tracing from StorageImpl
  2. Remove otel tracing from GrpcStorageImpl
  3. Cleanup StorageOption
    1. classes to specify @BetaApi on all otel related methods
    2. Add {Http,Grpc}StorageDefaults.getDefaultOpenTelemetry default which points at OpenTelemetry.noop()
    3. Relax dependency on OpenTelemetrySdk to only OpenTelemetry
  4. Add OtelStorageDecorator (~1700 Lines of the PR) to decorate nearly all public api methods (excluding batch())
    • Each method is "logicless" for the most part, and was generated with the help of IntelliJ live templates
    • Each method is generally: Define span, and scope invoke delegate catch any exception and complete the span
    • There are sub decorators for ReadChannel, WriteChannel, BlobWriteSession and CopyWriter which carry the originating span along for their lifetimes
  5. Remote com.google.cloud.storage.otel package and helpers
  6. Update assertions in ITOpenTelemetryTest to be wrapped in an assertAll

…g.c.storage.Storage methods

Add introductory support for OpenTelemetry tracing to com.google.cloud.storage.Storage method.

Actual RPC methods are not yet supported.
@BenWhitehead BenWhitehead requested review from a team as code owners January 3, 2025 21:36
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. api: storage Issues related to the googleapis/java-storage API. labels Jan 3, 2025
}

SpanData spanData = exporter.getExportedSpans().get(0);
assertAll(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Make sure all are validated rather than an early failure preventing a later assertion

@After
public void tearDown() throws Exception {
if (storage != null) {
storage.close();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

make sure we close the constructed storage instance so we don't leak grpc clients

/** @since 2.47.0 This new api is in preview and is subject to breaking changes. */
@BetaApi
public OpenTelemetry getDefaultOpenTelemetry() {
return OpenTelemetry.noop();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Make sure we default to a non-null value

/** @since 2.47.0 This new api is in preview and is subject to breaking changes. */
@BetaApi
public OpenTelemetry getDefaultOpenTelemetry() {
return OpenTelemetry.noop();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Make sure we default to a non-null value

ResponseContentLifecycleManager.noop(),
grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()),
defaultOpts);
return OtelStorageDecorator.decorate(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Weave in the decorator if necessary

new StorageImpl(
httpStorageOptions,
httpStorageOptions.blobWriteSessionConfig.createFactory(clock));
return OtelStorageDecorator.decorate(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Weave in the decorator if necessary

Comment on lines +76 to +89
Span span =
tracer
.spanBuilder("create")
.setAttribute("gsutil.uri", fmtBucket(bucketInfo.getName()))
.startSpan();
try (Scope ignore = span.makeCurrent()) {
return delegate.create(bucketInfo, options);
} catch (Throwable t) {
span.recordException(t);
span.setStatus(StatusCode.ERROR, t.getClass().getSimpleName());
throw t;
} finally {
span.end();
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This class is the largest chunk of the PR, but consists of generally templated code.

  1. Define a span and scope
  2. Invoke the delegate
  3. catch any error
  4. end the span

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

}
}

private static class OtelDecoratedReadChannel implements ReadChannel {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ReadChannel, WriteChannel, CopyWriter and BlobWriteSession have sub-decorators which carry their originating spans along for their lifetimes.

Copy link
Contributor

@sydney-munro sydney-munro left a comment

Choose a reason for hiding this comment

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

LGTM, we chatted offline about this at greater length than is reflected in this code review. No surprises here.

@sydney-munro sydney-munro added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Jan 6, 2025
@BenWhitehead BenWhitehead merged commit 6faf5ec into otel-v1-branch Jan 6, 2025
17 checks passed
@BenWhitehead BenWhitehead deleted the otel/decorator-refactor branch January 6, 2025 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: storage Issues related to the googleapis/java-storage API. kokoro:force-run Add this label to force Kokoro to re-run the tests. size: xl Pull request size is extra large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants