Flutter Logs installation
The PostHog Flutter SDK has built-in support for capturing structured Logs from your Flutter app across mobile and web. The SDK handles the OTLP encoding, batching, and flushing — and on mobile, on-disk persistence across app restarts and app-lifecycle integration (web buffers in memory via posthog-js). You just call Posthog().captureLog(...) or Posthog().logger.{trace,debug,info,warn,error,fatal}(...).
Manual capture only. Logs are emitted by your code. The SDK does not autocapture system log streams (
debugPrint, ordart:developer'slog).
Minimum version:
posthog_flutter5.27.0or later (the release that adds Logs support). On mobile it pulls inposthog-android3.48.0or later automatically.
- 1
Install posthog_flutter
RequiredIf you haven't installed
posthog_flutteryet, follow the steps below. For full details, see the Flutter SDK guide.PostHog is available for install via Pub.
Configuration
Set your PostHog project token and enable automatic event tracking if you want the library to capture lifecycle events for you.
Remember that the application lifecycle events won't have any special context set for you by the time it is initialized. If you are using a self-hosted instance of PostHog you will need to have the public hostname or IP for your instance as well.
To start, add
posthog_flutterto yourpubspec.yaml:pubspec.yamlThen complete the setup for each platform:
For Session Replay and Surveys, you must set up the SDK manually by disabling the
com.posthog.posthog.AUTO_INITmode.Android setup
There are 2 ways of initializing the SDK, automatically and manually.
Automatically:
Add your PostHog configuration to your
AndroidManifest.xmlfile located in theandroid/app/src/main:android/app/src/main/AndroidManifest.xmlOr manually (more control and more configurations available):
Add your PostHog configuration to your
AndroidManifest.xmlfile located in theandroid/app/src/main:android/app/src/main/AndroidManifest.xmlIn both cases, you'll also need to update the minimum Android SDK version to
23inandroid/app/build.gradle:android/app/build.gradleiOS setup
There are 2 ways of initializing the SDK, automatically and manually.
You'll need to have Cocoapods installed.
Automatically:
Add your PostHog configuration to the
Info.plistfile located in theios/Runnerdirectory:ios/Runner/Info.plistOr manually (more control and more configurations available):
Add your PostHog configuration to the
Info.plistfile located in theios/Runnerdirectory:ios/Runner/Info.plistIn both cases, you'll need to set the minimum platform version to iOS 13.0 in your Podfile:
ios/PodfileDart setup (For manual step only)
If you followed the automatic SDK setup, then there's no more configuration needed in Dart.
If you followed the manual SDK setup:
DartWeb setup
For Web, add your
Web snippet(which you can find in your project settings) in the<header>of yourweb/index.htmlfile:web/index.htmlFor more information please check: /docs/libraries/js
- 2
Configure logs in your PostHogConfig
RequiredConfigure Logs through
config.logsConfigbefore callingPosthog().setup(...). All fields are optional; unset fields fall back to the native defaults, which are tuned for mobile (cellular bandwidth, battery, app lifecycle).DartThese resource attributes are captured at
setup(...)and apply to every batch.Web behavior. On Flutter Web, the SDK attaches to an already-initialized
posthog-jsinstance, soconfig.logsConfigis not applied on web. Configure your log options in theposthog.init({...})call in yourweb/index.htmlinstead.captureLogandloggerstill work on web (they are forwarded toposthog-js), andbeforeSendstill runs (in Dart) on web. Web also requires a recentposthog-jsbuild that exposescaptureLog.For example, set the same service identity on the
posthog-jssnippet inweb/index.html:HTMLSee the JavaScript Logs installation guide for the full
posthog-jslogs config. - 3
Capture logs
RequiredUse
Posthog().loggerfor the per-level convenience API, orPosthog().captureLogfor full control over level, attributes, and trace context.DartThe per-level facade methods are
trace,debug,info,warn,error, andfatal, each taking aString bodyand an optionalMap<String, Object>of attributes. Available severity levels forcaptureLogarePostHogLogSeverity.trace,.debug,.info,.warn,.error, and.fatal.The optional W3C trace fields (
traceId,spanId,traceFlags) are available oncaptureLogonly, not on theloggerfacade.Records are buffered, batched, persisted to disk, and flushed automatically – every 30 seconds, when the buffer hits the threshold, when the app moves to the background, or on
Posthog().flush().flush()drains events, Session Replay, and Logs together.Each record is automatically tagged with the current distinct ID, session ID, active feature flags, and (on mobile) the current screen and app foreground/background state at the moment of capture. On web,
url.fullis tagged instead of screen name and app state. - 4
Test your setup
Recommended- Capture a test log from your app:Dart
- Open the PostHog Logs UI.
- Filter by
service.name = 'my-app'(or whatever value you set above).
You should see your record arrive within a few seconds.
- Capture a test log from your app:
- 5
Tune buffering, rate cap, and resource attributes
OptionalThe
logsConfighas knobs for high-volume apps:DartFull configuration reference:
Field Default What it does serviceNameapp bundle id (iOS) / app namespace (Android) OTLP service.nameresource attributeserviceVersionapp version OTLP service.versionresource attributeenvironmentnone OTLP deployment.environmentresource attributeresourceAttributes{}Extra OTLP resource attributes flushInterval30sPeriodic flush interval flushAt20Buffer threshold that triggers an automatic flush maxBatchSize50Max records per outbound POST maxBufferSize1000Max records held on disk before FIFO eviction rateCapMaxLogs500Max records per rateCapWindow. Set to0to disable.rateCapWindow10sRate-cap window length Defaults are tuned for cellular-aware mobile apps. Raise
rateCapMaxLogsandmaxBufferSizefor high-volume scenarios.On web, these fields are not applied – configure them in your
posthog.init({...})call inweb/index.htmlinstead. - 6
Filter or redact with beforeSend
OptionalUse
config.logsConfig.beforeSendfor redaction, sampling, or filtering by level. It is aList<BeforeSendLogCallback>, where each callback is aFutureOr<PostHogLogRecord?> Function(PostHogLogRecord). Callbacks run in Dart on all platforms (including web), evaluated left-to-right. Each callback receives a mutablePostHogLogRecord(with mutablebody,level, andattributes) and returns either the (possibly mutated) record ornullto drop it. Callbacks can be synchronous or asynchronous.DartReturning
nullfrom any callback short-circuits and drops the record. Settingrecord.bodyto an empty or whitespace-only string also drops the record. A callback that throws is logged and the record is dropped (fail-closed). Next steps
CheckpointWhat you can do with your logsAction Description Why you need logs What logs show you that nothing else does Search logs Use the search interface to find specific log entries Filter by level Filter by INFO,WARN,ERROR, etc.Link session replay Connect logs to users and session replays by passing posthogDistinctIdandsessionIdLink logs to a person Surface every log emitted on behalf of a user on their PostHog person profile Logging best practices Learn what to log, how to structure logs, and patterns that make logs useful in production