Skip to content

Commit ff8d775

Browse files
chore: refactor otel integration (#2794)
* chore: refactor otel exporter Previously bigtable client would construct 2 otel instances: - one for internal metrics not relevant for customers - another for user visible metrics The 2nd otel instance would be used for both exporting to cloud monitoring and to end user provided exporters. This was done by having the enduser provide a SdkMeterProviderBuilder and use a utility to inject the bigtable builtin exporter. This created a number of problems and overheads. This PR changes the split, now there is a builtin otel instance with a bigtable exporter preconfigured. This receives both internal and user visible cloud monitoring metrics. This exporter can be disabled via EnhancedStubSettings#disableInternalMetrics() In addition, if an enduser provides their own otel instance via CustomOpenTelemetryMetricsProvider, this will be dual written in parallel to the builtin one. Now the default case is that we have 1 otel instance and we dont have to inject our internal exporter into the use otel instance. Change-Id: Ic0b8efdcdf342aef8f589c2c9e05b7672a0e5d08 * combine the exporters Change-Id: Id8a2052a4d49a9623a2b63debe1f8ef10210f84c
1 parent bc46174 commit ff8d775

13 files changed

Lines changed: 235 additions & 300 deletions

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ public BigtableDataClient createDefault() {
111111
sharedClientContext.getClientContext().toBuilder()
112112
.setTracerFactory(
113113
EnhancedBigtableStub.createBigtableTracerFactory(
114-
defaultSettings.getStubSettings(), sharedClientContext.getOpenTelemetry()))
114+
defaultSettings.getStubSettings(),
115+
sharedClientContext.getBuiltinOpenTelemetry(),
116+
sharedClientContext.getUserOpenTelemetry()))
115117
.build();
116118

117119
return BigtableDataClient.createWithClientContext(
@@ -140,7 +142,9 @@ public BigtableDataClient createForAppProfile(@Nonnull String appProfileId) thro
140142
sharedClientContext.getClientContext().toBuilder()
141143
.setTracerFactory(
142144
EnhancedBigtableStub.createBigtableTracerFactory(
143-
settings.getStubSettings(), sharedClientContext.getOpenTelemetry()))
145+
settings.getStubSettings(),
146+
sharedClientContext.getBuiltinOpenTelemetry(),
147+
sharedClientContext.getUserOpenTelemetry()))
144148
.build();
145149
return BigtableDataClient.createWithClientContext(
146150
settings, sharedClientContext.withClientContext(clientContext));
@@ -168,7 +172,9 @@ public BigtableDataClient createForInstance(@Nonnull String projectId, @Nonnull
168172
sharedClientContext.getClientContext().toBuilder()
169173
.setTracerFactory(
170174
EnhancedBigtableStub.createBigtableTracerFactory(
171-
settings.getStubSettings(), sharedClientContext.getOpenTelemetry()))
175+
settings.getStubSettings(),
176+
sharedClientContext.getBuiltinOpenTelemetry(),
177+
sharedClientContext.getUserOpenTelemetry()))
172178
.build();
173179

174180
return BigtableDataClient.createWithClientContext(
@@ -197,7 +203,9 @@ public BigtableDataClient createForInstance(
197203
sharedClientContext.getClientContext().toBuilder()
198204
.setTracerFactory(
199205
EnhancedBigtableStub.createBigtableTracerFactory(
200-
settings.getStubSettings(), sharedClientContext.getOpenTelemetry()))
206+
settings.getStubSettings(),
207+
sharedClientContext.getBuiltinOpenTelemetry(),
208+
sharedClientContext.getUserOpenTelemetry()))
201209
.build();
202210
return BigtableDataClient.createWithClientContext(
203211
settings, sharedClientContext.withClientContext(clientContext));

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java

