@@ -3,9 +3,10 @@ import {
33 captureException ,
44 debug ,
55 flushIfServerless ,
6+ SEMANTIC_ATTRIBUTE_CACHE_HIT ,
7+ SEMANTIC_ATTRIBUTE_CACHE_KEY ,
68 SEMANTIC_ATTRIBUTE_SENTRY_OP ,
79 SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
8- SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
910 SPAN_STATUS_ERROR ,
1011 SPAN_STATUS_OK ,
1112 startSpan ,
@@ -20,6 +21,11 @@ type MaybeInstrumentedDriver = Driver & {
2021 __sentry_instrumented__ ?: boolean ;
2122} ;
2223
24+ /**
25+ * Methods that should have a attribute to indicate a cache hit.
26+ */
27+ const KEYED_METHODS = new Set ( [ 'hasItem' , 'getItem' , 'getItemRaw' , 'getItems' ] ) ;
28+
2329/**
2430 * Creates a Nitro plugin that instruments the storage driver.
2531 */
@@ -74,7 +80,6 @@ function instrumentDriver(driver: MaybeInstrumentedDriver, mountBase: string): D
7480 'setItems' ,
7581 'removeItem' ,
7682 'getKeys' ,
77- 'getMeta' ,
7883 'clear' ,
7984 ] ;
8085
@@ -86,7 +91,7 @@ function instrumentDriver(driver: MaybeInstrumentedDriver, mountBase: string): D
8691 }
8792
8893 // Replace with instrumented
89- driver [ methodName ] = createMethodWrapper ( original , methodName , driver . name ?? 'unknown' , mountBase ) ;
94+ driver [ methodName ] = createMethodWrapper ( original , methodName , driver , mountBase ) ;
9095 }
9196
9297 // Mark as instrumented
@@ -101,25 +106,31 @@ function instrumentDriver(driver: MaybeInstrumentedDriver, mountBase: string): D
101106function createMethodWrapper (
102107 original : ( ...args : unknown [ ] ) => unknown ,
103108 methodName : string ,
104- driverName : string ,
109+ driver : Driver ,
105110 mountBase : string ,
106111) : ( ...args : unknown [ ] ) => unknown {
107112 return new Proxy ( original , {
108113 async apply ( target , thisArg , args ) {
109- const attributes = getSpanAttributes ( methodName , driverName ?? 'unknown' , mountBase ) ;
114+ const attributes = getSpanAttributes ( methodName , driver , mountBase , args ) ;
110115
111- debug . log ( `[storage] Running method: "${ methodName } " on driver: "${ driverName } "` ) ;
116+ debug . log ( `[storage] Running method: "${ methodName } " on driver: "${ driver . name ?? 'unknown' } "` ) ;
117+
118+ const spanName = KEYED_METHODS . has ( methodName ) ? String ( args ?. [ 0 ] ) : `storage.${ normalizeMethodName ( methodName ) } ` ;
112119
113120 return startSpan (
114121 {
115- name : `storage. ${ methodName } ` ,
122+ name : spanName ,
116123 attributes,
117124 } ,
118125 async span => {
119126 try {
120127 const result = await target . apply ( thisArg , args ) ;
121128 span . setStatus ( { code : SPAN_STATUS_OK } ) ;
122129
130+ if ( KEYED_METHODS . has ( methodName ) ) {
131+ span . setAttribute ( SEMANTIC_ATTRIBUTE_CACHE_HIT , true ) ;
132+ }
133+
123134 return result ;
124135 } catch ( error ) {
125136 span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'internal_error' } ) ;
@@ -161,15 +172,26 @@ function wrapStorageMount(storage: Storage): Storage['mount'] {
161172/**
162173 * Gets the span attributes for the storage method.
163174 */
164- function getSpanAttributes ( methodName : string , driverName : string , mountBase : string ) : SpanAttributes {
175+ function getSpanAttributes ( methodName : string , driver : Driver , mountBase : string , args : unknown [ ] ) : SpanAttributes {
165176 const attributes : SpanAttributes = {
166- [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'app.storage.nuxt' ,
167- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'custom' ,
168- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.app.storage.nuxt' ,
177+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : `cache.${ normalizeMethodName ( methodName ) } ` ,
178+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.cache.nuxt' ,
169179 'nuxt.storage.op' : methodName ,
170- 'nuxt.storage.driver' : driverName ,
171180 'nuxt.storage.mount' : mountBase ,
181+ 'nuxt.storage.driver' : driver . name ?? 'unknown' ,
172182 } ;
173183
184+ // Add the key if it's a get/set/del call
185+ if ( args ?. [ 0 ] && typeof args [ 0 ] === 'string' ) {
186+ attributes [ SEMANTIC_ATTRIBUTE_CACHE_KEY ] = `${ mountBase } ${ args [ 0 ] } ` ;
187+ }
188+
174189 return attributes ;
175190}
191+
192+ /**
193+ * Normalizes the method name to snake_case to be used in span names or op.
194+ */
195+ function normalizeMethodName ( methodName : string ) : string {
196+ return methodName . replace ( / [ A - Z ] / g, letter => `_${ letter . toLowerCase ( ) } ` ) ;
197+ }
0 commit comments