live_log_care 2.3.1 copy "live_log_care: ^2.3.1" to clipboard
live_log_care: ^2.3.1 copied to clipboard

Redaction-safe logging for Flutter: build-mode gated (silent in release) and auto-scrubs passwords, tokens, cookies, OTPs and PII from logs, Dio and Bloc.

live_log_care #

Redaction-safe logging for Flutter. A drop-in logging facade that is build-mode gated (silent in release) and automatically scrubs secrets and PII β€” passwords, tokens, cookies, OTPs, national IDs, bearer/JWT tokens, card numbers β€” from your log messages, your Dio traffic and your Bloc state, before anything is written.

Most apps leak credentials to device logs without realizing it: a PrettyDioLogger left on in release, a cookie printed by an auth interceptor, a Bloc state containing a password. live_log_care makes the safe path the default one.

Features #

  • πŸ”’ Automatic redaction β€” secrets are masked everywhere, including nested maps, lists, headers and request/response bodies.
  • πŸŒ— True build-mode gating β€” uses ProductionFilter, so in release only warning/error are emitted (not the logger default, which silently drops all release logs).
  • πŸ›°οΈ Redaction-safe Dio interceptor β€” replaces PrettyDioLogger; debug-only by default.
  • 🧊 Bloc observer β€” routes Bloc/Cubit lifecycle + errors through the same gate.
  • πŸͺ Pluggable crash reporting β€” forward release errors to Crashlytics/Sentry via a tiny interface; the package itself pulls in neither.
  • βš™οΈ Configurable β€” add your own sensitive keys/patterns, change the mask, set per-build levels, swap the printer.

Install #

flutter pub add live_log_care

Drop this into main.dart β€” same pattern used in production Mdarj apps. Two lines at startup; Dio wiring goes where you create your client.

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:live_log_care/live_log_care.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Use LiveLog.d/i/w/e(...) everywhere instead of print/debugPrint.
  // Every message is redaction-scrubbed and gated by build mode
  // (silent below `warning` in release).
  //
  // clean(): borderless, copy-friendly output β€” each log is one
  // dart:developer event, so multi-line JSON stays a single selectable
  // block with no `I/flutter (PID): β”‚` prefix in the VS Code Debug Console.
  // Secrets show in DEBUG only; RELEASE is always redacted.
  LiveLog.configure(LiveLogConfig.clean());
  Bloc.observer = LiveLogBlocObserver();

  // ... DI, Firebase, runApp, etc.
}

On your Dio instance (factory / DI module):

dio.interceptors.add(RedactingDioInterceptor());
// prettyJson: true is the default β€” indented, copyable body JSON.

Then log as usual:

LiveLog.d('dev-only diagnostic');
LiveLog.i('user opened loan #$id');
LiveLog.w('retrying request');
LiveLog.e('payment failed', error: e, stackTrace: s);

// Secrets are masked automatically (release always; debug shows real values
// unless you pass revealSecretsInDebug: false):
LiveLog.d({'login': 'a@b.com', 'password': 'hunter2'});

HTTP traffic renders as labeled boxes; Body JSON has no β”‚ prefix so you can copy it straight into a formatter:

[D] β”Œβ”€ Response (200) ──────────────────────────────────
    β”‚ GET  https://api.example.com/items
    β”œβ”€ Body ────────────────────────────────────────────
{
  "success": true,
  "data": []
}
    └───────────────────────────────────────────────────

Optional knobs (only when you need them):

LiveLog.configure(LiveLogConfig.clean(
  releaseLevel: LogLevel.error,       // quieter release
  revealSecretsInDebug: false,        // redact in debug too
  decorateHttp: false,                // flat `β†’ METHOD url` instead of boxes
));
LogRedactor.addSensitiveKeys(['iban', 'card_holder']);

Crash reporting (optional) #

class CrashlyticsSink implements CrashSink {
  @override
  void recordError(Object error, StackTrace? st, Object? context) =>
      FirebaseCrashlytics.instance.recordError(error, st, reason: context);
}

LiveLog.crashSink = CrashlyticsSink(); // only release `error`s are forwarded

Configuration #

Everything has a secure default; configure only what you need, once at startup:

LiveLog.configure(
  const LiveLogConfig(
    releaseLevel: LogLevel.error, // even quieter in release
    // enabled: false,            // kill switch
    // printer: CleanPrinter(),   // or BoxedPrinter() (default), or your own
    // output: DevLogOutput(),    // or ConsoleOutput() (default), MultiOutput, FileOutput
    // filter: MyFilter(),        // custom gating; default is a ThresholdFilter
    // redactionEnabled: true,    // (default) never turn this off in production
    // revealSecretsInDebug: false,// redact in debug too (defaults to kDebugMode; release always redacted)
  ),
);

// Teach the redactor about your domain's secrets:
LogRedactor.addSensitiveKeys(['iban', 'card_holder']);
LogRedactor.addValuePatterns([RegExp(r'\b\d{16}\b')]); // bare 16-digit numbers
LogRedactor.mask = '[hidden]';

The logging engine is self-contained β€” no third-party logger dependency. Compose your own pipeline from the bundled building blocks, or implement LogPrinter / LogOutput / LogFilter yourself:

// Console + a rotating file, both fed the same redacted, gated stream:
LiveLog.configure(
  LiveLogConfig(
    output: MultiOutput([const ConsoleOutput(), FileOutput('app.log')]),
  ),
);

What gets redacted by default #

Keys (case-insensitive, substring): password, passwd, pwd, token, access_token, refresh_token, id_token, auth_token, authorization, bearer, cookie, set-cookie, session_id, api_session, national_id, ssn, otp, secret, client_secret, api_key, x-api-key, private_key, credit_card, card_number, cvv, cvc.

Values: Bearer <token> and JWTs anywhere in a string. Add your own with addValuePatterns.

Redaction reduces risk; it is not a guarantee for arbitrarily-shaped data. Keep debug network logging out of release for anything highly sensitive (the default).

Real secret values are shown while debugging locally by default β€” revealSecretsInDebug defaults to kDebugMode, so values are un-masked in debug builds only; release builds are always redacted regardless, so there's no production-leak risk. To redact in debug too β€” recommended if your debug logs may be screenshotted, screen-shared, or captured in CI β€” set revealSecretsInDebug: false.

License #

MIT

1
likes
160
points
46
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Redaction-safe logging for Flutter: build-mode gated (silent in release) and auto-scrubs passwords, tokens, cookies, OTPs and PII from logs, Dio and Bloc.

Repository (GitHub)
View/report issues

Topics

#logging #security #redaction #dio

License

MIT (license)

Dependencies

dio, flutter, flutter_bloc

More

Packages that depend on live_log_care