Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
03aabb2
chore(datastore): Update generated stubs and native image config
lqiu96 Apr 1, 2026
25af60d
chore(datastore): Rename internal metrics recorder hierarchy and fix …
lqiu96 Apr 1, 2026
2093485
Merge branch 'main' of github.com:googleapis/google-cloud-java into d…
lqiu96 Apr 1, 2026
f2f1e9b
chore: Fix variable names
lqiu96 Apr 1, 2026
ae438e8
chore: Fix variable names
lqiu96 Apr 1, 2026
6c8def8
chore: Resolve merge conflicts
lqiu96 Apr 1, 2026
29f7ce1
chore: Remove metrics sample
lqiu96 Apr 1, 2026
0bf197b
chore: Update to remove the extra attributes
lqiu96 Apr 2, 2026
842d262
feat(datastore): Add built-in Cloud Monitoring metrics export
lqiu96 Apr 1, 2026
20be0a9
chore(datastore): Restore constants needed by built-in metrics pipeli…
lqiu96 Apr 2, 2026
5dc702f
chore: Remove duplicate declaration of attempt and operation metrics
lqiu96 Apr 2, 2026
c82e1d8
test: update DatastoreImplMetricsTest to expect singular GAX metric n…
lqiu96 Apr 2, 2026
b36e61c
chore: Remove unnecessary transaction null check
lqiu96 Apr 2, 2026
c47a6eb
chore: Resolve merge conflicts
lqiu96 Apr 2, 2026
2acc3a3
chore: Ensure that view properally remaps singular to plural metrics
lqiu96 Apr 2, 2026
5f41919
chore: Update logic to determine the PID
lqiu96 Apr 2, 2026
a7ae636
chore: Remove the unncessary filtering logic for the private Otel ins…
lqiu96 Apr 2, 2026
ddd06f8
chore: Remove the unused clientName attribute
lqiu96 Apr 2, 2026
0707021
merge main into datastore-csm-impl-2
lqiu96 Apr 8, 2026
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: 10 additions & 3 deletions java-datastore/google-cloud-datastore/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,20 @@
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-monitoring</artifactId>
<version>3.90.0-SNAPSHOT</version><!-- {x-version-update:google-cloud-monitoring:current} -->
</dependency>
<dependency>
<groupId>com.google.api.grpc</groupId>
<artifactId>proto-google-cloud-monitoring-v3</artifactId>
<version>3.90.0-SNAPSHOT</version><!-- {x-version-update:google-cloud-monitoring:current} -->
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
Expand All @@ -216,7 +224,6 @@
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-metrics</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,25 @@ public T call() throws DatastoreException {
}
}

