Skip to content

Commit 701ac21

Browse files
committed
fix: remove connection-id from metrics
The OpenTelemetry metrics that were gathered by the JDBC driver also included a unique Connection ID for each connection. This creats too many time series.
1 parent 7768a6b commit 701ac21

File tree

2 files changed

+60
-14
lines changed

2 files changed

+60
-14
lines changed

src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ class JdbcConnection extends AbstractJdbcConnection {
9191

9292
private final Metrics metrics;
9393

94-
private final Attributes openTelemetryAttributes;
94+
private final Attributes openTelemetryMetricsAttributes;
9595

9696
JdbcConnection(String connectionUrl, ConnectionOptions options) throws SQLException {
9797
super(connectionUrl, options);
9898
this.useLegacyIsValidCheck = useLegacyValidCheck();
9999
OpenTelemetry openTelemetry = getSpanner().getOptions().getOpenTelemetry();
100-
this.openTelemetryAttributes =
101-
createOpenTelemetryAttributes(getConnectionOptions().getDatabaseId());
100+
this.openTelemetryMetricsAttributes =
101+
createOpenTelemetryAttributes(getConnectionOptions().getDatabaseId(), false);
102102
this.metrics = new Metrics(openTelemetry);
103103
}
104104

@@ -114,17 +114,20 @@ static boolean useLegacyValidCheck() {
114114
}
115115

116116
@VisibleForTesting
117-
static Attributes createOpenTelemetryAttributes(DatabaseId databaseId) {
117+
static Attributes createOpenTelemetryAttributes(DatabaseId databaseId, boolean includeConnectionId) {
118118
AttributesBuilder attributesBuilder = Attributes.builder();
119-
attributesBuilder.put("connection_id", UUID.randomUUID().toString());
119+
// A unique connection ID should only be included for tracing and not for metrics.
120+
if (includeConnectionId) {
121+
attributesBuilder.put("connection_id", UUID.randomUUID().toString());
122+
}
120123
attributesBuilder.put("database", databaseId.getDatabase());
121124
attributesBuilder.put("instance_id", databaseId.getInstanceId().getInstance());
122125
attributesBuilder.put("project_id", databaseId.getInstanceId().getProject());
123126
return attributesBuilder.build();
124127
}
125128

126129
public void recordClientLibLatencyMetric(long value) {
127-
metrics.recordClientLibLatency(value, openTelemetryAttributes);
130+
metrics.recordClientLibLatency(value, openTelemetryMetricsAttributes);
128131
}
129132

130133
@Override

src/test/java/com/google/cloud/spanner/jdbc/it/ITOpenTelemetryTest.java

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,17 @@
5151
import java.sql.ResultSet;
5252
import java.sql.SQLException;
5353
import java.sql.Statement;
54+
import java.util.ArrayList;
55+
import java.util.List;
5456
import java.util.Properties;
5557
import java.util.UUID;
58+
import java.util.concurrent.Callable;
59+
import java.util.concurrent.ExecutorService;
60+
import java.util.concurrent.Executors;
61+
import java.util.concurrent.Future;
5662
import java.util.concurrent.ThreadLocalRandom;
5763
import java.util.concurrent.TimeUnit;
64+
import java.util.function.Supplier;
5865
import org.junit.AfterClass;
5966
import org.junit.Before;
6067
import org.junit.BeforeClass;
@@ -125,21 +132,22 @@ public void setup() {
125132
}
126133

127134
@Test
128-
public void testGlobalOpenTelemetry() throws SQLException, IOException, InterruptedException {
135+
public void testGlobalOpenTelemetry() throws Exception {
129136
GlobalOpenTelemetry.resetForTest();
130137
GlobalOpenTelemetry.set(openTelemetry);
131138
Properties info = new Properties();
132139
info.put("enableExtendedTracing", "true");
133140
try (Connection connection = createConnection(env, database, info)) {
134141
testOpenTelemetry(connection);
142+
testOpenTelemetryConcurrency(() -> createConnection(env, database, info));
135143
} finally {
136144
GlobalOpenTelemetry.resetForTest();
137145
}
138146
}
139147

140148
@Test
141149
public void testOpenTelemetryInProperties()
142-
throws SQLException, IOException, InterruptedException {
150+
throws Exception {
143151
// Make sure there is no Global OpenTelemetry.
144152
GlobalOpenTelemetry.resetForTest();
145153
Properties info = new Properties();
@@ -148,6 +156,7 @@ public void testOpenTelemetryInProperties()
148156
try (Connection connection = createConnection(env, database, info)) {
149157
testOpenTelemetry(connection);
150158
}
159+
testOpenTelemetryConcurrency(() -> createConnection(env, database, info));
151160
}
152161

153162
private void testOpenTelemetry(Connection connection)
@@ -159,14 +168,14 @@ private void testOpenTelemetry(Connection connection)
159168

160169
// Test executeQuery(String)
161170
try (ResultSet resultSet = statement.executeQuery(sql)) {
162-
assertQueryResult(resultSet, sql, uuid);
171+
assertQueryResult(resultSet, sql, uuid, true);
163172
}
164173

165174
// Test execute(String)
166175
uuid = UUID.randomUUID();
167176
sql = "select '" + uuid + "'";
168177
assertTrue(statement.execute(sql));
169-
assertQueryResult(statement.getResultSet(), sql, uuid);
178+
assertQueryResult(statement.getResultSet(), sql, uuid, true);
170179

171180
// Test executeUpdate(String)
172181
uuid = UUID.randomUUID();
@@ -189,15 +198,15 @@ private void testOpenTelemetry(Connection connection)
189198
String sql = "select '" + uuid + "'";
190199
try (PreparedStatement statement = connection.prepareStatement(sql)) {
191200
try (ResultSet resultSet = statement.executeQuery()) {
192-
assertQueryResult(resultSet, sql, uuid);
201+
assertQueryResult(resultSet, sql, uuid, true);
193202
}
194203
}
195204

196205
uuid = UUID.randomUUID();
197206
sql = "select '" + uuid + "'";
198207
try (PreparedStatement statement = connection.prepareStatement(sql)) {
199208
assertTrue(statement.execute());
200-
assertQueryResult(statement.getResultSet(), sql, uuid);
209+
assertQueryResult(statement.getResultSet(), sql, uuid, true);
201210
}
202211

203212
uuid = UUID.randomUUID();
@@ -216,15 +225,49 @@ private void testOpenTelemetry(Connection connection)
216225
assertUpdateResult(statement.executeLargeUpdate(), spannerSql);
217226
}
218227
}
228+
229+
private interface ConnectionProducer {
230+
Connection createConnection() throws SQLException;
231+
}
232+
233+
private void testOpenTelemetryConcurrency(ConnectionProducer connectionProducer) throws Exception {
234+
int numThreads = 16;
235+
int numIterations = 1000;
236+
ExecutorService executor = Executors.newFixedThreadPool(16);
237+
List<Future<?>> futures = new ArrayList<>(numThreads);
238+
for (int n=0; n<numThreads; n++) {
239+
futures.add(executor.submit((Callable<Void>) () -> {
240+
try (Connection connection = connectionProducer.createConnection(); Statement statement = connection.createStatement()) {
241+
for (int i = 0; i < numIterations; i++) {
242+
UUID uuid = UUID.randomUUID();
243+
String sql = "select '" + uuid + "'";
219244

220-
private void assertQueryResult(ResultSet resultSet, String sql, UUID uuid)
245+
try (ResultSet resultSet = statement.executeQuery(sql)) {
246+
assertQueryResult(resultSet, sql, uuid, false);
247+
}
248+
}
249+
}
250+
return null;
251+
}));
252+
}
253+
executor.shutdown();
254+
assertTrue(executor.awaitTermination(600L, TimeUnit.SECONDS));
255+
for (Future<?> future : futures) {
256+
// Just verify that we did not get an exception.
257+
future.get();
258+
}
259+
}
260+
261+
private void assertQueryResult(ResultSet resultSet, String sql, UUID uuid, boolean assertTrace)
221262
throws SQLException, IOException, InterruptedException {
222263
assertTrue(resultSet.next());
223264
assertEquals(uuid.toString(), resultSet.getString(1));
224265
assertFalse(resultSet.next());
225266

226267
flushOpenTelemetry();
227-
assertTrace(sql);
268+
if (assertTrace) {
269+
assertTrace(sql);
270+
}
228271
}
229272

230273
private void assertUpdateResult(long updateCount, String sql)

0 commit comments

Comments
 (0)