Skip to content

Commit 398933f

Browse files
feat: add downstream write latency to bigtableproxy (#9790)
NOTE: this depends on and includes https://togithub.com/GoogleCloudPlatform/java-docs-samples/pull/9789
1 parent 40877f9 commit 398933f

File tree

6 files changed

+36
-0
lines changed

6 files changed

+36
-0
lines changed

bigtable/bigtable-proxy/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ in a project your choosing. The metrics will be published under the namespace
4545
Cloud Bigtable service.
4646
* `bigtableproxy.client.gfe.duration_missing.count` Count of calls missing gfe response headers
4747
* `bigtableproxy.client.call.duration` Total duration of how long the outbound call took
48+
* `bigtableproxy.server.write_wait.duration` Total amount of time spent waiting for the downstream
49+
client to be ready for data.
4850
* `bigtableproxy.client.channel.count` Number of open channels
4951
* `bigtableproxy.client.channel_change_count` Number of channel transitions by previous and next
5052
states.

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/core/CallProxy.java

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud.bigtable.examples.proxy.core;
1818

1919
import com.google.cloud.bigtable.examples.proxy.metrics.Tracer;
20+
import com.google.common.base.Stopwatch;
2021
import io.grpc.ClientCall;
2122
import io.grpc.Metadata;
2223
import io.grpc.ServerCall;
@@ -30,6 +31,8 @@ class CallProxy<ReqT, RespT> {
3031
final RequestProxy serverCallListener;
3132
final ResponseProxy clientCallListener;
3233

34+
private final Stopwatch downstreamStopwatch = Stopwatch.createUnstarted();
35+
3336
/**
3437
* @param tracer a lifecycle observer to publish metrics.
3538
* @param serverCall the incoming server call. This will be triggered a customer client.
@@ -157,6 +160,7 @@ public void onMessage(RespT message) {
157160
// The incoming call is not ready for more responses. Stop requesting additional data
158161
// and wait for it to catch up.
159162
needToRequest = true;
163+
downstreamStopwatch.reset().start();
160164
}
161165
}
162166
}
@@ -169,6 +173,10 @@ public void onReady() {
169173
// Called from RequestProxy, which is a different thread than the ClientCall.Listener
170174
// callbacks.
171175
synchronized void onServerReady() {
176+
if (downstreamStopwatch.isRunning()) {
177+
tracer.onDownstreamLatency(downstreamStopwatch.elapsed());
178+
downstreamStopwatch.stop();
179+
}
172180
if (needToRequest) {
173181
serverCallListener.clientCall.request(1);
174182
needToRequest = false;

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/metrics/Metrics.java

+2
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,7 @@ public interface Metrics {
4848

4949
void recordChannelStateChange(ConnectivityState prevState, ConnectivityState newState);
5050

51+
void recordDownstreamLatency(MetricsAttributes attrs, Duration latency);
52+
5153
interface MetricsAttributes {}
5254
}

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/metrics/MetricsImpl.java

+15
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public class MetricsImpl implements Closeable, Metrics {
9595
private final DoubleHistogram clientQueueLatencies;
9696
private final DoubleHistogram clientCallLatencies;
9797
private final DoubleHistogram clientCallFirstByteLatencies;
98+
private final DoubleHistogram downstreamLatencies;
9899
private final LongCounter serverCallsStarted;
99100
private final LongHistogram requestSizes;
100101
private final LongHistogram responseSizes;
@@ -211,6 +212,15 @@ private static SdkMeterProvider createMeterProvider(Credentials credentials, Str
211212
.setUnit("ms")
212213
.build();
213214

215+
downstreamLatencies =
216+
meter
217+
.histogramBuilder(METRIC_PREFIX + "server.write_wait.duration")
218+
.setDescription(
219+
"Total amount of time spent waiting for the downstream client to be"
220+
+ " ready for data")
221+
.setUnit("ms")
222+
.build();
223+
214224
channelCounter =
215225
meter
216226
.upDownCounterBuilder(METRIC_PREFIX + "client.channel.count")
@@ -352,6 +362,11 @@ public void recordChannelStateChange(ConnectivityState prevState, ConnectivitySt
352362
channelStateChangeCounter.add(1, attributes);
353363
}
354364

365+
@Override
366+
public void recordDownstreamLatency(MetricsAttributes attrs, Duration latency) {
367+
downstreamLatencies.record(toMs(latency), unwrap(attrs));
368+
}
369+
355370
private static double toMs(Duration duration) {
356371
return duration.toNanos() / 1_000_000.0;
357372
}

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/metrics/Tracer.java

+6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class Tracer extends ClientStreamTracer {
5151
private final Stopwatch stopwatch;
5252
private volatile Optional<Duration> grpcQueueDuration = Optional.empty();
5353
private final AtomicLong responseSize = new AtomicLong();
54+
private volatile Duration downstreamLatency;
5455

5556
public Tracer(Metrics metrics, CallLabels callLabels) {
5657
this.metrics = metrics;
@@ -116,6 +117,7 @@ public void inboundMessage(int seqNo) {
116117

117118
public void onCallFinished(Status status) {
118119
grpcQueueDuration.ifPresent(d -> metrics.recordQueueLatency(attrs, d));
120+
metrics.recordDownstreamLatency(attrs, downstreamLatency);
119121
metrics.recordResponseSize(attrs, responseSize.get());
120122
metrics.recordCallLatency(
121123
attrs, status, Duration.ofMillis(stopwatch.elapsed(TimeUnit.MILLISECONDS)));
@@ -128,4 +130,8 @@ public void onCredentialsFetch(Status status, Duration duration) {
128130
public CallLabels getCallLabels() {
129131
return callLabels;
130132
}
133+
134+
public void onDownstreamLatency(Duration latency) {
135+
downstreamLatency = downstreamLatency.plus(latency);
136+
}
131137
}

bigtable/bigtable-proxy/src/test/java/com/google/cloud/bigtable/examples/proxy/metrics/NoopMetrics.java

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public void recordCallLatency(MetricsAttributes attrs, Status status, Duration d
5555
@Override
5656
public void recordFirstByteLatency(MetricsAttributes attrs, Duration duration) {}
5757

58+
@Override
59+
public void recordDownstreamLatency(MetricsAttributes attrs, Duration latency) {}
60+
5861
@Override
5962
public void updateChannelCount(int delta) {}
6063

0 commit comments

Comments
 (0)