/**
* Closes the Datastore client and releases all resources.
*
* <p>This method closes the underlying RPC channel and then closes the {@link
* com.google.cloud.datastore.telemetry.DatastoreMetricsRecorder}. For clients using the built-in
* Cloud Monitoring exporter, closing the recorder flushes any buffered metrics and shuts down the
* private {@link io.opentelemetry.sdk.OpenTelemetrySdk} instance. For clients using a
* user-provided {@link io.opentelemetry.api.OpenTelemetry} instance, the recorder close is a
* no-op since the user owns that instance's lifecycle.
*/
@Override
public void close() throws Exception {
try {
datastoreRpc.close();
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to close channels", e);
}
// Close the default Metrics Recorder if exists
getOptions().getMetricsRecorder().close();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,39 @@

package com.google.cloud.datastore;

import com.google.api.core.BetaApi;
import io.opentelemetry.api.OpenTelemetry;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
* Represents the options that are used to configure the use of OpenTelemetry for telemetry
* collection in the Datastore SDK.
*/
public class DatastoreOpenTelemetryOptions {
private final boolean tracingEnabled;
private final boolean metricsEnabled;
private final boolean exportBuiltinMetricsToGoogleCloudMonitoring;
private final @Nullable OpenTelemetry openTelemetry;

DatastoreOpenTelemetryOptions(Builder builder) {
this.tracingEnabled = builder.tracingEnabled;
this.metricsEnabled = builder.metricsEnabled;
this.exportBuiltinMetricsToGoogleCloudMonitoring =
builder.exportBuiltinMetricsToGoogleCloudMonitoring;
this.openTelemetry = builder.openTelemetry;
}

/**
* Returns whether either tracing or metrics are enabled. Telemetry is disabled by default.
* Returns whether either tracing or custom metrics (via a user-provided {@link OpenTelemetry}
* instance) are enabled.
*
* <p><b>Note:</b> This method does <em>not</em> reflect the state of built-in metrics export to
* Google Cloud Monitoring, which is controlled separately by {@link
* #isExportBuiltinMetricsToGoogleCloudMonitoring()} and is {@code false} by default. To check
* whether any telemetry is active, also consult that flag.
*
* @return {@code true} if either tracing or metrics are enabled, {@code false} otherwise.
* @return {@code true} if tracing or custom OTel metrics are enabled, {@code false} otherwise.
*/
public boolean isEnabled() {
return tracingEnabled || metricsEnabled;
Expand All @@ -50,24 +64,54 @@ public boolean isTracingEnabled() {
}

/**
* Returns whether metrics are enabled.
* Returns whether metrics are enabled for the custom (user-provided) OpenTelemetry backend.
*
* @return {@code true} if metrics are enabled, {@code false} otherwise.
*/
public boolean isMetricsEnabled() {
return metricsEnabled;
}

/**
* Returns whether built-in metrics should be exported to Google Cloud Monitoring.
*
* <p>When enabled, client-side metrics are automatically exported to Google Cloud Monitoring
* using the Cloud Monitoring API. This is independent of the custom OpenTelemetry backend
* configured via {@link #getOpenTelemetry()}.
*
* @return {@code true} if built-in metrics export to Cloud Monitoring is enabled, {@code false}
* otherwise.
*/
@BetaApi
public boolean isExportBuiltinMetricsToGoogleCloudMonitoring() {
return exportBuiltinMetricsToGoogleCloudMonitoring;
}

/**
* Returns the custom {@link OpenTelemetry} instance, if one was provided.
*
* @return the custom {@link OpenTelemetry} instance, or {@code null} if none was provided.
*/
@Nullable
public OpenTelemetry getOpenTelemetry() {
return openTelemetry;
}

/**
* Returns a new {@link Builder} initialized with the values from this options instance.
*
* @return a new {@link Builder}.
*/
@Nonnull
public DatastoreOpenTelemetryOptions.Builder toBuilder() {
return new DatastoreOpenTelemetryOptions.Builder(this);
}

/**
* Returns a new default {@link Builder}.
*
* @return a new {@link Builder}.
*/
@Nonnull
public static DatastoreOpenTelemetryOptions.Builder newBuilder() {
return new DatastoreOpenTelemetryOptions.Builder();
Expand All @@ -77,25 +121,31 @@ public static class Builder {

private boolean tracingEnabled;
private boolean metricsEnabled;
private boolean exportBuiltinMetricsToGoogleCloudMonitoring;

@Nullable private OpenTelemetry openTelemetry;

private Builder() {
tracingEnabled = false;
metricsEnabled = false;
// TODO: This is disabled by default until the Firestore namespace is deployed
exportBuiltinMetricsToGoogleCloudMonitoring = false;
openTelemetry = null;
}

private Builder(DatastoreOpenTelemetryOptions options) {
this.tracingEnabled = options.tracingEnabled;
this.metricsEnabled = options.metricsEnabled;
this.exportBuiltinMetricsToGoogleCloudMonitoring =
options.exportBuiltinMetricsToGoogleCloudMonitoring;
this.openTelemetry = options.openTelemetry;
}

/**
* Sets whether tracing should be enabled.
*
* @param enabled Whether tracing should be enabled.
* @return this builder instance.
*/
@Nonnull
public DatastoreOpenTelemetryOptions.Builder setTracingEnabled(boolean enabled) {
Expand All @@ -104,23 +154,43 @@ public DatastoreOpenTelemetryOptions.Builder setTracingEnabled(boolean enabled)
}

/**
* Sets whether metrics should be enabled.
* Sets whether metrics should be enabled for the custom (user-provided) OpenTelemetry backend.
*
* @param enabled Whether metrics should be enabled.
* @return the builder instance.
* @return this builder instance.
*/
@Nonnull
DatastoreOpenTelemetryOptions.Builder setMetricsEnabled(boolean enabled) {
this.metricsEnabled = enabled;
return this;
}

/**
* Sets whether built-in metrics should be exported to Google Cloud Monitoring.
*
* <p>When enabled (the default), client-side metrics are automatically exported to Google Cloud
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a contradiction between the Javadoc and the implementation. The Javadoc states that built-in metrics export is enabled by default, but the Builder constructor (line 132) initializes it to false. Based on the TODO comment at line 131, it seems false is the intended default for now. Please update the Javadoc to reflect this.

Suggested change
* <p>When enabled (the default), client-side metrics are automatically exported to Google Cloud
* <p>When enabled, client-side metrics are automatically exported to Google Cloud

* Monitoring using the Cloud Monitoring API. This can be disabled to prevent metrics from being
* sent to Cloud Monitoring while still allowing metrics to flow to a custom OpenTelemetry
* backend.
*
* @param exportBuiltinMetrics Whether built-in metrics should be exported to Cloud Monitoring.
* @return this builder instance.
*/
@BetaApi
@Nonnull
public DatastoreOpenTelemetryOptions.Builder setExportBuiltinMetricsToGoogleCloudMonitoring(
boolean exportBuiltinMetrics) {
this.exportBuiltinMetricsToGoogleCloudMonitoring = exportBuiltinMetrics;
return this;
}

/**
* Sets the {@link OpenTelemetry} to use with this Datastore instance. If telemetry collection
* is enabled, but an `OpenTelemetry` is not provided, the Datastore SDK will attempt to use the
* `GlobalOpenTelemetry`.
* is enabled, but an {@code OpenTelemetry} is not provided, the Datastore SDK will attempt to
* use the {@code GlobalOpenTelemetry}.
*
* @param openTelemetry The OpenTelemetry that should be used by this Datastore instance.
* @return this builder instance.
*/
@Nonnull
public DatastoreOpenTelemetryOptions.Builder setOpenTelemetry(
Expand All @@ -129,6 +199,11 @@ public DatastoreOpenTelemetryOptions.Builder setOpenTelemetry(
return this;
}

/**
* Builds a new {@link DatastoreOpenTelemetryOptions} instance from this builder.
*
* @return a new {@link DatastoreOpenTelemetryOptions}.
*/
@Nonnull
public DatastoreOpenTelemetryOptions build() {
return new DatastoreOpenTelemetryOptions(this);
Expand Down
Loading
Loading