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 defaultrevealSecretsInDebug 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
117
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