Skip to content

Commit 3a7a8ad

Browse files
authored
feat: add num_sessions_in_pool metric (#128)
* feat: add num_sessions_in_pool metric * add tests
1 parent 0e58788 commit 3a7a8ad

File tree

4 files changed

+200
-63
lines changed

4 files changed

+200
-63
lines changed

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,21 @@ class MetricRegistryConstants {
3030
LabelKey.create("instance_id", "Name of the instance");
3131
private static final LabelKey LIBRARY_VERSION =
3232
LabelKey.create("library_version", "Library version");
33+
private static final LabelKey SESSION_TYPE = LabelKey.create("Type", "Type of the Sessions");
3334

3435
/** The label value is used to represent missing value. */
3536
private static final LabelValue UNSET_LABEL = LabelValue.create(null);
3637

38+
static final LabelValue NUM_IN_USE_SESSIONS = LabelValue.create("num_in_use_sessions");
39+
static final LabelValue NUM_SESSIONS_BEING_PREPARED =
40+
LabelValue.create("num_sessions_being_prepared");
41+
static final LabelValue NUM_READ_SESSIONS = LabelValue.create("num_read_sessions");
42+
static final LabelValue NUM_WRITE_SESSIONS = LabelValue.create("num_write_prepared_sessions");
43+
3744
static final ImmutableList<LabelKey> SPANNER_LABEL_KEYS =
3845
ImmutableList.of(CLIENT_ID, DATABASE, INSTANCE_ID, LIBRARY_VERSION);
46+
static final ImmutableList<LabelKey> SPANNER_LABEL_KEYS_WITH_TYPE =
47+
ImmutableList.of(CLIENT_ID, DATABASE, INSTANCE_ID, LIBRARY_VERSION, SESSION_TYPE);
3948

4049
static final ImmutableList<LabelValue> SPANNER_DEFAULT_LABEL_VALUES =
4150
ImmutableList.of(UNSET_LABEL, UNSET_LABEL, UNSET_LABEL, UNSET_LABEL);
@@ -46,20 +55,20 @@ class MetricRegistryConstants {
4655
// The Metric name and description
4756
static final String MAX_IN_USE_SESSIONS = "cloud.google.com/java/spanner/max_in_use_sessions";
4857
static final String MAX_ALLOWED_SESSIONS = "cloud.google.com/java/spanner/max_allowed_sessions";
49-
static final String IN_USE_SESSIONS = "cloud.google.com/java/spanner/in_use_sessions";
5058
static final String GET_SESSION_TIMEOUTS = "cloud.google.com/java/spanner/get_session_timeouts";
5159
static final String NUM_ACQUIRED_SESSIONS = "cloud.google.com/java/spanner/num_acquired_sessions";
5260
static final String NUM_RELEASED_SESSIONS = "cloud.google.com/java/spanner/num_released_sessions";
61+
static final String NUM_SESSIONS_IN_POOL = "cloud.google.com/java/spanner/num_sessions_in_pool";
5362

5463
static final String MAX_IN_USE_SESSIONS_DESCRIPTION =
5564
"The maximum number of sessions in use during the last 10 minute interval.";
5665
static final String MAX_ALLOWED_SESSIONS_DESCRIPTION =
5766
"The maximum number of sessions allowed. Configurable by the user.";
58-
static final String IN_USE_SESSIONS_DESCRIPTION = "The number of sessions currently in use.";
5967
static final String SESSIONS_TIMEOUTS_DESCRIPTION =
6068
"The number of get sessions timeouts due to pool exhaustion";
6169
static final String NUM_ACQUIRED_SESSIONS_DESCRIPTION =
6270
"The number of sessions acquired from the session pool.";
6371
static final String NUM_RELEASED_SESSIONS_DESCRIPTION =
6472
"The number of sessions released by the user and pool maintainer.";
73+
static final String NUM_SESSIONS_IN_POOL_DESCRIPTION = "The number of sessions in the pool.";
6574
}

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

+65-23
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,24 @@
1818

1919
import static com.google.cloud.spanner.MetricRegistryConstants.COUNT;
2020
import static com.google.cloud.spanner.MetricRegistryConstants.GET_SESSION_TIMEOUTS;
21-
import static com.google.cloud.spanner.MetricRegistryConstants.IN_USE_SESSIONS;
22-
import static com.google.cloud.spanner.MetricRegistryConstants.IN_USE_SESSIONS_DESCRIPTION;
2321
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_ALLOWED_SESSIONS;
2422
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_ALLOWED_SESSIONS_DESCRIPTION;
2523
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_IN_USE_SESSIONS;
2624
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_IN_USE_SESSIONS_DESCRIPTION;
2725
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_ACQUIRED_SESSIONS;
2826
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_ACQUIRED_SESSIONS_DESCRIPTION;
27+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_IN_USE_SESSIONS;
28+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_READ_SESSIONS;
2929
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_RELEASED_SESSIONS;
3030
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_RELEASED_SESSIONS_DESCRIPTION;
31+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_SESSIONS_BEING_PREPARED;
32+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_SESSIONS_IN_POOL;
33+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_SESSIONS_IN_POOL_DESCRIPTION;
34+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_WRITE_SESSIONS;
3135
import static com.google.cloud.spanner.MetricRegistryConstants.SESSIONS_TIMEOUTS_DESCRIPTION;
3236
import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_DEFAULT_LABEL_VALUES;
3337
import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS;
38+
import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS_WITH_TYPE;
3439
import static com.google.cloud.spanner.SpannerExceptionFactory.newSpannerException;
3540

3641
import com.google.api.core.ApiFuture;
@@ -71,6 +76,7 @@
7176
import io.opencensus.trace.Status;
7277
import io.opencensus.trace.Tracer;
7378
import io.opencensus.trace.Tracing;
79+
import java.util.ArrayList;
7480
import java.util.Arrays;
7581
import java.util.HashSet;
7682
import java.util.Iterator;
@@ -2030,15 +2036,6 @@ private void initMetricsCollection(MetricRegistry metricRegistry, List<LabelValu
20302036
.setLabelKeys(SPANNER_LABEL_KEYS)
20312037
.build());
20322038

2033-
DerivedLongGauge numInUseSessionsMetric =
2034-
metricRegistry.addDerivedLongGauge(
2035-
IN_USE_SESSIONS,
2036-
MetricOptions.builder()
2037-
.setDescription(IN_USE_SESSIONS_DESCRIPTION)
2038-
.setUnit(COUNT)
2039-
.setLabelKeys(SPANNER_LABEL_KEYS)
2040-
.build());
2041-
20422039
DerivedLongCumulative sessionsTimeouts =
20432040
metricRegistry.addDerivedLongCumulative(
20442041
GET_SESSION_TIMEOUTS,
@@ -2066,6 +2063,15 @@ private void initMetricsCollection(MetricRegistry metricRegistry, List<LabelValu
20662063
.setLabelKeys(SPANNER_LABEL_KEYS)
20672064
.build());
20682065

2066+
DerivedLongGauge numSessionsInPoolMetric =
2067+
metricRegistry.addDerivedLongGauge(
2068+
NUM_SESSIONS_IN_POOL,
2069+
MetricOptions.builder()
2070+
.setDescription(NUM_SESSIONS_IN_POOL_DESCRIPTION)
2071+
.setUnit(COUNT)
2072+
.setLabelKeys(SPANNER_LABEL_KEYS_WITH_TYPE)
2073+
.build());
2074+
20692075
// The value of a maxSessionsInUse is observed from a callback function. This function is
20702076
// invoked whenever metrics are collected.
20712077
maxInUseSessionsMetric.createTimeSeries(
@@ -2090,18 +2096,6 @@ public long applyAsLong(SessionPoolOptions options) {
20902096
}
20912097
});
20922098

2093-
// The value of a numSessionsInUse is observed from a callback function. This function is
2094-
// invoked whenever metrics are collected.
2095-
numInUseSessionsMetric.createTimeSeries(
2096-
labelValues,
2097-
this,
2098-
new ToLongFunction<SessionPool>() {
2099-
@Override
2100-
public long applyAsLong(SessionPool sessionPool) {
2101-
return sessionPool.numSessionsInUse;
2102-
}
2103-
});
2104-
21052099
// The value of a numWaiterTimeouts is observed from a callback function. This function is
21062100
// invoked whenever metrics are collected.
21072101
sessionsTimeouts.createTimeSeries(
@@ -2133,5 +2127,53 @@ public long applyAsLong(SessionPool sessionPool) {
21332127
return sessionPool.numSessionsReleased;
21342128
}
21352129
});
2130+
2131+
List<LabelValue> labelValuesWithBeingPreparedType = new ArrayList<>(labelValues);
2132+
labelValuesWithBeingPreparedType.add(NUM_SESSIONS_BEING_PREPARED);
2133+
numSessionsInPoolMetric.createTimeSeries(
2134+
labelValuesWithBeingPreparedType,
2135+
this,
2136+
new ToLongFunction<SessionPool>() {
2137+
@Override
2138+
public long applyAsLong(SessionPool sessionPool) {
2139+
return sessionPool.numSessionsBeingPrepared;
2140+
}
2141+
});
2142+
2143+
List<LabelValue> labelValuesWithInUseType = new ArrayList<>(labelValues);
2144+
labelValuesWithInUseType.add(NUM_IN_USE_SESSIONS);
2145+
numSessionsInPoolMetric.createTimeSeries(
2146+
labelValuesWithInUseType,
2147+
this,
2148+
new ToLongFunction<SessionPool>() {
2149+
@Override
2150+
public long applyAsLong(SessionPool sessionPool) {
2151+
return sessionPool.numSessionsInUse;
2152+
}
2153+
});
2154+
2155+
List<LabelValue> labelValuesWithReadType = new ArrayList<>(labelValues);
2156+
labelValuesWithReadType.add(NUM_READ_SESSIONS);
2157+
numSessionsInPoolMetric.createTimeSeries(
2158+
labelValuesWithReadType,
2159+
this,
2160+
new ToLongFunction<SessionPool>() {
2161+
@Override
2162+
public long applyAsLong(SessionPool sessionPool) {
2163+
return sessionPool.readSessions.size();
2164+
}
2165+
});
2166+
2167+
List<LabelValue> labelValuesWithWriteType = new ArrayList<>(labelValues);
2168+
labelValuesWithWriteType.add(NUM_WRITE_SESSIONS);
2169+
numSessionsInPoolMetric.createTimeSeries(
2170+
labelValuesWithWriteType,
2171+
this,
2172+
new ToLongFunction<SessionPool>() {
2173+
@Override
2174+
public long applyAsLong(SessionPool sessionPool) {
2175+
return sessionPool.writePreparedSessions.size();
2176+
}
2177+
});
21362178
}
21372179
}

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

