-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(nuxt): Instrument storage API #17858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat(nuxt): Instrument storage API #17858
Conversation
07cb542
to
24a5470
Compare
a6dc41f
to
fe203a5
Compare
911b7fe
to
abe38de
Compare
64e5814
to
42ef2c7
Compare
size-limit report 📦
|
// Mounts are suffixed with a colon, so we need to add it to the set items | ||
const userMounts = new Set((userStorageMounts as string[]).map(m => `${m}:`)); | ||
|
||
debug.log('[storage] Starting to instrument storage drivers...'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably want to show this log conditionally based on debug: true
(also applies to other debug statements).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean with DEBUG && ....
? I don't think it works in server-added plugins as I tried and it fails to build. It also doesn't log anything when debug
is false.
'nuxt.storage.op': methodName, | ||
'nuxt.storage.mount': mountBase, | ||
'nuxt.storage.driver': driver.name ?? 'unknown', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those attribute names are new - just wondering what's the decision process behind using those. We have some pre-defined attribute names for databases (probably only partially applicable): https://develop.sentry.dev/sdk/telemetry/traces/span-operations/#database
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just wondering what's the decision process behind using those
None! I maybe understood that if we don't have a matching attribute name we could create our own. Sorry about that.
I took a read at this and I think we can use these instead:
'db.operation.name': methodName,
'db.collection.name ': mountBase,
'db.system.name': driver.name ?? 'unknown',
|
||
const spanName = KEYED_METHODS.has(methodName) | ||
? `${mountBase}${args?.[0]}` | ||
: `storage.${normalizeMethodName(methodName)}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaik, the span names usually look a bit different than span attributes. Using "storage" here is a bit repetitive and my suggestion would be {operation} {affected keys}
based on HTTP span names which are `{method} {endpoint}".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, this will tie in nicely with the multiple key handling for getItems
calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Played around with a few name formats and {operation} {keys}
feels redundant since the span description will contain the operation as well. Or is the redundancy usually desired in span names?
I changed it so it is in line with this:
Not sure if we should repeat the mount name for each cache key if it happens to be a multiple.

if (args?.[0] && typeof args[0] === 'string') { | ||
attributes[SEMANTIC_ATTRIBUTE_CACHE_KEY] = `${mountBase}${args[0]}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this always just one key or can there be multiple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you mean the first arg. yep it is possible, but it would be serialized to a string eg: key1,key2,key3
etc...
and if you mean if args would contain other keys in [1]
, then no, all the methods signatures place the keys at the first arg.
{
async hasItem(key, _opts) {},
async getItem(key, _opts) {},
async setItem(key, value, _opts) {},
async removeItem(key, _opts) {},
async getKeys(base, _opts) {},
async clear(base, _opts) {},
}
I also missed the possibility of those keys being objects containing a key
property, I will add a key normalizer to handle all these cases and format the multiple keys more nicely for the span names.
node-overhead report 🧳Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
|
ab3ecc1
to
d943f7d
Compare
What
This PR adds automatic instrumentation for Nuxt's storage layer (powered by unstorage), enabling performance monitoring for cache and key-value storage operations in Nuxt/Nitro applications.
Storage operations will now automatically create performance spans with detailed attributes for observability in Sentry.
What's New
nuxt.config.ts
vianitro.storage
getItem
,setItem
,hasItem
,removeItem
getItemRaw
,setItemRaw
getItems
,setItems
getKeys
,clear
get
,set
,has
,del
,remove
Implementation Details
Span Attributes:
sentry.op
:cache.{operation}
(e.g.,cache.get_item
,cache.set_item
)sentry.origin
:auto.cache.nuxt
cache.key
: Full key including mount prefixcache.hit
:true
for successful get/has operationsdb.operation.name
: Original method namedb.collection.name
: Storage mount pointdb.system.name
: Driver name (e.g.,memory
,fs
,redis
)Files Changed:
packages/nuxt/src/runtime/plugins/storage.server.ts
- Runtime instrumentation pluginpackages/nuxt/src/vite/storageConfig.ts
- Build-time configurationpackages/nuxt/src/module.ts
- Module integration