Lines changed: 42 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,12 @@
2626
import com.google.api.gax.rpc.ClientContext;
2727
import com.google.auth.Credentials;
2828
import com.google.auth.oauth2.ServiceAccountJwtAccessCredentials;
29-
import com.google.cloud.bigtable.data.v2.BigtableDataSettings;
29+
import com.google.bigtable.v2.InstanceName;
3030
import com.google.cloud.bigtable.data.v2.internal.JwtCredentialsWithAudience;
3131
import com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants;
3232
import com.google.cloud.bigtable.data.v2.stub.metrics.ChannelPoolMetricsTracer;
3333
import com.google.cloud.bigtable.data.v2.stub.metrics.CustomOpenTelemetryMetricsProvider;
34-
import com.google.cloud.bigtable.data.v2.stub.metrics.DefaultMetricsProvider;
35-
import com.google.cloud.bigtable.data.v2.stub.metrics.MetricsProvider;
36-
import com.google.cloud.bigtable.data.v2.stub.metrics.NoopMetricsProvider;
34+
import com.google.cloud.bigtable.data.v2.stub.metrics.Util;
3735
import com.google.cloud.bigtable.gaxx.grpc.BigtableTransportChannelProvider;
3836
import com.google.cloud.bigtable.gaxx.grpc.ChannelPrimer;
3937
import io.grpc.ManagedChannelBuilder;
@@ -57,9 +55,8 @@ public class BigtableClientContext {
5755

5856
private static final Logger logger = Logger.getLogger(BigtableClientContext.class.getName());
5957

60-
@Nullable private final OpenTelemetry openTelemetry;
61-
@Nullable private final OpenTelemetrySdk internalOpenTelemetry;
62-
private final MetricsProvider metricsProvider;
58+
@Nullable private final OpenTelemetrySdk builtinOpenTelemetry;
59+
@Nullable private final OpenTelemetry userOpenTelemetry;
6360
private final ClientContext clientContext;
6461
// the background executor shared for OTEL instances and monitoring client and all other
6562
// background tasks
@@ -89,17 +86,24 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
8986
builder.setBackgroundExecutorProvider(executorProvider);
9087

9188
// Set up OpenTelemetry
92-
OpenTelemetry openTelemetry = null;
89+
@Nullable OpenTelemetry userOtel = null;
90+
if (settings.getMetricsProvider() instanceof CustomOpenTelemetryMetricsProvider) {
91+
userOtel =
92+
((CustomOpenTelemetryMetricsProvider) settings.getMetricsProvider()).getOpenTelemetry();
93+
}
94+
95+
@Nullable OpenTelemetrySdk builtinOtel = null;
9396
try {
94-
// We don't want client side metrics to crash the client, so catch any exception when getting
95-
// the OTEL instance and log the exception instead.
96-
openTelemetry =
97-
getOpenTelemetryFromMetricsProvider(
98-
settings.getMetricsProvider(),
99-
credentials,
100-
settings.getMetricsEndpoint(),
101-
universeDomain,
102-
backgroundExecutor);
97+
if (settings.areInternalMetricsEnabled()) {
98+
builtinOtel =
99+
Util.createBuiltinOtel(
100+
InstanceName.of(settings.getProjectId(), settings.getInstanceId()),
101+
settings.getAppProfileId(),
102+
credentials,
103+
settings.getMetricsEndpoint(),
104+
universeDomain,
105+
backgroundExecutor);
106+
}
103107
} catch (Throwable t) {
104108
logger.log(Level.WARNING, "Failed to get OTEL, will skip exporting client side metrics", t);
105109
}
@@ -110,21 +114,16 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
110114
? ((InstantiatingGrpcChannelProvider) builder.getTransportChannelProvider()).toBuilder()
111115
: null;
112116

113-
@Nullable OpenTelemetrySdk internalOtel = null;
114117
@Nullable ChannelPoolMetricsTracer channelPoolMetricsTracer = null;
115118
// Internal metrics are scoped to the connections, so we need a mutable transportProvider,
116119
// otherwise there is
117120
// no reason to build the internal OtelProvider
118121
if (transportProvider != null) {
119-
internalOtel =
120-
settings
121-
.getInternalMetricsProvider()
122-
.createOtelProvider(settings, credentials, backgroundExecutor);
123-
if (internalOtel != null) {
124-
channelPoolMetricsTracer = new ChannelPoolMetricsTracer(internalOtel);
122+
if (builtinOtel != null) {
123+
channelPoolMetricsTracer = new ChannelPoolMetricsTracer(builtinOtel);
125124

126125
// Configure grpc metrics
127-
configureGrpcOtel(transportProvider, internalOtel);
126+
configureGrpcOtel(transportProvider, builtinOtel);
128127
}
129128
}
130129

@@ -149,7 +148,7 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
149148

150149
BigtableTransportChannelProvider btTransportProvider =
151150
BigtableTransportChannelProvider.create(
152-
(InstantiatingGrpcChannelProvider) transportProvider.build(),
151+
transportProvider.build(),
153152
channelPrimer,
154153
channelPoolMetricsTracer,
155154
backgroundExecutor);
@@ -162,12 +161,7 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
162161
channelPoolMetricsTracer.start(clientContext.getExecutor());
163162
}
164163

165-
return new BigtableClientContext(
166-
clientContext,
167-
openTelemetry,
168-
internalOtel,
169-
settings.getMetricsProvider(),
170-
executorProvider);
164+
return new BigtableClientContext(clientContext, builtinOtel, userOtel, executorProvider);
171165
}
172166

