Logging Plugin
The logging plugin provides console output for state changes, instance lifecycle events, and monitoring alerts. Reach for it when you want a passive, scannable record in the console or in CI logs — a running narrative of what your blocs are doing. For interactive, point-and-click inspection (state trees, diffs, time-travel) use DevTools instead; the two are complementary and can run side by side. Like all plugins, it observes every instance from outside — see Plugin Overview for the bigger picture.
Installation
Section titled “Installation”pnpm add @blac/logging-pluginQuick setup
Section titled “Quick setup”import { LoggingPlugin } from '@blac/logging-plugin';import { getPluginManager } from '@blac/core';
getPluginManager().install(new LoggingPlugin({ level: 'info' }), { environment: 'development',});What the output looks like
Section titled “What the output looks like”The default format: 'grouped' writes collapsible console.group entries for every event. Here is representative output for a short session — plugin install, a CartCubit state change, and its disposal:
▶ [BlaC] Plugin installed Registered types: 1 Total instances: 0
▶ [BlaC] Created CartCubit#a1b2c3d4 Class: CartCubit Instance ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890 Initial state: { items: [], total: 0 }
▶ [BlaC] CartCubit#a1b2c3d4 state changed Previous: { items: [], total: 0 } Current: { items: [{ id: 1, name: "Widget", qty: 2 }], total: 19.98 }
▶ [BlaC] Disposed CartCubit#a1b2c3d4 Lifespan: 4.2s State changes: 1 Final state: { items: [{ id: 1, name: "Widget", qty: 2 }], total: 19.98 }Groups are collapsed by default — click the ▶ arrow to expand. Switch to format: 'simple' for a flat, line-per-event view:
[BlaC] Plugin installed (1 types, 0 instances)[BlaC] Created CartCubit#a1b2c3d4[BlaC] CartCubit#a1b2c3d4 state: {"items":[],"total":0} → {"items":[{"id":1,"name":"W...[BlaC] Disposed CartCubit#a1b2c3d4 (lived 4.2s)The simple format truncates state JSON at 50 characters, which keeps CI logs scannable.
Configuration
Section titled “Configuration”Pass a LoggingPluginConfig object to the constructor:
new LoggingPlugin({ level: 'debug', format: 'grouped', include: ['CartCubit', 'AuthCubit'], logStateChanges: true, logLifecycle: true,});Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
level | 'minimal' | 'info' | 'debug' | 'verbose' | 'info' | Log verbosity |
format | 'simple' | 'grouped' | 'grouped' | Output format. 'grouped' uses console.group |
logger | Logger | console | Custom logger implementation |
prefix | string | '[BlaC]' | Prefix for log messages |
logLifecycle | boolean | true | Log instance creation and disposal |
logStateChanges | boolean | true | Log state changes |
includeCallstack | boolean | false | Show call stacks for state changes |
logPaths | boolean | false | Log the dirtytalk paths that changed |
include | string[] | — | Whitelist: only log these class names |
exclude | string[] | — | Blacklist: skip these class names |
filter | FilterFn | — | Custom filter function |
Monitoring options
Section titled “Monitoring options”| Option | Type | Default | Description |
|---|---|---|---|
instanceCountWarningThreshold | number | 50 | Warn when instance count exceeds this |
detectRapidLifecycles | boolean | true | Detect rapid create/dispose cycles |
rapidLifecycleWindowMs | number | 1000 | Time window for rapid lifecycle detection |
rapidLifecycleThreshold | number | 5 | Cycles in window to trigger warning |
Log levels
Section titled “Log levels”| Level | Lifecycle | State changes | Monitoring |
|---|---|---|---|
minimal | No | No | Yes |
info | Yes | Yes | Yes |
debug | Yes | Yes (detailed) | Yes |
verbose | Yes | Yes (full) | Yes |
Filtering
Section titled “Filtering”By class name
Section titled “By class name”new LoggingPlugin({ include: ['CartCubit', 'AuthCubit'], // only these exclude: ['TimerCubit'], // or skip these});Custom filter
Section titled “Custom filter”new LoggingPlugin({ filter: (ctx) => { // ctx: { instance, className, instanceId } return ctx.className !== 'InternalCubit'; // skip specific types },});Custom logger
Section titled “Custom logger”Replace console with your own logging implementation:
new LoggingPlugin({ logger: { log: (...args) => myLogger.info(...args), warn: (...args) => myLogger.warn(...args), error: (...args) => myLogger.error(...args), group: (label) => myLogger.group(label), groupEnd: () => myLogger.groupEnd(), },});Registry stats
Section titled “Registry stats”Call logStats() to print a summary of the current registry state:
const logging = new LoggingPlugin({ level: 'info' });getPluginManager().install(logging);
// later, in a debug context:logging.logStats();Rate limiting
Section titled “Rate limiting”State change logging is automatically disabled if more than 1,000 changes per second are detected. This prevents flooding the console in high-frequency scenarios. A warning is logged when rate limiting kicks in.
See also
Section titled “See also”- Plugin Overview — the plugin catalog and the install API
- DevTools — interactive inspection; pairs well with logging
- Performance — diagnosing the emit storms the rate limiter guards against
- Plugin Authoring — the hooks this plugin is built on