Skip to content

Commit 35ecd2d

Browse files
committed
Add errorFingerprinting config option to disable fingerprinting in browser
Minified browser code produces unstable fingerprints because function names are mangled, causing the same logical error to generate different fingerprints across deployments. - Add errorFingerprinting option to LogfireApiConfigOptions - Browser SDK defaults to false, Node SDK defaults to true - Conditionally compute fingerprint in reportError() based on setting
1 parent 0714d53 commit 35ecd2d

5 files changed

Lines changed: 56 additions & 21 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"logfire": minor
3+
"@pydantic/logfire-browser": minor
4+
"@pydantic/logfire-node": minor
5+
---
6+
7+
Add `errorFingerprinting` configuration option to control error fingerprint computation
8+
9+
Error fingerprinting enables grouping similar errors in the Logfire backend. However, minified browser code produces unstable fingerprints because function names are mangled, causing the same logical error to generate different fingerprints across deployments.
10+
11+
- Added `errorFingerprinting` option to `LogfireApiConfigOptions`
12+
- Browser SDK now defaults to `errorFingerprinting: false`
13+
- Node SDK keeps the default `errorFingerprinting: true`
14+
- Users can override the default in either SDK via the `configure()` options

packages/logfire-api/src/index.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -191,24 +191,21 @@ export function warning(message: string, attributes: Record<string, unknown> = {
191191
/**
192192
* Use this method to report an error to Logfire.
193193
* Captures the error stack trace and message in the respective semantic attributes and sets the correct level and status.
194-
* Computes a fingerprint for the error to enable issue grouping in the Logfire backend.
194+
* Computes a fingerprint for the error to enable issue grouping in the Logfire backend (if errorFingerprinting is enabled).
195195
*/
196196
export function reportError(message: string, error: Error, extraAttributes: Record<string, unknown> = {}) {
197-
const fingerprint = computeFingerprint(error)
197+
const attributes: Record<string, unknown> = {
198+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
199+
[ATTR_EXCEPTION_MESSAGE]: error.message ?? 'error',
200+
[ATTR_EXCEPTION_STACKTRACE]: error.stack,
201+
...extraAttributes,
202+
}
198203

199-
const span = startSpan(
200-
message,
201-
{
202-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
203-
[ATTR_EXCEPTION_MESSAGE]: error.message ?? 'error',
204-
[ATTR_EXCEPTION_STACKTRACE]: error.stack,
205-
[ATTRIBUTES_EXCEPTION_FINGERPRINT_KEY]: fingerprint,
206-
...extraAttributes,
207-
},
208-
{
209-
level: Level.Error,
210-
}
211-
)
204+
if (logfireApiConfig.enableErrorFingerprinting) {
205+
attributes[ATTRIBUTES_EXCEPTION_FINGERPRINT_KEY] = computeFingerprint(error)
206+
}
207+
208+
const span = startSpan(message, attributes, { level: Level.Error })
212209

213210
span.recordException(error)
214211
span.setStatus({ code: SpanStatusCode.ERROR, message: `${error.name}: ${error.message}` })

packages/logfire-api/src/logfireApiConfig.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ export interface ScrubbingOptions {
1313
}
1414

1515
export interface LogfireApiConfigOptions {
16+
/**
17+
* Whether to compute fingerprints for errors reported via reportError().
18+
* Fingerprints enable error grouping in the Logfire backend.
19+
* Defaults to true for Node.js, false for browser (minified code produces unstable fingerprints).
20+
*/
21+
errorFingerprinting?: boolean
1622
otelScope?: string
1723
/**
1824
* Options for scrubbing sensitive data. Set to False to disable.
@@ -44,6 +50,7 @@ export interface LogOptions {
4450

4551
export interface LogfireApiConfig {
4652
context: Context
53+
enableErrorFingerprinting: boolean
4754
otelScope: string
4855
scrubber: BaseScrubber
4956
tracer: Tracer
@@ -58,6 +65,7 @@ const DEFAULT_LOGFIRE_API_CONFIG: LogfireApiConfig = {
5865
get context() {
5966
return ContextAPI.active()
6067
},
68+
enableErrorFingerprinting: true,
6169
otelScope: DEFAULT_OTEL_SCOPE,
6270
scrubber: new LogfireAttributeScrubber(),
6371
tracer: TraceAPI.getTracer(DEFAULT_OTEL_SCOPE),
@@ -66,6 +74,10 @@ const DEFAULT_LOGFIRE_API_CONFIG: LogfireApiConfig = {
6674
export const logfireApiConfig: LogfireApiConfig = DEFAULT_LOGFIRE_API_CONFIG
6775

6876
export function configureLogfireApi(config: LogfireApiConfigOptions) {
77+
if (config.errorFingerprinting !== undefined) {
78+
logfireApiConfig.enableErrorFingerprinting = config.errorFingerprinting
79+
}
80+
6981
if (config.scrubbing !== undefined) {
7082
logfireApiConfig.scrubber = resolveScrubber(config.scrubbing)
7183
}

packages/logfire-browser/src/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ export interface LogfireConfigOptions {
7474
* Defaults to the `LOGFIRE_ENVIRONMENT` environment variable.
7575
*/
7676
environment?: string
77+
/**
78+
* Whether to compute fingerprints for errors reported via reportError().
79+
* Defaults to false for browser since minified code produces unstable fingerprints.
80+
*/
81+
errorFingerprinting?: boolean
7782
/**
7883
* The instrumentations to register - a common one [is the fetch instrumentation](https://www.npmjs.com/package/@opentelemetry/instrumentation-fetch).
7984
*/
@@ -119,9 +124,10 @@ export function configure(options: LogfireConfigOptions) {
119124
diag.setLogger(new DiagConsoleLogger(), options.diagLogLevel)
120125
}
121126

122-
if (options.scrubbing !== undefined) {
123-
configureLogfireApi({ scrubbing: options.scrubbing })
124-
}
127+
configureLogfireApi({
128+
errorFingerprinting: options.errorFingerprinting ?? false,
129+
scrubbing: options.scrubbing,
130+
})
125131

126132
const resource = resourceFromAttributes({
127133
[ATTR_BROWSER_LANGUAGE]: navigator.language,

packages/logfire-node/src/logfireConfig.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ export interface LogfireConfigOptions {
6969
* Defaults to the `LOGFIRE_ENVIRONMENT` environment variable.
7070
*/
7171
environment?: string
72+
/**
73+
* Whether to compute fingerprints for errors reported via reportError().
74+
* Fingerprints enable error grouping in the Logfire backend.
75+
* Defaults to true for Node.js.
76+
*/
77+
errorFingerprinting?: boolean
7278
/**
7379
* Additional third-party instrumentations to use.
7480
*/
@@ -169,12 +175,12 @@ const DEFAULT_LOGFIRE_CONFIG: LogfireConfig = {
169175
export const logfireConfig: LogfireConfig = DEFAULT_LOGFIRE_CONFIG
170176

171177
export function configure(config: LogfireConfigOptions = {}) {
172-
const { otelScope, scrubbing, ...cnf } = config
178+
const { errorFingerprinting, otelScope, scrubbing, ...cnf } = config
173179

174180
const env = process.env
175181

176-
if (otelScope !== undefined || scrubbing !== undefined) {
177-
logfireApi.configureLogfireApi({ otelScope, scrubbing })
182+
if (errorFingerprinting !== undefined || otelScope !== undefined || scrubbing !== undefined) {
183+
logfireApi.configureLogfireApi({ errorFingerprinting, otelScope, scrubbing })
178184
}
179185

180186
const token = cnf.token ?? env.LOGFIRE_TOKEN

0 commit comments

Comments
 (0)