@@ -3,9 +3,10 @@ import {
3
3
captureException ,
4
4
debug ,
5
5
flushIfServerless ,
6
+ SEMANTIC_ATTRIBUTE_CACHE_HIT ,
7
+ SEMANTIC_ATTRIBUTE_CACHE_KEY ,
6
8
SEMANTIC_ATTRIBUTE_SENTRY_OP ,
7
9
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
8
- SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
9
10
SPAN_STATUS_ERROR ,
10
11
SPAN_STATUS_OK ,
11
12
startSpan ,
@@ -20,6 +21,11 @@ type MaybeInstrumentedDriver = Driver & {
20
21
__sentry_instrumented__ ?: boolean ;
21
22
} ;
22
23
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
+
23
29
/**
24
30
* Creates a Nitro plugin that instruments the storage driver.
25
31
*/
@@ -74,7 +80,6 @@ function instrumentDriver(driver: MaybeInstrumentedDriver, mountBase: string): D
74
80
'setItems' ,
75
81
'removeItem' ,
76
82
'getKeys' ,
77
- 'getMeta' ,
78
83
'clear' ,
79
84
] ;
80
85
@@ -86,7 +91,7 @@ function instrumentDriver(driver: MaybeInstrumentedDriver, mountBase: string): D
86
91
}
87
92
88
93
// Replace with instrumented
89
- driver [ methodName ] = createMethodWrapper ( original , methodName , driver . name ?? 'unknown' , mountBase ) ;
94
+ driver [ methodName ] = createMethodWrapper ( original , methodName , driver , mountBase ) ;
90
95
}
91
96
92
97
// Mark as instrumented
@@ -101,25 +106,31 @@ function instrumentDriver(driver: MaybeInstrumentedDriver, mountBase: string): D
101
106
function createMethodWrapper (
102
107
original : ( ...args : unknown [ ] ) => unknown ,
103
108
methodName : string ,
104
- driverName : string ,
109
+ driver : Driver ,
105
110
mountBase : string ,
106
111
) : ( ...args : unknown [ ] ) => unknown {
107
112
return new Proxy ( original , {
108
113
async apply ( target , thisArg , args ) {
109
- const attributes = getSpanAttributes ( methodName , driverName ?? 'unknown' , mountBase ) ;
114
+ const attributes = getSpanAttributes ( methodName , driver , mountBase , args ) ;
110
115
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 ) } ` ;
112
119
113
120
return startSpan (
114
121
{
115
- name : `storage. ${ methodName } ` ,
122
+ name : spanName ,
116
123
attributes,
117
124
} ,
118
125
async span => {
119
126
try {
120
127
const result = await target . apply ( thisArg , args ) ;
121
128
span . setStatus ( { code : SPAN_STATUS_OK } ) ;
122
129
130
+ if ( KEYED_METHODS . has ( methodName ) ) {
131
+ span . setAttribute ( SEMANTIC_ATTRIBUTE_CACHE_HIT , true ) ;
132
+ }
133
+
123
134
return result ;
124
135
} catch ( error ) {
125
136
span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'internal_error' } ) ;
@@ -161,15 +172,26 @@ function wrapStorageMount(storage: Storage): Storage['mount'] {
161
172
/**
162
173
* Gets the span attributes for the storage method.
163
174
*/
164
- function getSpanAttributes ( methodName : string , driverName : string , mountBase : string ) : SpanAttributes {
175
+ function getSpanAttributes ( methodName : string , driver : Driver , mountBase : string , args : unknown [ ] ) : SpanAttributes {
165
176
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' ,
169
179
'nuxt.storage.op' : methodName ,
170
- 'nuxt.storage.driver' : driverName ,
171
180
'nuxt.storage.mount' : mountBase ,
181
+ 'nuxt.storage.driver' : driver . name ?? 'unknown' ,
172
182
} ;
173
183
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
+
174
189
return attributes ;
175
190
}
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