com.google.cloud.spanner.TraceWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of google-cloud-spanner Show documentation
Show all versions of google-cloud-spanner Show documentation
Java idiomatic client for Google Cloud Spanner.
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.spanner;
import com.google.cloud.spanner.Options.TagOption;
import com.google.cloud.spanner.Options.TransactionOption;
import com.google.cloud.spanner.SpannerOptions.TracingFramework;
import com.google.common.base.MoreObjects;
import io.opencensus.trace.BlankSpan;
import io.opencensus.trace.Span;
import io.opencensus.trace.Tracer;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
class TraceWrapper {
private static final AttributeKey TRANSACTION_TAG_KEY =
AttributeKey.stringKey("transaction.tag");
private static final AttributeKey STATEMENT_TAG_KEY =
AttributeKey.stringKey("statement.tag");
private static final AttributeKey DB_STATEMENT_KEY =
AttributeKey.stringKey("db.statement");
private static final AttributeKey> DB_STATEMENT_ARRAY_KEY =
AttributeKey.stringArrayKey("db.statement");
private static final AttributeKey THREAD_NAME_KEY = AttributeKey.stringKey("thread.name");
private final Tracer openCensusTracer;
private final io.opentelemetry.api.trace.Tracer openTelemetryTracer;
private final boolean enableExtendedTracing;
TraceWrapper(
Tracer openCensusTracer,
io.opentelemetry.api.trace.Tracer openTelemetryTracer,
boolean enableExtendedTracing) {
this.openTelemetryTracer = openTelemetryTracer;
this.openCensusTracer = openCensusTracer;
this.enableExtendedTracing = enableExtendedTracing;
}
ISpan spanBuilder(String spanName) {
return spanBuilder(spanName, Attributes.empty());
}
ISpan spanBuilder(String spanName, TransactionOption... options) {
return spanBuilder(spanName, createTransactionAttributes(options));
}
ISpan spanBuilder(String spanName, Attributes attributes) {
if (SpannerOptions.getActiveTracingFramework().equals(TracingFramework.OPEN_TELEMETRY)) {
return new OpenTelemetrySpan(
openTelemetryTracer.spanBuilder(spanName).setAllAttributes(attributes).startSpan());
} else {
return new OpenCensusSpan(openCensusTracer.spanBuilder(spanName).startSpan());
}
}
ISpan spanBuilderWithExplicitParent(String spanName, ISpan parentSpan) {
return spanBuilderWithExplicitParent(spanName, parentSpan, Attributes.empty());
}
ISpan spanBuilderWithExplicitParent(String spanName, ISpan parentSpan, Attributes attributes) {
if (SpannerOptions.getActiveTracingFramework().equals(TracingFramework.OPEN_TELEMETRY)) {
OpenTelemetrySpan otParentSpan = (OpenTelemetrySpan) parentSpan;
io.opentelemetry.api.trace.SpanBuilder otSpan =
openTelemetryTracer.spanBuilder(spanName).setAllAttributes(attributes);
if (otParentSpan != null && otParentSpan.getOpenTelemetrySpan() != null) {
otSpan = otSpan.setParent(Context.current().with(otParentSpan.getOpenTelemetrySpan()));
}
return new OpenTelemetrySpan(otSpan.startSpan());
} else {
OpenCensusSpan parentOcSpan = (OpenCensusSpan) parentSpan;
Span ocSpan =
openCensusTracer
.spanBuilderWithExplicitParent(
spanName, parentOcSpan != null ? parentOcSpan.getOpenCensusSpan() : null)
.startSpan();
return new OpenCensusSpan(ocSpan);
}
}
ISpan getCurrentSpan() {
if (SpannerOptions.getActiveTracingFramework().equals(TracingFramework.OPEN_TELEMETRY)) {
return new OpenTelemetrySpan(
io.opentelemetry.api.trace.Span.fromContext(io.opentelemetry.context.Context.current()));
} else {
return new OpenCensusSpan(openCensusTracer.getCurrentSpan());
}
}
ISpan getBlankSpan() {
if (SpannerOptions.getActiveTracingFramework().equals(TracingFramework.OPEN_TELEMETRY)) {
return new OpenTelemetrySpan(io.opentelemetry.api.trace.Span.getInvalid());
} else {
return new OpenCensusSpan(BlankSpan.INSTANCE);
}
}
IScope withSpan(ISpan span) {
if (SpannerOptions.getActiveTracingFramework().equals(TracingFramework.OPEN_TELEMETRY)) {
OpenTelemetrySpan openTelemetrySpan;
if (!(span instanceof OpenTelemetrySpan)) {
openTelemetrySpan = new OpenTelemetrySpan(null);
} else {
openTelemetrySpan = (OpenTelemetrySpan) span;
}
return new OpenTelemetryScope(openTelemetrySpan.getOpenTelemetrySpan().makeCurrent());
} else {
OpenCensusSpan openCensusSpan;
if (!(span instanceof OpenCensusSpan)) {
openCensusSpan = new OpenCensusSpan(null);
} else {
openCensusSpan = (OpenCensusSpan) span;
}
return new OpenCensusScope(openCensusTracer.withSpan(openCensusSpan.getOpenCensusSpan()));
}
}
Attributes createTransactionAttributes(TransactionOption... options) {
if (options != null && options.length > 0) {
Optional tagOption =
Arrays.stream(options)
.filter(option -> option instanceof TagOption)
.map(option -> (TagOption) option)
.findAny();
if (tagOption.isPresent()) {
return Attributes.of(TRANSACTION_TAG_KEY, tagOption.get().getTag());
}
}
return Attributes.empty();
}
Attributes createStatementAttributes(Statement statement, Options options) {
if (this.enableExtendedTracing || (options != null && options.hasTag())) {
AttributesBuilder builder = Attributes.builder();
if (this.enableExtendedTracing) {
builder.put(DB_STATEMENT_KEY, statement.getSql());
builder.put(THREAD_NAME_KEY, getTraceThreadName());
}
if (options != null && options.hasTag()) {
builder.put(STATEMENT_TAG_KEY, options.tag());
}
return builder.build();
}
return Attributes.empty();
}
Attributes createStatementBatchAttributes(Iterable statements, Options options) {
if (this.enableExtendedTracing || (options != null && options.hasTag())) {
AttributesBuilder builder = Attributes.builder();
if (this.enableExtendedTracing) {
builder.put(
DB_STATEMENT_ARRAY_KEY,
StreamSupport.stream(statements.spliterator(), false)
.map(Statement::getSql)
.collect(Collectors.toList()));
builder.put(THREAD_NAME_KEY, getTraceThreadName());
}
if (options != null && options.hasTag()) {
builder.put(STATEMENT_TAG_KEY, options.tag());
}
return builder.build();
}
return Attributes.empty();
}
private static String getTraceThreadName() {
return MoreObjects.firstNonNull(
Context.current().get(OpenTelemetryContextKeys.THREAD_NAME_KEY),
Thread.currentThread().getName());
}
}