Skip to content

Commit 9df99b3

Browse files
committed
afe_env and unit tests
1 parent 21dddef commit 9df99b3

9 files changed

+150
-51
lines changed

google-cloud-spanner/clirr-ignored-differences.xml

+12-5
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,13 @@
751751
<method>boolean isEnableBuiltInMetrics()</method>
752752
</difference>
753753

754+
<!-- Added AFE Server Timing option -->
755+
<difference>
756+
<differenceType>7012</differenceType>
757+
<className>com/google/cloud/spanner/SpannerOptions$SpannerEnvironment</className>
758+
<method>boolean isEnableAFEServerTiming()</method>
759+
</difference>
760+
754761
<!-- Added Monitoring host option -->
755762
<difference>
756763
<differenceType>7012</differenceType>
@@ -807,7 +814,7 @@
807814
<className>com/google/cloud/spanner/connection/Connection</className>
808815
<method>boolean isKeepTransactionAlive()</method>
809816
</difference>
810-
817+
811818
<!-- Automatic DML batching -->
812819
<difference>
813820
<differenceType>7012</differenceType>
@@ -839,7 +846,7 @@
839846
<className>com/google/cloud/spanner/connection/Connection</className>
840847
<method>boolean isAutoBatchDmlUpdateCountVerification()</method>
841848
</difference>
842-
849+
843850
<!-- Retry DML as Partitioned DML -->
844851
<difference>
845852
<differenceType>7012</differenceType>
@@ -863,7 +870,7 @@
863870
<className>com/google/cloud/spanner/connection/Connection</className>
864871
<method>java.lang.Object runTransaction(com.google.cloud.spanner.connection.Connection$TransactionCallable)</method>
865872
</difference>
866-
873+
867874
<!-- Added experimental host option -->
868875
<difference>
869876
<differenceType>7012</differenceType>
@@ -892,7 +899,7 @@
892899
<className>com/google/cloud/spanner/connection/Connection</className>
893900
<method>java.lang.String getDefaultSequenceKind()</method>
894901
</difference>
895-
902+
896903
<!-- Default isolation level -->
897904
<difference>
898905
<differenceType>7012</differenceType>
@@ -927,5 +934,5 @@
927934
<className>com/google/cloud/spanner/connection/ConnectionOptions</className>
928935
<field>VALID_PROPERTIES</field>
929936
</difference>
930-
937+
931938
</differences>

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

