diff --git a/google-cloud-bigtable/clirr-ignored-differences.xml b/google-cloud-bigtable/clirr-ignored-differences.xml index c3a0fa05e1..03733ff3b6 100644 --- a/google-cloud-bigtable/clirr-ignored-differences.xml +++ b/google-cloud-bigtable/clirr-ignored-differences.xml @@ -492,4 +492,16 @@ com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPoolSettings$Builder com.google.cloud.bigtable.gaxx.grpc.BigtableChannelPoolSettings$Builder setLoadBalancingStrategy(com.google.cloud.bigtable.gaxx.grpc.BigtableChannelPoolSettings$LoadBalancingStrategy) + + + 7004 + com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings$InternalMetricsProvider + * + + + + 7004 + com/google/cloud/bigtable/data/v2/stub/metrics/Util + * + 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 bac1ec4a06..25f49ca967 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 @@ -20,6 +20,7 @@ import com.google.api.gax.core.BackgroundResource; import com.google.api.gax.core.CredentialsProvider; import com.google.api.gax.core.FixedCredentialsProvider; +import com.google.api.gax.core.FixedExecutorProvider; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; import com.google.api.gax.rpc.ClientContext; import com.google.auth.Credentials; @@ -41,6 +42,7 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.concurrent.ScheduledExecutorService; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -75,6 +77,12 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings String universeDomain = settings.getUniverseDomain(); + ScheduledExecutorService backgroundExecutor = + settings.getBackgroundExecutorProvider().getExecutor(); + + FixedExecutorProvider executorProvider = FixedExecutorProvider.create(backgroundExecutor); + builder.setBackgroundExecutorProvider(executorProvider); + // Set up OpenTelemetry OpenTelemetry openTelemetry = null; try { @@ -85,7 +93,8 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings settings.getMetricsProvider(), credentials, settings.getMetricsEndpoint(), - universeDomain); + universeDomain, + backgroundExecutor); } catch (Throwable t) { logger.log(Level.WARNING, "Failed to get OTEL, will skip exporting client side metrics", t); } @@ -103,7 +112,9 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings // no reason to build the internal OtelProvider if (transportProvider != null) { internalOtel = - settings.getInternalMetricsProvider().createOtelProvider(settings, credentials); + settings + .getInternalMetricsProvider() + .createOtelProvider(settings, credentials, backgroundExecutor); if (internalOtel != null) { channelPoolMetricsTracer = new ChannelPoolMetricsTracer( @@ -213,7 +224,8 @@ private static OpenTelemetry getOpenTelemetryFromMetricsProvider( MetricsProvider metricsProvider, @Nullable Credentials defaultCredentials, @Nullable String metricsEndpoint, - String universeDomain) + String universeDomain, + ScheduledExecutorService executor) throws IOException { if (metricsProvider instanceof CustomOpenTelemetryMetricsProvider) { CustomOpenTelemetryMetricsProvider customMetricsProvider = @@ -225,7 +237,8 @@ private static OpenTelemetry getOpenTelemetryFromMetricsProvider( ? BigtableDataSettings.getMetricsCredentials() : defaultCredentials; DefaultMetricsProvider defaultMetricsProvider = (DefaultMetricsProvider) metricsProvider; - return defaultMetricsProvider.getOpenTelemetry(metricsEndpoint, universeDomain, credentials); + return defaultMetricsProvider.getOpenTelemetry( + metricsEndpoint, universeDomain, credentials, executor); } else if (metricsProvider instanceof NoopMetricsProvider) { return null; } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java index f4572333c9..acd3323957 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java @@ -69,6 +69,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; import java.util.logging.Logger; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -1388,11 +1389,14 @@ public String toString() { public interface InternalMetricsProvider { @Nullable OpenTelemetrySdk createOtelProvider( - EnhancedBigtableStubSettings userSettings, Credentials creds) throws IOException; + EnhancedBigtableStubSettings userSettings, + Credentials creds, + ScheduledExecutorService executor) + throws IOException; } private static final InternalMetricsProvider DEFAULT_INTERNAL_OTEL_PROVIDER = Util::newInternalOpentelemetry; private static final InternalMetricsProvider DISABLED_INTERNAL_OTEL_PROVIDER = - (ignored1, ignored2) -> null; + (ignored1, ignored2, ignored3) -> null; } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java index 1244ee5fdc..283abb7062 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java @@ -35,6 +35,7 @@ import com.google.api.core.InternalApi; import com.google.api.gax.core.CredentialsProvider; import com.google.api.gax.core.FixedCredentialsProvider; +import com.google.api.gax.core.FixedExecutorProvider; import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.rpc.PermissionDeniedException; import com.google.auth.Credentials; @@ -65,6 +66,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; @@ -115,7 +117,8 @@ static BigtableCloudMonitoringExporter create( @Nullable Credentials credentials, @Nullable String endpoint, String universeDomain, - TimeSeriesConverter converter) + TimeSeriesConverter converter, + @Nullable ScheduledExecutorService executorService) throws IOException { Preconditions.checkNotNull(universeDomain); MetricServiceSettings.Builder settingsBuilder = MetricServiceSettings.newBuilder(); @@ -127,6 +130,10 @@ static BigtableCloudMonitoringExporter create( settingsBuilder.setUniverseDomain(universeDomain); + if (executorService != null) { + settingsBuilder.setBackgroundExecutorProvider(FixedExecutorProvider.create(executorService)); + } + if (MONITORING_ENDPOINT_OVERRIDE_SYS_PROP != null) { logger.warning( "Setting the monitoring endpoint through system variable will be removed in future" diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java index f6df7fe6cd..9cc13939fb 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java @@ -23,7 +23,9 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import java.io.IOException; +import java.time.Duration; import java.util.Map; +import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Nullable; /** @@ -100,14 +102,29 @@ public static void registerBuiltinMetrics( @Nullable Credentials credentials, SdkMeterProviderBuilder builder, @Nullable String endpoint) throws IOException { registerBuiltinMetricsWithUniverseDomain( - credentials, builder, endpoint, Credentials.GOOGLE_DEFAULT_UNIVERSE); + credentials, builder, endpoint, Credentials.GOOGLE_DEFAULT_UNIVERSE, null); + } + + /** + * Register built-in metrics on the {@link SdkMeterProviderBuilder} with custom credentials, + * endpoint and executor service. + */ + public static void registerBuiltinMetrics( + @Nullable Credentials credentials, + SdkMeterProviderBuilder builder, + @Nullable String endpoint, + @Nullable ScheduledExecutorService executorService) + throws IOException { + registerBuiltinMetricsWithUniverseDomain( + credentials, builder, endpoint, Credentials.GOOGLE_DEFAULT_UNIVERSE, executorService); } static void registerBuiltinMetricsWithUniverseDomain( @Nullable Credentials credentials, SdkMeterProviderBuilder builder, @Nullable String endpoint, - String universeDomain) + String universeDomain, + @Nullable ScheduledExecutorService executorService) throws IOException { MetricExporter publicExporter = BigtableCloudMonitoringExporter.create( @@ -115,12 +132,17 @@ static void registerBuiltinMetricsWithUniverseDomain( credentials, endpoint, universeDomain, - new BigtableCloudMonitoringExporter.PublicTimeSeriesConverter()); + new BigtableCloudMonitoringExporter.PublicTimeSeriesConverter(), + executorService); for (Map.Entry entry : BuiltinMetricsConstants.getAllViews().entrySet()) { builder.registerView(entry.getKey(), entry.getValue()); } - builder.registerMetricReader(PeriodicMetricReader.create(publicExporter)); + builder.registerMetricReader( + PeriodicMetricReader.builder(publicExporter) + .setExecutor(executorService) + .setInterval(Duration.ofMinutes(1)) + .build()); } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CustomOpenTelemetryMetricsProvider.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CustomOpenTelemetryMetricsProvider.java index efcec28ffa..deef54d0f0 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CustomOpenTelemetryMetricsProvider.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CustomOpenTelemetryMetricsProvider.java @@ -20,6 +20,7 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import java.io.IOException; +import java.util.concurrent.ScheduledExecutorService; /** * Set a custom OpenTelemetry instance. @@ -85,13 +86,26 @@ public static void setupSdkMeterProvider(SdkMeterProviderBuilder builder, String setupSdkMeterProvider(builder, null, endpoint); } - /** Convenient method to set up SdkMeterProviderBuilder with a custom credentials and endpoint. */ + /** Convenient method to set up SdkMeterProviderBuilder with custom credentials and endpoint. */ public static void setupSdkMeterProvider( SdkMeterProviderBuilder builder, Credentials credentials, String endpoint) throws IOException { BuiltinMetricsView.registerBuiltinMetrics(credentials, builder, endpoint); } + /** + * Convenient method to set up SdkMeterProviderBuilder with custom credentials, endpoint and + * executor service. + */ + public static void setupSdkMeterProvider( + SdkMeterProviderBuilder builder, + Credentials credentials, + String endpoint, + ScheduledExecutorService executor) + throws IOException { + BuiltinMetricsView.registerBuiltinMetrics(credentials, builder, endpoint, executor); + } + @Override public String toString() { return MoreObjects.toStringHelper(this).add("openTelemetry", otel).toString(); diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/DefaultMetricsProvider.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/DefaultMetricsProvider.java index 7b18125b95..4a226d25d9 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/DefaultMetricsProvider.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/DefaultMetricsProvider.java @@ -22,6 +22,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import java.io.IOException; +import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Nullable; /** @@ -39,11 +40,14 @@ private DefaultMetricsProvider() {} @InternalApi public OpenTelemetry getOpenTelemetry( - @Nullable String metricsEndpoint, String universeDomain, @Nullable Credentials credentials) + @Nullable String metricsEndpoint, + String universeDomain, + @Nullable Credentials credentials, + ScheduledExecutorService executor) throws IOException { SdkMeterProviderBuilder meterProvider = SdkMeterProvider.builder(); BuiltinMetricsView.registerBuiltinMetricsWithUniverseDomain( - credentials, meterProvider, metricsEndpoint, universeDomain); + credentials, meterProvider, metricsEndpoint, universeDomain, executor); return OpenTelemetrySdk.builder().setMeterProvider(meterProvider.build()).build(); } 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 012aae024d..9ba2d39c49 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 @@ -52,6 +52,7 @@ import io.opentelemetry.sdk.metrics.View; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; import java.io.IOException; +import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Arrays; @@ -60,6 +61,7 @@ import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; @@ -256,7 +258,10 @@ static GrpcCallContext injectBigtableStreamTracer( } public static OpenTelemetrySdk newInternalOpentelemetry( - EnhancedBigtableStubSettings settings, Credentials credentials) throws IOException { + EnhancedBigtableStubSettings settings, + Credentials credentials, + ScheduledExecutorService executor) + throws IOException { SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); for (Map.Entry e : @@ -265,15 +270,19 @@ public static OpenTelemetrySdk newInternalOpentelemetry( } meterProviderBuilder.registerMetricReader( - PeriodicMetricReader.create( - BigtableCloudMonitoringExporter.create( - "application metrics", - credentials, - settings.getMetricsEndpoint(), - settings.getUniverseDomain(), - new BigtableCloudMonitoringExporter.InternalTimeSeriesConverter( - Suppliers.memoize( - () -> BigtableExporterUtils.createInternalMonitoredResource(settings)))))); + PeriodicMetricReader.builder( + BigtableCloudMonitoringExporter.create( + "application metrics", + credentials, + settings.getMetricsEndpoint(), + settings.getUniverseDomain(), + new BigtableCloudMonitoringExporter.InternalTimeSeriesConverter( + Suppliers.memoize( + () -> BigtableExporterUtils.createInternalMonitoredResource(settings))), + executor)) + .setExecutor(settings.getBackgroundExecutorProvider().getExecutor()) + .setInterval(Duration.ofMinutes(1)) + .build()); return OpenTelemetrySdk.builder().setMeterProvider(meterProviderBuilder.build()).build(); } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java index c3d326fbef..b8c187a8ac 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java @@ -167,7 +167,7 @@ public void transportTerminated(Attributes transportAttrs) { .stubSettings() .setTransportChannelProvider(transportChannelProvider) .setCredentialsProvider(credentialsProvider) - .setExecutorProvider(executorProvider) + .setBackgroundExecutorProvider(executorProvider) .setStreamWatchdogProvider(watchdogProvider) .setClock(apiClock);