173167
private static void configureGrpcOtel(
@@ -199,19 +193,23 @@ private static void configureGrpcOtel(
199193

200194
private BigtableClientContext(
201195
ClientContext clientContext,
202-
@Nullable OpenTelemetry openTelemetry,
203196
@Nullable OpenTelemetrySdk internalOtel,
204-
MetricsProvider metricsProvider,
197+
@Nullable OpenTelemetry userOpenTelemetry,
205198
ExecutorProvider backgroundExecutorProvider) {
206199
this.clientContext = clientContext;
207-
this.openTelemetry = openTelemetry;
208-
this.internalOpenTelemetry = internalOtel;
209-
this.metricsProvider = metricsProvider;
200+
this.userOpenTelemetry = userOpenTelemetry;
201+
this.builtinOpenTelemetry = internalOtel;
210202
this.backgroundExecutorProvider = backgroundExecutorProvider;
211203
}
212204

213-
public OpenTelemetry getOpenTelemetry() {
214-
return this.openTelemetry;
205+
@Nullable
206+
public OpenTelemetrySdk getBuiltinOpenTelemetry() {
207+
return builtinOpenTelemetry;
208+
}
209+
210+
@Nullable
211+
public OpenTelemetry getUserOpenTelemetry() {
212+
return this.userOpenTelemetry;
215213
}
216214

217215
public ClientContext getClientContext() {
@@ -220,53 +218,24 @@ public ClientContext getClientContext() {
220218

221219
public BigtableClientContext withClientContext(ClientContext clientContext) {
222220
return new BigtableClientContext(
223-
clientContext,
224-
openTelemetry,
225-
internalOpenTelemetry,
226-
metricsProvider,
227-
backgroundExecutorProvider);
221+
clientContext, builtinOpenTelemetry, userOpenTelemetry, backgroundExecutorProvider);
228222
}
229223

230224
public void close() throws Exception {
231225
for (BackgroundResource resource : clientContext.getBackgroundResources()) {
232226
resource.close();
233227
}
234-
if (internalOpenTelemetry != null) {
235-
internalOpenTelemetry.close();
228+
if (builtinOpenTelemetry != null) {
229+
builtinOpenTelemetry.close();
236230
}
237-
if (metricsProvider instanceof DefaultMetricsProvider && openTelemetry != null) {
238-
((OpenTelemetrySdk) openTelemetry).close();
231+
if (builtinOpenTelemetry != null) {
232+
builtinOpenTelemetry.close();
239233
}
240234
if (backgroundExecutorProvider.shouldAutoClose()) {
241235
backgroundExecutorProvider.getExecutor().shutdown();
242236
}
243237
}
244238

245-
private static OpenTelemetry getOpenTelemetryFromMetricsProvider(
246-
MetricsProvider metricsProvider,
247-
@Nullable Credentials defaultCredentials,
248-
@Nullable String metricsEndpoint,
249-
String universeDomain,
250-
ScheduledExecutorService executor)
251-
throws IOException {
252-
if (metricsProvider instanceof CustomOpenTelemetryMetricsProvider) {
253-
CustomOpenTelemetryMetricsProvider customMetricsProvider =
254-
(CustomOpenTelemetryMetricsProvider) metricsProvider;
255-
return customMetricsProvider.getOpenTelemetry();
256-
} else if (metricsProvider instanceof DefaultMetricsProvider) {
257-
Credentials credentials =
258-
BigtableDataSettings.getMetricsCredentials() != null
259-
? BigtableDataSettings.getMetricsCredentials()
260-
: defaultCredentials;
261-
DefaultMetricsProvider defaultMetricsProvider = (DefaultMetricsProvider) metricsProvider;
262-
return defaultMetricsProvider.getOpenTelemetry(
263-
metricsEndpoint, universeDomain, credentials, executor);
264-
} else if (metricsProvider instanceof NoopMetricsProvider) {
265-
return null;
266-
}
267-
throw new IOException("Invalid MetricsProvider type " + metricsProvider);
268-
}
269-
270239
private static void patchCredentials(EnhancedBigtableStubSettings.Builder settings)
271240
throws IOException {
272241
String audience = settings.getJwtAudience();

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ public class EnhancedBigtableStub implements AutoCloseable {
200200
public static EnhancedBigtableStub create(EnhancedBigtableStubSettings settings)
201201
throws IOException {
202202
BigtableClientContext bigtableClientContext = createBigtableClientContext(settings);
203-
OpenTelemetry openTelemetry = bigtableClientContext.getOpenTelemetry();
204203
ClientContext contextWithTracer =
205204
bigtableClientContext.getClientContext().toBuilder()
206-
.setTracerFactory(createBigtableTracerFactory(settings, openTelemetry))
205+
.setTracerFactory(
206+
createBigtableTracerFactory(
207+
settings,
208+
bigtableClientContext.getBuiltinOpenTelemetry(),
209+
bigtableClientContext.getUserOpenTelemetry()))
207210
.build();
208211
bigtableClientContext = bigtableClientContext.withClientContext(contextWithTracer);
209212
return new EnhancedBigtableStub(settings, bigtableClientContext);
@@ -222,18 +225,21 @@ public static BigtableClientContext createBigtableClientContext(
222225
}
223226

224227
public static ApiTracerFactory createBigtableTracerFactory(
225-
EnhancedBigtableStubSettings settings, @Nullable OpenTelemetry openTelemetry)
228+
EnhancedBigtableStubSettings settings,
229+
@Nullable OpenTelemetry builtinOtel,
230+
@Nullable OpenTelemetry userOtel)
226231
throws IOException {
227232
return createBigtableTracerFactory(
228-
settings, Tags.getTagger(), Stats.getStatsRecorder(), openTelemetry);
233+
settings, Tags.getTagger(), Stats.getStatsRecorder(), builtinOtel, userOtel);
229234
}
230235

231236
@VisibleForTesting
232237
public static ApiTracerFactory createBigtableTracerFactory(
233238
EnhancedBigtableStubSettings settings,
234239
Tagger tagger,
235240
StatsRecorder stats,
236-
@Nullable OpenTelemetry openTelemetry)
241+
@Nullable OpenTelemetry builtinOtel,
242+
@Nullable OpenTelemetry userOtel)
237243
throws IOException {
238244
String projectId = settings.getProjectId();
239245
String instanceId = settings.getInstanceId();
@@ -265,12 +271,14 @@ public static ApiTracerFactory createBigtableTracerFactory(
265271
.add(MetricsTracerFactory.create(tagger, stats, attributes))
266272
// Add user configured tracer
267273
.add(settings.getTracerFactory());
268-
BuiltinMetricsTracerFactory builtinMetricsTracerFactory =
269-
openTelemetry != null
270-
? BuiltinMetricsTracerFactory.create(openTelemetry, createBuiltinAttributes(settings))
271-
: null;
272-
if (builtinMetricsTracerFactory != null) {
273-
tracerFactories.add(builtinMetricsTracerFactory);
274+
275+
if (builtinOtel != null) {
276+
tracerFactories.add(
277+
BuiltinMetricsTracerFactory.create(builtinOtel, createBuiltinAttributes(settings)));
278+
}
279+
if (userOtel != null) {
280+
tracerFactories.add(
281+
BuiltinMetricsTracerFactory.create(userOtel, createBuiltinAttributes(settings)));
274282
}
275283
return new CompositeTracerFactory(tracerFactories.build());
276284
}

0 commit comments

Comments
 (0)