Skip to content

Commit eee333b

Browse files
authored
feat: Improve tracing by adding attributes (#3576)
1 parent 1af8e46 commit eee333b

File tree

7 files changed

+117
-29
lines changed

7 files changed

+117
-29
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java

+1
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ ResultSet readInternalWithOptions(
960960
SpannerImpl.READ,
961961
span,
962962
tracer,
963+
tracer.createTableAttributes(table, readOptions),
963964
session.getErrorHandler(),
964965
rpc.getReadRetrySettings(),
965966
rpc.getReadRetryableCodes()) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java

+23-17
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
import com.google.common.base.Function;
2727
import com.google.common.util.concurrent.ListenableFuture;
2828
import com.google.spanner.v1.BatchWriteResponse;
29+
import io.opentelemetry.api.common.Attributes;
2930
import javax.annotation.Nullable;
3031

3132
class DatabaseClientImpl implements DatabaseClient {
3233
private static final String READ_WRITE_TRANSACTION = "CloudSpanner.ReadWriteTransaction";
3334
private static final String READ_ONLY_TRANSACTION = "CloudSpanner.ReadOnlyTransaction";
3435
private static final String PARTITION_DML_TRANSACTION = "CloudSpanner.PartitionDMLTransaction";
3536
private final TraceWrapper tracer;
37+
private Attributes commonAttributes;
3638
@VisibleForTesting final String clientId;
3739
@VisibleForTesting final SessionPool pool;
3840
@VisibleForTesting final MultiplexedSessionDatabaseClient multiplexedSessionDatabaseClient;
@@ -50,7 +52,8 @@ class DatabaseClientImpl implements DatabaseClient {
5052
/* multiplexedSessionDatabaseClient = */ null,
5153
/* useMultiplexedSessionPartitionedOps= */ false,
5254
tracer,
53-
/* useMultiplexedSessionForRW = */ false);
55+
/* useMultiplexedSessionForRW = */ false,
56+
Attributes.empty());
5457
}
5558

5659
@VisibleForTesting
@@ -62,7 +65,8 @@ class DatabaseClientImpl implements DatabaseClient {
6265
/* multiplexedSessionDatabaseClient = */ null,
6366
/* useMultiplexedSessionPartitionedOps= */ false,
6467
tracer,
65-
/* useMultiplexedSessionForRW = */ false);
68+
/* useMultiplexedSessionForRW = */ false,
69+
Attributes.empty());
6670
}
6771

