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

feat: introductory beta level support for OpenTelemetry tracing on c.g.c.storage.Storage methods #2837

Merged
merged 29 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f6dd4ab
feat: Instrument HTTP with OpenTelemetry (#2780)
sydney-munro Oct 17, 2024
5e6eb84
feat: Add OpenTelemetry Traces to GRPC (#2783)
sydney-munro Oct 22, 2024
c0abdf9
feat: create(Blob) instrumentation (#2792)
sydney-munro Oct 29, 2024
d9fd4bd
feat: Add CreateBlob for HTTP (#2803)
sydney-munro Oct 29, 2024
4538213
feat: Instrument HTTP Reads and Rewrites (#2808)
sydney-munro Nov 7, 2024
dc5a734
feat: Take in a module name when creating a span (#2811)
sydney-munro Nov 8, 2024
d7243f4
feat: Instrument HTTP readAllBytes (#2812)
sydney-munro Nov 11, 2024
2a85338
feat: Instrument ReadAllBytes and CreateFrom in gRPC (#2815)
sydney-munro Nov 14, 2024
57aeade
feat: Instrument gRPC downloadTo and Copy (#2818)
sydney-munro Nov 18, 2024
bd2fd5e
feat: Instrument HTTP createFrom (#2824)
sydney-munro Nov 25, 2024
6a2b3ca
chore: misc otel internalization/cleanup (#2835)
BenWhitehead Dec 5, 2024
125fc4e
feat: Instrument Reader and Writer methods (#2829)
sydney-munro Dec 6, 2024
56af555
chore: remove unnecessary context propagation (#2853)
sydney-munro Dec 17, 2024
3f8cb0f
Merge branch 'main' into otel-v1-branch
sydney-munro Dec 17, 2024
156b643
lint
sydney-munro Dec 17, 2024
cf94763
fix test failures
sydney-munro Dec 17, 2024
55e5770
remove otel-v1-branch sync repo settings and fix integ test
sydney-munro Dec 17, 2024
7c19e78
fix: cleanup span names for reader and writer (#2855)
BenWhitehead Dec 18, 2024
92989f5
pr comments
sydney-munro Dec 18, 2024
588b1c6
pr comments
sydney-munro Dec 18, 2024
499a95c
pr comments/fix typo
sydney-munro Dec 18, 2024
0776746
remove duplicated logic
sydney-munro Dec 19, 2024
f623d67
add back testbench deleted lines
sydney-munro Dec 19, 2024
3236dea
testbench formatting
sydney-munro Dec 19, 2024
3bb8a5c
fixing tests and adding top level http spans
sydney-munro Dec 26, 2024
1780daa
add uuid to bucket create test
sydney-munro Dec 26, 2024
e5dfebc
remove HttpStorageRpc tracing layer
sydney-munro Jan 2, 2025
6faf5ec
chore: refactor otel tracing of Storage to be a decorator rather than…
BenWhitehead Jan 6, 2025
114a960
chore: fix copy test
BenWhitehead Jan 6, 2025
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
13 changes: 13 additions & 0 deletions google-cloud-storage/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,17 @@
<method>boolean equals(java.lang.Object)</method>
</difference>

<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/storage/StorageOptions$Builder</className>
<method>com.google.cloud.storage.StorageOptions$Builder setOpenTelemetry(io.opentelemetry.api.OpenTelemetry)</method>
</difference>

<difference>
<differenceType>7013</differenceType>
<className>com/google/cloud/storage/StorageOptions</className>
<method>io.opentelemetry.api.OpenTelemetry getOpenTelemetry()</method>
</difference>


</differences>
9 changes: 9 additions & 0 deletions google-cloud-storage/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
<groupId>io.opencensus</groupId>
<artifactId>opencensus-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-context</artifactId>
</dependency>
<dependency>
<groupId>com.google.api.grpc</groupId>
<artifactId>proto-google-iam-v1</artifactId>
Expand Down Expand Up @@ -205,6 +209,11 @@
<artifactId>grpc-googleapis</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
<scope>test</scope>
</dependency>

<!--
We're not using this directly, however there appears to be some resolution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,11 @@
import io.grpc.MethodDescriptor;
import io.grpc.Status;
import io.grpc.protobuf.ProtoUtils;
import io.opentelemetry.api.OpenTelemetry;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.net.URI;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -119,6 +121,7 @@ public final class GrpcStorageOptions extends StorageOptions
private final boolean grpcClientMetricsManuallyEnabled;
private final GrpcInterceptorProvider grpcInterceptorProvider;
private final BlobWriteSessionConfig blobWriteSessionConfig;
private transient OpenTelemetry openTelemetry;

private GrpcStorageOptions(Builder builder, GrpcStorageDefaults serviceDefaults) {
super(builder, serviceDefaults);
Expand All @@ -135,6 +138,7 @@ private GrpcStorageOptions(Builder builder, GrpcStorageDefaults serviceDefaults)
this.grpcClientMetricsManuallyEnabled = builder.grpcMetricsManuallyEnabled;
this.grpcInterceptorProvider = builder.grpcInterceptorProvider;
this.blobWriteSessionConfig = builder.blobWriteSessionConfig;
this.openTelemetry = builder.openTelemetry;
}

@Override
Expand All @@ -157,6 +161,11 @@ StorageSettings getStorageSettings() throws IOException {
return resolveSettingsAndOpts().x();
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
this.openTelemetry = HttpStorageOptions.getDefaultInstance().getOpenTelemetry();
}

/**
* We have to perform several introspections and detections to cross-wire/support several features
* that are either gapic primitives, ServiceOption primitives or GCS semantic requirements.
Expand Down Expand Up @@ -349,6 +358,13 @@ private Tuple<StorageSettings, Opts<UserProject>> resolveSettingsAndOpts() throw
return Tuple.of(builder.build(), defaultOpts);
}

/** @since 2.47.0 This new api is in preview and is subject to breaking changes. */
@BetaApi
@Override
public OpenTelemetry getOpenTelemetry() {
return openTelemetry;
}

/** @since 2.14.0 */
@Override
public GrpcStorageOptions.Builder toBuilder() {
Expand All @@ -364,6 +380,7 @@ public int hashCode() {
enableGrpcClientMetrics,
grpcInterceptorProvider,
blobWriteSessionConfig,
openTelemetry,
baseHashCode());
}

Expand All @@ -382,6 +399,7 @@ public boolean equals(Object o) {
&& Objects.equals(terminationAwaitDuration, that.terminationAwaitDuration)
&& Objects.equals(grpcInterceptorProvider, that.grpcInterceptorProvider)
&& Objects.equals(blobWriteSessionConfig, that.blobWriteSessionConfig)
&& Objects.equals(openTelemetry, that.openTelemetry)
&& this.baseEquals(that);
}

Expand Down Expand Up @@ -423,6 +441,7 @@ public static final class Builder extends StorageOptions.Builder {
GrpcStorageDefaults.INSTANCE.grpcInterceptorProvider();
private BlobWriteSessionConfig blobWriteSessionConfig =
GrpcStorageDefaults.INSTANCE.getDefaultStorageWriterConfig();
private OpenTelemetry openTelemetry = GrpcStorageDefaults.INSTANCE.getDefaultOpenTelemetry();

private boolean grpcMetricsManuallyEnabled = false;

Expand All @@ -437,6 +456,7 @@ public static final class Builder extends StorageOptions.Builder {
this.enableGrpcClientMetrics = gso.enableGrpcClientMetrics;
this.grpcInterceptorProvider = gso.grpcInterceptorProvider;
this.blobWriteSessionConfig = gso.blobWriteSessionConfig;
this.openTelemetry = gso.openTelemetry;
}

/**
Expand Down Expand Up @@ -619,6 +639,19 @@ public GrpcStorageOptions.Builder setBlobWriteSessionConfig(
return this;
}

/**
* Enable OpenTelemetry Tracing and provide an instance for the client to use.
*
* @param openTelemetry User defined instance of OpenTelemetry to be used by the library
* @since 2.47.0 This new api is in preview and is subject to breaking changes.
*/
@BetaApi
public GrpcStorageOptions.Builder setOpenTelemetry(OpenTelemetry openTelemetry) {
requireNonNull(openTelemetry, "openTelemetry must be non null");
this.openTelemetry = openTelemetry;
return this;
}

/** @since 2.14.0 */
@Override
public GrpcStorageOptions build() {
Expand Down Expand Up @@ -695,6 +728,12 @@ public GrpcInterceptorProvider grpcInterceptorProvider() {
public BlobWriteSessionConfig getDefaultStorageWriterConfig() {
return BlobWriteSessionConfigs.getDefault();
}

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

/**
Expand Down Expand Up @@ -751,22 +790,27 @@ public Storage create(StorageOptions options) {
new InternalZeroCopyGrpcStorageStub(
stubSettings, clientContext, grpcStorageCallableFactory);
StorageClient client = new InternalStorageClient(stub);
return new GrpcStorageImpl(
grpcStorageOptions,
client,
stub.getObjectMediaResponseMarshaller,
grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()),
defaultOpts);
GrpcStorageImpl grpcStorage =
new GrpcStorageImpl(
grpcStorageOptions,
client,
stub.getObjectMediaResponseMarshaller,
grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()),
defaultOpts);
return OtelStorageDecorator.decorate(
grpcStorage, options.getOpenTelemetry(), Transport.GRPC);
} else {
StorageClient client = StorageClient.create(storageSettings);
return new GrpcStorageImpl(
grpcStorageOptions,
client,
ResponseContentLifecycleManager.noop(),
grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()),
defaultOpts);
GrpcStorageImpl grpcStorage =
new GrpcStorageImpl(
grpcStorageOptions,
client,
ResponseContentLifecycleManager.noop(),
grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()),
defaultOpts);
return OtelStorageDecorator.decorate(
grpcStorage, options.getOpenTelemetry(), Transport.GRPC);
}

} catch (IOException e) {
throw new IllegalStateException(
"Unable to instantiate gRPC com.google.cloud.storage.Storage client.", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.google.cloud.storage.spi.v1.StorageRpc;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import io.opentelemetry.api.OpenTelemetry;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
Expand All @@ -59,6 +60,8 @@ public class HttpStorageOptions extends StorageOptions {
private transient RetryDependenciesAdapter retryDepsAdapter;
private final BlobWriteSessionConfig blobWriteSessionConfig;

private transient OpenTelemetry openTelemetry;

private HttpStorageOptions(Builder builder, StorageDefaults serviceDefaults) {
super(builder, serviceDefaults);
this.retryAlgorithmManager =
Expand All @@ -67,6 +70,7 @@ private HttpStorageOptions(Builder builder, StorageDefaults serviceDefaults) {
builder.storageRetryStrategy, defaults().getStorageRetryStrategy()));
retryDepsAdapter = new RetryDependenciesAdapter();
blobWriteSessionConfig = builder.blobWriteSessionConfig;
openTelemetry = builder.openTelemetry;
}

@Override
Expand All @@ -84,14 +88,22 @@ StorageRpc getStorageRpcV1() {
return (StorageRpc) getRpc();
}

/** @since 2.47.0 This new api is in preview and is subject to breaking changes. */
@BetaApi
@Override
public OpenTelemetry getOpenTelemetry() {
return openTelemetry;
}

@Override
public HttpStorageOptions.Builder toBuilder() {
return new HttpStorageOptions.Builder(this);
}

@Override
public int hashCode() {
return Objects.hash(retryAlgorithmManager, blobWriteSessionConfig, baseHashCode());
return Objects.hash(
retryAlgorithmManager, blobWriteSessionConfig, openTelemetry, baseHashCode());
}

@Override
Expand All @@ -105,12 +117,14 @@ public boolean equals(Object o) {
HttpStorageOptions that = (HttpStorageOptions) o;
return Objects.equals(retryAlgorithmManager, that.retryAlgorithmManager)
&& Objects.equals(blobWriteSessionConfig, that.blobWriteSessionConfig)
&& Objects.equals(openTelemetry, that.openTelemetry)
&& this.baseEquals(that);
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
this.retryDepsAdapter = new RetryDependenciesAdapter();
this.openTelemetry = HttpStorageOptions.getDefaultInstance().getOpenTelemetry();
}

public static HttpStorageOptions.Builder newBuilder() {
Expand All @@ -135,6 +149,7 @@ public static class Builder extends StorageOptions.Builder {
private StorageRetryStrategy storageRetryStrategy;
private BlobWriteSessionConfig blobWriteSessionConfig =
HttpStorageDefaults.INSTANCE.getDefaultStorageWriterConfig();
private OpenTelemetry openTelemetry = HttpStorageDefaults.INSTANCE.getDefaultOpenTelemetry();

Builder() {}

Expand All @@ -143,6 +158,7 @@ public static class Builder extends StorageOptions.Builder {
HttpStorageOptions hso = (HttpStorageOptions) options;
this.storageRetryStrategy = hso.retryAlgorithmManager.retryStrategy;
this.blobWriteSessionConfig = hso.blobWriteSessionConfig;
this.openTelemetry = hso.getOpenTelemetry();
}

@Override
Expand Down Expand Up @@ -268,6 +284,19 @@ public HttpStorageOptions build() {
}
return options;
}

/**
* Enable OpenTelemetry Tracing and provide an instance for the client to use.
*
* @param openTelemetry User defined instance of OpenTelemetry to be used by the library
* @since 2.47.0 This new api is in preview and is subject to breaking changes.
*/
@BetaApi
public HttpStorageOptions.Builder setOpenTelemetry(OpenTelemetry openTelemetry) {
requireNonNull(openTelemetry, "openTelemetry must be non null");
this.openTelemetry = openTelemetry;
return this;
}
}

public static final class HttpStorageDefaults extends StorageDefaults {
Expand Down Expand Up @@ -301,6 +330,12 @@ public StorageRetryStrategy getStorageRetryStrategy() {
public BlobWriteSessionConfig getDefaultStorageWriterConfig() {
return BlobWriteSessionConfigs.getDefault();
}

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

/**
Expand Down Expand Up @@ -341,8 +376,12 @@ public Storage create(StorageOptions options) {
HttpStorageOptions httpStorageOptions = (HttpStorageOptions) options;
Clock clock = Clock.systemUTC();
try {
return new StorageImpl(
httpStorageOptions, httpStorageOptions.blobWriteSessionConfig.createFactory(clock));
StorageImpl storage =
new StorageImpl(
httpStorageOptions,
httpStorageOptions.blobWriteSessionConfig.createFactory(clock));
return OtelStorageDecorator.decorate(
storage, httpStorageOptions.getOpenTelemetry(), Transport.HTTP);
} catch (IOException e) {
throw new IllegalStateException(
"Unable to instantiate HTTP com.google.cloud.storage.Storage client.", e);
Expand Down
Loading
Loading