Skip to content

Commit 762d126

Browse files
committed
feat: Adding Lookup RPC OpenTelemetry Tracing (#1437)
* feat: Adding Lookup RPC OpenTelemetry Tracing - Removed OpenCensus Tracing - Added E2E tests with Global and Local OTel SDK - Moved OTel SDK setup to RemoteDatastoreHelper - Fixed pom to depend on BOM for all shared dependencies
1 parent 4a480c9 commit 762d126

File tree

7 files changed

+645
-14
lines changed

7 files changed

+645
-14
lines changed

google-cloud-datastore/pom.xml

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@
1818
<site.installationModule>google-cloud-datastore</site.installationModule>
1919
<opentelemetry.version>1.37.0</opentelemetry.version>
2020
</properties>
21+
<dependencyManagement>
22+
<dependencies>
23+
<dependency>
24+
<!-- Artifacts from google-cloud-java monorepo -->
25+
<groupId>com.google.cloud</groupId>
26+
<artifactId>gapic-libraries-bom</artifactId>
27+
<version>1.37.0</version>
28+
<type>pom</type>
29+
<scope>import</scope>
30+
</dependency>
31+
</dependencies>
32+
</dependencyManagement>
2133
<dependencies>
2234
<dependency>
2335
<groupId>com.google.api.grpc</groupId>
@@ -117,6 +129,11 @@
117129
</dependency>
118130

119131
<!-- OpenTelemetry -->
132+
<dependency>
133+
<groupId>io.opentelemetry</groupId>
134+
<artifactId>opentelemetry-sdk</artifactId>
135+
<version>${opentelemetry.version}</version>
136+
</dependency>
120137
<dependency>
121138
<groupId>io.opentelemetry</groupId>
122139
<artifactId>opentelemetry-api</artifactId>
@@ -136,7 +153,6 @@
136153
<type>test-jar</type>
137154
<scope>test</scope>
138155
</dependency>
139-
140156
<dependency>
141157
<groupId>com.google.guava</groupId>
142158
<artifactId>guava-testlib</artifactId>
@@ -178,12 +194,50 @@
178194
<version>1.4.4</version>
179195
<scope>test</scope>
180196
</dependency>
197+
<dependency>
198+
<groupId>com.google.testparameterinjector</groupId>
199+
<artifactId>test-parameter-injector</artifactId>
200+
<version>1.16</version>
201+
<scope>test</scope>
202+
</dependency>
203+
<!-- OpenTelemetry -->
181204
<dependency>
182205
<groupId>io.opentelemetry</groupId>
183-
<artifactId>opentelemetry-sdk</artifactId>
206+
<artifactId>opentelemetry-sdk-common</artifactId>
207+
<version>${opentelemetry.version}</version>
208+
<scope>test</scope>
209+
</dependency>
210+
<dependency>
211+
<groupId>io.opentelemetry</groupId>
212+
<artifactId>opentelemetry-sdk-trace</artifactId>
184213
<version>${opentelemetry.version}</version>
185214
<scope>test</scope>
186215
</dependency>
216+
<dependency>
217+
<groupId>io.opentelemetry</groupId>
218+
<artifactId>opentelemetry-semconv</artifactId>
219+
<version>1.1.0-alpha</version>
220+
<scope>test</scope>
221+
</dependency>
222+
<!-- END OpenTelemetry -->
223+
<!-- Cloud Ops -->
224+
<dependency>
225+
<groupId>com.google.cloud.opentelemetry</groupId>
226+
<artifactId>exporter-trace</artifactId>
227+
<version>0.15.0</version>
228+
<scope>test</scope>
229+
</dependency>
230+
<dependency>
231+
<groupId>com.google.cloud</groupId>
232+
<artifactId>google-cloud-trace</artifactId>
233+
<scope>test</scope>
234+
</dependency>
235+
<dependency>
236+
<groupId>com.google.api.grpc</groupId>
237+
<artifactId>proto-google-cloud-trace-v1</artifactId>
238+
<scope>test</scope>
239+
</dependency>
240+
<!-- END Cloud Ops -->
187241
</dependencies>
188242

189243
<build>

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.google.common.base.Preconditions;
3030
import com.google.common.collect.AbstractIterator;
3131
import com.google.common.collect.ImmutableList;
32+
import com.google.common.collect.ImmutableMap;
3233
import com.google.common.collect.Iterables;
3334
import com.google.common.collect.Sets;
3435
import com.google.datastore.v1.ExplainOptions;
@@ -61,6 +62,9 @@ final class DatastoreImpl extends BaseService<DatastoreOptions> implements Datas
6162
TransactionOperationExceptionHandler.build();
6263
private final TraceUtil traceUtil = TraceUtil.getInstance();
6364

65+
private final com.google.cloud.datastore.telemetry.TraceUtil otelTraceUtil =
66+
getOptions().getTraceUtil();
67+
6468
private final ReadOptionProtoPreparer readOptionProtoPreparer;
6569
private final AggregationQueryExecutor aggregationQueryExecutor;
6670

@@ -450,13 +454,26 @@ protected Entity computeNext() {
450454

451455
com.google.datastore.v1.LookupResponse lookup(
452456
final com.google.datastore.v1.LookupRequest requestPb) {
453-
Span span = traceUtil.startSpan(TraceUtil.SPAN_NAME_LOOKUP);
454-
try (Scope scope = traceUtil.getTracer().withSpan(span)) {
457+
com.google.cloud.datastore.telemetry.TraceUtil.Span span =
458+
otelTraceUtil.startSpan(com.google.cloud.datastore.telemetry.TraceUtil.SPAN_NAME_LOOKUP);
459+
final ReadOptions readOptions = requestPb.getReadOptions();
460+
span.setAttribute(
461+
"isTransactional", (readOptions.hasTransaction() || readOptions.hasNewTransaction()));
462+
463+
try (com.google.cloud.datastore.telemetry.TraceUtil.Scope ignored = span.makeCurrent()) {
455464
return RetryHelper.runWithRetries(
456465
new Callable<com.google.datastore.v1.LookupResponse>() {
457466
@Override
458467
public com.google.datastore.v1.LookupResponse call() throws DatastoreException {
459-
return datastoreRpc.lookup(requestPb);
468+
com.google.datastore.v1.LookupResponse response = datastoreRpc.lookup(requestPb);
469+
span.addEvent(
470+
com.google.cloud.datastore.telemetry.TraceUtil.SPAN_NAME_LOOKUP + ": Completed",
471+
new ImmutableMap.Builder<String, Object>()
472+
.put("Received", response.getFoundCount())
473+
.put("Missing", response.getMissingCount())
474+
.put("Deferred", response.getDeferredCount())
475+
.build());
476+
return response;
460477
}
461478
},
462479
retrySettings,
@@ -465,10 +482,10 @@ public com.google.datastore.v1.LookupResponse call() throws DatastoreException {
465482
: TRANSACTION_OPERATION_EXCEPTION_HANDLER,
466483
getOptions().getClock());
467484
} catch (RetryHelperException e) {
468-
span.setStatus(Status.UNKNOWN.withDescription(e.getMessage()));
485+
span.end(e);
469486
throw DatastoreException.translateAndThrow(e);
470487
} finally {
471-
span.end(TraceUtil.END_SPAN_OPTIONS);
488+
span.end();
472489
}
473490
}
474491

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public TraceUtil.Span setAttribute(String key, String value) {
6161
return this;
6262
}
6363

64+
@Override
65+
public TraceUtil.Span setAttribute(String key, boolean value) {
66+
return this;
67+
}
68+
6469
@Override
6570
public Scope makeCurrent() {
6671
return new Scope();

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@ public TraceUtil.Span setAttribute(String key, String value) {
175175
return this;
176176
}
177177

178+
@Override
179+
public TraceUtil.Span setAttribute(String key, boolean value) {
180+
span.setAttribute(ATTRIBUTE_SERVICE_PREFIX + key, value);
181+
return this;
182+
}
183+
178184
@Override
179185
public Scope makeCurrent() {
180186
try (io.opentelemetry.context.Scope scope = span.makeCurrent()) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public interface TraceUtil {
3232
static final String ENABLE_TRACING_ENV_VAR = "DATASTORE_ENABLE_TRACING";
3333
static final String LIBRARY_NAME = "com.google.cloud.datastore";
3434

35+
static final String SPAN_NAME_LOOKUP = "Lookup";
3536
/**
3637
* Creates and returns an instance of the TraceUtil class.
3738
*
@@ -80,6 +81,9 @@ interface Span {
8081
/** Adds the given attribute to this span. */
8182
Span setAttribute(String key, String value);
8283

84+
/** Adds the given attribute to this span. */
85+
Span setAttribute(String key, boolean value);
86+
8387
/** Marks this span as the current span. */
8488
Scope makeCurrent();
8589

google-cloud-datastore/src/main/java/com/google/cloud/datastore/testing/RemoteDatastoreHelper.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919
import com.google.api.core.InternalApi;
2020
import com.google.api.gax.retrying.RetrySettings;
2121
import com.google.cloud.datastore.Datastore;
22+
import com.google.cloud.datastore.DatastoreOpenTelemetryOptions;
2223
import com.google.cloud.datastore.DatastoreOptions;
2324
import com.google.cloud.datastore.Key;
2425
import com.google.cloud.datastore.Query;
2526
import com.google.cloud.datastore.QueryResults;
2627
import com.google.cloud.datastore.StructuredQuery;
2728
import com.google.cloud.http.HttpTransportOptions;
29+
import io.opentelemetry.sdk.OpenTelemetrySdk;
2830
import java.util.UUID;
31+
import javax.annotation.Nullable;
2932
import org.threeten.bp.Duration;
3033

3134
/**
@@ -38,13 +41,13 @@
3841
* RetrySettings#getTotalTimeout()} is {@code 120000} and {@link
3942
* RetrySettings#getInitialRetryDelay()} is {@code 250}. {@link
4043
* HttpTransportOptions#getConnectTimeout()} and {@link HttpTransportOptions#getReadTimeout()} are
41-
* both both set to {@code 60000}.
44+
* both both set to {@code 60000}. If an OpenTelemetrySdk object is passed in, OpenTelemetry Trace
45+
* collection will be enabled for the Client application.
4246
*
4347
* <p>Internal testing use only
4448
*/
4549
@InternalApi
4650
public class RemoteDatastoreHelper {
47-
4851
private final DatastoreOptions options;
4952
private final Datastore datastore;
5053
private final String namespace;
@@ -78,18 +81,30 @@ public static RemoteDatastoreHelper create() {
7881
}
7982

8083
/** Creates a {@code RemoteStorageHelper} object. */
81-
public static RemoteDatastoreHelper create(String databaseId) {
84+
public static RemoteDatastoreHelper create(
85+
String databaseId, @Nullable OpenTelemetrySdk openTelemetrySdk) {
8286
HttpTransportOptions transportOptions = DatastoreOptions.getDefaultHttpTransportOptions();
8387
transportOptions =
8488
transportOptions.toBuilder().setConnectTimeout(60000).setReadTimeout(60000).build();
85-
DatastoreOptions datastoreOption =
89+
DatastoreOptions.Builder datastoreOptionBuilder =
8690
DatastoreOptions.newBuilder()
8791
.setDatabaseId(databaseId)
8892
.setNamespace(UUID.randomUUID().toString())
8993
.setRetrySettings(retrySettings())
90-
.setTransportOptions(transportOptions)
91-
.build();
92-
return new RemoteDatastoreHelper(datastoreOption);
94+
.setTransportOptions(transportOptions);
95+
96+
if (openTelemetrySdk != null) {
97+
datastoreOptionBuilder.setOpenTelemetryOptions(
98+
DatastoreOpenTelemetryOptions.newBuilder()
99+
.setOpenTelemetry(openTelemetrySdk)
100+
.setTracingEnabled(true)
101+
.build());
102+
}
103+
return new RemoteDatastoreHelper(datastoreOptionBuilder.build());
104+
}
105+
106+
public static RemoteDatastoreHelper create(String databaseId) {
107+
return create(databaseId, /*openTelemetrySdk=*/ null);
93108
}
94109

95110
private static RetrySettings retrySettings() {

0 commit comments

Comments
 (0)