-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(server-utils)!: Emit low cardinality knex, tedious and prisma db span names #23602
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,9 +5,14 @@ | |
| import * as diagnosticsChannel from 'node:diagnostics_channel'; | ||
| import type { IntegrationFn, Span, SpanAttributes } from '@sentry/core'; | ||
| import { | ||
| _INTERNAL_getSqlQuerySummary, | ||
| _INTERNAL_sanitizeSqlQuery, | ||
| DB_SPAN_NAME_FALLBACK, | ||
| debug, | ||
| defineIntegration, | ||
| getActiveSpan, | ||
| getClient, | ||
| hasSpanStreamingEnabled, | ||
| SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, | ||
| SPAN_STATUS_ERROR, | ||
| startInactiveSpan, | ||
|
|
@@ -17,6 +22,7 @@ import { | |
| import { | ||
| DB_NAMESPACE, | ||
| DB_OPERATION_NAME, | ||
| DB_QUERY_SUMMARY, | ||
| DB_QUERY_TEXT, | ||
| DB_SYSTEM_NAME, | ||
| DB_USER, | ||
|
|
@@ -167,6 +173,11 @@ function subscribeQuery(): void { | |
| connection?.filename || connection?.database || extractDatabaseFromConnectionString(connectionString); | ||
|
|
||
| const dbStatement = query?.sql != null ? truncate(query.sql, MAX_QUERY_LENGTH) : undefined; | ||
| // The statement is sanitized before it is summarized, so that a string literal containing | ||
| // `from`/`join` can't leak a value into the summary. | ||
| const querySummary = dbStatement | ||
| ? _INTERNAL_getSqlQuerySummary(_INTERNAL_sanitizeSqlQuery(dbStatement)) | ||
| : undefined; | ||
| const attributes: SpanAttributes = { | ||
| [SENTRY_KIND]: 'client', | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, | ||
|
|
@@ -180,10 +191,20 @@ function subscribeQuery(): void { | |
| [SERVER_PORT]: connection?.port ?? extractPortFromConnectionString(connectionString), | ||
| [NETWORK_TRANSPORT]: connection?.filename === ':memory:' ? 'inproc' : undefined, | ||
| [DB_QUERY_TEXT]: dbStatement, | ||
| [DB_QUERY_SUMMARY]: querySummary, | ||
| }; | ||
|
|
||
| const sentryClient = getClient(); | ||
| // With span streaming, span names have to be low cardinality, so `{db.query.summary}` is used | ||
| // instead of the full statement, falling back to `getName`'s `{operation} {namespace}.{table}` | ||
| // when there is no statement to summarize. | ||
| const streamedName = | ||
| sentryClient && hasSpanStreamingEnabled(sentryClient) | ||
| ? querySummary || getName(name, operation, table) || DB_SPAN_NAME_FALLBACK | ||
| : undefined; | ||
|
|
||
| return startInactiveSpan({ | ||
| name: dbStatement ?? getName(name, operation, table) ?? 'knex.query', | ||
| name: streamedName ?? dbStatement ?? getName(name, operation, table) ?? 'knex.query', | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feat PR missing integration testsMedium Severity Flagged because the PR review guidelines ask feat PRs to include at least one integration or E2E test. This change adds streamed low-cardinality names and Additional Locations (2)Triggered by project rule: PR Review Guidelines for Cursor Bot Reviewed by Cursor Bugbot for commit c57ede4. Configure here. |
||
| op: 'db', | ||
| parentSpan, | ||
| attributes, | ||
|
|
||


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.
Truncation breaks summary sanitization
Medium Severity
Knex truncates the SQL with
truncatebefore_INTERNAL_sanitizeSqlQueryand_INTERNAL_getSqlQuerySummary. Truncation can cut an open string literal, so the sanitize pass misses it andFROM/JOINtokens inside that literal can land indb.query.summaryand the streamed span name, which is the leak this sanitization step is meant to block.Reviewed by Cursor Bugbot for commit c57ede4. Configure here.