Learn how to leverage BugSnag to see errors linked to your performance data
By linking your application’s errors and performance data together, you can see where errors occurred in the full context of a distributed trace. You can navigate from the error to the relevant distributed trace with just one click in your BugSnag dashboard.
To link errors with distributed traces you need to use both BugSnag Error and BugSnag Performance SDKs. With the exception of JavaScript and React Native (described below), the two SDKs automatically link their data when supported versions of the SDKs are used.
Platform | Minimum Error SDK | Minimum Performance SDK | ||
---|---|---|---|---|
Android | bugsnag-android |
v6.6.0 | bugsnag-android-performance |
v1.4.0 |
Flutter | bugsnag-flutter |
v4.0.0 | bugsnag-flutter-performance |
v1.1.0 |
iOS | bugsnag-cocoa |
v6.30.1 | bugsnag-cocoa-performance |
v1.6.0 |
React Native | bugsnag-js |
v8.06.0 | bugsnag-js-performance |
v2.8.0 |
Unity | bugsnag-unity |
v8.2.0 | bugsnag-unity-performance |
v1.6.0 |
Web | bugsnag-js |
v8.0.0 | bugsnag-js-performance |
v2.8.0 |
The JavaScript and React Native SDKs require a manual configuration step to link their data. As part of the Basic configuration of the Performance SDK, pass in the bugsnag
field with a reference to the BugSnag Error client which is accessed via the Bugsnag
global in most cases:
BugsnagPerformance.start({
apiKey: 'YOUR_API_KEY',
bugsnag: Bugsnag
})
If you are using a different OTel-compliant SDK or a version of the BugSnag Error SDK not supporting error linking, you can combine performance and error data manually by setting the active trace and span ID in the metadata of error events.
The following snippets show how this can be achieved, adding a correlation
metadata section with traceId
and spanId
keys populated from current span’s context:
using System.Diagnostics;
var currentActivity = Activity.Current;
if (currentActivity == null){
return;
}
var bugsnag = new Bugsnag.Client(new Configuration("YOUR_API_KEY"));
bugsnag.BeforeNotify((Report report) =>
{
report.Event.Metadata.Add("correlation", new Dictionary<string, object> {
{ "traceId", currentActivity.TraceId.ToString() },
{ "spanId", currentActivity.SpanId.ToString() }
});
}
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
Bugsnag bugsnag = new Bugsnag(this.bugsnagToken);
bugsnag.addCallback(report -> {
Span currentSpan = Span.current();
if(Objects.nonNull(currentSpan)) {
SpanContext spanContext = currentSpan.getSpanContext();
report.addToTab("correlation", "traceId", spanContext.getTraceId());
report.addToTab("correlation", "spanId", spanContext.getSpanId());
}
});
import { trace, context } from '@opentelemetry/api';
import Bugsnag from '@bugsnag/js'
Bugsnag.start({
apiKey: 'YOUR_API_KEY',
onError: function (event: any) {
const spanContext = trace.getSpanContext(context.active());
event.addMetadata('correlation', {
traceId: spanContext.traceId,
spanId: spanContext.spanId
});
}
})
from opentelemetry import trace
import bugsnag
def callback(event):
current_span = trace.get_current_span()
if current_span != None:
span_context = current_span.get_span_context()
event.add_tab("correlation", {
"traceId": trace.format_trace_id(span_context.trace_id),
"spanId": trace.format_span_id(span_context.span_id),
})
bugsnag.before_notify(callback)
import (
"go.opentelemetry.io/otel"
"github.com/bugsnag/bugsnag-go"
)
traceCtx := trace.SpanContextFromContext(ctx)
bugsnag.Notify(err, ctx, bugsnag.MetaData{
"correlation": {
"traceId": traceCtx.TraceID().String(),
"spanId": traceCtx.SpanID().String(),
},
})
require 'opentelemetry'
Bugsnag.configure do |config|
config.add_on_error(proc do |event|
current_span = OpenTelemetry::Trace.current_span
if current_span
event.add_metadata(:correlation, {
traceId: current_span.context.hex_trace_id,
spanId: current_span.context.hex_span_id,
})
end
end)
end