Skip to content

Commit dcaa152

Browse files
feat: add channel state transition counter (GoogleCloudPlatform#9755)
NOTE: this depends on and includes https://togithub.com/GoogleCloudPlatform/java-docs-samples/pull/9754
1 parent 305697c commit dcaa152

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

bigtable/bigtable-proxy/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ in a project your choosing. The metrics will be published under the namespace
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
4848
* `bigtableproxy.client.channel.count` Number of open channels
49+
* `bigtableproxy.client.channel_change_count` Number of channel transitions by previous and next
50+
states.
4951
* `bigtableproxy.client.call.max_outstanding_count` Maximum number of concurrent RPCs in a single
5052
minute window
5153
* `bigtableproxy.presence` Counts number of proxy processes (emit 1 per process).

bigtable/bigtable-proxy/src/main/java/com/google/cloud/bigtable/examples/proxy/channelpool/DataChannel.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ public DataChannel(
100100
this.warmingExecutor = warmingExecutor;
101101
this.metrics = metrics;
102102

103+
new StateTransitionWatcher().run();
104+
103105
try {
104106
warm();
105107
} catch (RuntimeException e) {
@@ -366,4 +368,20 @@ public <RequestT, ResponseT> ClientCall<RequestT, ResponseT> newCall(
366368
public String authority() {
367369
return inner.authority();
368370
}
371+
372+
class StateTransitionWatcher implements Runnable {
373+
private ConnectivityState prevState = null;
374+
375+
@Override
376+
public void run() {
377+
if (closed.get()) {
378+
return;
379+
}
380+
381+
ConnectivityState newState = inner.getState(false);
382+
metrics.recordChannelStateChange(prevState, newState);
383+
prevState = newState;
384+
inner.notifyWhenStateChanged(prevState, this);
385+
}
386+
}
369387
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.google.cloud.bigtable.examples.proxy.core.CallLabels;
2020
import com.google.cloud.bigtable.examples.proxy.metrics.Metrics.MetricsAttributes;
21+
import io.grpc.ConnectivityState;
2122
import io.grpc.Status;
2223
import java.time.Duration;
2324

@@ -45,5 +46,7 @@ public interface Metrics {
4546

4647
void updateChannelCount(int delta);
4748

49+
void recordChannelStateChange(ConnectivityState prevState, ConnectivityState newState);
50+
4851
interface MetricsAttributes {}
4952
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.cloud.opentelemetry.metric.MetricConfiguration;
2525
import com.google.common.annotations.VisibleForTesting;
2626
import com.google.common.collect.ImmutableList;
27+
import io.grpc.ConnectivityState;
2728
import io.grpc.Status;
2829
import io.opentelemetry.api.OpenTelemetry;
2930
import io.opentelemetry.api.common.AttributeKey;
@@ -51,6 +52,7 @@
5152
import java.time.Duration;
5253
import java.time.Instant;
5354
import java.time.temporal.ChronoUnit;
55+
import java.util.Optional;
5456
import java.util.concurrent.TimeUnit;
5557
import java.util.concurrent.atomic.AtomicInteger;
5658
import org.slf4j.Logger;
@@ -76,6 +78,11 @@ public class MetricsImpl implements Closeable, Metrics {
7678
private static final AttributeKey<String> METHOD_KEY = AttributeKey.stringKey("method");
7779
private static final AttributeKey<String> STATUS_KEY = AttributeKey.stringKey("status");
7880

81+
private static final AttributeKey<String> PREV_CHANNEL_STATE =
82+
AttributeKey.stringKey("prev_state");
83+
private static final AttributeKey<String> CURRENT_CHANNEL_STATE =
84+
AttributeKey.stringKey("current_state");
85+
7986
private static final String METRIC_PRESENCE_NAME = METRIC_PREFIX + "presence";
8087
private static final String METRIC_PRESENCE_DESC = "Number of proxy processes";
8188
private static final String METRIC_PRESENCE_UNIT = "{process}";
@@ -91,6 +98,7 @@ public class MetricsImpl implements Closeable, Metrics {
9198
private final LongCounter serverCallsStarted;
9299
private final LongHistogram requestSizes;
93100
private final LongHistogram responseSizes;
101+
private final LongCounter channelStateChangeCounter;
94102

95103
private final ObservableLongGauge outstandingRpcCountGauge;
96104
private final ObservableLongGauge presenceGauge;
@@ -225,6 +233,13 @@ private static SdkMeterProvider createMeterProvider(Credentials credentials, Str
225233
.setUnit(METRIC_PRESENCE_UNIT)
226234
.ofLongs()
227235
.buildWithCallback(o -> o.record(1));
236+
237+
channelStateChangeCounter =
238+
meter
239+
.counterBuilder(METRIC_PREFIX + "client.channel_change_count")
240+
.setDescription("Counter of channel state transitions")
241+
.setUnit("{change}")
242+
.build();
228243
}
229244

230245
@Override
@@ -324,6 +339,19 @@ public void updateChannelCount(int delta) {
324339
channelCounter.add(delta);
325340
}
326341

342+
@Override
343+
public void recordChannelStateChange(ConnectivityState prevState, ConnectivityState newState) {
344+
Attributes attributes =
345+
Attributes.builder()
346+
.put(
347+
PREV_CHANNEL_STATE, Optional.ofNullable(prevState).map(Enum::name).orElse("<null>"))
348+
.put(
349+
CURRENT_CHANNEL_STATE,
350+
Optional.ofNullable(newState).map(Enum::name).orElse("<null>"))
351+
.build();
352+
channelStateChangeCounter.add(1, attributes);
353+
}
354+
327355
private static Attributes unwrap(MetricsAttributes wrapped) {
328356
return ((MetricsAttributesImpl) wrapped).getAttributes();
329357
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud.bigtable.examples.proxy.metrics;
1818

1919
import com.google.cloud.bigtable.examples.proxy.core.CallLabels;
20+
import io.grpc.ConnectivityState;
2021
import io.grpc.Status;
2122
import java.time.Duration;
2223

@@ -56,4 +57,7 @@ public void recordFirstByteLatency(MetricsAttributes attrs, Duration duration) {
5657

5758
@Override
5859
public void updateChannelCount(int delta) {}
60+
61+
@Override
62+
public void recordChannelStateChange(ConnectivityState prevState, ConnectivityState newState) {}
5963
}

0 commit comments

Comments
 (0)