faro 0.12.0
faro: ^0.12.0 copied to clipboard
Grafana Faro SDK for Flutter applications - Monitor your Flutter app with ease.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased] #
0.12.0 - 2026-03-05 #
Deprecated #
markEventStart()andmarkEventEnd()are now deprecated. UsestartSpan()for duration tracking. UsestartUserAction()when you need interaction-level correlation across logs, events, exceptions, and spans. UsestartSpanManual()for manual span lifecycle control.
Added #
- UI activity monitoring for user actions: The SDK now automatically
monitors Flutter widget rebuilds to detect UI responses to user actions.
This emits bounded activity signals that keep user actions alive while the
UI is updating, similar to DOM mutation observation in the Web SDK.
Disable via
enableUiActivityMonitoring: falseinFaroConfig. - Asset load lifecycle signals: Asset loads via
FaroAssetTrackingnow emit activity signals to keep user actions alive during resource loading. - Expanded asset tracking:
FaroAssetBundlenow also tracksloadBufferandloadStructuredBinaryDatain addition toloadandloadString.
Changed #
-
BREAKING:
FaroAssetTrackingreplacesFaroAssetBundlein public API:FaroAssetBundleis no longer exported frompackage:faro/faro.dart. UseFaroAssetTracking(child: ...)instead ofDefaultAssetBundle(bundle: FaroAssetBundle(), child: ...).// Before DefaultAssetBundle( bundle: FaroAssetBundle(), child: const FaroUserInteractionWidget(child: MyApp()), ) // After FaroAssetTracking( child: const FaroUserInteractionWidget(child: MyApp()), ) -
HTTP tracking no longer emits the legacy
http_requestcustom event fromHttpTrackingClient. -
HTTP request telemetry continues to be available through span-derived
faro.tracing.fetchevents and OTLP spans. -
Pending operation lifecycle signals are now span-driven via
UserActionConstants.pendingOperationKey:- HTTP spans set this marker automatically.
- Custom spans can opt in by setting this attribute to
true. - Marker-based pending operations use span ID as operation ID.
- The marker attribute is exported with the span/event attributes.
0.11.0 - 2026-03-03 #
Added #
-
User Actions: Group related telemetry (logs, events, exceptions, traces) under a single action context to track end-to-end user interactions. (Resolves #131)
Faro().startUserAction('name')starts a new action that buffers and enriches telemetry with action contextFaro().getActiveUserAction()returns the currently active action handle- Automatic lifecycle management with follow-up timeout (100ms) and halt timeout (10s)
- HTTP requests and navigation events automatically extend action lifetime via signal channels
- Telemetry items captured during an action include
action.nameandaction.idfor correlation in Grafana - Only one action can be active at a time; overlapping calls return
null - Spans created during an action automatically receive
faro.action.user.nameandfaro.action.user.parentIdattributes viaFaroUserActionSpanProcessor
-
HTTP Tracking Filter: New
HttpTrackingFilterfor controlling which URLs are instrumented- Automatically excludes Faro collector URL from tracking
- Supports
ignoreUrlspatterns fromFaroConfigto skip custom URL patterns
-
New dependency: Added
dartypod(^0.2.0) for lightweight dependency injection
Changed #
- Documentation consolidation: Replaced separate
Getting Started.md,Features.md, andConfigurations.mdwith a single comprehensiveReference.md
0.10.0 - 2026-02-09 #
Added #
-
Session sampling support: New
samplingconfiguration option allows controlling what percentage of sessions send telemetry data. This enables cost management and traffic reduction for high-volume applications. (Resolves #89)- Use
SamplingRate(0.5)for fixed 50% sampling - Use
SamplingFunction((context) => ...)for dynamic sampling based on session context (user attributes, app environment, etc.) - If not provided, all sessions are sampled (100%)
- Sampling decision is made once per session at initialization and applies to all telemetry types (events, logs, exceptions, measurements, traces)
- Example:
sampling: SamplingFunction((context) => context.meta.user?.attributes?['role'] == 'beta' ? 1.0 : 0.1) - Aligns with Faro Web SDK sampling behavior
- Use
-
ContextScope for span context lifetime control: New
contextScopeparameter onstartSpan()controls how long a span remains active in zone context for auto-assignment.ContextScope.callback(default) deactivates the span when the callback completes, preventing timer/stream callbacks from inheriting it.ContextScope.zonekeeps the span active for the entire zone lifetime, useful when you want timer callbacks to be children of the parent span. (Resolves #105) -
Span.noParent sentinel: New
Span.noParentstatic constant allows explicitly starting a span with no parent, ignoring the active span in zone context. Useful for timer callbacks or event-driven scenarios where you want to start a fresh, independent trace. (Resolves #105)
Fixed #
- SDK-internal span attributes now use typed values: HTTP span attributes (
http.status_code,http.request_size,http.response_size) are now sent as integers instead of strings, enabling proper numeric queries in Tempo (e.g.,status_code > 400) - Session attributes support typed values:
sessionAttributesconfig now acceptsMap<String, Object>allowing typed custom attributes. Thedevice_is_physicalattribute is now sent as a boolean instead of a string. (Resolves #133)
0.9.0 - 2026-01-28 #
Fixed #
- OTLP trace attributes now preserve types: Span attributes and event attributes now correctly preserve their original types (int, double, bool, String) when sent via OTLP
- Previously, all attribute values were converted to strings, making numeric querying and bucketing difficult in Grafana/Tempo
- Now attributes like
user.account_count: 42are sent as integers, enabling queries likeaccount_count > 10and proper histogram bucketing - Updated
TraceAttributeValueto supportstringValue,intValue,doubleValue, andboolValuefields per OTLP specification - Updated
Span.setAttributes()andSpan.addEvent()to acceptMap<String, Object>for typed values - Updated
Span.setAttribute(String key, Object value)to accept any supported type (previously only String) - Backward compatible:
Span.setAttribute(String key, String value)still works for string-only use cases - Resolves issue #126: OTLP trace attributes forced to string type
0.8.0 - 2026-01-13 #
Added #
-
User management with FaroUser model: New
FaroUserclass for comprehensive user identification- Replaces the legacy
Usermodel with a more feature-rich implementation - Supports
id,username,email, and customattributesfields - Custom attributes align with Faro Web SDK MetaUser for cross-platform consistency
- Includes
FaroUser.cleared()constructor to explicitly clear user data
- Replaces the legacy
-
User persistence: New
persistUseroption inFaroConfig(default:true)- Automatically saves user identity to device storage
- Restores user on subsequent app launches for consistent session tracking
- Early events like
appStartinclude user data when persistence is enabled - Fires
user_setevent on restore anduser_updatedevent on changes
-
Initial user configuration: New
initialUseroption inFaroConfig- Set a user immediately on SDK initialization
- Use
FaroUser.cleared()to explicitly clear any persisted user on start - Useful for apps that know the user at startup or need to force logout state
-
New setUser() API: Streamlined method for setting user identity
Faro().setUser(FaroUser(...))to set userFaro().setUser(FaroUser.cleared())to clear user- Returns
Future<void>for awaiting persistence completion
Changed #
- Deprecated setUserMeta(): Use
setUser(FaroUser(...))instead- Legacy method still works but will be removed in a future version
- Migration: Replace
setUserMeta(userId: 'x', userName: 'y', userEmail: 'z')withsetUser(FaroUser(id: 'x', username: 'y', email: 'z')) - Breaking: Now requires SDK initialization (
init()orrunApp()) before calling. Previously,setUserMeta()could be called before initialization. Calls made before initialization will now be silently ignored.
0.7.0 - 2025-12-02 #
⚠️ Note: This release updates Android build requirements.
Due to the
device_info_plusv12 upgrade, your Android project now requires:
- Android Gradle Plugin ≥8.7.0
- Gradle wrapper ≥8.10
- Kotlin ≥2.2.0
- Java 17
Added #
- Human-readable device model name: Added new
deviceModelNamefield toDeviceInfoanddevice_model_namesession attribute- iOS: Returns marketing name (e.g., "iPhone 15 Pro") instead of internal identifier ("iPhone16,1")
- Android: Same as
deviceModel- Android does not provide a mapping from model codes to marketing names
Changed #
- Upgraded
device_info_plusfrom v11.4.0 to v12.3.0- Enables access to new
modelNameproperty on iOS for human-readable device names - Includes latest device identifier mappings (iPhone 16/17 series, iPad Pro M5, etc.)
- Enables access to new
0.6.0 - 2025-11-25 #
Added #
- control Flutter error reporting: new
enableFlutterErrorReportinginFaroConfigto control Flutter error reporting (default = true)
0.5.0 - 2025-10-31 #
Added #
- Custom session attributes: New optional
sessionAttributesparameter inFaroConfigfor adding custom labels to all telemetry- Allows setting custom key-value pairs that are included in all telemetry data (logs, events, exceptions, traces, measurements)
- Useful for access control labels, team/department segmentation, and environment-specific metadata
- Custom attributes are merged with default attributes (SDK version, device info, etc.)
- Default attributes take precedence if naming conflicts occur
- Equivalent to
sessionTracking.session.attributesin Faro Web SDK
0.4.2 - 2025-08-28 #
Changed #
- Removed intl dependency: Replaced custom date formatting with built-in
DateTime.toIso8601String()method- Removed
intlpackage dependency to reduce package footprint - Updated timestamp generation in Event, FaroLog, FaroException, and Measurement models
- Uses standard ISO 8601 format via Dart's native
DateTime.toIso8601String()method - Maintains compatibility while eliminating external dependency
- Removed
0.4.1 - 2025-07-16 #
Fixed #
-
SDK name consistency across telemetry types: Updated SDK identification to use consistent naming
- Changed hardcoded 'rum-flutter' SDK name to use
FaroConstants.sdkNamefor consistency with OpenTelemetry traces - Maintains backend-compatible version '1.3.5' for proper web SDK version validation
- Added actual Faro Flutter SDK version to session attributes as 'faro_sdk_version' for tracking real SDK version
- Changed hardcoded 'rum-flutter' SDK name to use
-
FaroZoneSpanManager span status preservation: Fixed issue where manually set span statuses were overridden by automatic status setting
- Added
statusHasBeenSetproperty toSpaninterface to track when status has been manually set - Updated
FaroZoneSpanManager.executeWithSpan()to respect manually set span statuses for both success and error cases - Prevents overriding of custom span statuses (e.g., business logic errors) when code executes without throwing exceptions
- Maintains existing behavior for spans that haven't had their status manually set
- Resolves issue #86: FaroZoneSpanManager overrides manually set span statuses on success
- Added
0.4.0 - 2025-07-02 ⚠️ BREAKING CHANGES #
Changed #
- BREAKING: Package structure refactoring to follow Flutter plugin conventions: Reorganized the package to align with Flutter/Dart ecosystem standards and best practices
-
Breaking Change: Main entry point changed from
faro_sdk.darttofaro.dart- The package now follows the standard
lib/<package_name>.dartconvention - Removed
lib/faro_sdk.dartfile entirely lib/faro.dartis now the single main entry point with selective barrel exports
- The package now follows the standard
-
Migration: Update your imports to use the new main entry point
// Before import 'package:faro/faro_sdk.dart'; // After import 'package:faro/faro.dart'; -
Architecture Improvements:
- Moved core
Faroclass implementation fromlib/faro.darttolib/src/faro.dart lib/faro.dartnow serves as a clean barrel export file exposing only public APIs- All implementation details properly organized under
lib/src/directory - Clear separation between public API surface and private implementation
- Follows established Flutter ecosystem conventions used by popular packages like Provider, BLoC, and Dio
- Moved core
-
Benefits:
- Cleaner API boundaries: Clear distinction between public and private APIs
- Better maintainability: Implementation details can evolve without affecting public interface
- Consistent developer experience: Matches patterns developers expect from other Flutter packages
- Future-proof: Enables easier API evolution and versioning
- Community alignment: Follows official Flutter/Dart documentation recommendations
-
No functionality changes: All existing public APIs remain the same, only import paths have changed
-
Added #
-
Type-Safe Log Level API: New
LogLevelenum for improved logging reliability and developer experience- Introduced
LogLevelenum with values:trace,debug,info,log,warn,error - Aligns with Grafana Faro Web SDK for cross-platform consistency
- Includes
fromString()method for backward compatibility, supporting both'warn'and'warning'variants
- Introduced
-
Enhanced Tracing and Span API: Major improvements to distributed tracing capabilities
- New
startSpan<T>()method for automatic span lifecycle management with callback-based execution - New
startSpanManual()method for manual span lifecycle management when precise control is needed - New
getActiveSpan()method to access the currently active span from anywhere in the execution context - Zone-based span context management ensures proper parent-child relationships across async boundaries
- Automatic session ID injection - all spans now include both
session_idandsession.idattributes - Improved error handling with automatic span status updates when exceptions occur
- Enhanced span status tracking with proper OpenTelemetry status code mapping
- Support for custom parent span specification to create explicit span hierarchies
- Comprehensive documentation with detailed examples for common tracing patterns
- New
-
Centralized Session Management: New
SessionIdProviderfor consistent session handling across the SDK- Dedicated session ID generation and management
- Better integration with tracing system for session context propagation
- Factory pattern for testable session management
-
SDK Constants Management: New centralized constants system
- Added
FaroConstantsclass for SDK version and name management - Better version tracking and consistency across the codebase
- Added
-
BREAKING: Synchronous API for telemetry methods: Refactored telemetry methods to remove unnecessary async patterns for improved performance and developer experience
-
Breaking Change: The following methods changed from
Future<void>?tovoid:pushEvent()- Send custom eventspushLog()- Send custom logspushError()- Send custom errorspushMeasurement()- Send custom measurementsmarkEventEnd()- Mark event completion
-
Migration: Remove
awaitkeywords from calls to these methods as they are now synchronous// Before await Faro().pushEvent('event_name'); await Faro().pushLog('message', level: LogLevel.info); // After Faro().pushEvent('event_name'); Faro().pushLog('message', level: LogLevel.info); -
Benefits:
- Improved performance by eliminating unnecessary async overhead
- Cleaner API that better reflects the synchronous nature of these operations
- Reduced complexity in application code
-
Internal Architecture: Introduced
BatchTransportFactorysingleton pattern for better dependency management and testing
-
-
BREAKING: pushLog API requires LogLevel enum: Enhanced logging API for better type safety and consistency
- Breaking Change:
pushLog()now requires aLogLevelparameter instead of optionalString? - Migration: Replace
level: "warn"withlevel: LogLevel.warnin your pushLog calls - Benefit: Eliminates typos in log levels and provides better IDE support
- Compatibility: Existing string-based log levels in internal code updated to use LogLevel enum
- Documentation: All examples and documentation updated to reflect the new API
- Breaking Change:
-
Tracing Architecture Refactoring: Complete redesign of the internal tracing system
- Replaced legacy
tracer.dartandtracer_provider.dartwith newFaroTracerimplementation - New
FaroZoneSpanManagerfor robust zone-based span context management - Improved
Spanclass with cleaner API and better OpenTelemetry integration - Enhanced span creation and management with proper resource attribution
- Better separation of concerns between tracing components
- Zone-based implementation ensures proper parent-child relationships across async boundaries
- Enhanced developer experience with multiple tracing approaches for different use cases
- Better integration between tracing and other SDK components
- Replaced legacy
-
Session Management: Extracted session logic from distributed components
- Removed deprecated
generate_session.dartutility - Centralized session management in dedicated provider
- Improved testability and maintainability of session-related functionality
- Removed deprecated
0.3.7 - 2025-06-10 #
Added #
- Enhanced HTTP tracing attributes: HTTP spans now include additional attributes for better observability
- Added
http.request_sizeattribute with request content length - Added
http.response_sizeattribute with response content length - Added
http.content_typeattribute with response content type - Provides more comprehensive HTTP request/response metadata for monitoring
- Added
- Session attributes in OpenTelemetry traces: Tracer resources now automatically include session attributes
- Session metadata is propagated to all OpenTelemetry spans
- Enables correlation of traces with user sessions and custom session data
- Supports dynamic session attribute values (strings, numbers, booleans, objects)
- Added comprehensive test coverage for
DartOtelTracerResourcesFactory
- Human-readable timestamps for Android crashes: Added readable timestamp formatting for crash reports
- Crash context now includes both original Unix epoch timestamp and human-readable ISO 8601 format
- Added
timestamp_readable_utcfield alongside existingtimestampfield - Timestamps converted to UTC ISO 8601 format (e.g., "2025-06-04T23:49:20.296Z")
- Includes new
TimestampExtensionutility for reusable timestamp conversion - Improves debugging experience with easily interpretable crash timestamps
- Resolves issue #53: Add human readable timestamp for Android crashes
- Trace event duration: Added duration information to trace events
- Events now include
duration_nsattribute with span duration in nanoseconds - Duration calculated as
endTime - startTimewhen both timestamps are valid - Improves observability by providing timing information for traced operations
- Resolves issue #23: Add duration to Faro events
- Events now include
Fixed #
- Span event naming: Fixed incorrect event names for tracing spans
- HTTP spans now correctly use
faro.tracing.fetchevent name - Non-HTTP spans use
span.{name}format for better event categorization - Added logic to detect HTTP spans based on
http.schemeorhttp.methodattributes - Resolves issue #41: Incorrect span event names being sent to collector
- HTTP spans now correctly use
- Event data URL formatting: Fixed inconsistent formatting of event_data_url parameter
- Attribute values are now properly sanitized to remove surrounding quotes
- Ensures consistent formatting across all event attributes
- Resolves issue #25: Inconsistent event_data_url formatting
0.3.6 - 2025-06-05 #
Added #
- Data Collection Persistence: The
enableDataCollectionsetting now persists across app restarts- Automatically saves the data collection preference to device storage using SharedPreferences
- Defaults to enabled on first app launch
- Fire-and-forget persistence - no need to await setting changes
- Maintains full backward compatibility with existing API
- Resolves issue #62: "Persist faro.enableDataCollection"
- GitHub issue templates for bug reports and feature requests
- Pull request template for standardized contributions
- Code of Conduct (Contributor Covenant v1.4)
- Comprehensive Contributing Guidelines with setup instructions and development workflow
- Maintainers documentation listing current project maintainers
Changed #
- Major documentation overhaul:
- Enhanced README with improved badges, clearer setup instructions, and better project description
- Completely rewritten Features documentation with detailed explanations and code examples
- Improved Getting Started guide with step-by-step setup for both Grafana Cloud and self-hosted options
- Updated example app to demonstrate latest SDK features and best practices
Improved #
- Project governance and community guidelines establishment
- Developer experience with better onboarding documentation
- Code contribution workflow with standardized templates and processes
Fixed #
- Critical NullPointerException in Android frame monitoring: Fixed crash when frame monitoring callbacks execute after Flutter engine detachment
- Added proper cleanup in
stopFrameMonitoring()to remove Choreographer callbacks - Added null checks in
handleFrameDrop(),handleSlowFrameDrop(), andhandleRefreshRate()methods - Added safety guards to prevent frame processing when monitoring is stopped
- Prevents crashes when app goes to background or during configuration changes
- Added proper cleanup in
0.3.5 - 2025-05-28 #
Added #
- Support for custom HTTP headers in
FaroConfigvia thecollectorHeadersfield- Allows users to specify headers that will be included in all requests to the collector endpoint
- Useful for deployments that require specific headers for routing or authentication
0.3.4 - 2025-05-22 #
0.3.3 #
Changed #
- Updated intl dependency to newer version to be compatible with latest flutter version
0.3.0 #
Changed #
- Restructure where faro code is located. Moved from
packages/faroto root. Since we only have one package in this repo for now
0.2.2 #
0.2.0 #
Changed #
- Renamed package from
rum_sdktofaro - Renamed main API class from
RumFluttertoFaro - Renamed all related classes with "Rum" prefix to "Faro" prefix
- Updated all import statements to use the new package name
- Updated documentation with new package name and examples
0.0.1 #
Added #
The following Key Metrics of Flutter Applications are Added in the Alpha Release.
- Mobile App Performance
- cpu usage
- memory usage
- cold/warm start
- ANR ( android)
- Native slow/frozen frames
- Flutter Errors & Exceptions
- Events
- session start
- route changes
- user interaction
- Http network info
- Load Duration , method , resource/type , request/response size
- Rum Asset Bundle
- Asset Size, Load time
- Custom events, logs, measurement, error
- Offline Caching of Events