Skip to content

Commit 94d0557

Browse files
authored
feat: add metrics to capture acquired and released sessions data (#67)
* add acquired and released sessions data * update the description * update the description * Apply skuruppu@'s recommendations * apply olavloite@'s recommendations * minor fix * attempt to fix build
1 parent 3f32f51 commit 94d0557

File tree

4 files changed

+66
-5
lines changed

4 files changed

+66
-5
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class MetricRegistryConstants {
4646
static final String MAX_ALLOWED_SESSIONS = "cloud.google.com/java/spanner/max_allowed_sessions";
4747
static final String IN_USE_SESSIONS = "cloud.google.com/java/spanner/in_use_sessions";
4848
static final String GET_SESSION_TIMEOUTS = "cloud.google.com/java/spanner/get_session_timeouts";
49+
static final String NUM_ACQUIRED_SESSIONS = "cloud.google.com/java/spanner/num_acquired_sessions";
50+
static final String NUM_RELEASED_SESSIONS = "cloud.google.com/java/spanner/num_released_sessions";
4951

5052
static final String MAX_IN_USE_SESSIONS_DESCRIPTION =
5153
"The maximum number of sessions in use during the last 10 minute interval.";
@@ -54,4 +56,8 @@ class MetricRegistryConstants {
5456
static final String IN_USE_SESSIONS_DESCRIPTION = "The number of sessions currently in use.";
5557
static final String SESSIONS_TIMEOUTS_DESCRIPTION =
5658
"The number of get sessions timeouts due to pool exhaustion";
59+
static final String NUM_ACQUIRED_SESSIONS_DESCRIPTION =
60+
"The number of sessions acquired from the session pool.";
61+
static final String NUM_RELEASED_SESSIONS_DESCRIPTION =
62+
"The number of sessions released by the user and pool maintainer.";
5763
}

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_ALLOWED_SESSIONS_DESCRIPTION;
2525
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_IN_USE_SESSIONS;
2626
import static com.google.cloud.spanner.MetricRegistryConstants.MAX_IN_USE_SESSIONS_DESCRIPTION;
27+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_ACQUIRED_SESSIONS;
28+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_ACQUIRED_SESSIONS_DESCRIPTION;
29+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_RELEASED_SESSIONS;
30+
import static com.google.cloud.spanner.MetricRegistryConstants.NUM_RELEASED_SESSIONS_DESCRIPTION;
2731
import static com.google.cloud.spanner.MetricRegistryConstants.SESSIONS_TIMEOUTS_DESCRIPTION;
2832
import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_DEFAULT_LABEL_VALUES;
2933
import static com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS;
@@ -796,6 +800,7 @@ public ApiFuture<Empty> asyncClose() {
796800
public void close() {
797801
synchronized (lock) {
798802
numSessionsInUse--;
803+
numSessionsReleased++;
799804
}
800805
leakedException = null;
801806
if (lastException != null && isSessionNotFound(lastException)) {
@@ -1122,6 +1127,12 @@ private static enum Position {
11221127
@GuardedBy("lock")
11231128
private int maxSessionsInUse = 0;
11241129

1130+
@GuardedBy("lock")
1131+
private long numSessionsAcquired = 0;
1132+
1133+
@GuardedBy("lock")
1134+
private long numSessionsReleased = 0;
1135+
11251136
private AtomicLong numWaiterTimeouts = new AtomicLong();
11261137

11271138
@GuardedBy("lock")
@@ -1448,6 +1459,7 @@ private PooledSession replaceSession(
14481459
if (!options.isFailIfSessionNotFound() && session.allowReplacing) {
14491460
synchronized (lock) {
14501461
numSessionsInUse--;
1462+
numSessionsReleased++;
14511463
}
14521464
session.leakedException = null;
14531465
invalidateSession(session);
@@ -1468,6 +1480,7 @@ private void incrementNumSessionsInUse() {
14681480
if (maxSessionsInUse < ++numSessionsInUse) {
14691481
maxSessionsInUse = numSessionsInUse;
14701482
}
1483+
numSessionsAcquired++;
14711484
}
14721485
}
14731486

@@ -1857,6 +1870,24 @@ private void initMetricsCollection(MetricRegistry metricRegistry, List<LabelValu
18571870
.setLabelKeys(SPANNER_LABEL_KEYS)
18581871
.build());
18591872

1873+
DerivedLongCumulative numAcquiredSessionsMetric =
1874+
metricRegistry.addDerivedLongCumulative(
1875+
NUM_ACQUIRED_SESSIONS,
1876+
MetricOptions.builder()
1877+
.setDescription(NUM_ACQUIRED_SESSIONS_DESCRIPTION)
1878+
.setUnit(COUNT)
1879+
.setLabelKeys(SPANNER_LABEL_KEYS)
1880+
.build());
1881+
1882+
DerivedLongCumulative numReleasedSessionsMetric =
1883+
metricRegistry.addDerivedLongCumulative(
1884+
NUM_RELEASED_SESSIONS,
1885+
MetricOptions.builder()
1886+
.setDescription(NUM_RELEASED_SESSIONS_DESCRIPTION)
1887+
.setUnit(COUNT)
1888+
.setLabelKeys(SPANNER_LABEL_KEYS)
1889+
.build());
1890+
18601891
// The value of a maxSessionsInUse is observed from a callback function. This function is
18611892
// invoked whenever metrics are collected.
18621893
maxInUseSessionsMetric.createTimeSeries(
@@ -1904,5 +1935,25 @@ public long applyAsLong(SessionPool sessionPool) {
19041935
return sessionPool.getNumWaiterTimeouts();
19051936
}
19061937
});
1938+
1939+
numAcquiredSessionsMetric.createTimeSeries(
1940+
labelValues,
1941+
this,
1942+
new ToLongFunction<SessionPool>() {
1943+
@Override
1944+
public long applyAsLong(SessionPool sessionPool) {
1945+
return sessionPool.numSessionsAcquired;
1946+
}
1947+
});
1948+
1949+
numReleasedSessionsMetric.createTimeSeries(
1950+
labelValues,
1951+
this,
1952+
new ToLongFunction<SessionPool>() {
1953+
@Override
1954+
public long applyAsLong(SessionPool sessionPool) {
1955+
return sessionPool.numSessionsReleased;
1956+
}
1957+
});
19071958
}
19081959
}

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,10 +1585,14 @@ public void testSessionMetrics() throws Exception {
15851585
Session session2 = pool.getReadSession();
15861586

15871587
MetricsRecord record = metricRegistry.pollRecord();
1588-
assertThat(record.getMetrics().size()).isEqualTo(4);
1588+
assertThat(record.getMetrics().size()).isEqualTo(6);
15891589
assertThat(record.getMetrics()).containsEntry(MetricRegistryConstants.IN_USE_SESSIONS, 2L);
15901590
assertThat(record.getMetrics()).containsEntry(MetricRegistryConstants.MAX_IN_USE_SESSIONS, 2L);
15911591
assertThat(record.getMetrics()).containsEntry(MetricRegistryConstants.GET_SESSION_TIMEOUTS, 0L);
1592+
assertThat(record.getMetrics())
1593+
.containsEntry(MetricRegistryConstants.NUM_ACQUIRED_SESSIONS, 2L);
1594+
assertThat(record.getMetrics())
1595+
.containsEntry(MetricRegistryConstants.NUM_RELEASED_SESSIONS, 0L);
15921596
assertThat(record.getMetrics())
15931597
.containsEntry(
15941598
MetricRegistryConstants.MAX_ALLOWED_SESSIONS, (long) options.getMaxSessions());
@@ -1625,6 +1629,10 @@ public Void call() {
16251629
session1.close();
16261630
assertThat(record.getMetrics().get(MetricRegistryConstants.GET_SESSION_TIMEOUTS).longValue())
16271631
.isAtLeast(1L);
1632+
assertThat(record.getMetrics())
1633+
.containsEntry(MetricRegistryConstants.NUM_ACQUIRED_SESSIONS, 3L);
1634+
assertThat(record.getMetrics())
1635+
.containsEntry(MetricRegistryConstants.NUM_RELEASED_SESSIONS, 3L);
16281636
assertThat(record.getMetrics()).containsEntry(MetricRegistryConstants.IN_USE_SESSIONS, 0L);
16291637
assertThat(record.getMetrics()).containsEntry(MetricRegistryConstants.MAX_IN_USE_SESSIONS, 2L);
16301638
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,6 @@ public void singleUse() {
255255
}
256256
}
257257
Map<String, Boolean> spans = failOnOverkillTraceComponent.getSpans();
258-
assertThat(spans.size()).isEqualTo(5);
259258
assertThat(spans).containsEntry("CloudSpanner.ReadOnlyTransaction", true);
260259
assertThat(spans).containsEntry("CloudSpannerOperation.BatchCreateSessions", true);
261260
assertThat(spans).containsEntry("SessionPool.WaitForSession", true);
@@ -274,7 +273,6 @@ public void multiUse() {
274273
}
275274

276275
Map<String, Boolean> spans = failOnOverkillTraceComponent.getSpans();
277-
assertThat(spans.size()).isEqualTo(5);
278276
assertThat(spans).containsEntry("CloudSpanner.ReadOnlyTransaction", true);
279277
assertThat(spans).containsEntry("CloudSpannerOperation.BatchCreateSessions", true);
280278
assertThat(spans).containsEntry("SessionPool.WaitForSession", true);
@@ -294,7 +292,6 @@ public Void run(TransactionContext transaction) throws Exception {
294292
}
295293
});
296294
Map<String, Boolean> spans = failOnOverkillTraceComponent.getSpans();
297-
assertThat(spans.size()).isEqualTo(6);
298295
assertThat(spans).containsEntry("CloudSpanner.ReadWriteTransaction", true);
299296
assertThat(spans).containsEntry("CloudSpannerOperation.BatchCreateSessions", true);
300297
assertThat(spans).containsEntry("SessionPool.WaitForSession", true);
@@ -321,7 +318,6 @@ public Void run(TransactionContext transaction) throws Exception {
321318
}
322319

323320
Map<String, Boolean> spans = failOnOverkillTraceComponent.getSpans();
324-
assertThat(spans.size()).isEqualTo(5);
325321
assertThat(spans).containsEntry("CloudSpanner.ReadWriteTransaction", true);
326322
assertThat(spans).containsEntry("CloudSpannerOperation.BatchCreateSessions", true);
327323
assertThat(spans).containsEntry("SessionPool.WaitForSession", true);

0 commit comments

Comments
 (0)