6872
DatabaseClientImpl(
@@ -72,14 +76,16 @@ class DatabaseClientImpl implements DatabaseClient {
7276
@Nullable MultiplexedSessionDatabaseClient multiplexedSessionDatabaseClient,
7377
boolean useMultiplexedSessionPartitionedOps,
7478
TraceWrapper tracer,
75-
boolean useMultiplexedSessionForRW) {
79+
boolean useMultiplexedSessionForRW,
80+
Attributes commonAttributes) {
7681
this.clientId = clientId;
7782
this.pool = pool;
7883
this.useMultiplexedSessionBlindWrite = useMultiplexedSessionBlindWrite;
7984
this.multiplexedSessionDatabaseClient = multiplexedSessionDatabaseClient;
8085
this.useMultiplexedSessionPartitionedOps = useMultiplexedSessionPartitionedOps;
8186
this.tracer = tracer;
8287
this.useMultiplexedSessionForRW = useMultiplexedSessionForRW;
88+
this.commonAttributes = commonAttributes;
8389
}
8490

8591
@VisibleForTesting
@@ -138,7 +144,7 @@ public Timestamp write(final Iterable<Mutation> mutations) throws SpannerExcepti
138144
public CommitResponse writeWithOptions(
139145
final Iterable<Mutation> mutations, final TransactionOption... options)
140146
throws SpannerException {
141-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
147+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
142148
try (IScope s = tracer.withSpan(span)) {
143149
if (canUseMultiplexedSessionsForRW() && getMultiplexedSessionDatabaseClient() != null) {
144150
return getMultiplexedSessionDatabaseClient().writeWithOptions(mutations, options);
@@ -161,7 +167,7 @@ public Timestamp writeAtLeastOnce(final Iterable<Mutation> mutations) throws Spa
161167
public CommitResponse writeAtLeastOnceWithOptions(
162168
final Iterable<Mutation> mutations, final TransactionOption... options)
163169
throws SpannerException {
164-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
170+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
165171
try (IScope s = tracer.withSpan(span)) {
166172
if (useMultiplexedSessionBlindWrite && getMultiplexedSessionDatabaseClient() != null) {
167173
return getMultiplexedSessionDatabaseClient()
@@ -181,7 +187,7 @@ public CommitResponse writeAtLeastOnceWithOptions(
181187
public ServerStream<BatchWriteResponse> batchWriteAtLeastOnce(
182188
final Iterable<MutationGroup> mutationGroups, final TransactionOption... options)
183189
throws SpannerException {
184-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
190+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
185191
try (IScope s = tracer.withSpan(span)) {
186192
return runWithSessionRetry(session -> session.batchWriteAtLeastOnce(mutationGroups, options));
187193
} catch (RuntimeException e) {
@@ -194,7 +200,7 @@ public ServerStream<BatchWriteResponse> batchWriteAtLeastOnce(
194200

195201
@Override
196202
public ReadContext singleUse() {
197-
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION);
203+
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION, commonAttributes);
198204
try (IScope s = tracer.withSpan(span)) {
199205
return getMultiplexedSession().singleUse();
200206
} catch (RuntimeException e) {
@@ -206,7 +212,7 @@ public ReadContext singleUse() {
206212

207213
@Override
208214
public ReadContext singleUse(TimestampBound bound) {
209-
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION);
215+
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION, commonAttributes);
210216
try (IScope s = tracer.withSpan(span)) {
211217
return getMultiplexedSession().singleUse(bound);
212218
} catch (RuntimeException e) {
@@ -218,7 +224,7 @@ public ReadContext singleUse(TimestampBound bound) {
218224

219225
@Override
220226
public ReadOnlyTransaction singleUseReadOnlyTransaction() {
221-
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION);
227+
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION, commonAttributes);
222228
try (IScope s = tracer.withSpan(span)) {
223229
return getMultiplexedSession().singleUseReadOnlyTransaction();
224230
} catch (RuntimeException e) {
@@ -230,7 +236,7 @@ public ReadOnlyTransaction singleUseReadOnlyTransaction() {
230236

231237
@Override
232238
public ReadOnlyTransaction singleUseReadOnlyTransaction(TimestampBound bound) {
233-
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION);
239+
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION, commonAttributes);
234240
try (IScope s = tracer.withSpan(span)) {
235241
return getMultiplexedSession().singleUseReadOnlyTransaction(bound);
236242
} catch (RuntimeException e) {
@@ -242,7 +248,7 @@ public ReadOnlyTransaction singleUseReadOnlyTransaction(TimestampBound bound) {
242248

243249
@Override
244250
public ReadOnlyTransaction readOnlyTransaction() {
245-
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION);
251+
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION, commonAttributes);
246252
try (IScope s = tracer.withSpan(span)) {
247253
return getMultiplexedSession().readOnlyTransaction();
248254
} catch (RuntimeException e) {
@@ -254,7 +260,7 @@ public ReadOnlyTransaction readOnlyTransaction() {
254260

255261
@Override
256262
public ReadOnlyTransaction readOnlyTransaction(TimestampBound bound) {
257-
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION);
263+
ISpan span = tracer.spanBuilder(READ_ONLY_TRANSACTION, commonAttributes);
258264
try (IScope s = tracer.withSpan(span)) {
259265
return getMultiplexedSession().readOnlyTransaction(bound);
260266
} catch (RuntimeException e) {
@@ -266,7 +272,7 @@ public ReadOnlyTransaction readOnlyTransaction(TimestampBound bound) {
266272

267273
@Override
268274
public TransactionRunner readWriteTransaction(TransactionOption... options) {
269-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
275+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
270276
try (IScope s = tracer.withSpan(span)) {
271277
return getMultiplexedSessionForRW().readWriteTransaction(options);
272278
} catch (RuntimeException e) {
@@ -278,7 +284,7 @@ public TransactionRunner readWriteTransaction(TransactionOption... options) {
278284

279285
@Override
280286
public TransactionManager transactionManager(TransactionOption... options) {
281-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
287+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
282288
try (IScope s = tracer.withSpan(span)) {
283289
return getMultiplexedSessionForRW().transactionManager(options);
284290
} catch (RuntimeException e) {
@@ -290,7 +296,7 @@ public TransactionManager transactionManager(TransactionOption... options) {
290296

291297
@Override
292298
public AsyncRunner runAsync(TransactionOption... options) {
293-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
299+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
294300
try (IScope s = tracer.withSpan(span)) {
295301
return getMultiplexedSessionForRW().runAsync(options);
296302
} catch (RuntimeException e) {
@@ -302,7 +308,7 @@ public AsyncRunner runAsync(TransactionOption... options) {
302308

303309
@Override
304310
public AsyncTransactionManager transactionManagerAsync(TransactionOption... options) {
305-
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, options);
311+
ISpan span = tracer.spanBuilder(READ_WRITE_TRANSACTION, commonAttributes, options);
306312
try (IScope s = tracer.withSpan(span)) {
307313
return getMultiplexedSessionForRW().transactionManagerAsync(options);
308314
} catch (RuntimeException e) {
@@ -322,7 +328,7 @@ public long executePartitionedUpdate(final Statement stmt, final UpdateOption...
322328

323329
private long executePartitionedUpdateWithPooledSession(
324330
final Statement stmt, final UpdateOption... options) {
325-
ISpan span = tracer.spanBuilder(PARTITION_DML_TRANSACTION);
331+
ISpan span = tracer.spanBuilder(PARTITION_DML_TRANSACTION, commonAttributes);
326332
try (IScope s = tracer.withSpan(span)) {
327333
return runWithSessionRetry(session -> session.executePartitionedUpdate(stmt, options));
328334
} catch (RuntimeException e) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionClient.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.common.base.Preconditions;
2626
import com.google.common.collect.ImmutableMap;
2727
import com.google.common.collect.Maps;
28+
import io.opentelemetry.api.common.Attributes;
2829
import java.util.ArrayList;
2930
import java.util.Collections;
3031
import java.util.List;
@@ -125,7 +126,8 @@ private BatchCreateSessionsRunnable(
125126
public void run() {
126127
List<SessionImpl> sessions;
127128
int remainingSessionsToCreate = sessionCount;
128-
ISpan span = spanner.getTracer().spanBuilder(SpannerImpl.BATCH_CREATE_SESSIONS);
129+
ISpan span =
130+
spanner.getTracer().spanBuilder(SpannerImpl.BATCH_CREATE_SESSIONS, commonAttributes);
129131
try (IScope s = spanner.getTracer().withSpan(span)) {
130132
spanner
131133
.getTracer()
@@ -170,6 +172,7 @@ interface SessionConsumer {
170172
private final ExecutorFactory<ScheduledExecutorService> executorFactory;
171173
private final ScheduledExecutorService executor;
172174
private final DatabaseId db;
175+
private final Attributes commonAttributes;
173176

174177
@GuardedBy("this")
175178
private volatile long sessionChannelCounter;
@@ -182,6 +185,7 @@ interface SessionConsumer {
182185
this.db = db;
183186
this.executorFactory = executorFactory;
184187
this.executor = executorFactory.get();
188+
this.commonAttributes = spanner.getTracer().createCommonAttributes(db);
185189
}
186190

187191
@Override
@@ -205,7 +209,7 @@ SessionImpl createSession() {
205209
synchronized (this) {
206210
options = optionMap(SessionOption.channelHint(sessionChannelCounter++));
207211
}
208-
ISpan span = spanner.getTracer().spanBuilder(SpannerImpl.CREATE_SESSION);
212+
ISpan span = spanner.getTracer().spanBuilder(SpannerImpl.CREATE_SESSION, this.commonAttributes);
209213
try (IScope s = spanner.getTracer().withSpan(span)) {
210214
com.google.spanner.v1.Session session =
211215
spanner
@@ -250,7 +254,10 @@ void createMultiplexedSession(SessionConsumer consumer) {
250254
* GRPC channel. In case of an error during the gRPC calls, an exception will be thrown.
251255
*/
252256
SessionImpl createMultiplexedSession() {
253-
ISpan span = spanner.getTracer().spanBuilder(SpannerImpl.CREATE_MULTIPLEXED_SESSION);
257+
ISpan span =
258+
spanner
259+
.getTracer()
260+
.spanBuilder(SpannerImpl.CREATE_MULTIPLEXED_SESSION, this.commonAttributes);
254261
try (IScope s = spanner.getTracer().withSpan(span)) {
255262
com.google.spanner.v1.Session session =
256263
spanner

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ public DatabaseClient getDatabaseClient(DatabaseId db) {
315315
getOptions().getSessionPoolOptions().getUseMultiplexedSessionBlindWrite(),
316316
multiplexedSessionDatabaseClient,
317317
getOptions().getSessionPoolOptions().getUseMultiplexedSessionPartitionedOps(),
318-
useMultiplexedSessionForRW);
318+
useMultiplexedSessionForRW,
319+
this.tracer.createCommonAttributes(db));
319320
dbClients.put(db, dbClient);
320321
return dbClient;
321322
}
@@ -329,15 +330,17 @@ DatabaseClientImpl createDatabaseClient(
329330
boolean useMultiplexedSessionBlindWrite,
330331
@Nullable MultiplexedSessionDatabaseClient multiplexedSessionClient,
331332
boolean useMultiplexedSessionPartitionedOps,
332-
boolean useMultiplexedSessionForRW) {
333+
boolean useMultiplexedSessionForRW,
334+
Attributes commonAttributes) {
333335
return new DatabaseClientImpl(
334336
clientId,
335337
pool,
336338
useMultiplexedSessionBlindWrite,
337339
multiplexedSessionClient,
338340
useMultiplexedSessionPartitionedOps,
339341
tracer,
340-
useMultiplexedSessionForRW);
342+
useMultiplexedSessionForRW,
343+
commonAttributes);
341344
}
342345

343346
@Override

google-cloud-spanner/src/main/java/com/google/cloud/spanner/TraceWrapper.java

+27-5
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ class TraceWrapper {
3838
AttributeKey.stringKey("transaction.tag");
3939
private static final AttributeKey<String> STATEMENT_TAG_KEY =
4040
AttributeKey.stringKey("statement.tag");
41+
private static final AttributeKey<String> INSTANCE_NAME_KEY =
42+
AttributeKey.stringKey("instance.name");
43+
private static final AttributeKey<String> DB_NAME_KEY = AttributeKey.stringKey("db.name");
4144
private static final AttributeKey<String> DB_STATEMENT_KEY =
4245
AttributeKey.stringKey("db.statement");
4346
private static final AttributeKey<List<String>> DB_STATEMENT_ARRAY_KEY =
4447
AttributeKey.stringArrayKey("db.statement");
48+
private static final AttributeKey<String> DB_TABLE_NAME_KEY = AttributeKey.stringKey("db.table");
4549
private static final AttributeKey<String> THREAD_NAME_KEY = AttributeKey.stringKey("thread.name");
4650

4751
private final Tracer openCensusTracer;
@@ -61,8 +65,8 @@ ISpan spanBuilder(String spanName) {
6165
return spanBuilder(spanName, Attributes.empty());
6266
}
6367

64-
ISpan spanBuilder(String spanName, TransactionOption... options) {
65-
return spanBuilder(spanName, createTransactionAttributes(options));
68+
ISpan spanBuilder(String spanName, Attributes commonAttributes, TransactionOption... options) {
69+
return spanBuilder(spanName, createTransactionAttributes(commonAttributes, options));
6670
}
6771

6872
ISpan spanBuilder(String spanName, Attributes attributes) {
@@ -137,18 +141,20 @@ IScope withSpan(ISpan span) {
137141
}
138142
}
139143

140-
Attributes createTransactionAttributes(TransactionOption... options) {
144+
Attributes createTransactionAttributes(
145+
Attributes commonAttributes, TransactionOption... options) {
146+
AttributesBuilder builder = commonAttributes.toBuilder();
141147
if (options != null && options.length > 0) {
142148
Optional<TagOption> tagOption =
143149
Arrays.stream(options)
144150
.filter(option -> option instanceof TagOption)
145151
.map(option -> (TagOption) option)
146152
.findAny();
147153
if (tagOption.isPresent()) {
148-
return Attributes.of(TRANSACTION_TAG_KEY, tagOption.get().getTag());
154+
builder.put(TRANSACTION_TAG_KEY, tagOption.get().getTag());
149155
}
150156
}
151-
return Attributes.empty();
157+
return builder.build();
152158
}
153159

154160
Attributes createStatementAttributes(Statement statement, Options options) {
@@ -185,6 +191,22 @@ Attributes createStatementBatchAttributes(Iterable<Statement> statements, Option
185191
return Attributes.empty();
186192
}
187193

194+
Attributes createTableAttributes(String tableName, Options options) {
195+
AttributesBuilder builder = Attributes.builder();
196+
builder.put(DB_TABLE_NAME_KEY, tableName);
197+
if (options != null && options.hasTag()) {
198+
builder.put(STATEMENT_TAG_KEY, options.tag());
199+
}
200+
return builder.build();
201+
}
202+
203+
Attributes createCommonAttributes(DatabaseId db) {
204+
AttributesBuilder builder = Attributes.builder();
205+
builder.put(DB_NAME_KEY, db.getDatabase());
206+
builder.put(INSTANCE_NAME_KEY, db.getInstanceId().getInstance());
207+
return builder.build();
208+
}
209+
188210
private static String getTraceThreadName() {
189211
return MoreObjects.firstNonNull(
190212
Context.current().get(OpenTelemetryContextKeys.THREAD_NAME_KEY),

google-cloud-spanner/src/test/java/com/google/cloud/spanner/IntegrationTestWithClosedSessionsEnv.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.cloud.spanner.SessionPool.PooledSessionFuture;
2121
import com.google.cloud.spanner.SessionPool.SessionFutureWrapper;
2222
import com.google.cloud.spanner.testing.RemoteSpannerHelper;
23+
import io.opentelemetry.api.common.Attributes;
2324

2425
/**
2526
* Subclass of {@link IntegrationTestEnv} that allows the user to specify when the underlying
@@ -52,7 +53,8 @@ DatabaseClientImpl createDatabaseClient(
5253
boolean useMultiplexedSessionBlindWriteIgnore,
5354
MultiplexedSessionDatabaseClient ignore,
5455
boolean useMultiplexedSessionPartitionedOpsIgnore,
55-
boolean useMultiplexedSessionForRWIgnore) {
56+
boolean useMultiplexedSessionForRWIgnore,
57+
Attributes attributes) {
5658
return new DatabaseClientWithClosedSessionImpl(clientId, pool, tracer);
5759
}
5860
}

0 commit comments

Comments
 (0)