ispectify_bloc 7.0.0-dev6
ispectify_bloc: ^7.0.0-dev6 copied to clipboard
BLoC and Cubit observer for ISpect with event, transition, change, error, completion, and redacted metadata logging.
ispectify_bloc plugs the bloc and flutter_bloc ecosystem into the ISpect toolkit. One BlocObserver forwards every event, state change, transition, and error through the log pipeline, so the whole state-management timeline shows up in the log viewer.
- Events, transitions, errors, and create/close lifecycle hooks.
- Family and typed-predicate filtering. Mute BLoCs without formatting caller-owned objects.
- Zero configuration. Set
Bloc.observerand the rest is done.
Install #
dependencies:
flutter_bloc: ^8.0.0
ispectify: ^7.0.0-dev6
ispectify_bloc: ^7.0.0-dev6
Quick start #
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:ispect/ispect.dart';
import 'package:ispectify_bloc/ispectify_bloc.dart';
ISpect.run(
() => runApp(const MyApp()),
onInit: () {
Bloc.observer = ISpectBlocObserver(logger: ISpect.logger);
},
);
The observer emits logs under the bloc-event, bloc-transition, bloc-state, bloc-create, bloc-close, bloc-done, and bloc-error log-type keys, each with a dedicated icon, palette entry, and localized description in the log viewer. Filter them in the debug panel or through ISpectSettingsState.disabledLogTypes.
Settings #
ISpectBlocSettings controls which lifecycle events are captured and whether event/state payloads are written to trace meta. Full bounded payloads are captured and redacted by default. The compact preset keeps lifecycle visibility while replacing values with coarse structural labels such as String, int, List, or Map.
const settings = ISpectBlocSettings(
printEvents: true,
printTransitions: true,
printChanges: true,
printCreations: true,
printClosings: true,
printCompletions: true,
printErrors: true,
printEventFullData: true,
printStateFullData: true,
enableRedaction: true,
captureMode: DiagnosticCaptureMode.balanced,
resourceLimits: DiagnosticResourceLimits.constrained,
);
Balanced capture retains guarded, bounded toJson() or toString() output
before redaction. Set captureMode: DiagnosticCaptureMode.strict when
application-defined formatters must never run.
Presets #
// Logs disabled entirely.
ISpectBlocObserver(settings: ISpectBlocSettings.silent);
// Skip per-change / per-completion noise — keeps creations, transitions, errors.
ISpectBlocObserver(settings: ISpectBlocSettings.minimal);
ISpectBlocObserver(settings: ISpectBlocSettings.compact);
compact uses strict capture automatically.
Omit resourceLimits to inherit the logger policy; set it locally to tune
state payload and pending-correlation budgets for this observer.
For an existing customized settings object,
copyWith(inheritResourceLimits: true) restores logger-owned budgets and
copyWith(inheritRedactionService: true) restores the global
ISpectRedaction.service.
Filtering noisy blocs #
ISpectBlocObserver(
// Pattern filters see only Bloc, Cubit, or BlocBase.
filters: ['Cubit'],
// Use explicit type checks when an exact application class must be muted.
filterPredicate: (candidate) =>
candidate is AnalyticsBloc || candidate is MetricsCubit,
settings: ISpectBlocSettings(
// Or skip individual events / transitions / changes by inspecting them.
eventFilter: (bloc, event) => event is! HeartbeatEvent,
),
);
Data redaction #
Sensitive data is masked before it reaches logs or observers. Redaction is on by default. The built-in rules cover auth headers, tokens, passwords, API keys, cookies, common PII (SSN, passport, driver's license), financial data (credit cards, IBAN), and phone numbers.
The default policy is a single source of truth. Configure it once and core logs, traces, persistence, network and database adapters, BLoC and Riverpod observers, supported exports, clipboard helpers, and cURL generation resolve it when each diagnostic operation runs.
Redaction works best paired with deliberate capture. Use the integration's metadataOnly() or compact preset when payload values are unnecessary, and register project-specific keys for the business identifiers only your application understands.
The default DiagnosticCaptureMode.balanced keeps diagnostics useful by
allowing guarded toJson() and toString() capture. The result is bounded
immediately and redacted before it leaves the active pipeline. Select
DiagnosticCaptureMode.strict when application-defined formatters must never
run. Network metadataOnly() and production() presets, plus BLoC/Riverpod
compact, select strict capture automatically. Persistence, export, and
observer delivery do not re-run formatters after capture.
Global configuration #
import 'package:ispectify/ispectify.dart';
ISpectRedaction.configure(
service: RedactionService(
additionalSensitiveKeys: {
'x-custom-secret',
'internal_token',
},
additionalSensitiveKeyPatterns: [
RegExp(r'my_app_secret_\w+', caseSensitive: false),
],
fullyMaskedKeys: {'filename'},
placeholder: '***',
visibleEdgeLength: 3,
),
);
additionalSensitiveKeys and additionalSensitiveKeyPatterns extend the built-in policy. Use sensitiveKeys or sensitiveKeyPatterns only when you intentionally want to replace the corresponding defaults:
final replacementPolicy = RedactionService(
sensitiveKeys: {
'x-custom-secret',
'internal_token',
},
sensitiveKeyPatterns: [
RegExp(r'my_app_secret_\w+', caseSensitive: false),
],
);
Flutter apps can pass the same policy as ISpect.run(redactionService: ...); ISpect.dispose() restores the policy that was active before that run. An explicit RedactionService supplied to one integration stays local and takes precedence over the global policy. Existing integrations without an explicit service pick up later global reconfiguration. The policy is scoped to the current Dart isolate.
Local exceptions #
final redactor = RedactionService(
ignoredKeys: {'mobile', 'platform_token'},
ignoredValues: {'<test-token>', 'public-api-key'},
);
Disabling #
ISpectRedaction.configure(enabled: false) is the global content-masking
opt-out. Each interceptor also accepts enableRedaction: false on its settings
object for a local opt-out. Size limits, private-storage checks, the selected
capture mode, and the compile-time ISPECT_ENABLED gate remain enforced.
Only disable redaction in isolated local or deterministic test environments. Exported sessions and observer events should be handled according to the data they contain.
The ISpect toolkit #
ISpect is a modular monorepo. Pick the packages your project needs. Each one works on its own.
| Package | What it does |
|---|---|
ispect |
Flutter UI: debug panel, log viewer, navigation observer, inspector integration. |
ispect_layout |
Visual layout inspector with sizes, constraints, decorations, compare mode, and a color picker. |
ispectify |
Pure-Dart logging core: typed log entries, filtering, tracing, observers. |
ispectify_dio |
Dio HTTP interceptor with automatic redaction. |
ispectify_http |
http package interceptor with automatic redaction. |
ispectify_ws |
Provider-agnostic WebSocket capture (any client) with automatic redaction. |
ispectify_db |
Database operation tracing for SQL, ORMs, and KV stores. |
ispectify_bloc |
BLoC event, state, transition, and error observer. |
ispectify_riverpod |
Riverpod provider add, update, dispose, and failure observer. |
Contributing #
Contributions are welcome. See CONTRIBUTING.md for guidelines, and open issues or pull requests at the ISpect repository.
License #
MIT. See LICENSE.