feat(handler): implement StreamHandler, ConsoleHandler, StderrHandler emit
StreamHandler.emit() writes formatted output to a Writable stream. ConsoleHandler maps log levels to console.warn/error/log. StderrHandler emits via console.error. handleError() logs diagnostics instead of throwing. FileHandler throws NotImplementedError on construction. Removed Node.js stream import and conditional require() block.
This commit is contained in:
parent
e6b7f02166
commit
3a6332a855
1 changed files with 83 additions and 42 deletions
119
src/handler.ts
119
src/handler.ts
|
|
@ -1,17 +1,9 @@
|
|||
import * as stream from 'stream';
|
||||
|
||||
import { LogLevel, checkLevel, NOTSET } from './log-level';
|
||||
import { LogLevel, checkLevel, NOTSET, WARNING, ERROR } from './log-level';
|
||||
import { LogRecord } from './log-record';
|
||||
import { Formatter, DEFAULT_FORMATTER } from './formatter';
|
||||
import { Filterer } from './filter';
|
||||
import { NotImplementedError } from './helper/error';
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
const stream = require('stream');
|
||||
}
|
||||
else {
|
||||
const stream = require('./helper/stream');
|
||||
}
|
||||
import { Writable, DEFAULT_STREAM, StderrWritable } from './helper/stream';
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Handler classes and functions
|
||||
|
|
@ -115,14 +107,13 @@ export class Handler extends Filterer {
|
|||
* I/O thread lock.
|
||||
*/
|
||||
handle(record: LogRecord) {
|
||||
var rv = this.filter(record);
|
||||
const rv = this.filter(record);
|
||||
if (!rv) { return }
|
||||
let filtered = record;
|
||||
if ((rv as any) instanceof LogRecord) {
|
||||
record = rv as unknown as LogRecord
|
||||
}
|
||||
if (rv) {
|
||||
//locking here
|
||||
this.emit(record)
|
||||
filtered = rv as unknown as LogRecord
|
||||
}
|
||||
this.emit(filtered)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -144,23 +135,73 @@ export class Handler extends Filterer {
|
|||
* Handle errors which occur during an emit() call.
|
||||
*
|
||||
* This method should be called from handlers when an exception is
|
||||
* encountered during an emit() call. If raiseExceptions is false,
|
||||
* exceptions get silently ignored. This is what is mostly wanted
|
||||
* for a logging system - most users will not care about errors in
|
||||
* the logging system, they are more interested in application errors.
|
||||
* You could, however, replace this with a custom handler if you wish.
|
||||
* The record which was being processed is passed in to this method.
|
||||
* encountered during an emit() call.
|
||||
*/
|
||||
handleError(record: LogRecord) {
|
||||
throw new NotImplementedError(
|
||||
'still need to find portable way for stacktracing...'
|
||||
)
|
||||
try {
|
||||
console.error('--- Logging error ---');
|
||||
console.error('Error in handler for record:', record.scope, record.msg);
|
||||
}
|
||||
catch (_) {
|
||||
// silently ignore errors in error handling
|
||||
}
|
||||
}
|
||||
|
||||
get formatter(): Formatter|null { return this._formatter }
|
||||
set formatter(fmt: Formatter) { this._formatter = fmt }
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler class which writes logging records, appropriately formatted,
|
||||
* to a stream. Note that this class does not close the stream, as
|
||||
* the default stream may be shared.
|
||||
*/
|
||||
export class StreamHandler extends Handler {
|
||||
protected stream: Writable;
|
||||
|
||||
constructor(stream?: Writable) {
|
||||
super();
|
||||
this.stream = stream ?? DEFAULT_STREAM;
|
||||
}
|
||||
|
||||
emit(record: LogRecord) {
|
||||
try {
|
||||
const msg = this.format(record);
|
||||
this.stream.write(msg);
|
||||
}
|
||||
catch (e) {
|
||||
this.handleError(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler class which writes logging records to the browser console,
|
||||
* mapping log levels to the appropriate console method.
|
||||
*
|
||||
* This is the primary handler for browser environments.
|
||||
*/
|
||||
export class ConsoleHandler extends Handler {
|
||||
emit(record: LogRecord) {
|
||||
try {
|
||||
const msg = this.format(record);
|
||||
|
||||
if (record.levelno >= ERROR) {
|
||||
console.error(msg);
|
||||
}
|
||||
else if (record.levelno >= WARNING) {
|
||||
console.warn(msg);
|
||||
}
|
||||
else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
this.handleError(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface FileHandlerOptions {
|
||||
filename: string
|
||||
filemode?: string
|
||||
|
|
@ -168,20 +209,13 @@ export interface FileHandlerOptions {
|
|||
errors?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler class which writes logging records, appropriately formatted,
|
||||
to a stream. Note that this class does not close the stream, as
|
||||
sys.stdout or sys.stderr may be used.
|
||||
*/
|
||||
export class StreamHandler extends Handler {
|
||||
constructor(stream?: stream.Writable) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class FileHandler extends StreamHandler {
|
||||
constructor(options: FileHandlerOptions) {
|
||||
super();
|
||||
throw new NotImplementedError(
|
||||
'FileHandler is not available in browser environments. ' +
|
||||
'Use ConsoleHandler or a storage-backed handler instead.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,8 +225,15 @@ export class FileHandler extends StreamHandler {
|
|||
* sys.stderr at handler construction time.
|
||||
*/
|
||||
export class StderrHandler extends Handler {
|
||||
/**
|
||||
* Initialize the handler.
|
||||
*/
|
||||
constructor(level: LogLevel) { super(level) }
|
||||
|
||||
emit(record: LogRecord) {
|
||||
try {
|
||||
const msg = this.format(record);
|
||||
console.error(msg);
|
||||
}
|
||||
catch (e) {
|
||||
this.handleError(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue