diff --git a/sentry-jcache/src/main/java/io/sentry/jcache/SentryJCacheWrapper.java b/sentry-jcache/src/main/java/io/sentry/jcache/SentryJCacheWrapper.java index d5022a5455..816e10bfb1 100644 --- a/sentry-jcache/src/main/java/io/sentry/jcache/SentryJCacheWrapper.java +++ b/sentry-jcache/src/main/java/io/sentry/jcache/SentryJCacheWrapper.java @@ -33,6 +33,7 @@ public final class SentryJCacheWrapper implements Cache { private static final String TRACE_ORIGIN = "auto.cache.jcache"; + private static final String OPERATION_ATTRIBUTE = "db.operation.name"; private final @NotNull Cache delegate; private final @NotNull IScopes scopes; @@ -50,7 +51,7 @@ public SentryJCacheWrapper(final @NotNull Cache delegate, final @NotNull I @Override public V get(final K key) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key); } @@ -70,7 +71,7 @@ public V get(final K key) { @Override public Map getAll(final Set keys) { - final ISpan span = startSpanForKeys("cache.get", keys); + final ISpan span = startSpanForKeys("cache.get", keys, "getAll"); if (span == null) { return delegate.getAll(keys); } @@ -97,7 +98,7 @@ public boolean containsKey(final K key) { @Override public void put(final K key, final V value) { - final ISpan span = startSpan("cache.put", key); + final ISpan span = startSpan("cache.put", key, "put"); if (span == null) { delegate.put(key, value); return; @@ -116,7 +117,7 @@ public void put(final K key, final V value) { @Override public V getAndPut(final K key, final V value) { - final ISpan span = startSpan("cache.put", key); + final ISpan span = startSpan("cache.put", key, "getAndPut"); if (span == null) { return delegate.getAndPut(key, value); } @@ -135,7 +136,7 @@ public V getAndPut(final K key, final V value) { @Override public void putAll(final Map map) { - final ISpan span = startSpanForKeys("cache.put", map.keySet()); + final ISpan span = startSpanForKeys("cache.put", map.keySet(), "putAll"); if (span == null) { delegate.putAll(map); return; @@ -181,7 +182,7 @@ public V getAndReplace(final K key, final V value) { @Override public boolean remove(final K key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "remove"); if (span == null) { return delegate.remove(key); } @@ -200,7 +201,7 @@ public boolean remove(final K key) { @Override public boolean remove(final K key, final V oldValue) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "remove"); if (span == null) { return delegate.remove(key, oldValue); } @@ -219,7 +220,7 @@ public boolean remove(final K key, final V oldValue) { @Override public V getAndRemove(final K key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "getAndRemove"); if (span == null) { return delegate.getAndRemove(key); } @@ -238,7 +239,7 @@ public V getAndRemove(final K key) { @Override public void removeAll(final Set keys) { - final ISpan span = startSpanForKeys("cache.remove", keys); + final ISpan span = startSpanForKeys("cache.remove", keys, "removeAll"); if (span == null) { delegate.removeAll(keys); return; @@ -257,7 +258,7 @@ public void removeAll(final Set keys) { @Override public void removeAll() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "removeAll"); if (span == null) { delegate.removeAll(); return; @@ -278,7 +279,7 @@ public void removeAll() { @Override public void clear() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "clear"); if (span == null) { delegate.clear(); return; @@ -306,7 +307,7 @@ public void close() { public T invoke( final K key, final EntryProcessor entryProcessor, final Object... arguments) throws EntryProcessorException { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "invoke"); if (span == null) { return delegate.invoke(key, entryProcessor, arguments); } @@ -328,7 +329,7 @@ public Map> invokeAll( final Set keys, final EntryProcessor entryProcessor, final Object... arguments) { - final ISpan span = startSpanForKeys("cache.get", keys); + final ISpan span = startSpanForKeys("cache.get", keys, "invokeAll"); if (span == null) { return delegate.invokeAll(keys, entryProcessor, arguments); } @@ -400,7 +401,10 @@ public Iterator> iterator() { // -- span helpers -- - private @Nullable ISpan startSpan(final @NotNull String operation, final @Nullable Object key) { + private @Nullable ISpan startSpan( + final @NotNull String operation, + final @Nullable Object key, + final @NotNull String operationName) { if (!scopes.getOptions().isEnableCacheTracing()) { return null; } @@ -420,11 +424,14 @@ public Iterator> iterator() { if (keyString != null) { span.setData(SpanDataConvention.CACHE_KEY_KEY, Arrays.asList(keyString)); } + span.setData(OPERATION_ATTRIBUTE, operationName); return span; } private @Nullable ISpan startSpanForKeys( - final @NotNull String operation, final @NotNull Set keys) { + final @NotNull String operation, + final @NotNull Set keys, + final @NotNull String operationName) { if (!scopes.getOptions().isEnableCacheTracing()) { return null; } @@ -443,6 +450,7 @@ public Iterator> iterator() { span.setData( SpanDataConvention.CACHE_KEY_KEY, keys.stream().map(String::valueOf).collect(Collectors.toList())); + span.setData(OPERATION_ATTRIBUTE, operationName); return span; } } diff --git a/sentry-jcache/src/test/kotlin/io/sentry/jcache/SentryJCacheWrapperTest.kt b/sentry-jcache/src/test/kotlin/io/sentry/jcache/SentryJCacheWrapperTest.kt index 375e0f0ca5..b0572878da 100644 --- a/sentry-jcache/src/test/kotlin/io/sentry/jcache/SentryJCacheWrapperTest.kt +++ b/sentry-jcache/src/test/kotlin/io/sentry/jcache/SentryJCacheWrapperTest.kt @@ -64,6 +64,7 @@ class SentryJCacheWrapperTest { assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) assertEquals("auto.cache.jcache", span.spanContext.origin) + assertEquals("get", span.getData("db.operation.name")) } @Test @@ -98,6 +99,7 @@ class SentryJCacheWrapperTest { assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) val cacheKeys = span.getData(SpanDataConvention.CACHE_KEY_KEY) as List<*> assertTrue(cacheKeys.containsAll(listOf("k1", "k2"))) + assertEquals("getAll", span.getData("db.operation.name")) } @Test @@ -127,6 +129,7 @@ class SentryJCacheWrapperTest { assertEquals("cache.put", span.operation) assertEquals(SpanStatus.OK, span.status) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("put", span.getData("db.operation.name")) } // -- getAndPut -- @@ -142,6 +145,7 @@ class SentryJCacheWrapperTest { assertEquals("oldValue", result) assertEquals(1, tx.spans.size) assertEquals("cache.put", tx.spans.first().operation) + assertEquals("getAndPut", tx.spans.first().getData("db.operation.name")) } // -- putAll -- @@ -161,6 +165,7 @@ class SentryJCacheWrapperTest { assertEquals("testCache", span.description) val cacheKeys = span.getData(SpanDataConvention.CACHE_KEY_KEY) as List<*> assertTrue(cacheKeys.containsAll(listOf("k1", "k2"))) + assertEquals("putAll", span.getData("db.operation.name")) } // -- putIfAbsent -- @@ -236,6 +241,7 @@ class SentryJCacheWrapperTest { val span = tx.spans.first() assertEquals("cache.remove", span.operation) assertEquals(SpanStatus.OK, span.status) + assertEquals("remove", span.getData("db.operation.name")) } // -- remove(K, V) -- @@ -251,6 +257,7 @@ class SentryJCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.remove", tx.spans.first().operation) + assertEquals("remove", tx.spans.first().getData("db.operation.name")) } // -- getAndRemove -- @@ -266,6 +273,7 @@ class SentryJCacheWrapperTest { assertEquals("value", result) assertEquals(1, tx.spans.size) assertEquals("cache.remove", tx.spans.first().operation) + assertEquals("getAndRemove", tx.spans.first().getData("db.operation.name")) } // -- removeAll(Set) -- @@ -283,6 +291,7 @@ class SentryJCacheWrapperTest { val span = tx.spans.first() assertEquals("cache.remove", span.operation) assertEquals("testCache", span.description) + assertEquals("removeAll", span.getData("db.operation.name")) } // -- removeAll() -- @@ -297,6 +306,7 @@ class SentryJCacheWrapperTest { verify(delegate).removeAll() assertEquals(1, tx.spans.size) assertEquals("cache.flush", tx.spans.first().operation) + assertEquals("removeAll", tx.spans.first().getData("db.operation.name")) } // -- clear -- @@ -314,6 +324,7 @@ class SentryJCacheWrapperTest { assertEquals("cache.flush", span.operation) assertEquals(SpanStatus.OK, span.status) assertNull(span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("clear", span.getData("db.operation.name")) } // -- invoke -- @@ -330,6 +341,7 @@ class SentryJCacheWrapperTest { assertEquals("result", result) assertEquals(1, tx.spans.size) assertEquals("cache.get", tx.spans.first().operation) + assertEquals("invoke", tx.spans.first().getData("db.operation.name")) } // -- invokeAll -- @@ -348,6 +360,7 @@ class SentryJCacheWrapperTest { assertEquals(resultMap, result) assertEquals(1, tx.spans.size) assertEquals("cache.get", tx.spans.first().operation) + assertEquals("invokeAll", tx.spans.first().getData("db.operation.name")) } // -- passthrough operations -- diff --git a/sentry-spring-7/src/main/java/io/sentry/spring7/cache/SentryCacheWrapper.java b/sentry-spring-7/src/main/java/io/sentry/spring7/cache/SentryCacheWrapper.java index 95d1b3c802..1b8b091217 100644 --- a/sentry-spring-7/src/main/java/io/sentry/spring7/cache/SentryCacheWrapper.java +++ b/sentry-spring-7/src/main/java/io/sentry/spring7/cache/SentryCacheWrapper.java @@ -20,6 +20,7 @@ public final class SentryCacheWrapper implements Cache { private static final String TRACE_ORIGIN = "auto.cache.spring"; + private static final String OPERATION_ATTRIBUTE = "db.operation.name"; private final @NotNull Cache delegate; private final @NotNull IScopes scopes; @@ -41,7 +42,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable ValueWrapper get(final @NotNull Object key) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key); } @@ -61,7 +62,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable T get(final @NotNull Object key, final @Nullable Class type) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key, type); } @@ -81,7 +82,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable T get(final @NotNull Object key, final @NotNull Callable valueLoader) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key, valueLoader); } @@ -108,7 +109,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable CompletableFuture retrieve(final @NotNull Object key) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "retrieve"); if (span == null) { return delegate.retrieve(key); } @@ -143,7 +144,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public CompletableFuture retrieve( final @NotNull Object key, final @NotNull Supplier> valueLoader) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "retrieve"); if (span == null) { return delegate.retrieve(key, valueLoader); } @@ -178,7 +179,7 @@ public CompletableFuture retrieve( @Override public void put(final @NotNull Object key, final @Nullable Object value) { - final ISpan span = startSpan("cache.put", key); + final ISpan span = startSpan("cache.put", key, "put"); if (span == null) { delegate.put(key, value); return; @@ -207,7 +208,7 @@ public void put(final @NotNull Object key, final @Nullable Object value) { @Override public void evict(final @NotNull Object key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "evict"); if (span == null) { delegate.evict(key); return; @@ -226,7 +227,7 @@ public void evict(final @NotNull Object key) { @Override public boolean evictIfPresent(final @NotNull Object key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "evictIfPresent"); if (span == null) { return delegate.evictIfPresent(key); } @@ -245,7 +246,7 @@ public boolean evictIfPresent(final @NotNull Object key) { @Override public void clear() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "clear"); if (span == null) { delegate.clear(); return; @@ -264,7 +265,7 @@ public void clear() { @Override public boolean invalidate() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "invalidate"); if (span == null) { return delegate.invalidate(); } @@ -281,7 +282,10 @@ public boolean invalidate() { } } - private @Nullable ISpan startSpan(final @NotNull String operation, final @Nullable Object key) { + private @Nullable ISpan startSpan( + final @NotNull String operation, + final @Nullable Object key, + final @NotNull String operationName) { if (!scopes.getOptions().isEnableCacheTracing()) { return null; } @@ -301,6 +305,7 @@ public boolean invalidate() { if (keyString != null) { span.setData(SpanDataConvention.CACHE_KEY_KEY, Arrays.asList(keyString)); } + span.setData(OPERATION_ATTRIBUTE, operationName); return span; } } diff --git a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/cache/SentryCacheWrapperTest.kt b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/cache/SentryCacheWrapperTest.kt index 9e20fe2155..2a90f45516 100644 --- a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/cache/SentryCacheWrapperTest.kt +++ b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/cache/SentryCacheWrapperTest.kt @@ -63,6 +63,7 @@ class SentryCacheWrapperTest { assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) assertEquals("auto.cache.spring", span.spanContext.origin) + assertEquals("get", span.getData("db.operation.name")) } @Test @@ -156,6 +157,7 @@ class SentryCacheWrapperTest { assertEquals("myKey", span.description) assertEquals(SpanStatus.OK, span.status) assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) + assertEquals("retrieve", span.getData("db.operation.name")) assertTrue(span.isFinished) } @@ -320,6 +322,7 @@ class SentryCacheWrapperTest { assertEquals("cache.put", span.operation) assertEquals(SpanStatus.OK, span.status) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("put", span.getData("db.operation.name")) } // -- putIfAbsent -- @@ -350,6 +353,7 @@ class SentryCacheWrapperTest { val span = tx.spans.first() assertEquals("cache.remove", span.operation) assertEquals(SpanStatus.OK, span.status) + assertEquals("evict", span.getData("db.operation.name")) } // -- evictIfPresent -- @@ -365,6 +369,7 @@ class SentryCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.remove", tx.spans.first().operation) + assertEquals("evictIfPresent", tx.spans.first().getData("db.operation.name")) } // -- clear -- @@ -382,6 +387,7 @@ class SentryCacheWrapperTest { assertEquals("cache.flush", span.operation) assertEquals(SpanStatus.OK, span.status) assertNull(span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("clear", span.getData("db.operation.name")) } // -- invalidate -- @@ -397,6 +403,7 @@ class SentryCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.flush", tx.spans.first().operation) + assertEquals("invalidate", tx.spans.first().getData("db.operation.name")) } // -- no span when no active transaction -- diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/cache/SentryCacheWrapper.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/cache/SentryCacheWrapper.java index f9e2d82379..f4f170cbfd 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/cache/SentryCacheWrapper.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/cache/SentryCacheWrapper.java @@ -20,6 +20,7 @@ public final class SentryCacheWrapper implements Cache { private static final String TRACE_ORIGIN = "auto.cache.spring"; + private static final String OPERATION_ATTRIBUTE = "db.operation.name"; private final @NotNull Cache delegate; private final @NotNull IScopes scopes; @@ -41,7 +42,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable ValueWrapper get(final @NotNull Object key) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key); } @@ -61,7 +62,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable T get(final @NotNull Object key, final @Nullable Class type) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key, type); } @@ -81,7 +82,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable T get(final @NotNull Object key, final @NotNull Callable valueLoader) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key, valueLoader); } @@ -108,7 +109,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable CompletableFuture retrieve(final @NotNull Object key) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "retrieve"); if (span == null) { return delegate.retrieve(key); } @@ -143,7 +144,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public CompletableFuture retrieve( final @NotNull Object key, final @NotNull Supplier> valueLoader) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "retrieve"); if (span == null) { return delegate.retrieve(key, valueLoader); } @@ -178,7 +179,7 @@ public CompletableFuture retrieve( @Override public void put(final @NotNull Object key, final @Nullable Object value) { - final ISpan span = startSpan("cache.put", key); + final ISpan span = startSpan("cache.put", key, "put"); if (span == null) { delegate.put(key, value); return; @@ -207,7 +208,7 @@ public void put(final @NotNull Object key, final @Nullable Object value) { @Override public void evict(final @NotNull Object key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "evict"); if (span == null) { delegate.evict(key); return; @@ -226,7 +227,7 @@ public void evict(final @NotNull Object key) { @Override public boolean evictIfPresent(final @NotNull Object key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "evictIfPresent"); if (span == null) { return delegate.evictIfPresent(key); } @@ -245,7 +246,7 @@ public boolean evictIfPresent(final @NotNull Object key) { @Override public void clear() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "clear"); if (span == null) { delegate.clear(); return; @@ -264,7 +265,7 @@ public void clear() { @Override public boolean invalidate() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "invalidate"); if (span == null) { return delegate.invalidate(); } @@ -281,7 +282,10 @@ public boolean invalidate() { } } - private @Nullable ISpan startSpan(final @NotNull String operation, final @Nullable Object key) { + private @Nullable ISpan startSpan( + final @NotNull String operation, + final @Nullable Object key, + final @NotNull String operationName) { if (!scopes.getOptions().isEnableCacheTracing()) { return null; } @@ -301,6 +305,7 @@ public boolean invalidate() { if (keyString != null) { span.setData(SpanDataConvention.CACHE_KEY_KEY, Arrays.asList(keyString)); } + span.setData(OPERATION_ATTRIBUTE, operationName); return span; } } diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/cache/SentryCacheWrapperTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/cache/SentryCacheWrapperTest.kt index c618688ebb..090bae8390 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/cache/SentryCacheWrapperTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/cache/SentryCacheWrapperTest.kt @@ -63,6 +63,7 @@ class SentryCacheWrapperTest { assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) assertEquals("auto.cache.spring", span.spanContext.origin) + assertEquals("get", span.getData("db.operation.name")) } @Test @@ -156,6 +157,7 @@ class SentryCacheWrapperTest { assertEquals("myKey", span.description) assertEquals(SpanStatus.OK, span.status) assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) + assertEquals("retrieve", span.getData("db.operation.name")) assertTrue(span.isFinished) } @@ -320,6 +322,7 @@ class SentryCacheWrapperTest { assertEquals("cache.put", span.operation) assertEquals(SpanStatus.OK, span.status) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("put", span.getData("db.operation.name")) } // -- putIfAbsent -- @@ -350,6 +353,7 @@ class SentryCacheWrapperTest { val span = tx.spans.first() assertEquals("cache.remove", span.operation) assertEquals(SpanStatus.OK, span.status) + assertEquals("evict", span.getData("db.operation.name")) } // -- evictIfPresent -- @@ -365,6 +369,7 @@ class SentryCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.remove", tx.spans.first().operation) + assertEquals("evictIfPresent", tx.spans.first().getData("db.operation.name")) } // -- clear -- @@ -382,6 +387,7 @@ class SentryCacheWrapperTest { assertEquals("cache.flush", span.operation) assertEquals(SpanStatus.OK, span.status) assertNull(span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("clear", span.getData("db.operation.name")) } // -- invalidate -- @@ -397,6 +403,7 @@ class SentryCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.flush", tx.spans.first().operation) + assertEquals("invalidate", tx.spans.first().getData("db.operation.name")) } // -- no span when no active transaction -- diff --git a/sentry-spring/src/main/java/io/sentry/spring/cache/SentryCacheWrapper.java b/sentry-spring/src/main/java/io/sentry/spring/cache/SentryCacheWrapper.java index 1d106c9e7c..c765b1e143 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/cache/SentryCacheWrapper.java +++ b/sentry-spring/src/main/java/io/sentry/spring/cache/SentryCacheWrapper.java @@ -18,6 +18,7 @@ public final class SentryCacheWrapper implements Cache { private static final String TRACE_ORIGIN = "auto.cache.spring"; + private static final String OPERATION_ATTRIBUTE = "db.operation.name"; private final @NotNull Cache delegate; private final @NotNull IScopes scopes; @@ -39,7 +40,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable ValueWrapper get(final @NotNull Object key) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key); } @@ -59,7 +60,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable T get(final @NotNull Object key, final @Nullable Class type) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key, type); } @@ -79,7 +80,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public @Nullable T get(final @NotNull Object key, final @NotNull Callable valueLoader) { - final ISpan span = startSpan("cache.get", key); + final ISpan span = startSpan("cache.get", key, "get"); if (span == null) { return delegate.get(key, valueLoader); } @@ -106,7 +107,7 @@ public SentryCacheWrapper(final @NotNull Cache delegate, final @NotNull IScopes @Override public void put(final @NotNull Object key, final @Nullable Object value) { - final ISpan span = startSpan("cache.put", key); + final ISpan span = startSpan("cache.put", key, "put"); if (span == null) { delegate.put(key, value); return; @@ -135,7 +136,7 @@ public void put(final @NotNull Object key, final @Nullable Object value) { @Override public void evict(final @NotNull Object key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "evict"); if (span == null) { delegate.evict(key); return; @@ -154,7 +155,7 @@ public void evict(final @NotNull Object key) { @Override public boolean evictIfPresent(final @NotNull Object key) { - final ISpan span = startSpan("cache.remove", key); + final ISpan span = startSpan("cache.remove", key, "evictIfPresent"); if (span == null) { return delegate.evictIfPresent(key); } @@ -173,7 +174,7 @@ public boolean evictIfPresent(final @NotNull Object key) { @Override public void clear() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "clear"); if (span == null) { delegate.clear(); return; @@ -192,7 +193,7 @@ public void clear() { @Override public boolean invalidate() { - final ISpan span = startSpan("cache.flush", null); + final ISpan span = startSpan("cache.flush", null, "invalidate"); if (span == null) { return delegate.invalidate(); } @@ -209,7 +210,10 @@ public boolean invalidate() { } } - private @Nullable ISpan startSpan(final @NotNull String operation, final @Nullable Object key) { + private @Nullable ISpan startSpan( + final @NotNull String operation, + final @Nullable Object key, + final @NotNull String operationName) { if (!scopes.getOptions().isEnableCacheTracing()) { return null; } @@ -229,6 +233,7 @@ public boolean invalidate() { if (keyString != null) { span.setData(SpanDataConvention.CACHE_KEY_KEY, Arrays.asList(keyString)); } + span.setData(OPERATION_ATTRIBUTE, operationName); return span; } } diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/cache/SentryCacheWrapperTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/cache/SentryCacheWrapperTest.kt index c251163947..007f537411 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/cache/SentryCacheWrapperTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/cache/SentryCacheWrapperTest.kt @@ -61,6 +61,7 @@ class SentryCacheWrapperTest { assertEquals(true, span.getData(SpanDataConvention.CACHE_HIT_KEY)) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) assertEquals("auto.cache.spring", span.spanContext.origin) + assertEquals("get", span.getData("db.operation.name")) } @Test @@ -152,6 +153,7 @@ class SentryCacheWrapperTest { assertEquals("cache.put", span.operation) assertEquals(SpanStatus.OK, span.status) assertEquals(listOf("myKey"), span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("put", span.getData("db.operation.name")) } // -- putIfAbsent -- @@ -182,6 +184,7 @@ class SentryCacheWrapperTest { val span = tx.spans.first() assertEquals("cache.remove", span.operation) assertEquals(SpanStatus.OK, span.status) + assertEquals("evict", span.getData("db.operation.name")) } // -- evictIfPresent -- @@ -197,6 +200,7 @@ class SentryCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.remove", tx.spans.first().operation) + assertEquals("evictIfPresent", tx.spans.first().getData("db.operation.name")) } // -- clear -- @@ -214,6 +218,7 @@ class SentryCacheWrapperTest { assertEquals("cache.flush", span.operation) assertEquals(SpanStatus.OK, span.status) assertNull(span.getData(SpanDataConvention.CACHE_KEY_KEY)) + assertEquals("clear", span.getData("db.operation.name")) } // -- invalidate -- @@ -229,6 +234,7 @@ class SentryCacheWrapperTest { assertTrue(result) assertEquals(1, tx.spans.size) assertEquals("cache.flush", tx.spans.first().operation) + assertEquals("invalidate", tx.spans.first().getData("db.operation.name")) } // -- no span when no active transaction --