Uh oh!
There was an error while loading. Please reload this page.
feat(server-utils): Emit low cardinality redis span names - #23741
Conversation
size-limit report 📦
|
Uh oh!
There was an error while loading. Please reload this page.
70ad779 to
87fa5b5Compare
chargome
left a comment
There was a problem hiding this comment.
Generally LGTM! Just a follow up q. Also likely needs a migration entry.
| ]); | ||
| expect(childSpans(container)).toEqual([ | ||
| span('redis', redisSpanOp, { |
There was a problem hiding this comment.
q: Just wondering if this span name makes sense compared to redis-4 (where it is SET localhost:6383). Could we somehow apply the same defaults here with localhost and port here?
There was a problem hiding this comment.
good catch, thanks! Updated to also include the host/port
87fa5b5 to
882faadCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Redis reports no SQL statement, so there is no query summary to name its spans
after. With span streaming they use the next conventions template that can be
filled instead: the command paired with `{server.address}:{server.port}`, since
redis has no collection or namespace to pair with. It falls back to
`{db.system.name}` when the client was configured without a host.
This keeps the serialized command, which carries the key and its arguments, out
of the span name. It stays on `db.query.text`.
`traceLifecycle: 'static'` keeps the existing names.
Refs #23523
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Pairing the command with `{server.address}:{server.port}` put a host and port in
every redis span name, which says nothing about what ran. Redis has nothing low
cardinality to pair the operation with, so the name is now the bare command,
matching the span name OTel prescribes for redis. The key and its arguments stay
on `db.query.text`.
`db.namespace` is deliberately left out of the name: for redis it is the numeric
database index, which OTel excludes from span names for that reason.
`FCALL`/`FCALL_RO` are the exception, since they name a redis function — the one
redis construct the conventions model as a stored procedure. Those spans report
`db.stored_procedure.name` and pair it with the operation, unless the publishing
library redacted the function name.
Batch spans now report the `MULTI`/`PIPELINE` operation they were already named
after, so their name follows from their attributes too.
Refs #23523
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Naming streamed redis spans after the bare command dropped the only target the
conventions can fill for redis, leaving `SET` to say nothing about where the
command went. Pair the operation with `{server.address}:{server.port}` again,
falling back to `{db.system.name}` when the client was configured without a host.
The native diagnostics_channel subscriber gets the same name, built from the
`serverAddress`/`serverPort` its payload already carries.
`FCALL`/`FCALL_RO` keep naming the redis function they call: the conventions rank
`db.stored_procedure.name` ahead of the connection.
Refs #23523
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>… suites The streamed expectations these suites gained were written before #23830 landed, so they still expected cache spans to be named after the cache key and carried no `cache.operation` attribute. Name them after the cache operation the hook now uses, and fold the repeated peer/operation attributes into a `cacheSpan` helper so the two cannot drift apart again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
node-redis v4 writes its `localhost:6379` socket defaults back into `client.options`, v5 does not. Reading the options as-is therefore reported `server.address`/`server.port` for a v4 client and neither for the identically configured v5 one — so the same client got `SET localhost:6383` on v4 and the bare `redis` fallback on v5 once span names became low cardinality. Resolve the connection the way node-redis >= 5.12 reports it on its own diagnostics channel instead: a TCP client falls back to `localhost:6379`, and a unix socket reports its path as the address and no port. Batch spans go through the same helper rather than repeating the option lookup. The redis-cache suite picks up the low-cardinality cache names from #23830 in the same pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add the `db.query` (redis, ioredis) row to the span name table and the prose covering why the connection replaces the serialized command, the new `db.stored_procedure.name` attribute on `FCALL`, and the node-redis connection defaults that now apply in both trace lifecycles. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both comments misled a review bot. The connect span shares its trace with the command spans and lands in the same container, so say what `unordered` is actually guarding against, and spell out that the conventions have no address-only template, which is why a unix socket keeps the `redis` fallback even though its address is known. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#23844 ported this app to span streaming while this branch was open, so its ioredis assertions still expected the serialized command as the span name. The route builds its client without a host or port, so the name reports ioredis' own `localhost:6379` defaults, which the expectations now pin as `server.address`/`server.port` too. The duplicate-span check keys off `db.query.text`, which still tells the two commands apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3692135 to
6a59114CompareThere was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6a59114. Configure here.
| ...(options?.socket?.host != null ? { [SERVER_ADDRESS]: options.socket.host } : {}), | ||
| ...(options?.socket?.port != null ? { [SERVER_PORT]: options.socket.port } : {}), | ||
| [SERVER_ADDRESS]: host, | ||
| ...(port != null ? { [SERVER_PORT]: port } : {}), |
There was a problem hiding this comment.
URL clients get default Redis target
Medium Severity
nodeRedisAttributes now treats a missing socket.host/socket.path as localhost:6379 and never reads options.url. A node-redis client configured only with a URL therefore reports the wrong server.address/server.port and, when streaming, a wrong span name such as SET localhost:6379.
Reviewed by Cursor Bugbot for commit 6a59114. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Composes the start-time cache classification with develop's low-cardinality redis db span names (#23741): at each span start site the cache name/op wins for cache-prefixed keys, the streamed db name applies otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Looks like we ran into some timing issues with merging PRs. #23741 changed redis span names to be low cardinality when span streaming is enabled, and some e2e tests were converted to span streaming at the same time. However, the e2e tests didn't take these changes into account. Partially my bad because I wasn't aware that we test redis spans in so many e2e tests. Good to have them though! Partially ... merge queues?


With span streaming enabled, redis
db.queryspans are named{db.operation.name} {server.address}:{server.port}. Redis has no SQL statement to summarize and no collection to pair the command with, so the connection is the only low-cardinality target left. The command and its arguments stay ondb.query.text.db.namespaceis not used: for redis it is the numeric database index.set test-key [1 other arguments]set localhost:6379SET test-key [1 other arguments]SET localhost:6379redis-SETSET localhost:6379SET test-key [1 other arguments]redisFCALLfcall my_funcMULTI/PIPELINEChanges:
FCALL/FCALL_ROare named after the redis functiondb.stored_procedure.nameattribute holds that function namedb.operation.nameserver.addressandserver.portcache.*span names #23830MIGRATION.mdentry addednode-redis v4 writes its
localhost:6379socket defaults back intoclient.options, v5 does not. The same client therefore reported a connection on v4 and none on v5. Both now resolve it the way node-redis >= 5.12 publishes it on its diagnostics channel, in both trace lifecycles.Refs #23523