mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
Merge pull request #1267 from ZachHaber/master
Make Appender Type extensible from other modules and the user
This commit is contained in:
commit
6a0e492b43
@ -9,7 +9,7 @@ charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.js]
|
||||
[*.{js,ts,[cm]js,[cm]ts}]
|
||||
quote_type = single
|
||||
curly_bracket_next_line = true
|
||||
indent_brace_style = Allman
|
||||
|
||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -10,6 +10,11 @@
|
||||
*.css text eol=lf
|
||||
*.html text eol=lf
|
||||
*.js text eol=lf
|
||||
*.cjs text eol=lf
|
||||
*.mjs text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.cts text eol=lf
|
||||
*.mts text eol=lf
|
||||
*.json text eol=lf
|
||||
*.md text eol=lf
|
||||
*.sh text eol=lf
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"homepage": "https://log4js-node.github.io/log4js-node/",
|
||||
"files": [
|
||||
"lib",
|
||||
"types",
|
||||
"types/*.d.ts",
|
||||
"CHANGELOG.md",
|
||||
"SECURITY.md"
|
||||
],
|
||||
|
||||
120
types/log4js.d.ts
vendored
120
types/log4js.d.ts
vendored
@ -1,13 +1,21 @@
|
||||
// Type definitions for log4js
|
||||
|
||||
type Format = string | ((req: any, res: any, formatter: ((str: string) => string)) => string);
|
||||
type Format =
|
||||
| string
|
||||
| ((req: any, res: any, formatter: (str: string) => string) => string);
|
||||
|
||||
export interface Log4js {
|
||||
getLogger(category?: string): Logger;
|
||||
configure(filename: string): Log4js;
|
||||
configure(config: Configuration): Log4js;
|
||||
addLayout(name: string, config: (a: any) => (logEvent: LoggingEvent) => string): void;
|
||||
connectLogger(logger: Logger, options: { format?: Format; level?: string; nolog?: any; }): any; // express.Handler;
|
||||
addLayout(
|
||||
name: string,
|
||||
config: (a: any) => (logEvent: LoggingEvent) => string
|
||||
): void;
|
||||
connectLogger(
|
||||
logger: Logger,
|
||||
options: { format?: Format; level?: string; nolog?: any }
|
||||
): any; // express.Handler;
|
||||
levels: Levels;
|
||||
shutdown(cb: (error: Error) => void): void | null;
|
||||
}
|
||||
@ -17,9 +25,21 @@ export function getLogger(category?: string): Logger;
|
||||
export function configure(filename: string): Log4js;
|
||||
export function configure(config: Configuration): Log4js;
|
||||
|
||||
export function addLayout(name: string, config: (a: any) => (logEvent: LoggingEvent) => any): void;
|
||||
export function addLayout(
|
||||
name: string,
|
||||
config: (a: any) => (logEvent: LoggingEvent) => any
|
||||
): void;
|
||||
|
||||
export function connectLogger(logger: Logger, options: { format?: Format; level?: string; nolog?: any; statusRules?: any[], context?: boolean }): any; // express.Handler;
|
||||
export function connectLogger(
|
||||
logger: Logger,
|
||||
options: {
|
||||
format?: Format;
|
||||
level?: string;
|
||||
nolog?: any;
|
||||
statusRules?: any[];
|
||||
context?: boolean;
|
||||
}
|
||||
): any; // express.Handler;
|
||||
|
||||
export function recording(): Recording;
|
||||
|
||||
@ -56,9 +76,9 @@ export interface Level {
|
||||
}
|
||||
|
||||
export interface LoggingEvent {
|
||||
categoryName: string; // name of category
|
||||
level: Level; // level of message
|
||||
data: any[]; // objects to log
|
||||
categoryName: string; // name of category
|
||||
level: Level; // level of message
|
||||
data: any[]; // objects to log
|
||||
startTime: Date;
|
||||
pid: number;
|
||||
context: any;
|
||||
@ -89,7 +109,13 @@ export interface CustomLayout {
|
||||
type: string;
|
||||
}
|
||||
|
||||
export type Layout = BasicLayout | ColoredLayout | MessagePassThroughLayout | DummyLayout | PatternLayout | CustomLayout;
|
||||
export type Layout =
|
||||
| BasicLayout
|
||||
| ColoredLayout
|
||||
| MessagePassThroughLayout
|
||||
| DummyLayout
|
||||
| PatternLayout
|
||||
| CustomLayout;
|
||||
|
||||
/**
|
||||
* Category Filter
|
||||
@ -97,7 +123,7 @@ export type Layout = BasicLayout | ColoredLayout | MessagePassThroughLayout | Du
|
||||
* @see https://log4js-node.github.io/log4js-node/categoryFilter.html
|
||||
*/
|
||||
export interface CategoryFilterAppender {
|
||||
type: "categoryFilter";
|
||||
type: 'categoryFilter';
|
||||
// the category (or categories if you provide an array of values) that will be excluded from the appender.
|
||||
exclude?: string | string[];
|
||||
// the name of the appender to filter. see https://log4js-node.github.io/log4js-node/layouts.html
|
||||
@ -110,7 +136,7 @@ export interface CategoryFilterAppender {
|
||||
* @see https://log4js-node.github.io/log4js-node/noLogFilter.html
|
||||
*/
|
||||
export interface NoLogFilterAppender {
|
||||
type: "noLogFilter";
|
||||
type: 'noLogFilter';
|
||||
// the regular expression (or the regular expressions if you provide an array of values)
|
||||
// will be used for evaluating the events to pass to the appender.
|
||||
// The events, which will match the regular expression, will be excluded and so not logged.
|
||||
@ -265,11 +291,11 @@ export interface StandardOutputAppender {
|
||||
export interface TCPAppender {
|
||||
type: 'tcp';
|
||||
// (defaults to 5000)
|
||||
port?: number
|
||||
port?: number;
|
||||
// (defaults to localhost)
|
||||
host?: string
|
||||
host?: string;
|
||||
// (defaults to __LOG4JS__)
|
||||
endMsg?: string
|
||||
endMsg?: string;
|
||||
// (defaults to a serialized log event)
|
||||
layout?: Layout;
|
||||
}
|
||||
@ -279,6 +305,35 @@ export interface CustomAppender {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of all Appenders to allow for declaration merging
|
||||
* @example
|
||||
* declare module 'log4js' {
|
||||
* interface Appenders {
|
||||
* StorageTestAppender: {
|
||||
* type: 'storageTest';
|
||||
* storageMedium: 'dvd' | 'usb' | 'hdd';
|
||||
* };
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
export interface Appenders {
|
||||
CategoryFilterAppender: CategoryFilterAppender;
|
||||
ConsoleAppender: ConsoleAppender;
|
||||
FileAppender: FileAppender;
|
||||
SyncfileAppender: SyncfileAppender;
|
||||
DateFileAppender: DateFileAppender;
|
||||
LogLevelFilterAppender: LogLevelFilterAppender;
|
||||
NoLogFilterAppender: NoLogFilterAppender;
|
||||
MultiFileAppender: MultiFileAppender;
|
||||
MultiprocessAppender: MultiprocessAppender;
|
||||
RecordingAppender: RecordingAppender;
|
||||
StandardErrorAppender: StandardErrorAppender;
|
||||
StandardOutputAppender: StandardOutputAppender;
|
||||
TCPAppender: TCPAppender;
|
||||
CustomAppender: CustomAppender;
|
||||
}
|
||||
|
||||
export interface AppenderModule {
|
||||
configure: (config: Config, layouts: LayoutsParam) => AppenderFunction;
|
||||
}
|
||||
@ -287,7 +342,7 @@ export type AppenderFunction = (loggingEvent: LoggingEvent) => void;
|
||||
|
||||
// TODO: Actually add types here...
|
||||
// It's supposed to be the full config element
|
||||
export type Config = any
|
||||
export type Config = any;
|
||||
|
||||
export interface LayoutsParam {
|
||||
basicLayout: LayoutFunction;
|
||||
@ -307,20 +362,7 @@ export interface PatternToken {
|
||||
|
||||
export type LayoutFunction = (loggingEvent: LoggingEvent) => string;
|
||||
|
||||
export type Appender = CategoryFilterAppender
|
||||
| ConsoleAppender
|
||||
| FileAppender
|
||||
| SyncfileAppender
|
||||
| DateFileAppender
|
||||
| LogLevelFilterAppender
|
||||
| NoLogFilterAppender
|
||||
| MultiFileAppender
|
||||
| MultiprocessAppender
|
||||
| RecordingAppender
|
||||
| StandardErrorAppender
|
||||
| StandardOutputAppender
|
||||
| TCPAppender
|
||||
| CustomAppender;
|
||||
export type Appender = Appenders[keyof Appenders];
|
||||
|
||||
export interface Levels {
|
||||
ALL: Level;
|
||||
@ -338,8 +380,14 @@ export interface Levels {
|
||||
}
|
||||
|
||||
export interface Configuration {
|
||||
appenders: { [name: string]: Appender; };
|
||||
categories: { [name: string]: { appenders: string[]; level: string; enableCallStack?: boolean; } };
|
||||
appenders: { [name: string]: Appender };
|
||||
categories: {
|
||||
[name: string]: {
|
||||
appenders: string[];
|
||||
level: string;
|
||||
enableCallStack?: boolean;
|
||||
};
|
||||
};
|
||||
pm2?: boolean;
|
||||
pm2InstanceVar?: string;
|
||||
levels?: Levels;
|
||||
@ -347,11 +395,11 @@ export interface Configuration {
|
||||
}
|
||||
|
||||
export interface Recording {
|
||||
configure(loggingEvent: LoggingEvent): void
|
||||
replay(): LoggingEvent[]
|
||||
playback(): LoggingEvent[]
|
||||
reset(): void
|
||||
erase(): void
|
||||
configure(loggingEvent: LoggingEvent): void;
|
||||
replay(): LoggingEvent[];
|
||||
playback(): LoggingEvent[];
|
||||
reset(): void;
|
||||
erase(): void;
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
|
||||
117
types/test.ts
117
types/test.ts
@ -3,10 +3,10 @@ import * as log4js from './log4js';
|
||||
log4js.configure('./filename');
|
||||
const logger1 = log4js.getLogger();
|
||||
logger1.level = 'debug';
|
||||
logger1.debug("Some debug messages");
|
||||
logger1.debug('Some debug messages');
|
||||
logger1.fatal({
|
||||
whatever: 'foo'
|
||||
})
|
||||
whatever: 'foo',
|
||||
});
|
||||
|
||||
const logger3 = log4js.getLogger('cheese');
|
||||
logger3.trace('Entering cheese testing');
|
||||
@ -18,40 +18,44 @@ logger3.fatal('Cheese was breeding ground for listeria.');
|
||||
|
||||
log4js.configure({
|
||||
appenders: { cheese: { type: 'console', filename: 'cheese.log' } },
|
||||
categories: { default: { appenders: ['cheese'], level: 'error' } }
|
||||
categories: { default: { appenders: ['cheese'], level: 'error' } },
|
||||
});
|
||||
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
out: { type: 'file', filename: 'pm2logs.log' }
|
||||
out: { type: 'file', filename: 'pm2logs.log' },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ['out'], level: 'info' }
|
||||
default: { appenders: ['out'], level: 'info' },
|
||||
},
|
||||
pm2: true,
|
||||
pm2InstanceVar: 'INSTANCE_ID'
|
||||
pm2InstanceVar: 'INSTANCE_ID',
|
||||
});
|
||||
|
||||
log4js.addLayout('json', config => function (logEvent) {
|
||||
return JSON.stringify(logEvent) + config.separator;
|
||||
log4js.addLayout(
|
||||
'json',
|
||||
(config) =>
|
||||
function (logEvent) {
|
||||
return JSON.stringify(logEvent) + config.separator;
|
||||
}
|
||||
);
|
||||
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
out: { type: 'stdout', layout: { type: 'json', separator: ',' } },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ['out'], level: 'info' },
|
||||
},
|
||||
});
|
||||
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
out: { type: 'stdout', layout: { type: 'json', separator: ',' } }
|
||||
file: { type: 'dateFile', filename: 'thing.log', pattern: '.mm' },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ['out'], level: 'info' }
|
||||
}
|
||||
});
|
||||
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
file: { type: 'dateFile', filename: 'thing.log', pattern: '.mm' }
|
||||
default: { appenders: ['file'], level: 'debug' },
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ['file'], level: 'debug' }
|
||||
}
|
||||
});
|
||||
|
||||
const logger4 = log4js.getLogger('thing');
|
||||
@ -66,13 +70,13 @@ log4js.shutdown();
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
cheeseLogs: { type: 'file', filename: 'cheese.log' },
|
||||
console: { type: 'console' }
|
||||
console: { type: 'console' },
|
||||
},
|
||||
categories: {
|
||||
cheese: { appenders: ['cheeseLogs'], level: 'error' },
|
||||
another: { appenders: ['console'], level: 'trace' },
|
||||
default: { appenders: ['console', 'cheeseLogs'], level: 'trace' }
|
||||
}
|
||||
default: { appenders: ['console', 'cheeseLogs'], level: 'trace' },
|
||||
},
|
||||
});
|
||||
|
||||
const logger6 = log4js.getLogger('cheese');
|
||||
@ -80,7 +84,10 @@ const logger6 = log4js.getLogger('cheese');
|
||||
const otherLogger = log4js.getLogger();
|
||||
|
||||
// this will get coloured output on console, and appear in cheese.log
|
||||
otherLogger.error('AAArgh! Something went wrong', { some: 'otherObject', useful_for: 'debug purposes' });
|
||||
otherLogger.error('AAArgh! Something went wrong', {
|
||||
some: 'otherObject',
|
||||
useful_for: 'debug purposes',
|
||||
});
|
||||
otherLogger.log('This should appear as info output');
|
||||
|
||||
// these will not appear (logging level beneath error)
|
||||
@ -101,22 +108,21 @@ anotherLogger.debug('Just checking');
|
||||
const pantsLog = log4js.getLogger('pants');
|
||||
pantsLog.debug('Something for pants');
|
||||
|
||||
|
||||
import { configure, getLogger } from './log4js';
|
||||
configure('./filename');
|
||||
const logger2 = getLogger();
|
||||
logger2.level = 'debug';
|
||||
logger2.debug("Some debug messages");
|
||||
logger2.debug('Some debug messages');
|
||||
|
||||
configure({
|
||||
appenders: { cheese: { type: 'file', filename: 'cheese.log' } },
|
||||
categories: { default: { appenders: ['cheese'], level: 'error' } }
|
||||
categories: { default: { appenders: ['cheese'], level: 'error' } },
|
||||
});
|
||||
|
||||
log4js.configure('./filename').getLogger();
|
||||
const logger7 = log4js.getLogger();
|
||||
logger7.level = 'debug';
|
||||
logger7.debug("Some debug messages");
|
||||
logger7.debug('Some debug messages');
|
||||
|
||||
const levels: log4js.Levels = log4js.levels;
|
||||
const level: log4js.Level = levels.getLevel('info');
|
||||
@ -124,40 +130,63 @@ const level: log4js.Level = levels.getLevel('info');
|
||||
log4js.connectLogger(logger1, {
|
||||
format: ':x, :y',
|
||||
level: 'info',
|
||||
context: true
|
||||
context: true,
|
||||
});
|
||||
|
||||
log4js.connectLogger(logger2, {
|
||||
format: (req, _res, format) => format(`:remote-addr - ${req.id} - ":method :url HTTP/:http-version" :status :content-length ":referrer" ":user-agent"`)
|
||||
format: (req, _res, format) =>
|
||||
format(
|
||||
`:remote-addr - ${req.id} - ":method :url HTTP/:http-version" :status :content-length ":referrer" ":user-agent"`
|
||||
),
|
||||
});
|
||||
|
||||
//support for passing in an appender module
|
||||
log4js.configure({
|
||||
appenders: { thing: { type: { configure: () => () => {} }}},
|
||||
categories: { default: { appenders: ['thing'], level: 'debug'}}
|
||||
appenders: { thing: { type: { configure: () => () => {} } } },
|
||||
categories: { default: { appenders: ['thing'], level: 'debug' } },
|
||||
});
|
||||
|
||||
declare module './log4js' {
|
||||
interface Appenders {
|
||||
StorageTestAppender: {
|
||||
type: 'storageTest';
|
||||
storageMedium: 'dvd' | 'usb' | 'hdd';
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
log4js.configure({
|
||||
appenders: { test: { type: 'storageTest', storageMedium: 'dvd' } },
|
||||
categories: { default: { appenders: ['test'], level: 'debug' } },
|
||||
});
|
||||
|
||||
log4js.configure({
|
||||
appenders: { rec: { type: 'recording' } },
|
||||
categories: { default: { appenders: ['rec'], 'level': 'debug' } }
|
||||
categories: { default: { appenders: ['rec'], level: 'debug' } },
|
||||
});
|
||||
const logger8 = log4js.getLogger();
|
||||
logger8.level = 'debug'
|
||||
logger8.debug('This will go to the recording!')
|
||||
logger8.debug('Another one')
|
||||
const recording = log4js.recording()
|
||||
const loggingEvents = recording.playback()
|
||||
logger8.level = 'debug';
|
||||
logger8.debug('This will go to the recording!');
|
||||
logger8.debug('Another one');
|
||||
const recording = log4js.recording();
|
||||
const loggingEvents = recording.playback();
|
||||
if (loggingEvents.length !== 2) {
|
||||
throw new Error(`Expected 2 recorded events, got ${loggingEvents.length}`)
|
||||
throw new Error(`Expected 2 recorded events, got ${loggingEvents.length}`);
|
||||
}
|
||||
if (loggingEvents[0].data[0] !== 'This will go to the recording!') {
|
||||
throw new Error(`Expected message 'This will go to the recording!', got ${loggingEvents[0].data[0]}`)
|
||||
throw new Error(
|
||||
`Expected message 'This will go to the recording!', got ${loggingEvents[0].data[0]}`
|
||||
);
|
||||
}
|
||||
if (loggingEvents[1].data[0] !== 'Another one') {
|
||||
throw new Error(`Expected message 'Another one', got ${loggingEvents[1].data[0]}`)
|
||||
throw new Error(
|
||||
`Expected message 'Another one', got ${loggingEvents[1].data[0]}`
|
||||
);
|
||||
}
|
||||
recording.reset()
|
||||
const loggingEventsPostReset = recording.playback()
|
||||
recording.reset();
|
||||
const loggingEventsPostReset = recording.playback();
|
||||
if (loggingEventsPostReset.length !== 0) {
|
||||
throw new Error(`Expected 0 recorded events after reset, got ${loggingEventsPostReset.length}`)
|
||||
throw new Error(
|
||||
`Expected 0 recorded events after reset, got ${loggingEventsPostReset.length}`
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user