low level log archigture. minimum resources, user friendly, powerfull logger library. supported browser & nodejs
npm install @napp/loggerLightweight, extensible logging core for Node.js and browsers.
- Minimal overhead, no runtime deps
- Hierarchical loggers via dot-separated logname (e.g. app.core.api)
- Pluggable writers with filterLogname and filterLevel
- Customizable levelParser and errorParser
- Ergonomic API with short aliases: t/d/i/w/e/f
- ESM and CJS builds, TypeScript types included
``bash`
npm install @napp/logger
`ts
import { LogManager, LogLevel, getLogger } from '@napp/logger';
// 1) Create a LogManager and add a writer
const manager = new LogManager();
manager.addWriter({
// optional: name for your writer (auto if omitted)
writerName: 'console-writer',
// optional: accept only logs that start with this logname path
filterLogname: ['app'],
// optional: accept only logs with level >= Warn
filterLevel: LogLevel.Warn,
// required: actual writer implementation
doWriter: (log) => {
const sev = LogManager.getSeverityText(log.level);
console.log([${sev}] ${log.logname}:, log.message, log.attr);
}
});
// 2) Set as default manager (enables helper getLogger)
LogManager.setDefault(manager);
// 3) Get a logger and write
const logger = getLogger('app.core');
logger.info('This will be skipped (below Warn)');
logger.warn('This will be written', { module: 'init' });
logger.error('Something failed');
`
- LogManager
- Owns writers and dispatches logsaddWriter({ writerName?, filterLogname?, filterLevel?, doWriter })
- removeWriter(name)
- LogManager.setDefault()
- Global default: / LogManager.getDefault()
- Logger
- Created via LogManager.factory(logname, opt?) or getLogger(logname, opt?)trace/debug/info/warn/error/fatal
- Methods: and aliases t/d/i/w/e/flog(level: string|number, message, attr?)
- using a levelParserchild(childName, { inheritBaseAttr?, baseAttr?, errorParser?, levelParser? })
- isLevelEnabled(level)
- computed from registered writers it would matcherrorThrow(err, message, attr?)
- converts Error to structured attr.error
- Writer filters
- filterLogname: string | string[] — a path prefix matcher on logname['app','core']
- e.g. writer with accepts app.core and app.core.*filterLevel: LogLevel
- — minimum accepted severity
- Levels
- Enum: Trace=1, Debug=5, Info=9, Warn=13, Error=17, Fatal=21LogManager.getSeverityText(level)
- returns TRACE|DEBUG|INFO|WARN|ERROR|FATALlevelParser
- Default maps strings ('info', 'error', …) and numeric ranges
`ts
// Create manager, add writers
const m = new LogManager();
const writerId = m.addWriter({
writerName: 'w1',
filterLogname: 'app.module', // or ['app','module']
filterLevel: LogLevel.Info,
doWriter: (log) => {/ send to console, HTTP, file, etc. /}
});
// Remove writer by name
m.removeWriter('w1');
// Make default manager for convenience
LogManager.setDefault(m);
// Create loggers
const logger = m.factory('app.module', { baseAttr: { service: 'users' } });
const child = logger.child('repo', { inheritBaseAttr: true });
// Write logs
logger.info('Ready');
logger.warn('Slow query', { ms: 1200 });
child.errorThrow(new Error('db down'), 'DB error');
// Check if a level would be emitted (vs current writer filters)
if (logger.isLevelEnabled(LogLevel.Debug)) {
logger.debug('expensive computation detail', { / ... /});
}
// Parse custom string/number levels
const custom = m.factory('app.custom', {
levelParser: (lvl) => lvl === 'critical' ? LogLevel.Fatal : LogLevel.Info
});
custom.log('critical', 'fatal-like');
`
`ts
// Level parser – used by logger.log(level, ...)
LogManager.setDefaultLevelParser((level) => {
if (level === 'notice') return LogLevel.Info;
return LogLevel.Warn;
});
// Error parser – used by logger.errorThrow()
LogManager.setDefaultErrorParser((err) => ({
name: 'CustomError',
message: err.message,
code: 'E_CUSTOM'
}));
`
1) Create a LogManager, add one or more writers.getLogger
2) Set the manager as default to use globally, or keep a reference and use manager.factory(...).filterLogname
3) Use to route logs by hierarchical name; use filterLevel to enforce minimum severity.baseAttr
4) Use to attach common attributes; child() to extend logger scope.logger.log()
5) For dynamic string/number levels, use with a custom levelParser if needed.errorThrow()
6) Use to transform native Error into structured attributes via errorParser.
1) LogManager үүсгээд writer нэмнэ (консол, файл, HTTP гэх мэт рүү бичих хэсэг).LogManager.setDefault(...)
2) гэж тохируулбал getLogger(...)-оор дурын газраас логгер авна. Эсвэл manager.factory(...)-г шууд ашиглаж болно.filterLogname
3) нь logname (жишээ нь app.core.api) дээр суурилсан мод хэлбэрийн шүүлтүүр; filterLevel нь тухайн writer-д очих доод түвшинг тогтооно.baseAttr
4) -аар нийтлэг аттрибутууд нэмэж, child(...)-аар модуль/дэд хэсгийн логгер үүсгэнэ.logger.log(...)
5) Түвшинг стринг/тоо байдлаар өгөх бол ашиглана. Шаардлагатай бол levelParser-аа өөрчилж болно.errorThrow(err, message, attr?)
6) Алдааг бүтцэт мэдээлэл болгохын тулд -г ашиглана (errorParser өөрчилж болно).
- Types bundled: types at dist/index.d.tsmodule
- ESM and CJS main entries are provided
- Node engine for development/test: >=22`
- Library runs in both Node.js and modern browsers (writer implementation is up to you)
MIT