+14-6
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,24 @@ class BuiltInMetricsRecorder extends OpenTelemetryMetricsRecorder {
9595
* @param attributes Map of the attributes to store
9696
*/
9797
void recordServerTimingHeaderMetrics(
98-
double gfeLatency,
99-
double afeLatency,
98+
Long gfeLatency,
99+
Long afeLatency,
100100
Long gfeHeaderMissingCount,
101101
Long afeHeaderMissingCount,
102102
Map<String, String> attributes) {
103103
io.opentelemetry.api.common.Attributes otelAttributes = toOtelAttributes(attributes);
104-
gfeLatencyRecorder.record(gfeLatency, otelAttributes);
105-
gfeHeaderMissingCountRecorder.add(gfeHeaderMissingCount, otelAttributes);
106-
afeLatencyRecorder.record(afeLatency, otelAttributes);
107-
afeHeaderMissingCountRecorder.add(afeHeaderMissingCount, otelAttributes);
104+
if (gfeLatency != null) {
105+
gfeLatencyRecorder.record(gfeLatency, otelAttributes);
106+
}
107+
if (gfeHeaderMissingCount > 0) {
108+
gfeHeaderMissingCountRecorder.add(gfeHeaderMissingCount, otelAttributes);
109+
}
110+
if (afeLatency != null) {
111+
afeLatencyRecorder.record(afeLatency, otelAttributes);
112+
}
113+
if (afeHeaderMissingCount > 0) {
114+
afeHeaderMissingCountRecorder.add(afeHeaderMissingCount, otelAttributes);
115+
}
108116
}
109117

110118
Attributes toOtelAttributes(Map<String, String> attributes) {

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

+15-29
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,9 @@ class BuiltInMetricsTracer extends MetricsTracer implements ApiTracer {
3737
private final BuiltInMetricsRecorder builtInOpenTelemetryMetricsRecorder;
3838
// These are RPC specific attributes and pertain to a specific API Trace
3939
private final Map<String, String> attributes = new HashMap<>();
40-
4140
private Long gfeLatency = null;
42-
4341
private Long afeLatency = null;
44-
4542
private long gfeHeaderMissingCount = 0;
46-
4743
private long afeHeaderMissingCount = 0;
4844

4945
BuiltInMetricsTracer(
@@ -60,11 +56,9 @@ class BuiltInMetricsTracer extends MetricsTracer implements ApiTracer {
6056
@Override
6157
public void attemptSucceeded() {
6258
super.attemptSucceeded();
63-
if (gfeLatency != null) {
64-
attributes.put(STATUS_ATTRIBUTE, StatusCode.Code.OK.toString());
65-
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
66-
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
67-
}
59+
attributes.put(STATUS_ATTRIBUTE, StatusCode.Code.OK.toString());
60+
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
61+
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
6862
}
6963

7064
/**
@@ -74,11 +68,9 @@ public void attemptSucceeded() {
7468
@Override
7569
public void attemptCancelled() {
7670
super.attemptCancelled();
77-
if (gfeLatency != null) {
78-
attributes.put(STATUS_ATTRIBUTE, StatusCode.Code.CANCELLED.toString());
79-
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
80-
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
81-
}
71+
attributes.put(STATUS_ATTRIBUTE, StatusCode.Code.CANCELLED.toString());
72+
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
73+
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
8274
}
8375

8476
/**
@@ -92,11 +84,9 @@ public void attemptCancelled() {
9284
@Override
9385
public void attemptFailedDuration(Throwable error, java.time.Duration delay) {
9486
super.attemptFailedDuration(error, delay);
95-
if (gfeLatency != null) {
96-
attributes.put(STATUS_ATTRIBUTE, extractStatus(error));
97-
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
98-
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
99-
}
87+
attributes.put(STATUS_ATTRIBUTE, extractStatus(error));
88+
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
89+
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
10090
}
10191

10292
/**
@@ -109,11 +99,9 @@ public void attemptFailedDuration(Throwable error, java.time.Duration delay) {
10999
@Override
110100
public void attemptFailedRetriesExhausted(Throwable error) {
111101
super.attemptFailedRetriesExhausted(error);
112-
if (gfeLatency != null) {
113-
attributes.put(STATUS_ATTRIBUTE, extractStatus(error));
114-
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
115-
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
116-
}
102+
attributes.put(STATUS_ATTRIBUTE, extractStatus(error));
103+
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
104+
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
117105
}
118106

119107
/**
@@ -126,11 +114,9 @@ public void attemptFailedRetriesExhausted(Throwable error) {
126114
@Override
127115
public void attemptPermanentFailure(Throwable error) {
128116
super.attemptPermanentFailure(error);
129-
if (gfeLatency != null) {
130-
attributes.put(STATUS_ATTRIBUTE, extractStatus(error));
131-
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
132-
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
133-
}
117+
attributes.put(STATUS_ATTRIBUTE, extractStatus(error));
118+
builtInOpenTelemetryMetricsRecorder.recordServerTimingHeaderMetrics(
119+
gfeLatency, afeLatency, gfeHeaderMissingCount, afeHeaderMissingCount, attributes);
134120
}
135121

136122
void recordGFELatency(Long gfeLatency) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java

+7
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,10 @@ private static boolean isEmulatorEnabled(SpannerOptions options, String emulator
683683
&& options.getHost().endsWith(emulatorHost);
684684
}
685685

686+
public static boolean isEnableAFEServerTiming() {
687+
return !Boolean.parseBoolean(System.getenv("SPANNER_DISABLE_AFE_SERVER_TIMING"));
688+
}
689+
686690
private static final RetrySettings ADMIN_REQUESTS_LIMIT_EXCEEDED_RETRY_SETTINGS =
687691
RetrySettings.newBuilder()
688692
.setInitialRetryDelayDuration(Duration.ofSeconds(5L))
@@ -2030,6 +2034,9 @@ <ReqT, RespT> GrpcCallContext newCallContext(
20302034
if (endToEndTracingEnabled) {
20312035
context = context.withExtraHeaders(metadataProvider.newEndToEndTracingHeader());
20322036
}
2037+
if (isEnableAFEServerTiming()) {
2038+
context = context.withExtraHeaders(metadataProvider.newAfeServerTimingHeader());
2039+
}
20332040
if (callCredentialsProvider != null) {
20342041
CallCredentials callCredentials = callCredentialsProvider.getCallCredentials();
20352042
if (callCredentials != null) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/HeaderInterceptor.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -173,22 +173,19 @@ private void processHeader(
173173
if (compositeTracer != null) {
174174
compositeTracer.recordGFELatency(gfeLatency);
175175
}
176-
177176
if (span != null) {
178177
span.setAttribute("gfe_latency", String.valueOf(gfeLatency));
179178
}
180179
} else {
181180
measureMap.put(SPANNER_GFE_HEADER_MISSING_COUNT, 1L).record(tagContext);
182181
spannerRpcMetrics.recordGfeHeaderMissingCount(1L, attributes);
183-
184182
if (compositeTracer != null) {
185183
compositeTracer.recordGfeHeaderMissingCount(1L);
186184
}
187185
}
188186

189-
// Record AFE latency
190-
// TODO: Add condition to check if AFE is enabled
191-
if (compositeTracer != null) {
187+
// Record AFE metrics
188+
if (compositeTracer != null && GapicSpannerRpc.isEnableAFEServerTiming()) {
192189
if (serverTimingMetrics.containsKey(AFE_TIMING_HEADER)) {
193190
long afeLatency = serverTimingMetrics.get(AFE_TIMING_HEADER);
194191
compositeTracer.recordAFELatency(afeLatency);

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/SpannerMetadataProvider.java

+8
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class SpannerMetadataProvider {
3838
private final String resourceHeaderKey;
3939
private static final String ROUTE_TO_LEADER_HEADER_KEY = "x-goog-spanner-route-to-leader";
4040
private static final String END_TO_END_TRACING_HEADER_KEY = "x-goog-spanner-end-to-end-tracing";
41+
private static final String AFE_SERVER_TIMING_HEADER_KEY =
42+
"x-goog-spanner-enable-afe-server-timing";
4143
private static final Pattern[] RESOURCE_TOKEN_PATTERNS = {
4244
Pattern.compile("^(?<headerValue>projects/[^/]*/instances/[^/]*/databases/[^/]*)(.*)?"),
4345
Pattern.compile("^(?<headerValue>projects/[^/]*/instances/[^/]*)(.*)?")
@@ -47,6 +49,8 @@ class SpannerMetadataProvider {
4749
ImmutableMap.of(ROUTE_TO_LEADER_HEADER_KEY, Collections.singletonList("true"));
4850
private static final Map<String, List<String>> END_TO_END_TRACING_HEADER_MAP =
4951
ImmutableMap.of(END_TO_END_TRACING_HEADER_KEY, Collections.singletonList("true"));
52+
private static final Map<String, List<String>> AFE_SERVER_TIMING_HEADER_MAP =
53+
ImmutableMap.of(AFE_SERVER_TIMING_HEADER_KEY, Collections.singletonList("true"));
5054

5155
private SpannerMetadataProvider(Map<String, String> headers, String resourceHeaderKey) {
5256
this.resourceHeaderKey = resourceHeaderKey;
@@ -96,6 +100,10 @@ Map<String, List<String>> newEndToEndTracingHeader() {
96100
return END_TO_END_TRACING_HEADER_MAP;
97101
}
98102

103+
Map<String, List<String>> newAfeServerTimingHeader() {
104+
return AFE_SERVER_TIMING_HEADER_MAP;
105+
}
106+
99107
private Map<Metadata.Key<String>, String> constructHeadersAsMetadata(
100108
Map<String, String> headers) {
101109
ImmutableMap.Builder<Metadata.Key<String>, String> headersAsMetadataBuilder =

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ abstract class AbstractNettyMockServerTest {
4747
protected static AtomicInteger fakeServerTiming =
4848
new AtomicInteger(new Random().nextInt(1000) + 1);
4949

50+
protected static AtomicInteger fakeAFEServerTiming =
51+
new AtomicInteger(new Random().nextInt(500) + 1);
52+
5053
protected Spanner spanner;
5154

5255
@BeforeClass
@@ -72,7 +75,9 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
7275
public void sendHeaders(Metadata headers) {
7376
headers.put(
7477
Metadata.Key.of("server-timing", Metadata.ASCII_STRING_MARSHALLER),
75-
String.format("gfet4t7; dur=%d", fakeServerTiming.get()));
78+
String.format(
79+
"afet4t7; dur=%d, gfet4t7; dur=%d",
80+
fakeAFEServerTiming.get(), fakeServerTiming.get()));
7681
super.sendHeaders(headers);
7782
}
7883
},

0 commit comments

Comments
 (0)