Skip to main content

Session sampling

Exclude instrumentations from session sampling​

sdkSampler sets the percentage of sessions (0-100) whose events are reported. A sampled-out session still starts the SDK and keeps sending the traceparent header, so its requests still correlate with your backend traces, but its events are not reported. Use excludeFromSampling to keep specific instrumentation categories reporting on a sampled-out session. This is useful when you ship sdkSampler: 0 (or a low rate) for cost control but still want every error and log.

import 'package:cx_flutter_plugin/cx_excludable_instrumentation.dart';

var options = CXExporterOptions(
// ...other options...
sdkSampler: 0,
excludeFromSampling: const [
CXExcludableInstrumentation.errors,
CXExcludableInstrumentation.logs,
],
);

Supported categories: errors, logs, network, userInteractions, mobileVitals, customSpan, customMeasurement. Defaults to an empty list, so a sampled-out session reports none of these categories. The SDK still sends a single initialization event for it, so you can tell a sampled-out session apart from one where the SDK never started.

instrumentations always wins over excludeFromSampling. Listing a category does not turn back on an instrumentation you set to false, and the list has no effect on a session that is sampled in.

Telling excluded events apart in beforeSend​

Every event carries isSessionSampledIn (read-only). false means the event reached export only because its category is listed in excludeFromSampling — the session itself was sampled out. Use it in beforeSend to apply your own filtering on top of the exclude list, e.g. keep only errors from sampled-out sessions:

var options = CXExporterOptions(
// ...other options...
sdkSampler: 5,
excludeFromSampling: const [
CXExcludableInstrumentation.errors,
CXExcludableInstrumentation.logs,
],
beforeSend: (event) {
// Session sampled out: forward only error-severity events, drop the rest.
if (!event.isSessionSampledIn &&
event.eventContext?.severity != CxLogSeverity.error) {
return null;
}
return event;
},
);

event.isSessionSampledIn is a convenience accessor over event.sessionContext?.isSessionSampledIn, and defaults to true when the event carries no session context. The flag is also mirrored on instrumentation_data.otelSpan.attributes as cx_rum.session_context.isSessionSampledIn.

Session identity is read-only in beforeSend: isSessionSampledIn, session_id and session_creation_date are restored from the SDK's own values after your callback returns, and clearing sessionContext entirely restores it whole. Writing to them has no effect. The user identity fields (user_id, user_name, user_email, user_metadata) remain editable, so redacting user data in beforeSend works as before.

Crash events do not reach beforeSend. On both iOS and Android, crash events are uploaded directly by the native SDK rather than taking the round trip to Dart and back, so a dying process is not racing the extra hop. A beforeSend callback therefore never sees them: filtering, redaction, or label edits you apply there do not apply to crashes. If you need to keep data out of crash payloads, keep it out of the values you pass to the SDK (setLabels, setUserContext, reportError data) rather than relying on beforeSend.

Requires the native SDKs bundled with plugin ≥ 0.11.0 (iOS 2.13.1 / Android 2.19.1). Against older natives the flag is absent and reads as true.

Last updated on
Was this page helpful?