diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index cef5e58f3a29..5af8e9dc9618 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -187,8 +187,7 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO */ static BigtableDataClient createWithClientContext( BigtableDataSettings settings, BigtableClientContext context) throws IOException { - EnhancedBigtableStub stub = - EnhancedBigtableStub.createWithClientContext(settings.getStubSettings(), context); + EnhancedBigtableStub stub = new EnhancedBigtableStub(settings.getStubSettings(), context); return new BigtableDataClient(stub); } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java index 47cf7b15ed10..544d75d6a78e 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java @@ -16,9 +16,8 @@ package com.google.cloud.bigtable.data.v2; import com.google.api.core.BetaApi; -import com.google.api.gax.rpc.ClientContext; +import com.google.bigtable.v2.InstanceName; import com.google.cloud.bigtable.data.v2.stub.BigtableClientContext; -import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStub; import java.io.IOException; import javax.annotation.Nonnull; @@ -75,8 +74,7 @@ public final class BigtableDataClientFactory implements AutoCloseable { public static BigtableDataClientFactory create(BigtableDataSettings defaultSettings) throws IOException { BigtableClientContext sharedClientContext = - EnhancedBigtableStub.createBigtableClientContext(defaultSettings.getStubSettings()); - + BigtableClientContext.create(defaultSettings.getStubSettings()); return new BigtableDataClientFactory(sharedClientContext, defaultSettings); } @@ -107,17 +105,11 @@ public void close() throws Exception { */ public BigtableDataClient createDefault() { try { - ClientContext clientContext = - sharedClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - defaultSettings.getStubSettings(), - sharedClientContext.getBuiltinOpenTelemetry(), - sharedClientContext.getUserOpenTelemetry())) - .build(); + BigtableClientContext ctx = + sharedClientContext.createChild( + sharedClientContext.getInstanceName(), sharedClientContext.getAppProfileId()); - return BigtableDataClient.createWithClientContext( - defaultSettings, sharedClientContext.withClientContext(clientContext)); + return BigtableDataClient.createWithClientContext(defaultSettings, ctx); } catch (IOException e) { // Should never happen because the connection has been established already throw new RuntimeException( @@ -137,17 +129,12 @@ public BigtableDataClient createDefault() { public BigtableDataClient createForAppProfile(@Nonnull String appProfileId) throws IOException { BigtableDataSettings settings = defaultSettings.toBuilder().setAppProfileId(appProfileId).build(); + BigtableClientContext ctx = + sharedClientContext.createChild( + InstanceName.of(settings.getProjectId(), settings.getInstanceId()), + settings.getAppProfileId()); - ClientContext clientContext = - sharedClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), - sharedClientContext.getBuiltinOpenTelemetry(), - sharedClientContext.getUserOpenTelemetry())) - .build(); - return BigtableDataClient.createWithClientContext( - settings, sharedClientContext.withClientContext(clientContext)); + return BigtableDataClient.createWithClientContext(settings, ctx); } /** @@ -167,18 +154,12 @@ public BigtableDataClient createForInstance(@Nonnull String projectId, @Nonnull .setInstanceId(instanceId) .setDefaultAppProfileId() .build(); + BigtableClientContext ctx = + sharedClientContext.createChild( + InstanceName.of(settings.getProjectId(), settings.getInstanceId()), + settings.getAppProfileId()); - ClientContext clientContext = - sharedClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), - sharedClientContext.getBuiltinOpenTelemetry(), - sharedClientContext.getUserOpenTelemetry())) - .build(); - - return BigtableDataClient.createWithClientContext( - settings, sharedClientContext.withClientContext(clientContext)); + return BigtableDataClient.createWithClientContext(settings, ctx); } /** @@ -199,15 +180,11 @@ public BigtableDataClient createForInstance( .setInstanceId(instanceId) .setAppProfileId(appProfileId) .build(); - ClientContext clientContext = - sharedClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), - sharedClientContext.getBuiltinOpenTelemetry(), - sharedClientContext.getUserOpenTelemetry())) - .build(); - return BigtableDataClient.createWithClientContext( - settings, sharedClientContext.withClientContext(clientContext)); + BigtableClientContext ctx = + sharedClientContext.createChild( + InstanceName.of(settings.getProjectId(), settings.getInstanceId()), + settings.getAppProfileId()); + + return BigtableDataClient.createWithClientContext(settings, ctx); } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java index d71355d6cd9f..c89f36819064 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java @@ -24,18 +24,25 @@ import com.google.api.gax.core.FixedExecutorProvider; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.rpc.ClientContext; +import com.google.api.gax.tracing.ApiTracerFactory; import com.google.auth.Credentials; import com.google.auth.oauth2.ServiceAccountJwtAccessCredentials; import com.google.bigtable.v2.InstanceName; import com.google.cloud.bigtable.data.v2.internal.JwtCredentialsWithAudience; import com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants; import com.google.cloud.bigtable.data.v2.stub.metrics.ChannelPoolMetricsTracer; +import com.google.cloud.bigtable.data.v2.stub.metrics.CompositeTracerFactory; import com.google.cloud.bigtable.data.v2.stub.metrics.CustomOpenTelemetryMetricsProvider; import com.google.cloud.bigtable.data.v2.stub.metrics.Util; import com.google.cloud.bigtable.gaxx.grpc.BigtableTransportChannelProvider; import com.google.cloud.bigtable.gaxx.grpc.ChannelPrimer; +import com.google.common.collect.ImmutableList; import io.grpc.ManagedChannelBuilder; import io.grpc.opentelemetry.GrpcOpenTelemetry; +import io.opencensus.stats.Stats; +import io.opencensus.stats.StatsRecorder; +import io.opencensus.tags.Tagger; +import io.opencensus.tags.Tags; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.io.IOException; @@ -55,15 +62,30 @@ public class BigtableClientContext { private static final Logger logger = Logger.getLogger(BigtableClientContext.class.getName()); + private final boolean isChild; + private final InstanceName instanceName; + private final String appProfileId; + private final ApiTracerFactory userTracerFactory; @Nullable private final OpenTelemetrySdk builtinOpenTelemetry; @Nullable private final OpenTelemetry userOpenTelemetry; private final ClientContext clientContext; // the background executor shared for OTEL instances and monitoring client and all other // background tasks private final ExecutorProvider backgroundExecutorProvider; + private final Tagger ocTagger; + private final StatsRecorder ocRecorder; public static BigtableClientContext create(EnhancedBigtableStubSettings settings) throws IOException { + return create(settings, Tags.getTagger(), Stats.getStatsRecorder()); + } + + public static BigtableClientContext create( + EnhancedBigtableStubSettings settings, Tagger ocTagger, StatsRecorder ocRecorder) + throws IOException { + InstanceName instanceName = InstanceName.of(settings.getProjectId(), settings.getInstanceId()); + String appProfileId = settings.getAppProfileId(); + EnhancedBigtableStubSettings.Builder builder = settings.toBuilder(); // Set up credentials @@ -85,6 +107,8 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings FixedExecutorProvider.create(backgroundExecutor, shouldAutoClose); builder.setBackgroundExecutorProvider(executorProvider); + ApiTracerFactory userTracerFactory = settings.getTracerFactory(); + // Set up OpenTelemetry @Nullable OpenTelemetry userOtel = null; if (settings.getMetricsProvider() instanceof CustomOpenTelemetryMetricsProvider) { @@ -158,7 +182,17 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings channelPoolMetricsTracer.start(clientContext.getExecutor()); } - return new BigtableClientContext(clientContext, builtinOtel, userOtel, executorProvider); + return new BigtableClientContext( + false, + instanceName, + appProfileId, + clientContext, + userTracerFactory, + builtinOtel, + userOtel, + ocTagger, + ocRecorder, + executorProvider); } private static void configureGrpcOtel( @@ -189,14 +223,53 @@ private static void configureGrpcOtel( } private BigtableClientContext( + boolean isChild, + InstanceName instanceName, + String appProfileId, ClientContext clientContext, - @Nullable OpenTelemetrySdk internalOtel, - @Nullable OpenTelemetry userOpenTelemetry, - ExecutorProvider backgroundExecutorProvider) { - this.clientContext = clientContext; - this.userOpenTelemetry = userOpenTelemetry; - this.builtinOpenTelemetry = internalOtel; + ApiTracerFactory userTracerFactory, + @Nullable OpenTelemetrySdk builtinOtel, + @Nullable OpenTelemetry userOtel, + Tagger ocTagger, + StatsRecorder ocRecorder, + ExecutorProvider backgroundExecutorProvider) + throws IOException { + this.isChild = isChild; + this.instanceName = instanceName; + this.appProfileId = appProfileId; + + this.userTracerFactory = userTracerFactory; + this.builtinOpenTelemetry = builtinOtel; + this.userOpenTelemetry = userOtel; + this.ocTagger = ocTagger; + this.ocRecorder = ocRecorder; this.backgroundExecutorProvider = backgroundExecutorProvider; + + ImmutableList.Builder tracerFactories = ImmutableList.builder(); + tracerFactories + .add(Util.createOCTracingFactory(instanceName, appProfileId)) + .add(Util.createOCMetricsFactory(instanceName, appProfileId, ocTagger, ocRecorder)) + .add(userTracerFactory); + + if (builtinOtel != null) { + tracerFactories.add(Util.createOtelMetricsFactory(builtinOtel, instanceName, appProfileId)); + } + if (userOtel != null) { + tracerFactories.add(Util.createOtelMetricsFactory(userOtel, instanceName, appProfileId)); + } + + this.clientContext = + clientContext.toBuilder() + .setTracerFactory(new CompositeTracerFactory(tracerFactories.build())) + .build(); + } + + public InstanceName getInstanceName() { + return instanceName; + } + + public String getAppProfileId() { + return appProfileId; } @Nullable @@ -213,12 +286,26 @@ public ClientContext getClientContext() { return this.clientContext; } - public BigtableClientContext withClientContext(ClientContext clientContext) { + public BigtableClientContext createChild(InstanceName instanceName, String appProfileId) + throws IOException { return new BigtableClientContext( - clientContext, builtinOpenTelemetry, userOpenTelemetry, backgroundExecutorProvider); + true, + instanceName, + appProfileId, + clientContext, + userTracerFactory, + builtinOpenTelemetry, + userOpenTelemetry, + ocTagger, + ocRecorder, + backgroundExecutorProvider); } public void close() throws Exception { + if (isChild) { + return; + } + for (BackgroundResource resource : clientContext.getBackgroundResources()) { resource.close(); } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java index b3cc8d36551e..bf94964434af 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java @@ -15,18 +15,12 @@ */ package com.google.cloud.bigtable.data.v2.stub; -import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.APP_PROFILE_KEY; -import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_PROJECT_ID_KEY; -import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLIENT_NAME_KEY; -import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.INSTANCE_ID_KEY; - import com.google.api.core.ApiFuture; import com.google.api.core.BetaApi; import com.google.api.core.InternalApi; import com.google.api.gax.batching.Batcher; import com.google.api.gax.batching.BatcherImpl; import com.google.api.gax.batching.FlowController; -import com.google.api.gax.grpc.GaxGrpcProperties; import com.google.api.gax.grpc.GrpcCallContext; import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcRawCallableFactory; @@ -45,8 +39,6 @@ import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallSettings; import com.google.api.gax.rpc.UnaryCallable; -import com.google.api.gax.tracing.ApiTracerFactory; -import com.google.api.gax.tracing.OpencensusTracerFactory; import com.google.api.gax.tracing.SpanName; import com.google.api.gax.tracing.TracedServerStreamingCallable; import com.google.api.gax.tracing.TracedUnaryCallable; @@ -64,7 +56,6 @@ import com.google.bigtable.v2.ReadRowsResponse; import com.google.bigtable.v2.RowRange; import com.google.bigtable.v2.SampleRowKeysResponse; -import com.google.cloud.bigtable.Version; import com.google.cloud.bigtable.data.v2.internal.NameUtil; import com.google.cloud.bigtable.data.v2.internal.PrepareQueryRequest; import com.google.cloud.bigtable.data.v2.internal.PrepareResponse; @@ -96,10 +87,6 @@ import com.google.cloud.bigtable.data.v2.stub.changestream.ReadChangeStreamUserCallable; import com.google.cloud.bigtable.data.v2.stub.metrics.BigtableTracerStreamingCallable; import com.google.cloud.bigtable.data.v2.stub.metrics.BigtableTracerUnaryCallable; -import com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsTracerFactory; -import com.google.cloud.bigtable.data.v2.stub.metrics.CompositeTracerFactory; -import com.google.cloud.bigtable.data.v2.stub.metrics.MetricsTracerFactory; -import com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants; import com.google.cloud.bigtable.data.v2.stub.metrics.StatsHeadersServerStreamingCallable; import com.google.cloud.bigtable.data.v2.stub.metrics.StatsHeadersUnaryCallable; import com.google.cloud.bigtable.data.v2.stub.metrics.TracedBatcherUnaryCallable; @@ -122,22 +109,12 @@ import com.google.cloud.bigtable.data.v2.stub.sql.PlanRefreshingCallable; import com.google.cloud.bigtable.data.v2.stub.sql.SqlRowMergingCallable; import com.google.cloud.bigtable.gaxx.retrying.RetryInfoRetryAlgorithm; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Functions; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.protobuf.ByteString; import io.grpc.MethodDescriptor; -import io.opencensus.stats.Stats; -import io.opencensus.stats.StatsRecorder; -import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; -import io.opencensus.tags.Tagger; -import io.opencensus.tags.Tags; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.Attributes; import java.io.IOException; import java.time.Duration; import java.util.List; @@ -167,7 +144,6 @@ public class EnhancedBigtableStub implements AutoCloseable { private final EnhancedBigtableStubSettings settings; private final BigtableClientContext bigtableClientContext; - private final boolean closeClientContext; private final RequestContext requestContext; private final FlowController bulkMutationFlowController; private final DynamicFlowControlStats bulkMutationDynamicFlowControlStats; @@ -198,117 +174,19 @@ public class EnhancedBigtableStub implements AutoCloseable { public static EnhancedBigtableStub create(EnhancedBigtableStubSettings settings) throws IOException { - BigtableClientContext bigtableClientContext = createBigtableClientContext(settings); - ClientContext contextWithTracer = - bigtableClientContext.getClientContext().toBuilder() - .setTracerFactory( - createBigtableTracerFactory( - settings, - bigtableClientContext.getBuiltinOpenTelemetry(), - bigtableClientContext.getUserOpenTelemetry())) - .build(); - bigtableClientContext = bigtableClientContext.withClientContext(contextWithTracer); + BigtableClientContext bigtableClientContext = BigtableClientContext.create(settings); return new EnhancedBigtableStub(settings, bigtableClientContext); } - public static EnhancedBigtableStub createWithClientContext( - EnhancedBigtableStubSettings settings, BigtableClientContext clientContext) - throws IOException { - - return new EnhancedBigtableStub(settings, clientContext, false); - } - - public static BigtableClientContext createBigtableClientContext( - EnhancedBigtableStubSettings settings) throws IOException { - return BigtableClientContext.create(settings); - } - - public static ApiTracerFactory createBigtableTracerFactory( - EnhancedBigtableStubSettings settings, - @Nullable OpenTelemetry builtinOtel, - @Nullable OpenTelemetry userOtel) - throws IOException { - return createBigtableTracerFactory( - settings, Tags.getTagger(), Stats.getStatsRecorder(), builtinOtel, userOtel); - } - - @VisibleForTesting - public static ApiTracerFactory createBigtableTracerFactory( - EnhancedBigtableStubSettings settings, - Tagger tagger, - StatsRecorder stats, - @Nullable OpenTelemetry builtinOtel, - @Nullable OpenTelemetry userOtel) - throws IOException { - String projectId = settings.getProjectId(); - String instanceId = settings.getInstanceId(); - String appProfileId = settings.getAppProfileId(); - - ImmutableMap attributes = - ImmutableMap.builder() - .put(RpcMeasureConstants.BIGTABLE_PROJECT_ID, TagValue.create(projectId)) - .put(RpcMeasureConstants.BIGTABLE_INSTANCE_ID, TagValue.create(instanceId)) - .put(RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID, TagValue.create(appProfileId)) - .build(); - - ImmutableList.Builder tracerFactories = ImmutableList.builder(); - tracerFactories - .add( - // Add OpenCensus Tracing - new OpencensusTracerFactory( - ImmutableMap.builder() - // Annotate traces with the same tags as metrics - .put(RpcMeasureConstants.BIGTABLE_PROJECT_ID.getName(), projectId) - .put(RpcMeasureConstants.BIGTABLE_INSTANCE_ID.getName(), instanceId) - .put(RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID.getName(), appProfileId) - // Also annotate traces with library versions - .put("gax", GaxGrpcProperties.getGaxGrpcVersion()) - .put("grpc", GaxGrpcProperties.getGrpcVersion()) - .put("gapic", Version.VERSION) - .build())) - // Add OpenCensus Metrics - .add(MetricsTracerFactory.create(tagger, stats, attributes)) - // Add user configured tracer - .add(settings.getTracerFactory()); - - if (builtinOtel != null) { - tracerFactories.add( - BuiltinMetricsTracerFactory.create(builtinOtel, createBuiltinAttributes(settings))); - } - if (userOtel != null) { - tracerFactories.add( - BuiltinMetricsTracerFactory.create(userOtel, createBuiltinAttributes(settings))); - } - return new CompositeTracerFactory(tracerFactories.build()); - } - - static Attributes createBuiltinAttributes(EnhancedBigtableStubSettings settings) { - return Attributes.of( - BIGTABLE_PROJECT_ID_KEY, - settings.getProjectId(), - INSTANCE_ID_KEY, - settings.getInstanceId(), - APP_PROFILE_KEY, - settings.getAppProfileId(), - CLIENT_NAME_KEY, - "bigtable-java/" + Version.VERSION); - } - public EnhancedBigtableStub( EnhancedBigtableStubSettings settings, BigtableClientContext clientContext) { - this(settings, clientContext, true); - } - - public EnhancedBigtableStub( - EnhancedBigtableStubSettings settings, - BigtableClientContext clientContext, - boolean closeClientContext) { this.settings = settings; this.bigtableClientContext = clientContext; - this.closeClientContext = closeClientContext; this.requestContext = RequestContext.create( - settings.getProjectId(), settings.getInstanceId(), settings.getAppProfileId()); + clientContext.getInstanceName().getProject(), + clientContext.getInstanceName().getInstance(), + clientContext.getAppProfileId()); this.bulkMutationFlowController = new FlowController(settings.bulkMutateRowsSettings().getDynamicFlowControlSettings()); this.bulkMutationDynamicFlowControlStats = new DynamicFlowControlStats(); @@ -1430,12 +1308,10 @@ private SpanName getSpanName(String methodName) { @Override public void close() { - if (closeClientContext) { - try { - bigtableClientContext.close(); - } catch (Exception e) { - throw new IllegalStateException("failed to close client context", e); - } + try { + bigtableClientContext.close(); + } catch (Exception e) { + throw new IllegalStateException("failed to close client context", e); } } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java index f5ba5f52fcb8..cc341c994e21 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java @@ -15,11 +15,19 @@ */ package com.google.cloud.bigtable.data.v2.stub.metrics; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.APP_PROFILE_KEY; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_PROJECT_ID_KEY; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLIENT_NAME_KEY; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.INSTANCE_ID_KEY; + import com.google.api.core.InternalApi; +import com.google.api.gax.grpc.GaxGrpcProperties; import com.google.api.gax.rpc.ApiCallContext; import com.google.api.gax.rpc.ApiException; import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.StatusCode.Code; +import com.google.api.gax.tracing.ApiTracerFactory; +import com.google.api.gax.tracing.OpencensusTracerFactory; import com.google.auth.Credentials; import com.google.bigtable.v2.AuthorizedViewName; import com.google.bigtable.v2.CheckAndMutateRowRequest; @@ -35,6 +43,7 @@ import com.google.bigtable.v2.ResponseParams; import com.google.bigtable.v2.SampleRowKeysRequest; import com.google.bigtable.v2.TableName; +import com.google.cloud.bigtable.Version; import com.google.cloud.bigtable.data.v2.BigtableDataSettings; import com.google.cloud.bigtable.data.v2.stub.MetadataExtractorInterceptor; import com.google.common.base.Suppliers; @@ -44,6 +53,12 @@ import io.grpc.Status; import io.grpc.StatusException; import io.grpc.StatusRuntimeException; +import io.opencensus.stats.StatsRecorder; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; +import io.opencensus.tags.Tagger; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.metrics.InstrumentSelector; import io.opentelemetry.sdk.metrics.SdkMeterProvider; @@ -225,4 +240,49 @@ public static String formatZoneIdMetricLabel( .filter(s -> !s.isEmpty()) .orElse("global"); } + + public static ApiTracerFactory createOCTracingFactory( + InstanceName instanceName, String appProfileId) { + return new OpencensusTracerFactory( + ImmutableMap.builder() + // Annotate traces with the same tags as metrics + .put(RpcMeasureConstants.BIGTABLE_PROJECT_ID.getName(), instanceName.getProject()) + .put(RpcMeasureConstants.BIGTABLE_INSTANCE_ID.getName(), instanceName.getInstance()) + .put(RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID.getName(), appProfileId) + // Also annotate traces with library versions + .put("gax", GaxGrpcProperties.getGaxGrpcVersion()) + .put("grpc", GaxGrpcProperties.getGrpcVersion()) + .put("gapic", Version.VERSION) + .build()); + } + + public static ApiTracerFactory createOCMetricsFactory( + InstanceName instanceName, String appProfileId, Tagger tagger, StatsRecorder stats) { + + ImmutableMap attributes = + ImmutableMap.builder() + .put( + RpcMeasureConstants.BIGTABLE_PROJECT_ID, TagValue.create(instanceName.getProject())) + .put( + RpcMeasureConstants.BIGTABLE_INSTANCE_ID, + TagValue.create(instanceName.getInstance())) + .put(RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID, TagValue.create(appProfileId)) + .build(); + return MetricsTracerFactory.create(tagger, stats, attributes); + } + + public static BuiltinMetricsTracerFactory createOtelMetricsFactory( + OpenTelemetry otel, InstanceName instanceName, String appProfileId) throws IOException { + Attributes attributes = + Attributes.of( + BIGTABLE_PROJECT_ID_KEY, + instanceName.getProject(), + INSTANCE_ID_KEY, + instanceName.getInstance(), + APP_PROFILE_KEY, + appProfileId, + CLIENT_NAME_KEY, + "bigtable-java/" + Version.VERSION); + return BuiltinMetricsTracerFactory.create(otel, attributes); + } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java index 639228b8e379..0f84417a7007 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java @@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.ServerStream; import com.google.api.gax.rpc.UnavailableException; import com.google.bigtable.v2.BigtableGrpc.BigtableImplBase; @@ -125,24 +124,17 @@ public void sendHeaders(Metadata headers) { .setProjectId(PROJECT_ID) .setInstanceId(INSTANCE_ID) .setAppProfileId(APP_PROFILE_ID) + // only testing opencensus + .setMetricsProvider(NoopMetricsProvider.INSTANCE) + .disableInternalMetrics() .build(); - BigtableClientContext bigtableClientContext = - EnhancedBigtableStub.createBigtableClientContext(settings.getStubSettings()); - ClientContext clientContext = - bigtableClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), - Tags.getTagger(), - localStats.getStatsRecorder(), - null, - null)) - .build(); attempts = settings.getStubSettings().readRowsSettings().getRetrySettings().getMaxAttempts(); stub = new EnhancedBigtableStub( - settings.getStubSettings(), bigtableClientContext.withClientContext(clientContext)); + settings.getStubSettings(), + BigtableClientContext.create( + settings.getStubSettings(), Tags.getTagger(), localStats.getStatsRecorder())); // Create another server without injecting the server-timing header and another stub that // connects to it. @@ -153,24 +145,17 @@ public void sendHeaders(Metadata headers) { .setProjectId(PROJECT_ID) .setInstanceId(INSTANCE_ID) .setAppProfileId(APP_PROFILE_ID) + .setMetricsProvider(NoopMetricsProvider.INSTANCE) + .disableInternalMetrics() .build(); - BigtableClientContext noHeaderBigtableClientContext = - EnhancedBigtableStub.createBigtableClientContext(noHeaderSettings.getStubSettings()); - ClientContext noHeaderClientContext = - noHeaderBigtableClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - noHeaderSettings.getStubSettings(), - Tags.getTagger(), - localStats.getStatsRecorder(), - null, - null)) - .build(); noHeaderStub = new EnhancedBigtableStub( noHeaderSettings.getStubSettings(), - noHeaderBigtableClientContext.withClientContext(noHeaderClientContext)); + BigtableClientContext.create( + noHeaderSettings.getStubSettings(), + Tags.getTagger(), + localStats.getStatsRecorder())); } @After diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java index 47b64fba1405..ab2fe6e205ef 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java @@ -25,7 +25,6 @@ import com.google.api.gax.batching.FlowController; import com.google.api.gax.grpc.GrpcCallContext; import com.google.api.gax.rpc.ApiCallContext; -import com.google.api.gax.rpc.ClientContext; import com.google.bigtable.v2.BigtableGrpc; import com.google.bigtable.v2.MutateRowsRequest; import com.google.bigtable.v2.MutateRowsResponse; @@ -120,23 +119,15 @@ public void setUp() throws Exception { .setProjectId(PROJECT_ID) .setInstanceId(INSTANCE_ID) .setAppProfileId(APP_PROFILE_ID) + .setMetricsProvider(NoopMetricsProvider.INSTANCE) + .disableInternalMetrics() .build(); BigtableClientContext bigtableClientContext = - EnhancedBigtableStub.createBigtableClientContext(settings.getStubSettings()); - ClientContext clientContext = - bigtableClientContext.getClientContext().toBuilder() - .setTracerFactory( - EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), - Tags.getTagger(), - localStats.getStatsRecorder(), - null, - null)) - .build(); - stub = - new EnhancedBigtableStub( - settings.getStubSettings(), bigtableClientContext.withClientContext(clientContext)); + BigtableClientContext.create( + settings.getStubSettings(), Tags.getTagger(), localStats.getStatsRecorder()); + + stub = new EnhancedBigtableStub(settings.getStubSettings(), bigtableClientContext); } @After