mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
feat: allow multiple appenders for filters configuration
This commit is contained in:
parent
0696f63f68
commit
8fd25d55e1
@ -6,7 +6,8 @@ This is not strictly an appender - it wraps around another appender and stops lo
|
||||
|
||||
- `type` - `"categoryFilter"`
|
||||
- `exclude` - `string | Array<string>` - the category (or categories if you provide an array of values) that will be excluded from the appender.
|
||||
- `appender` - `string` - the name of the appender to filter.
|
||||
- `appender` - `string | Array<String>` - the name of the appender to filter. (exists for backward compatibility)
|
||||
- `appenders` - `string | Array<String>` - the names of the appenders to filter.
|
||||
|
||||
## Example
|
||||
|
||||
@ -17,7 +18,7 @@ log4js.configure({
|
||||
"no-noise": {
|
||||
type: "categoryFilter",
|
||||
exclude: "noisy.component",
|
||||
appender: "everything",
|
||||
appenders: ["everything"],
|
||||
},
|
||||
},
|
||||
categories: {
|
||||
|
||||
@ -5,7 +5,8 @@ The log level filter allows you to restrict the log events that an appender will
|
||||
## Configuration
|
||||
|
||||
- `type` - `logLevelFilter`
|
||||
- `appender` - `string` - the name of an appender, defined in the same configuration, that you want to filter
|
||||
- `appender` - `string | Array<String>` - the name of the appender, defined in the same configuration, that you want to filter (exists for backward compatibility)
|
||||
- `appenders` - `string | Array<String>` - the names of the appenders, defined in the same configuration, that you want to filter
|
||||
- `level` - `string` - the minimum level of event to allow through the filter
|
||||
- `maxLevel` - `string` (optional, defaults to `FATAL`) - the maximum level of event to allow through the filter
|
||||
|
||||
@ -20,7 +21,7 @@ log4js.configure({
|
||||
emergencies: { type: "file", filename: "panic-now.log" },
|
||||
"just-errors": {
|
||||
type: "logLevelFilter",
|
||||
appender: "emergencies",
|
||||
appenders: ["emergencies"],
|
||||
level: "error",
|
||||
},
|
||||
},
|
||||
|
||||
@ -10,7 +10,8 @@ The multiprocess appender sends log events to a master server over TCP sockets.
|
||||
|
||||
- `type` - `multiprocess`
|
||||
- `mode` - `master|worker` - controls whether the appender listens for log events sent over the network, or is responsible for serialising events and sending them to a server.
|
||||
- `appender` - `string` (only needed if `mode` == `master`)- the name of the appender to send the log events to
|
||||
- `appender` - `string | Array<String>` (only needed if `mode` == `master`)- the name of the appender to send the log events to (exists for backward compatibility)
|
||||
- `appenders` - `string | Array<String>` (only needed if `mode` == `master`)- the names of the appenders to send the log events to
|
||||
- `loggerPort` - `integer` (optional, defaults to `5000`) - the port to listen on, or send to
|
||||
- `loggerHost` - `string` (optional, defaults to `localhost`) - the host/IP address to listen on, or send to
|
||||
|
||||
@ -23,7 +24,7 @@ log4js.configure({
|
||||
server: {
|
||||
type: "multiprocess",
|
||||
mode: "master",
|
||||
appender: "file",
|
||||
appenders: ["file"],
|
||||
loggerHost: "0.0.0.0",
|
||||
},
|
||||
},
|
||||
|
||||
@ -9,7 +9,8 @@ You can stop to log them through a regular expression.
|
||||
|
||||
- `type` - `"noLogFilter"`
|
||||
- `exclude` - `string | Array<string>` - 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.
|
||||
- `appender` - `string` - the name of an appender, defined in the same configuration, that you want to filter.
|
||||
- `appender` - `string | Array<String>` - the name of the appender, defined in the same configuration, that you want to filter. (exists for backward compatibility)
|
||||
- `appenders` - `string | Array<String>` - the names of the appenders, defined in the same configuration, that you want to filter.
|
||||
|
||||
## Example
|
||||
|
||||
@ -20,7 +21,7 @@ log4js.configure({
|
||||
filtered: {
|
||||
type: "noLogFilter",
|
||||
exclude: "not",
|
||||
appender: "everything",
|
||||
appenders: ["everything"],
|
||||
},
|
||||
},
|
||||
categories: {
|
||||
|
||||
@ -1,19 +1,49 @@
|
||||
const debug = require('debug')('log4js:categoryFilter');
|
||||
|
||||
function categoryFilter(excludes, appender) {
|
||||
function categoryFilter(excludes, appenders) {
|
||||
if (typeof excludes === 'string') excludes = [excludes];
|
||||
return (logEvent) => {
|
||||
debug(`Checking ${logEvent.categoryName} against ${excludes}`);
|
||||
if (excludes.indexOf(logEvent.categoryName) === -1) {
|
||||
debug('Not excluded, sending to appender');
|
||||
appender(logEvent);
|
||||
debug('Not excluded, sending to appenders');
|
||||
appenders.forEach((appender) => {
|
||||
appender(logEvent);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config, layouts, findAppender) {
|
||||
const appender = findAppender(config.appender);
|
||||
return categoryFilter(config.exclude, appender);
|
||||
const addToSet = function (input, set = new Set()) {
|
||||
const addAppender = function (appenderName) {
|
||||
debug(`actual appender is ${appenderName}`);
|
||||
const appender = findAppender(appenderName);
|
||||
if (!appender) {
|
||||
debug(`actual appender "${config.appender}" not found`);
|
||||
throw new Error(
|
||||
`categoryFilter appender "${config.appender}" not defined`
|
||||
);
|
||||
} else {
|
||||
set.add(appender);
|
||||
}
|
||||
};
|
||||
|
||||
if (input && !Array.isArray(input)) input = [input];
|
||||
if (input) input.forEach((appenderName) => addAppender(appenderName));
|
||||
|
||||
return set;
|
||||
};
|
||||
|
||||
const appenders = new Set();
|
||||
addToSet(config.appender, appenders);
|
||||
addToSet(config.appenders, appenders);
|
||||
|
||||
if (appenders.size === 0) {
|
||||
debug(`no appender found in config ${config}`);
|
||||
throw new Error('categoryFilter appender must have an "appender" defined');
|
||||
}
|
||||
|
||||
return categoryFilter(config.exclude, appenders);
|
||||
}
|
||||
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
function logLevelFilter(minLevelString, maxLevelString, appender, levels) {
|
||||
const debug = require('debug')('log4js:logLevelFilter');
|
||||
|
||||
function logLevelFilter(minLevelString, maxLevelString, appenders, levels) {
|
||||
const minLevel = levels.getLevel(minLevelString);
|
||||
const maxLevel = levels.getLevel(maxLevelString, levels.FATAL);
|
||||
return (logEvent) => {
|
||||
@ -7,14 +9,44 @@ function logLevelFilter(minLevelString, maxLevelString, appender, levels) {
|
||||
minLevel.isLessThanOrEqualTo(eventLevel) &&
|
||||
maxLevel.isGreaterThanOrEqualTo(eventLevel)
|
||||
) {
|
||||
appender(logEvent);
|
||||
appenders.forEach((appender) => {
|
||||
appender(logEvent);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config, layouts, findAppender, levels) {
|
||||
const appender = findAppender(config.appender);
|
||||
return logLevelFilter(config.level, config.maxLevel, appender, levels);
|
||||
const addToSet = function (input, set = new Set()) {
|
||||
const addAppender = function (appenderName) {
|
||||
debug(`actual appender is ${appenderName}`);
|
||||
const appender = findAppender(appenderName);
|
||||
if (!appender) {
|
||||
debug(`actual appender "${config.appender}" not found`);
|
||||
throw new Error(
|
||||
`logLevelFilter appender "${config.appender}" not defined`
|
||||
);
|
||||
} else {
|
||||
set.add(appender);
|
||||
}
|
||||
};
|
||||
|
||||
if (input && !Array.isArray(input)) input = [input];
|
||||
if (input) input.forEach((appenderName) => addAppender(appenderName));
|
||||
|
||||
return set;
|
||||
};
|
||||
|
||||
const appenders = new Set();
|
||||
addToSet(config.appender, appenders);
|
||||
addToSet(config.appenders, appenders);
|
||||
|
||||
if (appenders.size === 0) {
|
||||
debug(`no appender found in config ${config}`);
|
||||
throw new Error('logLevelFilter appender must have an "appender" defined');
|
||||
}
|
||||
|
||||
return logLevelFilter(config.level, config.maxLevel, appenders, levels);
|
||||
}
|
||||
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -6,10 +6,10 @@ const END_MSG = '__LOG4JS__';
|
||||
|
||||
/**
|
||||
* Creates a server, listening on config.loggerPort, config.loggerHost.
|
||||
* Output goes to config.actualAppender (config.appender is used to
|
||||
* Output goes to config.actualAppenders (config.appender is used to
|
||||
* set up that appender).
|
||||
*/
|
||||
function logServer(config, actualAppender, levels) {
|
||||
function logServer(config, actualAppenders, levels) {
|
||||
/**
|
||||
* Takes a utf-8 string, returns an object with
|
||||
* the correct log properties.
|
||||
@ -29,8 +29,10 @@ function logServer(config, actualAppender, levels) {
|
||||
let logMessage = '';
|
||||
|
||||
function logTheMessage(msg) {
|
||||
debug('(master) deserialising log event and sending to actual appender');
|
||||
actualAppender(deserializeLoggingEvent(clientSocket, msg));
|
||||
debug('(master) deserialising log event and sending to actual appenders');
|
||||
actualAppenders.forEach((actualAppender) => {
|
||||
actualAppender(deserializeLoggingEvent(clientSocket, msg));
|
||||
});
|
||||
}
|
||||
|
||||
function chunkReceived(chunk) {
|
||||
@ -55,7 +57,9 @@ function logServer(config, actualAppender, levels) {
|
||||
remoteAddress: clientSocket.remoteAddress,
|
||||
remotePort: clientSocket.remotePort,
|
||||
};
|
||||
actualAppender(loggingEvent);
|
||||
actualAppenders.forEach((actualAppender) => {
|
||||
actualAppender(loggingEvent);
|
||||
});
|
||||
}
|
||||
|
||||
clientSocket.on('data', chunkReceived);
|
||||
@ -75,7 +79,9 @@ function logServer(config, actualAppender, levels) {
|
||||
|
||||
function app(event) {
|
||||
debug('(master) log event sent directly to actual appender (local event)');
|
||||
return actualAppender(event);
|
||||
actualAppenders.forEach((actualAppender) => {
|
||||
actualAppender(event);
|
||||
});
|
||||
}
|
||||
|
||||
app.shutdown = function (cb) {
|
||||
@ -158,10 +164,10 @@ function workerAppender(config) {
|
||||
return log;
|
||||
}
|
||||
|
||||
function createAppender(config, appender, levels) {
|
||||
function createAppender(config, appenders, levels) {
|
||||
if (config.mode === 'master') {
|
||||
debug('Creating master appender');
|
||||
return logServer(config, appender, levels);
|
||||
return logServer(config, appenders, levels);
|
||||
}
|
||||
|
||||
debug('Creating worker appender');
|
||||
@ -169,23 +175,40 @@ function createAppender(config, appender, levels) {
|
||||
}
|
||||
|
||||
function configure(config, layouts, findAppender, levels) {
|
||||
let appender;
|
||||
const appenders = new Set();
|
||||
debug(`configure with mode = ${config.mode}`);
|
||||
if (config.mode === 'master') {
|
||||
if (!config.appender) {
|
||||
const addToSet = function (input, set = new Set()) {
|
||||
const addAppender = function (appenderName) {
|
||||
debug(`actual appender is ${appenderName}`);
|
||||
const appender = findAppender(appenderName);
|
||||
if (!appender) {
|
||||
debug(`actual appender "${config.appender}" not found`);
|
||||
throw new Error(
|
||||
`multiprocess master appender "${config.appender}" not defined`
|
||||
);
|
||||
} else {
|
||||
set.add(appender);
|
||||
}
|
||||
};
|
||||
|
||||
if (input && !Array.isArray(input)) input = [input];
|
||||
if (input) input.forEach((appenderName) => addAppender(appenderName));
|
||||
|
||||
return set;
|
||||
};
|
||||
|
||||
addToSet(config.appender, appenders);
|
||||
addToSet(config.appenders, appenders);
|
||||
|
||||
if (appenders.size === 0) {
|
||||
debug(`no appender found in config ${config}`);
|
||||
throw new Error('multiprocess master must have an "appender" defined');
|
||||
}
|
||||
debug(`actual appender is ${config.appender}`);
|
||||
appender = findAppender(config.appender);
|
||||
if (!appender) {
|
||||
debug(`actual appender "${config.appender}" not found`);
|
||||
throw new Error(
|
||||
`multiprocess master appender "${config.appender}" not defined`
|
||||
'multiprocess master appender must have an "appender" defined'
|
||||
);
|
||||
}
|
||||
}
|
||||
return createAppender(config, appender, levels);
|
||||
return createAppender(config, appenders, levels);
|
||||
}
|
||||
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -14,10 +14,10 @@ function removeNullOrEmptyRegexp(regexp) {
|
||||
* Returns a function that will exclude the events in case they match
|
||||
* with the regular expressions provided
|
||||
* @param {(string|string[])} filters contains the regexp that will be used for the evaluation
|
||||
* @param {*} appender
|
||||
* @param {*} appenders
|
||||
* @returns {function}
|
||||
*/
|
||||
function noLogFilter(filters, appender) {
|
||||
function noLogFilter(filters, appenders) {
|
||||
return (logEvent) => {
|
||||
debug(`Checking data: ${logEvent.data} against filters: ${filters}`);
|
||||
if (typeof filters === 'string') {
|
||||
@ -29,15 +29,45 @@ function noLogFilter(filters, appender) {
|
||||
filters.length === 0 ||
|
||||
logEvent.data.findIndex((value) => regex.test(value)) < 0
|
||||
) {
|
||||
debug('Not excluded, sending to appender');
|
||||
appender(logEvent);
|
||||
debug('Not excluded, sending to appenders');
|
||||
appenders.forEach((appender) => {
|
||||
appender(logEvent);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function configure(config, layouts, findAppender) {
|
||||
const appender = findAppender(config.appender);
|
||||
return noLogFilter(config.exclude, appender);
|
||||
const addToSet = function (input, set = new Set()) {
|
||||
const addAppender = function (appenderName) {
|
||||
debug(`actual appender is ${appenderName}`);
|
||||
const appender = findAppender(appenderName);
|
||||
if (!appender) {
|
||||
debug(`actual appender "${config.appender}" not found`);
|
||||
throw new Error(
|
||||
`noLogFilter appender "${config.appender}" not defined`
|
||||
);
|
||||
} else {
|
||||
set.add(appender);
|
||||
}
|
||||
};
|
||||
|
||||
if (input && !Array.isArray(input)) input = [input];
|
||||
if (input) input.forEach((appenderName) => addAppender(appenderName));
|
||||
|
||||
return set;
|
||||
};
|
||||
|
||||
const appenders = new Set();
|
||||
addToSet(config.appender, appenders);
|
||||
addToSet(config.appenders, appenders);
|
||||
|
||||
if (appenders.size === 0) {
|
||||
debug(`no appender found in config ${config}`);
|
||||
throw new Error('noLogFilter appender must have an "appender" defined');
|
||||
}
|
||||
|
||||
return noLogFilter(config.exclude, appenders);
|
||||
}
|
||||
|
||||
module.exports.configure = configure;
|
||||
|
||||
@ -365,7 +365,7 @@ test('Multiprocess Appender', async (batch) => {
|
||||
appenders: { master: { type: 'multiprocess', mode: 'master' } },
|
||||
categories: { default: { appenders: ['master'], level: 'trace' } },
|
||||
}),
|
||||
new Error('multiprocess master must have an "appender" defined')
|
||||
new Error('multiprocess master appender must have an "appender" defined')
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user