-
Notifications
You must be signed in to change notification settings - Fork 85
chore: refactor otel tracing of Storage to be a decorator rather than in method modification #2856
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
Conversation
…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.
| } | ||
|
|
||
| SpanData spanData = exporter.getExportedSpans().get(0); | ||
| assertAll( |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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
| 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(); | ||
| } |
There was a problem hiding this comment.
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.
- Define a span and scope
- Invoke the delegate
- catch any error
- end the span
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
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:
@BetaApion all otel related methods{Http,Grpc}StorageDefaults.getDefaultOpenTelemetrydefault which points atOpenTelemetry.noop()com.google.cloud.storage.otelpackage and helpersassertAll