+33-19
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import io.opencensus.metrics.LongGauge;
3030
import io.opencensus.metrics.MetricOptions;
3131
import io.opencensus.metrics.MetricRegistry;
32+
import java.util.ArrayList;
3233
import java.util.List;
3334
import java.util.Map;
3435

@@ -37,36 +38,39 @@ class MetricRegistryTestUtils {
3738
static class PointWithFunction<T> {
3839
private final T ref;
3940
private final ToLongFunction<T> function;
41+
private final List<LabelKey> key;
42+
private final List<LabelValue> values;
4043

41-
PointWithFunction(T obj, ToLongFunction<T> function) {
44+
PointWithFunction(
45+
T obj, ToLongFunction<T> function, List<LabelKey> keys, List<LabelValue> values) {
4246
this.ref = obj;
4347
this.function = function;
48+
this.key = keys;
49+
this.values = values;
4450
}
4551

46-
long get() {
52+
long value() {
4753
return function.applyAsLong(ref);
4854
}
55+
56+
List<LabelKey> keys() {
57+
return key;
58+
}
59+
60+
List<LabelValue> values() {
61+
return values;
62+
}
4963
}
5064

5165
static class MetricsRecord {
52-
private final Map<String, PointWithFunction> metrics;
53-
private final Map<List<LabelKey>, List<LabelValue>> labels;
66+
private final Map<String, List<PointWithFunction>> metrics;
5467

5568
private MetricsRecord() {
5669
this.metrics = Maps.newHashMap();
57-
this.labels = Maps.newHashMap();
5870
}
5971

60-
Map<String, Number> getMetrics() {
61-
Map<String, Number> copy = Maps.newHashMap();
62-
for (Map.Entry<String, PointWithFunction> entry : metrics.entrySet()) {
63-
copy.put(entry.getKey(), entry.getValue().get());
64-
}
65-
return copy;
66-
}
67-
68-
Map<List<LabelKey>, List<LabelValue>> getLabels() {
69-
return this.labels;
72+
Map<String, List<PointWithFunction>> getMetrics() {
73+
return metrics;
7074
}
7175
}
7276

@@ -85,8 +89,13 @@ private FakeDerivedLongGauge(
8589
@Override
8690
public <T> void createTimeSeries(
8791
List<LabelValue> labelValues, T t, ToLongFunction<T> toLongFunction) {
88-
this.record.metrics.put(this.name, new PointWithFunction(t, toLongFunction));
89-
this.record.labels.put(this.labelKeys, labelValues);
92+
if (!this.record.metrics.containsKey(this.name)) {
93+
this.record.metrics.put(this.name, new ArrayList<PointWithFunction>());
94+
}
95+
this.record
96+
.metrics
97+
.get(this.name)
98+
.add(new PointWithFunction(t, toLongFunction, labelKeys, labelValues));
9099
}
91100

92101
@Override
@@ -111,8 +120,13 @@ private FakeDerivedLongCumulative(
111120
@Override
112121
public <T> void createTimeSeries(
113122
List<LabelValue> labelValues, T t, ToLongFunction<T> toLongFunction) {
114-
this.record.metrics.put(this.name, new PointWithFunction(t, toLongFunction));
115-
this.record.labels.put(this.labelKeys, labelValues);
123+
if (!this.record.metrics.containsKey(this.name)) {
124+
this.record.metrics.put(this.name, new ArrayList<PointWithFunction>());
125+
}
126+
this.record
127+
.metrics
128+
.get(this.name)
129+
.add(new PointWithFunction(t, toLongFunction, labelKeys, labelValues));
116130
}
117131

118132
@Override

0 commit comments

Comments
 (0)