Skip to content
This repository was archived by the owner on Feb 24, 2026. It is now read-only.

Commit 5fa9386

Browse files
committed
feat: Adding Commit RPC Trace Instrumentation (#1440)
- Added end-to-end test for Datastore operationsput, add, update and delete. - Updated E2E Test to use the namespace correctly for efficient clean-up of test data
1 parent e8ae25e commit 5fa9386

File tree

3 files changed

+115
-8
lines changed

3 files changed

+115
-8
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,11 @@ private com.google.datastore.v1.CommitResponse commitMutation(
619619

620620
com.google.datastore.v1.CommitResponse commit(
621621
final com.google.datastore.v1.CommitRequest requestPb) {
622-
Span span = traceUtil.startSpan(TraceUtil.SPAN_NAME_COMMIT);
623-
try (Scope scope = traceUtil.getTracer().withSpan(span)) {
622+
com.google.cloud.datastore.telemetry.TraceUtil.Span span =
623+
otelTraceUtil.startSpan(com.google.cloud.datastore.telemetry.TraceUtil.SPAN_NAME_COMMIT);
624+
span.setAttribute("isTransactional", requestPb.hasTransaction());
625+
626+
try (com.google.cloud.datastore.telemetry.TraceUtil.Scope ignored = span.makeCurrent()) {
624627
return RetryHelper.runWithRetries(
625628
() -> datastoreRpc.commit(requestPb),
626629
retrySettings,
@@ -629,10 +632,10 @@ com.google.datastore.v1.CommitResponse commit(
629632
: TRANSACTION_OPERATION_EXCEPTION_HANDLER,
630633
getOptions().getClock());
631634
} catch (RetryHelperException e) {
632-
span.setStatus(Status.UNKNOWN.withDescription(e.getMessage()));
635+
span.end(e);
633636
throw DatastoreException.translateAndThrow(e);
634637
} finally {
635-
span.end(TraceUtil.END_SPAN_OPTIONS);
638+
span.end();
636639
}
637640
}
638641

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ public interface TraceUtil {
3333
static final String LIBRARY_NAME = "com.google.cloud.datastore";
3434

3535
static final String SPAN_NAME_LOOKUP = "Lookup";
36+
37+
static final String SPAN_NAME_COMMIT = "Commit";
38+
3639
/**
3740
* Creates and returns an instance of the TraceUtil class.
3841
*

google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITE2ETracingTest.java

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.google.cloud.datastore.it;
1818

19+
import static com.google.cloud.datastore.telemetry.TraceUtil.SPAN_NAME_COMMIT;
1920
import static com.google.cloud.datastore.telemetry.TraceUtil.SPAN_NAME_LOOKUP;
2021
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME;
2122
import static org.junit.Assert.assertEquals;
@@ -207,6 +208,8 @@ private boolean dfsContainsCallStack(long spanId, List<String> expectedCallStack
207208

208209
private static Key KEY1;
209210

211+
private static Key KEY2;
212+
210213
// Random int generator for trace ID and span ID
211214
private static Random random;
212215

@@ -233,9 +236,15 @@ private boolean dfsContainsCallStack(long spanId, List<String> expectedCallStack
233236

234237
private static Datastore datastore;
235238

239+
private static RemoteDatastoreHelper remoteDatastoreHelper;
240+
236241
@TestParameter boolean useGlobalOpenTelemetrySDK;
237242

238-
@TestParameter({"default", "test-db"})
243+
@TestParameter({
244+
/*(default)*/
245+
"",
246+
"test-db"
247+
})
239248
String datastoreNamedDatabase;
240249

241250
@BeforeClass
@@ -280,8 +289,7 @@ public void before() throws Exception {
280289
// but because gRPC traces need to be deterministically force-flushed for every test
281290
String namedDb = datastoreNamedDatabase();
282291
logger.log(Level.INFO, "Integration test using named database " + namedDb);
283-
RemoteDatastoreHelper remoteDatastoreHelper =
284-
RemoteDatastoreHelper.create(namedDb, openTelemetrySdk);
292+
remoteDatastoreHelper = RemoteDatastoreHelper.create(namedDb, openTelemetrySdk);
285293
options = remoteDatastoreHelper.getOptions();
286294
datastore = options.getService();
287295

@@ -292,7 +300,14 @@ public void before() throws Exception {
292300

293301
String projectId = options.getProjectId();
294302
String kind1 = "kind1";
295-
KEY1 = Key.newBuilder(projectId, kind1, "name", options.getDatabaseId()).build();
303+
KEY1 =
304+
Key.newBuilder(projectId, kind1, "name1", options.getDatabaseId())
305+
.setNamespace(options.getNamespace())
306+
.build();
307+
KEY2 =
308+
Key.newBuilder(projectId, kind1, "name2", options.getDatabaseId())
309+
.setNamespace(options.getNamespace())
310+
.build();
296311

297312
// Set up the tracer for custom TraceID injection
298313
rootSpanName =
@@ -319,6 +334,7 @@ public void after() throws Exception {
319334
if (isUsingGlobalOpenTelemetrySDK()) {
320335
GlobalOpenTelemetry.resetForTest();
321336
}
337+
remoteDatastoreHelper.deleteNamespace();
322338
rootSpanName = null;
323339
tracer = null;
324340
retrievedTrace = null;
@@ -527,4 +543,89 @@ public void lookupTraceTest() throws Exception {
527543

528544
fetchAndValidateTrace(customSpanContext.getTraceId(), SPAN_NAME_LOOKUP);
529545
}
546+
547+
@Test
548+
public void commitTraceTest() throws Exception {
549+
assertNotNull(customSpanContext);
550+
551+
Span rootSpan = getNewRootSpanWithContext();
552+
553+
Entity entity1 = Entity.newBuilder(KEY1).set("test_key", "test_value").build();
554+
try (Scope ignored = rootSpan.makeCurrent()) {
555+
Entity response = datastore.add(entity1);
556+
assertEquals(entity1, response);
557+
} finally {
558+
rootSpan.end();
559+
}
560+
waitForTracesToComplete();
561+
562+
fetchAndValidateTrace(customSpanContext.getTraceId(), SPAN_NAME_COMMIT);
563+
}
564+
565+
@Test
566+
public void putTraceTest() throws Exception {
567+
assertNotNull(customSpanContext);
568+
569+
Span rootSpan = getNewRootSpanWithContext();
570+
571+
Entity entity1 = Entity.newBuilder(KEY1).set("test_key", "test_value").build();
572+
try (Scope ignored = rootSpan.makeCurrent()) {
573+
Entity response = datastore.put(entity1);
574+
assertEquals(entity1, response);
575+
} finally {
576+
rootSpan.end();
577+
}
578+
waitForTracesToComplete();
579+
580+
fetchAndValidateTrace(customSpanContext.getTraceId(), SPAN_NAME_COMMIT);
581+
}
582+
583+
@Test
584+
public void updateTraceTest() throws Exception {
585+
assertNotNull(customSpanContext);
586+
587+
Entity entity1 = Entity.newBuilder(KEY1).set("test_field", "test_value1").build();
588+
Entity entity2 = Entity.newBuilder(KEY2).set("test_field", "test_value2").build();
589+
List<Entity> entityList = new ArrayList<>();
590+
entityList.add(entity1);
591+
entityList.add(entity2);
592+
593+
List<Entity> response = datastore.add(entity1, entity2);
594+
assertEquals(entityList, response);
595+
596+
Span rootSpan = getNewRootSpanWithContext();
597+
598+
try (Scope ignored = rootSpan.makeCurrent()) {
599+
Entity entity1_update =
600+
Entity.newBuilder(entity1).set("test_field", "new_test_value1").build();
601+
Entity entity2_update =
602+
Entity.newBuilder(entity2).set("test_field", "new_test_value1").build();
603+
datastore.update(entity1_update, entity2_update);
604+
} finally {
605+
rootSpan.end();
606+
}
607+
waitForTracesToComplete();
608+
609+
fetchAndValidateTrace(customSpanContext.getTraceId(), SPAN_NAME_COMMIT);
610+
}
611+
612+
@Test
613+
public void deleteTraceTest() throws Exception {
614+
assertNotNull(customSpanContext);
615+
616+
Entity entity1 = Entity.newBuilder(KEY1).set("test_key", "test_value").build();
617+
Entity response = datastore.put(entity1);
618+
assertEquals(entity1, response);
619+
620+
Span rootSpan = getNewRootSpanWithContext();
621+
622+
try (Scope ignored = rootSpan.makeCurrent()) {
623+
datastore.delete(entity1.getKey());
624+
} finally {
625+
rootSpan.end();
626+
}
627+
waitForTracesToComplete();
628+
629+
fetchAndValidateTrace(customSpanContext.getTraceId(), SPAN_NAME_COMMIT);
630+
}
530631
}

0 commit comments

Comments
 (0)