
Security News
TC39 Advances Temporal to Stage 4 Alongside Several ECMAScript Proposals
TC39’s March 2026 meeting advanced eight ECMAScript proposals, including Temporal reaching Stage 4 and securing its place in the ECMAScript 2026 specification.
@ncoderz/log-m8
Advanced tools
A fast, small, flexible and extensible logging system for TypeScript and JavaScript applications.
npm install @ncoderz/log-m8
import { LogM8 } from '@ncoderz/log-m8';
// Configure the logging system
LogM8.init();
// Get a logger
const logger = LogM8.getLogger('app.service');
// Log at various levels
logger.info('Service started');
logger.debug('Connection details:', { host: 'localhost', port: 3000 });
logger.error('Failed to connect', new Error('Connection refused'));
// Use context for structured logging
logger.setContext({ service: 'authentication', instance: 1 });
logger.warn('Rate limit exceeded');
// Child loggers inherit parent settings but can be configured separately
const dbLogger = logger.getLogger('database'); // app.service.database
dbLogger.setLevel('debug');
Log-m8 provides multiple logging levels in ascending order of verbosity:
| Level | Description |
|---|---|
off | Disables all logging |
fatal | Critical system failures requiring immediate intervention |
error | Failures preventing normal operation |
warn | Potentially problematic situations |
info | General informational messages about normal operation |
debug | Detailed diagnostic information for development |
track | Analytics and user behavior tracking events |
trace | Most detailed execution information for fine-grained debugging |
Loggers are organized hierarchically using dot notation:
const appLogger = LogM8.getLogger('app');
const dbLogger = LogM8.getLogger('app.database');
const cacheLogger = appLogger.getLogger('cache'); // 'app.cache'
This allows you to configure logging granularly by component while maintaining a clean organizational structure.
The LogM8.init() method configures the logging system:
LogM8.init({
// Default log level for all loggers (defaults to 'info')
level: 'info',
// Per-logger level overrides
loggers: {
'app.database': 'debug',
'app.service': 'warn'
},
// Appender configurations
appenders: [
{
name: 'console',
formatter: {
name: 'default-formatter',
format: ['{timestamp} {LEVEL} [{logger}]', '{message}', '{data}'],
timestampFormat: 'yyyy-MM-dd hh:mm:ss.SSS',
color: true
},
// Optional priority (higher runs first)
priority: 100,
},
{
name: 'file',
filename: 'app.log',
formatter: {
name: 'json-formatter',
format: ['timestamp', 'level', 'logger', 'message', 'data'],
timestampFormat: 'iso',
}
}
],
// Global filters
filters: [
{
name: 'match-filter',
deny: { 'context.sensitive': true }
}
]
});
Appenders are responsible for outputting log events to specific destinations.
Outputs log events to the console, mapping log levels to the appropriate console methods.
{
name: 'console',
// Optional formatter configuration
formatter: 'default-formatter',
// Optional per-appender filters
filters: ['sensitive-data']
}
Writes log events to a file, one line per event.
{
name: 'file',
filename: 'app.log',
// Optional: append to existing file (default: false)
append: true,
formatter: 'json-formatter'
}
Formatters transform log events into output formats suitable for different appenders.
timestamp: Formatted timestampLEVEL: Uppercase level label (Default Formatter Only. With standard padding, and optional colorization)level: Lowercase level namelogger: Logger namemessage: Primary log messagedata: Additional data argumentscontext.*: Nested context propertiesAll tokens support accessing nested items with data[0].property like notation.
A human-readable text formatter with customizable templates and optional colorized output.
{
name: 'default-formatter',
// Optional: custom format with token placeholders
format: ['{timestamp} {LEVEL} [{logger}]', '{message}', '{data}'],
// Optional: timestamp format ('iso', 'locale', or custom pattern)
timestampFormat: 'hh:mm:ss.SSS',
// Optional: colorize level labels
color: true
}
Formats log events as JSON objects, useful for machine processing and log aggregation.
{
name: 'json-formatter',
// Optional fields to include
format: ['timestamp', 'level', 'logger', 'message', 'data', 'context'],
// Pretty print
pretty: true
}
Filters control which log events are processed by appenders.
See Supported Formatter Tokens.
Provides allow/deny rules based on path-based equality or regex matching against log event properties.
{
name: 'match-filter',
// Optional: all rules must match to allow (AND logic)
allow: {
'logger': '/^app.*$/',
'data[0].type': 'audit'
},
// Optional: any match denies (OR logic)
deny: {
'context.userId': '1234',
'message': '/.*password.*/'
}
}
Log-m8 provides methods for controlling appenders and filters at runtime:
// Disable console appender (e.g., in production)
LogM8.disableAppender('console');
// Enable file appender
LogM8.enableAppender('file');
// Flush all appenders
LogM8.flushAppenders();
// Disable a filter for a specific appender
LogM8.disableFilter('sensitive-data', 'console');
// Enable a filter for a specific appender
LogM8.enableFilter('sensitive-data', 'console');
Appenders can be added and removed after initialization. This is useful for diagnostic injection, feature-flag-driven logging, or attaching test spies at runtime.
// Add an appender at runtime
LogM8.addAppender({
name: 'file',
filename: 'debug.log',
formatter: 'json-formatter',
priority: 10
});
// Add by name (uses factory defaults)
LogM8.addAppender('console');
// Check which appenders are active (returns names in priority order)
console.log(LogM8.getAppenderNames()); // ['file', 'console']
// Remove an appender (flushes and disposes it)
LogM8.removeAppender('file');
// Returns false if the appender doesn't exist
LogM8.removeAppender('unknown'); // false
Note: addAppender must be called after init() and the appender name must not
already be in use. To swap an appender's configuration, remove then re-add it.
You can change the effective logging thresholds without recreating loggers:
// Set global log level gate (does not change individual logger levels)
LogM8.setLevel('info');
// Set a specific logger's level via manager (equivalent to getLogger(...).setLevel)
LogM8.setLevel('debug', 'app.database');
// Or use the logger instance directly
const alpha = LogM8.getLogger('alpha');
alpha.setLevel('warn');
Behavior rules:
Example sequence:
const warnLogger = LogM8.getLogger('alpha');
warnLogger.setLevel('warn');
const debugLogger = LogM8.getLogger('beta');
debugLogger.setLevel('debug');
// Global: info → beta logs info+, alpha logs warn+
LogM8.setLevel('info');
// Global: debug → beta logs debug+, alpha still logs warn+
LogM8.setLevel('debug');
// Global: info again → beta logs info+, alpha still logs warn+
LogM8.setLevel('info');
You can extend log-m8 with custom appenders, formatters, and filters.
For example:
class SlackAppenderFactory implements PluginFactory {
name = 'slack';
kind = PluginKind.appender;
create(config) {
return new SlackAppender(config);
}
}
// Register before initialization
LogM8.registerPluginFactory(new SlackAppenderFactory());
// Use in configuration
LogM8.init({
appenders: [
{
name: 'slack',
webhookUrl: 'https://hooks.slack.com/...',
channel: '#alerts'
}
]
});
Log-m8 works in browsers with automatic environment detection:
<script src="https://cdn.jsdelivr.net/npm/@ncoderz/log-m8@latest/dist/browser/log-m8.global.js"></script>
<script>
const { LogM8 } = window.logM8;
LogM8.init({
level: 'info',
appenders: [{ name: 'console', formatter: 'default-formatter' }]
});
const logger = LogM8.getLogger('app');
logger.info('Application started');
</script>
FAQs
Logging system for TypeScript / JavaScript
We found that @ncoderz/log-m8 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
TC39’s March 2026 meeting advanced eight ECMAScript proposals, including Temporal reaching Stage 4 and securing its place in the ECMAScript 2026 specification.

Research
/Security News
Since January 31, 2026, we identified at least 72 additional malicious Open VSX extensions, including transitive GlassWorm loader extensions targeting developers.

Research
Six malicious Packagist packages posing as OphimCMS themes contain trojanized jQuery that exfiltrates URLs, injects ads, and loads FUNNULL-linked redirects.