Skip to content

Commit 79f3a07

Browse files
committed
perf: cache the key used for OTEL traces and metrics
The HeaderInterceptor creates a key consisting of the database name and method name that is used for OpenTelemetry attributes and metrics. The number of unique keys is low. However, the key is constructed from the DatabaseName and method name every time, which leads to a lot of string creation: 1. The DatabaseName.toString() method is called every time. This constructs a new string. 2. The result of DatabaseName.toString() is concatenated with the methodName to create yet another string. Instead of creating the key every time, we can cache the key values without doing the string creation and concatenation every time.
1 parent e97b92e commit 79f3a07

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/HeaderInterceptor.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class HeaderInterceptor implements ClientInterceptor {
8787
CacheBuilder.newBuilder().maximumSize(1000).build();
8888
private final Cache<String, Map<String, String>> builtInAttributesCache =
8989
CacheBuilder.newBuilder().maximumSize(1000).build();
90+
private final Cache<DatabaseName, Cache<String, String>> keyCache =
91+
CacheBuilder.newBuilder().maximumSize(1000).build();
9092

9193
// Get the global singleton Tagger object.
9294
private static final Tagger TAGGER = Tags.getTagger();
@@ -116,7 +118,7 @@ public void start(Listener<RespT> responseListener, Metadata headers) {
116118
try {
117119
Span span = Span.current();
118120
DatabaseName databaseName = extractDatabaseName(headers);
119-
String key = databaseName + method.getFullMethodName();
121+
String key = extractKey(databaseName, method.getFullMethodName());
120122
TagContext tagContext = getTagContext(key, method.getFullMethodName(), databaseName);
121123
Attributes attributes =
122124
getMetricAttributes(key, method.getFullMethodName(), databaseName);
@@ -201,6 +203,13 @@ private Map<String, Long> parseServerTimingHeader(String serverTiming) {
201203
return serverTimingMetrics;
202204
}
203205

206+
private String extractKey(DatabaseName databaseName, String methodName)
207+
throws ExecutionException {
208+
Cache<String, String> keys =
209+
keyCache.get(databaseName, () -> CacheBuilder.newBuilder().maximumSize(1000).build());
210+
return keys.get(methodName, () -> databaseName + methodName);
211+
}
212+
204213
private DatabaseName extractDatabaseName(Metadata headers) throws ExecutionException {
205214
String googleResourcePrefix = headers.get(GOOGLE_CLOUD_RESOURCE_PREFIX_KEY);
206215
if (googleResourcePrefix != null) {

0 commit comments

Comments
 (0)