obsly_flutter 0.2.0
obsly_flutter: ^0.2.0 copied to clipboard
Advanced Flutter SDK for comprehensive user behavior analytics, UI event tracking, and automatic screenshot capture with debug tools.
Obsly Flutter SDK #

Overview #
Obsly offers an advanced observability platform for iOS, Android and Web applications. This Flutter SDK mirrors the behavior and public API of the JavaScript Browser SDK, adapted to Flutter idioms.
- Automatic UI, navigation, network, console and crash capture
- Optional screenshot capture on UI and rage-click events
- Performance transactions and steps
- Custom metrics (counter, gauge, histogram timer)
- Tags, context, session and user identification
For API parity details, see the browser SDK documentation in the repository browser/README.md.
Table of Contents #
- Installation
- Initialization
- Wrap your app (required)
- Configuration
- Developer Methods
- Manage Sessions
- Client Identification
- Application Identification
- Tag
- Screenshot
- Performance
- Metrics
- Application Context
- SDK Control
- Miscellaneous
- Debug tools
- Requirements
- Getting Help
- License
Installation #
Add the dependency:
dependencies:
obsly_flutter: ^0.2.0
Initialization #
Initialize the SDK as early as possible, before building your app widget tree:
import 'package:flutter/widgets.dart';
import 'package:obsly_flutter/obsly_sdk.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await ObslySDK.instance.init(
InitParameters(
ObslyKey: 'YOUR_OBSLY_KEY',
instanceURL: 'https://api.obsly.com',
appName: 'MyFlutterApp',
appVersion: '1.0.0',
logLevel: 'error', // 'null' | 'error' | 'warn' | 'log' | 'debug'
debugMode: false,
config: const ObslyConfig(
enableAutomaticCapture: true,
enableScreenshotOnUi: false,
enableRageClickScreenshot: false,
),
// sessionID: 'optional-custom-session-id',
),
);
runApp(const MyApp());
}
Wrap your app (required) #
Wrap your MaterialApp (or root widget) so UI and navigation are intercepted globally. This also wires the screenshot capture boundary.
import 'package:flutter/material.dart';
import 'package:obsly_flutter/obsly_sdk.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ObslySDK.instance.wrapApp(
app: MaterialApp(
title: 'My App',
home: const HomePage(),
),
enableDebugTools: false, // set true to show the debug overlay
);
}
}
Configuration #
Init parameters (parity with JS Browser SDK):
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
ObslyKey |
String |
Yes | — | Authorization API key |
instanceURL |
String |
Yes | — | API server URL |
remoteConfigURL |
String? |
No | — | Remote config URL |
proEnv |
bool? |
No | — | Production environment flag |
appVersion |
String? |
No | — | App version |
appName |
String? |
No | — | App name |
logLevel |
String? |
No | "error" |
Allowed values: null, error, warn, log, debug |
config |
ObslyConfig? |
No | see below | Advanced configuration |
debugMode |
bool? |
No | false |
Enable debug overlay and verbose behavior |
sessionID |
String? |
No | — | Custom session ID on init |
ObslyConfig structure:
| Parameter | Type | Default | Description |
|---|---|---|---|
enableAutomaticCapture |
bool |
true |
Enable all automatic interceptors (UI, navigation, HTTP, console, crashes) |
enableDebugTools |
bool |
false |
Render floating debug tools when wrapping app |
logLevel |
LogLevel |
LogLevel.error |
Runtime log level (use setLogLevel for string-based) |
userId |
String? |
— | Pre-set user id |
appName |
String? |
— | Override app name |
appVersion |
String? |
— | Override app version |
enableScreenshotOnUi |
bool |
false |
Screenshot on UI and lifecycle events |
enableRageClickScreenshot |
bool |
false |
Screenshot subset for rage-click detection |
requestBlacklist |
List<String>? |
— | Wildcard URL blacklist for HTTP capture |
requestBodyWhitelist |
List<RequestBodyConfig>? |
— | URLs to capture request/response body on errors |
requestHeadersWhitelist |
List<RequestHeadersConfig>? |
— | URLs to capture whitelisted headers on errors |
rageClick |
RageClickConfig? |
— | Rage click configuration |
rateLimits |
RateLimits? |
— | Event type rate limits |
enableCrashes |
bool? |
— | Toggle crash events |
enableLifeCycleLog |
bool? |
— | Toggle lifecycle events |
enableRequestLog |
bool? |
— | Toggle request events |
enableTagger |
bool? |
— | Toggle tag events |
enablePerformance |
bool? |
— | Toggle performance events |
enableUI |
bool? |
— | Toggle UI events |
Rate Limit Configuration #
You can control the rate of captured events. Configure per-event-type limits inside ObslyConfig.rateLimits.
Event types:
- base, request, tag, console, ui, metric, error, performance, navigation
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
interval |
int |
1000 |
Interval in milliseconds for rate limiting |
trailing |
bool |
false |
Send trailing events after the rate limit period |
bucketSize |
int |
10 |
Max events to process within an interval (request: 20) |
emptyBucketDelay |
int |
1000 |
Delay in milliseconds before emptying the bucket |
rejectWhenBucketFull |
bool |
false |
If true, reject when full (console, error: true) |
Example:
final params = InitParameters(
ObslyKey: 'KEY',
instanceURL: 'https://api.url',
config: ObslyConfig(
rateLimits: const RateLimits(
error: RateLimitConfig(
interval: 2000,
bucketSize: 15,
trailing: true,
emptyBucketDelay: 2000,
rejectWhenBucketFull: false,
),
ui: RateLimitConfig(
bucketSize: 20,
emptyBucketDelay: 2000,
),
),
),
);
Request Headers Config #
Control which headers are captured for requests within a status range and URL pattern.
| Parameter | Type | Example | Description |
|---|---|---|---|
url |
String |
https://api.example.com/sensitive/* |
URL to capture headers (supports wildcards) |
fromStatus |
int |
400 |
Min HTTP status (inclusive) |
toStatus |
int |
599 |
Max HTTP status (inclusive) |
headers |
List<String> |
["content-type","x-request-id"] |
Specific headers to capture (supports wildcards) |
Example:
InitParameters(
ObslyKey: 'KEY',
instanceURL: 'https://api.url',
config: const ObslyConfig(
requestHeadersWhitelist: [
RequestHeadersConfig(
url: 'https://api.example.com/sensitive/*',
fromStatus: 400,
toStatus: 599,
headers: ['content-type', 'x-request-id'],
),
],
),
);
Request Body Config #
Capture request and/or response bodies on error ranges for matching URLs.
| Parameter | Type | Example | Description |
|---|---|---|---|
url |
String |
https://api.example.com/* |
URL to capture body (supports wildcards) |
fromStatus |
int |
400 |
Min HTTP status (inclusive) |
toStatus |
int |
599 |
Max HTTP status (inclusive) |
captureRequestBody |
bool |
true |
Capture request body |
captureResponseBody |
bool |
true |
Capture response body |
Example:
const config = ObslyConfig(
requestBodyWhitelist: [
RequestBodyConfig(
url: 'https://api.example.com/*',
fromStatus: 400,
toStatus: 599,
captureRequestBody: true,
captureResponseBody: true,
),
],
);
Wildcards #
Use wildcards in URL patterns and header names:
- URL:
https://example.com/*,https://*.example.com/*,*.example.com/* - Header:
*content*,content*,*type,x-*
Developer Methods #
All functions are available on ObslySDK.instance. For readability, performance and metrics are also exposed via namespaced getters Performance and Metrics.
Manage Sessions:
await ObslySDK.instance.closeCurrentSession();
await ObslySDK.instance.createNewSession('custom-session-id');
Client Identification:
await ObslySDK.instance.setUserID('user-123');
await ObslySDK.instance.setPersonID('person-456');
await ObslySDK.instance.setPassportID('passport-789');
await ObslySDK.instance.setContractID('contract-000');
Application Identification:
await ObslySDK.instance.setAppName('MyNewApp');
await ObslySDK.instance.setAppVersion('1.2.0');
Tag:
await ObslySDK.instance.addTag(
[Tag(key: 'user_tier', value: 'premium')],
'User Properties',
);
Screenshot:
await ObslySDK.instance.addScreenshot();
final base64Image = await ObslySDK.instance.getScreenshot();
Performance:
await ObslySDK.instance.Performance.startTransaction('DASHBOARD', 'Load Dashboard');
await ObslySDK.instance.Performance.startStep('Load Dashboard', 'DASHBOARD');
await ObslySDK.instance.Performance.finishStep('Load Dashboard', 'DASHBOARD');
await ObslySDK.instance.Performance.endTransaction('DASHBOARD');
Metrics:
ObslySDK.instance.Metrics.incCounter('CLICK_EVENT', 'FBL', 'OP', 'VIEW', 'OK');
ObslySDK.instance.Metrics.setGauge('CPU', 0.75, 'FBL', 'OP', 'VIEW', 'OK');
ObslySDK.instance.Metrics.startHistogramTimer('FETCH', 'FBL', 'OP', 'VIEW');
ObslySDK.instance.Metrics.endHistogramTimer('FETCH', 'FBL', 'OP', 'VIEW', 'OK');
Application Context:
await ObslySDK.instance.setView('HOME');
await ObslySDK.instance.setOperation('ONBOARDING');
await ObslySDK.instance.setFunctionalBlock('AUTH');
SDK Control:
await ObslySDK.instance.pauseTracker();
await ObslySDK.instance.resumeTracker();
await ObslySDK.instance.setRequestsBlacklist(['https://*.sensitive.com/*']);
await ObslySDK.instance.setLogLevel('warn'); // 'null' | 'error' | 'warn' | 'log' | 'debug'
final session = ObslySDK.instance.getSessionInfo();
Miscellaneous:
await ObslySDK.instance.addFeedback('5', 'Great experience');
Debug tools #
Enable the overlay by passing enableDebugTools: true to wrapApp. The overlay lets you inspect captured events and screenshots during development.
Requirements #
- Flutter >= 3.0.0
- Dart >= 3.0.0
Getting Help #
Questions or feedback? Email us at info@obsly.tech.
License #
MIT License - see LICENSE file for details.
Support #
- 📝 Documentation
- 🐛 Issues
- 💬 Discussions
Contributing #
Contributions are welcome! Please read our Contributing Guide for details.