Skip to content

Commit 0bf197b

Browse files
committed
chore: Update to remove the extra attributes
1 parent 29f7ce1 commit 0bf197b

File tree

6 files changed

+119
-177
lines changed

6 files changed

+119
-177
lines changed

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import com.google.cloud.RetryHelper;
4646
import com.google.cloud.RetryHelper.RetryHelperException;
4747
import com.google.cloud.ServiceOptions;
48-
import com.google.cloud.TransportOptions;
4948
import com.google.cloud.datastore.execution.AggregationQueryExecutor;
5049
import com.google.cloud.datastore.spi.v1.DatastoreRpc;
5150
import com.google.cloud.datastore.telemetry.DatastoreMetricsRecorder;
@@ -74,7 +73,6 @@
7473
import java.util.ArrayList;
7574
import java.util.Arrays;
7675
import java.util.Collections;
77-
import java.util.HashMap;
7876
import java.util.Iterator;
7977
import java.util.LinkedHashMap;
8078
import java.util.LinkedHashSet;
@@ -223,7 +221,7 @@ public T call() throws DatastoreException {
223221
}
224222
throw DatastoreException.propagateUserException(ex);
225223
} finally {
226-
recordAttempt(attemptStatus, datastore.getOptions().getTransportOptions());
224+
recordAttempt(attemptStatus);
227225
// If the transaction is active, then commit the rollback. If it was already successfully
228226
// rolled back, the transaction is inactive (prevents rolling back an already rolled back
229227
// transaction).
@@ -242,18 +240,10 @@ public T call() throws DatastoreException {
242240
* Records a single transaction commit attempt with the given status code. This is called once
243241
* per invocation of {@link #call()}, capturing the outcome of each individual commit attempt.
244242
*/
245-
private void recordAttempt(String status, TransportOptions transportOptions) {
246-
Map<String, String> attributes = new HashMap<>();
247-
attributes.put(TelemetryConstants.ATTRIBUTES_KEY_STATUS, status);
248-
attributes.put(
249-
TelemetryConstants.ATTRIBUTES_KEY_METHOD, TelemetryConstants.METHOD_TRANSACTION_COMMIT);
250-
attributes.put(
251-
TelemetryConstants.ATTRIBUTES_KEY_PROJECT_ID, datastore.getOptions().getProjectId());
252-
attributes.put(
253-
TelemetryConstants.ATTRIBUTES_KEY_DATABASE_ID, datastore.getOptions().getDatabaseId());
254-
attributes.put(
255-
TelemetryConstants.ATTRIBUTES_KEY_TRANSPORT,
256-
TelemetryConstants.getTransportName(transportOptions));
243+
private void recordAttempt(String status) {
244+
Map<String, String> attributes =
245+
TelemetryUtils.buildMetricAttributes(
246+
TelemetryConstants.METHOD_TRANSACTION_COMMIT, status);
257247
metricsRecorder.recordTransactionAttemptCount(1, attributes);
258248
}
259249
}
@@ -290,15 +280,8 @@ public <T> T runInTransaction(
290280
throw DatastoreException.translateAndThrow(e);
291281
} finally {
292282
long latencyMs = stopwatch.elapsed(TimeUnit.MILLISECONDS);
293-
Map<String, String> attributes = new HashMap<>();
294-
attributes.put(TelemetryConstants.ATTRIBUTES_KEY_STATUS, status);
295-
attributes.put(
296-
TelemetryConstants.ATTRIBUTES_KEY_METHOD, TelemetryConstants.METHOD_TRANSACTION_RUN);
297-
attributes.put(TelemetryConstants.ATTRIBUTES_KEY_PROJECT_ID, getOptions().getProjectId());
298-
attributes.put(TelemetryConstants.ATTRIBUTES_KEY_DATABASE_ID, getOptions().getDatabaseId());
299-
attributes.put(
300-
TelemetryConstants.ATTRIBUTES_KEY_TRANSPORT,
301-
TelemetryConstants.getTransportName(getOptions().getTransportOptions()));
283+
Map<String, String> attributes =
284+
TelemetryUtils.buildMetricAttributes(TelemetryConstants.METHOD_TRANSACTION_RUN, status);
302285
metricsRecorder.recordTransactionLatency(latencyMs, attributes);
303286
span.end();
304287
}
@@ -807,7 +790,7 @@ private <T> T runWithObservability(
807790

808791
DatastoreOptions options = getOptions();
809792
Callable<T> attemptCallable =
810-
TelemetryUtils.attemptMetricsCallable(callable, metricsRecorder, options, methodName);
793+
TelemetryUtils.attemptMetricsCallable(callable, metricsRecorder, methodName);
811794
try (TraceUtil.Scope ignored = span.makeCurrent()) {
812795
return RetryHelper.runWithRetries(
813796
attemptCallable, retrySettings, exceptionHandler, options.getClock());
@@ -817,7 +800,7 @@ private <T> T runWithObservability(
817800
throw DatastoreException.translateAndThrow(e);
818801
} finally {
819802
TelemetryUtils.recordOperationMetrics(
820-
metricsRecorder, options, operationStopwatch, methodName, operationStatus);
803+
metricsRecorder, operationStopwatch, methodName, operationStatus);
821804
span.end();
822805
}
823806
}

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/RetryAndTraceDatastoreRpcDecorator.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ <O> O invokeRpc(Callable<O> block, String startSpan, String methodName) {
205205
String operationStatus = StatusCode.Code.UNKNOWN.toString();
206206
try (TraceUtil.Scope ignored = span.makeCurrent()) {
207207
Callable<O> callable =
208-
TelemetryUtils.attemptMetricsCallable(
209-
block, metricsRecorder, datastoreOptions, methodName);
208+
TelemetryUtils.attemptMetricsCallable(block, metricsRecorder, methodName);
210209
O result =
211210
RetryHelper.runWithRetries(
212211
callable, this.retrySettings, EXCEPTION_HANDLER, this.datastoreOptions.getClock());
@@ -218,7 +217,7 @@ <O> O invokeRpc(Callable<O> block, String startSpan, String methodName) {
218217
throw DatastoreException.translateAndThrow(e);
219218
} finally {
220219
TelemetryUtils.recordOperationMetrics(
221-
metricsRecorder, datastoreOptions, stopwatch, methodName, operationStatus);
220+
metricsRecorder, stopwatch, methodName, operationStatus);
222221
span.end();
223222
}
224223
}

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/telemetry/OpenTelemetryDatastoreMetricsRecorder.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,16 @@ class OpenTelemetryDatastoreMetricsRecorder extends OpenTelemetryMetricsRecorder
4545

4646
private final OpenTelemetry openTelemetry;
4747

48+
// Datastore-specific transaction metrics (registered under the Datastore meter).
4849
private final DoubleHistogram transactionLatency;
4950
private final LongCounter transactionAttemptCount;
5051

52+
// GAX operation/attempt latency metrics re-registered under the Datastore meter with the
53+
// plural names required by the internal Cloud Monitoring descriptor. These override the
54+
// singular-named histograms registered by the parent GAX class.
55+
private final DoubleHistogram operationLatency;
56+
private final DoubleHistogram attemptLatency;
57+
5158
OpenTelemetryDatastoreMetricsRecorder(@Nonnull OpenTelemetry openTelemetry, String metricPrefix) {
5259
super(openTelemetry, metricPrefix);
5360
this.openTelemetry = openTelemetry;
@@ -66,12 +73,37 @@ class OpenTelemetryDatastoreMetricsRecorder extends OpenTelemetryMetricsRecorder
6673
.counterBuilder(TelemetryConstants.METRIC_NAME_TRANSACTION_ATTEMPT_COUNT)
6774
.setDescription("Number of attempts to commit a transaction")
6875
.build();
76+
77+
this.operationLatency =
78+
meter
79+
.histogramBuilder(TelemetryConstants.METRIC_NAME_OPERATION_LATENCY)
80+
.setDescription(
81+
"Total time until final operation success or failure, including retries and backoff.")
82+
.setUnit("ms")
83+
.build();
84+
85+
this.attemptLatency =
86+
meter
87+
.histogramBuilder(TelemetryConstants.METRIC_NAME_ATTEMPT_LATENCY)
88+
.setDescription("Time an individual attempt took")
89+
.setUnit("ms")
90+
.build();
6991
}
7092

7193
OpenTelemetry getOpenTelemetry() {
7294
return openTelemetry;
7395
}
7496

97+
@Override
98+
public void recordOperationLatency(double latencyMs, Map<String, String> attributes) {
99+
operationLatency.record(latencyMs, toOtelAttributes(attributes));
100+
}
101+
102+
@Override
103+
public void recordAttemptLatency(double latencyMs, Map<String, String> attributes) {
104+
attemptLatency.record(latencyMs, toOtelAttributes(attributes));
105+
}
106+
75107
@Override
76108
public void recordTransactionLatency(double latencyMs, Map<String, String> attributes) {
77109
transactionLatency.record(latencyMs, toOtelAttributes(attributes));

java-datastore/google-cloud-datastore/src/main/java/com/google/cloud/datastore/telemetry/TelemetryConstants.java

Lines changed: 48 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717
package com.google.cloud.datastore.telemetry;
1818

1919
import com.google.api.core.InternalApi;
20-
import com.google.api.gax.tracing.OpenTelemetryMetricsRecorder;
21-
import com.google.cloud.TransportOptions;
22-
import com.google.cloud.grpc.GrpcTransportOptions;
2320
import com.google.common.collect.ImmutableSet;
2421
import io.opentelemetry.api.common.AttributeKey;
2522
import java.util.Set;
@@ -33,80 +30,24 @@
3330
*/
3431
@InternalApi
3532
public class TelemetryConstants {
36-
// Built-in metrics constants for Cloud Monitoring export
33+
34+
// The Firestore namespace has not been deployed yet. Must target the custom namespace
35+
// until this is implemented.
3736
public static final String METRIC_PREFIX = "custom.googleapis.com/internal/client";
38-
public static final String GAX_METER_NAME = OpenTelemetryMetricsRecorder.GAX_METER_NAME;
3937
public static final String DATASTORE_METER_NAME = "java-datastore";
4038

4139
// Monitored resource type for Cloud Monitoring
4240
public static final String DATASTORE_RESOURCE_TYPE = "global";
4341

4442
// Resource label keys for the monitored resource
43+
// The Firestore namespace has not been deployed yet. Must target the global
44+
// Monitored Resource until this is implemented.
4545
public static final String RESOURCE_LABEL_PROJECT_ID = "project_id";
4646
public static final String RESOURCE_LABEL_DATABASE_ID = "database_id";
4747
public static final String RESOURCE_LABEL_LOCATION = "location";
4848
public static final Set<String> DATASTORE_RESOURCE_LABELS =
49-
ImmutableSet.of(RESOURCE_LABEL_PROJECT_ID);
50-
51-
// Resource attribute keys (used on OTel Resource)
52-
public static final AttributeKey<String> PROJECT_ID_KEY = AttributeKey.stringKey("project_id");
53-
public static final AttributeKey<String> DATABASE_ID_KEY = AttributeKey.stringKey("database_id");
54-
public static final AttributeKey<String> LOCATION_ID_KEY = AttributeKey.stringKey("location");
55-
56-
// Metric attribute keys (used on metric data points)
57-
public static final AttributeKey<String> CLIENT_UID_KEY = AttributeKey.stringKey("client_uid");
58-
public static final AttributeKey<String> CLIENT_NAME_KEY = AttributeKey.stringKey("client_name");
59-
public static final AttributeKey<String> METHOD_KEY = AttributeKey.stringKey("method");
60-
public static final AttributeKey<String> STATUS_KEY = AttributeKey.stringKey("status");
61-
public static final AttributeKey<String> DATABASE_KEY = AttributeKey.stringKey("database_id");
62-
public static final AttributeKey<String> LIBRARY_VERSION_KEY =
63-
AttributeKey.stringKey("library_version");
64-
public static final AttributeKey<String> TRANSPORT_KEY = AttributeKey.stringKey("transport");
65-
public static final AttributeKey<String> SERVICE_KEY = AttributeKey.stringKey("service");
66-
67-
public static final String SERVICE_VALUE = "datastore.googleapis.com";
68-
69-
/**
70-
* The allowlist of metric attributes that are permitted on every exported data point.
71-
*
72-
* <p>Cloud Monitoring is strict about label schemas: exporting a label that was not present when
73-
* the metric descriptor was first created will cause the entire {@code createTimeSeries} call to
74-
* fail.
75-
*/
76-
public static final Set<AttributeKey<?>> COMMON_ATTRIBUTES =
77-
ImmutableSet.of(
78-
CLIENT_UID_KEY,
79-
CLIENT_NAME_KEY,
80-
METHOD_KEY,
81-
STATUS_KEY,
82-
DATABASE_KEY,
83-
LIBRARY_VERSION_KEY,
84-
TRANSPORT_KEY,
85-
SERVICE_KEY);
86-
87-
// Metric names (short names, without prefix)
88-
public static final String METRIC_NAME_SHORT_OPERATION_LATENCY = "operation_latency";
89-
public static final String METRIC_NAME_SHORT_ATTEMPT_LATENCY = "attempt_latency";
90-
public static final String METRIC_NAME_SHORT_OPERATION_COUNT = "operation_count";
91-
public static final String METRIC_NAME_SHORT_ATTEMPT_COUNT = "attempt_count";
92-
public static final String METRIC_NAME_SHORT_TRANSACTION_LATENCY = "transaction_latency";
93-
public static final String METRIC_NAME_SHORT_TRANSACTION_ATTEMPT_COUNT =
94-
"transaction_attempt_count";
95-
96-
// Metrics collected at the GAX layer vs Datastore SDK layer
97-
public static final Set<String> GAX_METRICS =
98-
ImmutableSet.of(
99-
METRIC_NAME_SHORT_OPERATION_LATENCY,
100-
METRIC_NAME_SHORT_ATTEMPT_LATENCY,
101-
METRIC_NAME_SHORT_OPERATION_COUNT,
102-
METRIC_NAME_SHORT_ATTEMPT_COUNT);
103-
104-
public static final Set<String> DATASTORE_METRICS =
10549
ImmutableSet.of(
106-
METRIC_NAME_SHORT_TRANSACTION_LATENCY, METRIC_NAME_SHORT_TRANSACTION_ATTEMPT_COUNT);
107-
108-
// Environment variable to enable/disable built-in metrics
109-
public static final String ENABLE_METRICS_ENV_VAR = "DATASTORE_ENABLE_METRICS";
50+
RESOURCE_LABEL_PROJECT_ID, RESOURCE_LABEL_DATABASE_ID, RESOURCE_LABEL_LOCATION);
11051

11152
// Existing attribute key constants (string-based, used by MetricsHelper/TelemetryUtils)
11253
public static final String ATTRIBUTES_KEY_DOCUMENT_COUNT = "doc_count";
@@ -130,23 +71,58 @@ public class TelemetryConstants {
13071
/** Attribute key for the Datastore database ID. */
13172
public static final String ATTRIBUTES_KEY_DATABASE_ID = "database_id";
13273

133-
public static final String ATTRIBUTES_KEY_LIBRARY_VERSION = "library_version";
74+
// Resource attribute keys (used on OTel Resource)
75+
public static final AttributeKey<String> PROJECT_ID_KEY = AttributeKey.stringKey("project_id");
76+
public static final AttributeKey<String> DATABASE_ID_KEY = AttributeKey.stringKey("database_id");
77+
public static final AttributeKey<String> LOCATION_ID_KEY = AttributeKey.stringKey("location");
78+
79+
// Metric attribute keys (used on metric data points)
80+
public static final AttributeKey<String> CLIENT_UID_KEY = AttributeKey.stringKey("client_uid");
81+
public static final AttributeKey<String> METHOD_KEY = AttributeKey.stringKey("method");
82+
public static final AttributeKey<String> STATUS_KEY = AttributeKey.stringKey("status");
83+
public static final AttributeKey<String> SERVICE_KEY = AttributeKey.stringKey("service");
84+
85+
public static final String SERVICE_VALUE = "datastore.googleapis.com";
13486

135-
public static final String ATTRIBUTES_KEY_TRANSPORT = "transport";
87+
/** String key for the {@code service} metric attribute (value: {@code "service"}). */
88+
public static final String ATTRIBUTES_KEY_SERVICE = SERVICE_KEY.getKey();
89+
90+
/**
91+
* The allowlist of metric attributes that are permitted on every exported data point.
92+
*
93+
* <p>Cloud Monitoring is strict about label schemas: exporting a label that was not present when
94+
* the metric descriptor was first created will cause the entire {@code createTimeSeries} call to
95+
* fail. Only {@code status}, {@code method}, {@code service}, and {@code client_uid} are
96+
* accepted; all other attributes must be omitted from every {@code record*()} call.
97+
*/
98+
public static final Set<AttributeKey<?>> COMMON_ATTRIBUTES =
99+
ImmutableSet.of(CLIENT_UID_KEY, METHOD_KEY, STATUS_KEY, SERVICE_KEY);
136100

137101
/** Metric name for the total latency of a transaction. */
138102
public static final String METRIC_NAME_TRANSACTION_LATENCY =
139-
METRIC_PREFIX + "/transaction_latency";
103+
METRIC_PREFIX + "/transaction_latencies";
140104

141105
/** Metric name for the number of attempts a transaction took. */
142106
public static final String METRIC_NAME_TRANSACTION_ATTEMPT_COUNT =
143107
METRIC_PREFIX + "/transaction_attempt_count";
144108

145-
/** Metric name for the total latency of an operation (one full RPC call including retries). */
146-
public static final String METRIC_NAME_OPERATION_LATENCY = METRIC_PREFIX + "/operation_latency";
109+
/**
110+
* Metric name for the total latency of an operation (one full RPC call including retries).
111+
*
112+
* <p>The plural form ({@code operation_latencies}) is intentional: it matches the internal Cloud
113+
* Monitoring metric descriptor name. {@link OpenTelemetryDatastoreMetricsRecorder} overrides the
114+
* inherited GAX method to record to this name rather than the singular GAX default.
115+
*/
116+
public static final String METRIC_NAME_OPERATION_LATENCY = METRIC_PREFIX + "/operation_latencies";
147117

148-
/** Metric name for the latency of a single RPC attempt. */
149-
public static final String METRIC_NAME_ATTEMPT_LATENCY = METRIC_PREFIX + "/attempt_latency";
118+
/**
119+
* Metric name for the latency of a single RPC attempt.
120+
*
121+
* <p>The plural form ({@code attempt_latencies}) is intentional: it matches the internal Cloud
122+
* Monitoring metric descriptor name. {@link OpenTelemetryDatastoreMetricsRecorder} overrides the
123+
* inherited GAX method to record to this name rather than the singular GAX default.
124+
*/
125+
public static final String METRIC_NAME_ATTEMPT_LATENCY = METRIC_PREFIX + "/attempt_latencies";
150126

151127
/** Metric name for the count of operations. */
152128
public static final String METRIC_NAME_OPERATION_COUNT = METRIC_PREFIX + "/operation_count";
@@ -191,13 +167,5 @@ public String getTransport() {
191167
}
192168
}
193169

194-
public static String getTransportName(TransportOptions transportOptions) {
195-
if (transportOptions instanceof GrpcTransportOptions) {
196-
return Transport.GRPC.getTransport();
197-
} else {
198-
return Transport.HTTP.getTransport();
199-
}
200-
}
201-
202170
private TelemetryConstants() {}
203171
}

0 commit comments

Comments
 (0)