Update karma-related packages

This updates karma to 5.2.3, karma-coverage to the officially
published version 2.0.3 (we were previously relying on a git
commit) and karma-sourcemap-loader to 0.3.8.

DISABLE_THIRD_PARTY_CHECK=Update Karma

R=aerotwist@chromium.org

Change-Id: Iaa365379d7c2c6eb9145b1507be1a0a3ae812359
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2527043
Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org>
Commit-Queue: Paul Lewis <aerotwist@chromium.org>
Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org>
Reviewed-by: Paul Lewis <aerotwist@chromium.org>
This commit is contained in:
Tim van der Lippe
2020-11-09 17:42:16 +00:00
committed by Commit Bot
parent 77043d9e29
commit 5226a88fe0
1005 changed files with 29708 additions and 112370 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ class LoggingEvent {
/**
* Models a logging event.
* @constructor
* @param {String} categoryName name of category
* @param {string} categoryName name of category
* @param {Log4js.Level} level level of message
* @param {Array} data objects to log
* @author Seth Chisamore
-2
View File
@@ -1,5 +1,3 @@
'use strict';
function maxFileSizeUnitTransform(maxLogSize) {
if (typeof maxLogSize === 'number' && Number.isInteger(maxLogSize)) {
return maxLogSize;
-2
View File
@@ -1,5 +1,3 @@
'use strict';
const debug = require('debug')('log4js:categoryFilter');
function categoryFilter(excludes, appender) {
-2
View File
@@ -1,5 +1,3 @@
'use strict';
// eslint-disable-next-line no-console
const consoleLog = console.log.bind(console);
+8 -4
View File
@@ -1,9 +1,7 @@
'use strict';
const streams = require('streamroller');
const os = require('os');
const eol = os.EOL || '\n';
const eol = os.EOL;
/**
* File appender that rolls files according to a date pattern.
@@ -30,8 +28,14 @@ function appender(
options
);
logFile.on("drain", () => {
process.emit("log4js:pause", false);
});
const app = function (logEvent) {
logFile.write(layout(logEvent, timezoneOffset) + eol, 'utf8');
if (!logFile.write(layout(logEvent, timezoneOffset) + eol, "utf8")) {
process.emit("log4js:pause", true);
}
};
app.shutdown = function (complete) {
+16 -7
View File
@@ -1,11 +1,9 @@
'use strict';
const debug = require('debug')('log4js:file');
const path = require('path');
const streams = require('streamroller');
const os = require('os');
const eol = os.EOL || '\n';
const eol = os.EOL;
function openTheStream(file, fileSize, numFiles, options) {
const stream = new streams.RollingFileStream(
@@ -17,6 +15,9 @@ function openTheStream(file, fileSize, numFiles, options) {
stream.on('error', (err) => {
console.error('log4js.fileAppender - Writing to file %s, error happened ', file, err); //eslint-disable-line
});
stream.on('drain', () => {
process.emit("log4js:pause", false);
});
return stream;
}
@@ -52,7 +53,17 @@ function fileAppender(file, layout, logSize, numBackups, options, timezoneOffset
let writer = openTheStream(file, logSize, numBackups, options);
const app = function (loggingEvent) {
writer.write(layout(loggingEvent, timezoneOffset) + eol, 'utf8');
if (options.removeColor === true) {
// eslint-disable-next-line no-control-regex
const regex = /\x1b[[0-9;]*m/g;
loggingEvent.data = loggingEvent.data.map(d => {
if (typeof d === 'string') return d.replace(regex, '')
return d
})
}
if (!writer.write(layout(loggingEvent, timezoneOffset) + eol, "utf8")) {
process.emit('log4js:pause', true);
}
};
app.reopen = function () {
@@ -66,9 +77,7 @@ function fileAppender(file, layout, logSize, numBackups, options, timezoneOffset
app.shutdown = function (complete) {
process.removeListener('SIGHUP', app.sighupHandler);
writer.write('', 'utf-8', () => {
writer.end(complete);
});
writer.end('', 'utf-8', complete);
};
// On SIGHUP, close and reopen all files. This allows this appender to work with
-2
View File
@@ -1,5 +1,3 @@
'use strict';
const debug = require('debug')('log4js:fileSync');
const path = require('path');
const fs = require('fs');
+30 -6
View File
@@ -16,6 +16,7 @@ coreAppenders.set('categoryFilter', require('./categoryFilter'));
coreAppenders.set('noLogFilter', require('./noLogFilter'));
coreAppenders.set('file', require('./file'));
coreAppenders.set('dateFile', require('./dateFile'));
coreAppenders.set('fileSync', require('./fileSync'));
const appenders = new Map();
@@ -40,6 +41,22 @@ const loadAppenderModule = (type, config) => coreAppenders.get(type)
|| (require.main && tryLoading(path.join(path.dirname(require.main.filename), type), config))
|| tryLoading(path.join(process.cwd(), type), config);
const appendersLoading = new Set();
const getAppender = (name, config) => {
if (appenders.has(name)) return appenders.get(name);
if (!config.appenders[name]) return false;
if (appendersLoading.has(name)) throw new Error(`Dependency loop detected for appender ${name}.`);
appendersLoading.add(name);
debug(`Creating appender ${name}`);
// eslint-disable-next-line no-use-before-define
const appender = createAppender(name, config);
appendersLoading.delete(name);
appenders.set(name, appender);
return appender;
};
const createAppender = (name, config) => {
const appenderConfig = config.appenders[name];
const appenderModule = appenderConfig.type.configure
@@ -63,22 +80,29 @@ const createAppender = (name, config) => {
return appenderModule.configure(
adapters.modifyConfig(appenderConfig),
layouts,
appender => appenders.get(appender),
appender => getAppender(appender, config),
levels
);
}, () => {});
}, () => { });
};
const setup = (config) => {
appenders.clear();
appendersLoading.clear();
const usedAppenders = [];
Object.values(config.categories).forEach(category => {
usedAppenders.push(...category.appenders)
});
Object.keys(config.appenders).forEach((name) => {
debug(`Creating appender ${name}`);
appenders.set(name, createAppender(name, config));
// dodgy hard-coding of special case for tcp-server which may not have
// any categories associated with it, but needs to be started up anyway
if (usedAppenders.includes(name) || config.appenders[name].type === 'tcp-server') {
getAppender(name, config);
}
});
};
setup({ appenders: { out: { type: 'stdout' } } });
setup({ appenders: { out: { type: 'stdout' } }, categories: { default: { appenders: ['out'], level: 'trace' } } });
configuration.addListener((config) => {
configuration.throwExceptionIf(
-2
View File
@@ -1,5 +1,3 @@
'use strict';
function logLevelFilter(minLevelString, maxLevelString, appender, levels) {
const minLevel = levels.getLevel(minLevelString);
const maxLevel = levels.getLevel(maxLevelString, levels.FATAL);
+1 -1
View File
@@ -1,4 +1,4 @@
'use strict';
const debug = require('debug')('log4js:multiFile');
const path = require('path');
+19 -16
View File
@@ -1,4 +1,4 @@
'use strict';
const debug = require('debug')('log4js:multiprocess');
const net = require('net');
@@ -17,7 +17,7 @@ function logServer(config, actualAppender, levels) {
* the correct log properties.
*/
function deserializeLoggingEvent(clientSocket, msg) {
debug('deserialising log event');
debug('(master) deserialising log event');
const loggingEvent = LoggingEvent.deserialise(msg);
loggingEvent.remoteAddress = clientSocket.remoteAddress;
loggingEvent.remotePort = clientSocket.remotePort;
@@ -26,19 +26,20 @@ function logServer(config, actualAppender, levels) {
}
/* eslint prefer-arrow-callback:0 */
const server = net.createServer(function serverCreated(clientSocket) {
const server = net.createServer(function connectionHandler(clientSocket) {
debug('(master) connection received');
clientSocket.setEncoding('utf8');
let logMessage = '';
function logTheMessage(msg) {
if (logMessage.length > 0) {
debug('deserialising log event and sending to actual appender');
debug('(master) deserialising log event and sending to actual appender');
actualAppender(deserializeLoggingEvent(clientSocket, msg));
}
}
function chunkReceived(chunk) {
debug('chunk of data received');
debug('(master) chunk of data received');
let event;
logMessage += chunk || '';
if (logMessage.indexOf(END_MSG) > -1) {
@@ -67,19 +68,19 @@ function logServer(config, actualAppender, levels) {
clientSocket.on('error', handleError);
});
server.listen(config.loggerPort || 5000, config.loggerHost || 'localhost', function () {
debug('master server listening');
server.listen(config.loggerPort || 5000, config.loggerHost || 'localhost', function (e) {
debug('(master) master server listening, error was ', e);
// allow the process to exit, if this is the only socket active
server.unref();
});
function app(event) {
debug('log event sent directly to actual appender (local event)');
debug('(master) log event sent directly to actual appender (local event)');
return actualAppender(event);
}
app.shutdown = function (cb) {
debug('master shutdown called, closing server');
debug('(master) master shutdown called, closing server');
server.close(cb);
};
@@ -93,14 +94,14 @@ function workerAppender(config) {
let shutdownAttempts = 3;
function write(loggingEvent) {
debug('Writing log event to socket');
debug('(worker) Writing log event to socket');
socket.write(loggingEvent.serialise(), 'utf8');
socket.write(END_MSG, 'utf8');
}
function emptyBuffer() {
let evt;
debug('emptying worker buffer');
debug('(worker) emptying worker buffer');
/* eslint no-cond-assign:0 */
while ((evt = buffer.shift())) {
write(evt);
@@ -108,10 +109,12 @@ function workerAppender(config) {
}
function createSocket() {
debug(`worker appender creating socket to ${config.loggerHost || 'localhost'}:${config.loggerPort || 5000}`);
debug(
`(worker) worker appender creating socket to ${config.loggerHost || 'localhost'}:${config.loggerPort || 5000}`
);
socket = net.createConnection(config.loggerPort || 5000, config.loggerHost || 'localhost');
socket.on('connect', () => {
debug('worker socket connected');
debug('(worker) worker socket connected');
emptyBuffer();
canWrite = true;
});
@@ -126,14 +129,14 @@ function workerAppender(config) {
if (canWrite) {
write(loggingEvent);
} else {
debug('worker buffering log event because it cannot write at the moment');
debug('(worker) worker buffering log event because it cannot write at the moment');
buffer.push(loggingEvent);
}
}
log.shutdown = function (cb) {
debug('worker shutdown called');
debug('(worker) worker shutdown called');
if (buffer.length && shutdownAttempts) {
debug('worker buffer has items, waiting 100ms to empty');
debug('(worker) worker buffer has items, waiting 100ms to empty');
shutdownAttempts -= 1;
setTimeout(() => {
log.shutdown(cb);
+4 -4
View File
@@ -1,11 +1,11 @@
'use strict';
const debug = require('debug')('log4js:noLogFilter');
/**
* The function removes empty or null regexp from the array
* @param {Array<string>} regexp
* @returns {Array<string>} a filtered string array with not empty or null regexp
* @param {string[]} regexp
* @returns {string[]} a filtered string array with not empty or null regexp
*/
function removeNullOrEmptyRegexp(regexp) {
const filtered = regexp.filter(el => ((el != null) && (el !== '')));
@@ -15,7 +15,7 @@ function removeNullOrEmptyRegexp(regexp) {
/**
* Returns a function that will exclude the events in case they match
* with the regular expressions provided
* @param {string | Array<string>} filters contains the regexp that will be used for the evaluation
* @param {(string|string[])} filters contains the regexp that will be used for the evaluation
* @param {*} appender
* @returns {function}
*/
+4 -4
View File
@@ -1,4 +1,4 @@
'use strict';
const debug = require('debug')('log4js:recording');
@@ -21,9 +21,9 @@ function reset() {
}
module.exports = {
configure: configure,
replay: replay,
configure,
replay,
playback: replay,
reset: reset,
reset,
erase: reset
};
+1 -1
View File
@@ -1,4 +1,4 @@
'use strict';
function stderrAppender(layout, timezoneOffset) {
return (loggingEvent) => {
+1 -1
View File
@@ -1,4 +1,4 @@
'use strict';
function stdoutAppender(layout, timezoneOffset) {
return (loggingEvent) => {
+13 -5
View File
@@ -1,17 +1,18 @@
'use strict';
const debug = require('debug')('log4js:tcp');
const net = require('net');
function appender(config) {
function appender(config, layout) {
let canWrite = false;
const buffer = [];
let socket;
let shutdownAttempts = 3;
let endMsg = '__LOG4JS__';
function write(loggingEvent) {
debug('Writing log event to socket');
canWrite = socket.write(`${loggingEvent.serialise()}__LOG4JS__`, 'utf8');
canWrite = socket.write(`${layout(loggingEvent)}${endMsg}`, 'utf8');
}
function emptyBuffer() {
@@ -25,6 +26,7 @@ function appender(config) {
function createSocket() {
debug(`appender creating socket to ${config.host || 'localhost'}:${config.port || 5000}`);
endMsg = `${config.endMsg || '__LOG4JS__'}`;
socket = net.createConnection(config.port || 5000, config.host || 'localhost');
socket.on('connect', () => {
debug('socket connected');
@@ -68,9 +70,15 @@ function appender(config) {
return log;
}
function configure(config) {
function configure(config, layouts) {
debug(`configure with config = ${config}`);
return appender(config);
let layout = function (loggingEvent) {
return loggingEvent.serialise();
};
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return appender(config, layout);
}
module.exports.configure = configure;
+3 -3
View File
@@ -10,8 +10,8 @@ const categories = new Map();
* and level, if none is set on this category.
* This is recursive, so each parent also gets loaded with inherited appenders.
* Inheritance is blocked if a category has inherit=false
* @param {any} config
* @param {any} category the child category
* @param {*} config
* @param {*} category the child category
* @param {string} categoryName dotted path to category
* @return {void}
*/
@@ -57,7 +57,7 @@ function inheritFromParent(config, category, categoryName) {
* Walk all categories in the config, and pull down any configuration from parent to child.
* This includes inherited appenders, and level, where level is not set.
* Inheritance is skipped where a category has inherit=false.
* @param {any} config
* @param {*} config
*/
function addCategoryInheritance(config) {
if (!config.categories) return;
+59 -48
View File
@@ -1,18 +1,25 @@
const cluster = require('cluster');
const debug = require('debug')('log4js:clustering');
const LoggingEvent = require('./LoggingEvent');
const configuration = require('./configuration');
const debug = require("debug")("log4js:clustering");
const LoggingEvent = require("./LoggingEvent");
const configuration = require("./configuration");
let disabled = false;
let cluster = null;
try {
cluster = require("cluster"); //eslint-disable-line
} catch (e) {
debug("cluster module not present");
disabled = true;
}
const listeners = [];
let disabled = false;
let pm2 = false;
let pm2InstanceVar = 'NODE_APP_INSTANCE';
let pm2InstanceVar = "NODE_APP_INSTANCE";
const isPM2Master = () => pm2 && process.env[pm2InstanceVar] === '0';
const isPM2Master = () => pm2 && process.env[pm2InstanceVar] === "0";
const isMaster = () => disabled || cluster.isMaster || isPM2Master();
const sendToListeners = (logEvent) => {
const sendToListeners = logEvent => {
listeners.forEach(l => l(logEvent));
};
@@ -20,60 +27,64 @@ const sendToListeners = (logEvent) => {
// process.send
const receiver = (worker, message) => {
// prior to node v6, the worker parameter was not passed (args were message, handle)
debug('cluster message received from worker ', worker, ': ', message);
debug("cluster message received from worker ", worker, ": ", message);
if (worker.topic && worker.data) {
message = worker;
worker = undefined;
}
if (message && message.topic && message.topic === 'log4js:message') {
debug('received message: ', message.data);
if (message && message.topic && message.topic === "log4js:message") {
debug("received message: ", message.data);
const logEvent = LoggingEvent.deserialise(message.data);
sendToListeners(logEvent);
}
};
configuration.addListener((config) => {
// clear out the listeners, because configure has been called.
listeners.length = 0;
if (!disabled) {
configuration.addListener(config => {
// clear out the listeners, because configure has been called.
listeners.length = 0;
disabled = config.disableClustering;
pm2 = config.pm2;
pm2InstanceVar = config.pm2InstanceVar || 'NODE_APP_INSTANCE';
({
pm2,
disableClustering: disabled,
pm2InstanceVar = "NODE_APP_INSTANCE"
} = config);
debug(`clustering disabled ? ${disabled}`);
debug(`cluster.isMaster ? ${cluster.isMaster}`);
debug(`pm2 enabled ? ${pm2}`);
debug(`pm2InstanceVar = ${pm2InstanceVar}`);
debug(`process.env[${pm2InstanceVar}] = ${process.env[pm2InstanceVar]}`);
debug(`clustering disabled ? ${disabled}`);
debug(`cluster.isMaster ? ${cluster && cluster.isMaster}`);
debug(`pm2 enabled ? ${pm2}`);
debug(`pm2InstanceVar = ${pm2InstanceVar}`);
debug(`process.env[${pm2InstanceVar}] = ${process.env[pm2InstanceVar]}`);
// just in case configure is called after shutdown
if (pm2) {
process.removeListener('message', receiver);
}
if (cluster.removeListener) {
cluster.removeListener('message', receiver);
}
// just in case configure is called after shutdown
if (pm2) {
process.removeListener("message", receiver);
}
if (cluster && cluster.removeListener) {
cluster.removeListener("message", receiver);
}
if (config.disableClustering) {
debug('Not listening for cluster messages, because clustering disabled.');
} else if (isPM2Master()) {
// PM2 cluster support
// PM2 runs everything as workers - install pm2-intercom for this to work.
// we only want one of the app instances to write logs
debug('listening for PM2 broadcast messages');
process.on('message', receiver);
} else if (cluster.isMaster) {
debug('listening for cluster messages');
cluster.on('message', receiver);
} else {
debug('not listening for messages, because we are not a master process');
}
});
if (disabled || config.disableClustering) {
debug("Not listening for cluster messages, because clustering disabled.");
} else if (isPM2Master()) {
// PM2 cluster support
// PM2 runs everything as workers - install pm2-intercom for this to work.
// we only want one of the app instances to write logs
debug("listening for PM2 broadcast messages");
process.on("message", receiver);
} else if (cluster.isMaster) {
debug("listening for cluster messages");
cluster.on("message", receiver);
} else {
debug("not listening for messages, because we are not a master process");
}
});
}
module.exports = {
onlyOnMaster: (fn, notMaster) => (isMaster() ? fn() : notMaster),
isMaster: isMaster,
send: (msg) => {
isMaster,
send: msg => {
if (isMaster()) {
sendToListeners(msg);
} else {
@@ -83,10 +94,10 @@ module.exports = {
worker: process.pid
};
}
process.send({ topic: 'log4js:message', data: msg.serialise() });
process.send({ topic: "log4js:message", data: msg.serialise() });
}
},
onMessage: (listener) => {
onMessage: listener => {
listeners.push(listener);
}
};
+1 -1
View File
@@ -1,4 +1,4 @@
'use strict';
const util = require('util');
const debug = require('debug')('log4js:configuration');
+144 -134
View File
@@ -1,13 +1,12 @@
/* eslint-disable no-plusplus */
'use strict';
const levels = require("./levels");
const levels = require('./levels');
const DEFAULT_FORMAT = ':remote-addr - -'
+ ' ":method :url HTTP/:http-version"'
+ ' :status :content-length ":referrer"'
+ ' ":user-agent"';
const DEFAULT_FORMAT =
":remote-addr - -" +
' ":method :url HTTP/:http-version"' +
' :status :content-length ":referrer"' +
' ":user-agent"';
/**
* Return request url path,
@@ -15,26 +14,25 @@ const DEFAULT_FORMAT = ':remote-addr - -'
* for the assemble_tokens function at low, to pass the tests.
*
* @param {IncomingMessage} req
* @return {String}
* @return {string}
* @api private
*/
function getUrl(req) {
return req.originalUrl || req.url;
}
/**
* Adds custom {token, replacement} objects to defaults,
* overwriting the defaults if any tokens clash
*
* @param {IncomingMessage} req
* @param {ServerResponse} res
* @param {Array} customTokens
* [{ token: string-or-regexp, replacement: string-or-replace-function }]
* @return {Array}
*/
* Adds custom {token, replacement} objects to defaults,
* overwriting the defaults if any tokens clash
*
* @param {IncomingMessage} req
* @param {ServerResponse} res
* @param {Array} customTokens
* [{ token: string-or-regexp, replacement: string-or-replace-function }]
* @return {Array}
*/
function assembleTokens(req, res, customTokens) {
const arrayUniqueTokens = (array) => {
const arrayUniqueTokens = array => {
const a = array.concat();
for (let i = 0; i < a.length; ++i) {
for (let j = i + 1; j < a.length; ++j) {
@@ -49,49 +47,61 @@ function assembleTokens(req, res, customTokens) {
};
const defaultTokens = [];
defaultTokens.push({ token: ':url', replacement: getUrl(req) });
defaultTokens.push({ token: ':protocol', replacement: req.protocol });
defaultTokens.push({ token: ':hostname', replacement: req.hostname });
defaultTokens.push({ token: ':method', replacement: req.method });
defaultTokens.push({ token: ':status', replacement: res.__statusCode || res.statusCode });
defaultTokens.push({ token: ':response-time', replacement: res.responseTime });
defaultTokens.push({ token: ':date', replacement: new Date().toUTCString() });
defaultTokens.push({ token: ":url", replacement: getUrl(req) });
defaultTokens.push({ token: ":protocol", replacement: req.protocol });
defaultTokens.push({ token: ":hostname", replacement: req.hostname });
defaultTokens.push({ token: ":method", replacement: req.method });
defaultTokens.push({
token: ':referrer',
replacement: req.headers.referer || req.headers.referrer || ''
token: ":status",
replacement: res.__statusCode || res.statusCode
});
defaultTokens.push({
token: ':http-version',
token: ":response-time",
replacement: res.responseTime
});
defaultTokens.push({ token: ":date", replacement: new Date().toUTCString() });
defaultTokens.push({
token: ":referrer",
replacement: req.headers.referer || req.headers.referrer || ""
});
defaultTokens.push({
token: ":http-version",
replacement: `${req.httpVersionMajor}.${req.httpVersionMinor}`
});
defaultTokens.push({
token: ':remote-addr',
replacement: req.headers['x-forwarded-for']
|| req.ip
|| req._remoteAddress
|| (req.socket
&& (req.socket.remoteAddress
|| (req.socket.socket && req.socket.socket.remoteAddress)
)
)
token: ":remote-addr",
replacement:
req.headers["x-forwarded-for"] ||
req.ip ||
req._remoteAddress ||
(req.socket &&
(req.socket.remoteAddress ||
(req.socket.socket && req.socket.socket.remoteAddress)))
});
defaultTokens.push({ token: ':user-agent', replacement: req.headers['user-agent'] });
defaultTokens.push({
token: ':content-length',
replacement: res.getHeader('content-length')
|| (res.__headers && res.__headers['Content-Length'])
|| '-'
token: ":user-agent",
replacement: req.headers["user-agent"]
});
defaultTokens.push({
token: ":content-length",
replacement:
res.getHeader("content-length") ||
(res.__headers && res.__headers["Content-Length"]) ||
"-"
});
defaultTokens.push({
token: /:req\[([^\]]+)]/g,
replacement: function (_, field) {
replacement(_, field) {
return req.headers[field.toLowerCase()];
}
});
defaultTokens.push({
token: /:res\[([^\]]+)]/g,
replacement: function (_, field) {
return res.getHeader(field.toLowerCase()) || (res.__headers && res.__headers[field]);
replacement(_, field) {
return (
res.getHeader(field.toLowerCase()) ||
(res.__headers && res.__headers[field])
);
}
});
@@ -99,13 +109,13 @@ function assembleTokens(req, res, customTokens) {
}
/**
* Return formatted log line.
*
* @param {String} str
* @param {Array} tokens
* @return {String}
* @api private
*/
* Return formatted log line.
*
* @param {string} str
* @param {Array} tokens
* @return {string}
* @api private
*/
function format(str, tokens) {
for (let i = 0; i < tokens.length; i++) {
str = str.replace(tokens[i].token, tokens[i].replacement);
@@ -114,32 +124,32 @@ function format(str, tokens) {
}
/**
* Return RegExp Object about nolog
*
* @param {String|Array} nolog
* @return {RegExp}
* @api private
*
* syntax
* 1. String
* 1.1 "\\.gif"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga
* LOGGING http://example.com/hoge.agif
* 1.2 in "\\.gif|\\.jpg$"
* NOT LOGGING http://example.com/hoge.gif and
* http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga
* LOGGING http://example.com/hoge.agif,
* http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge
* 1.3 in "\\.(gif|jpe?g|png)$"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg
* LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3
* 2. RegExp
* 2.1 in /\.(gif|jpe?g|png)$/
* SAME AS 1.3
* 3. Array
* 3.1 ["\\.jpg$", "\\.png", "\\.gif"]
* SAME AS "\\.jpg|\\.png|\\.gif"
*/
* Return RegExp Object about nolog
*
* @param {(string|Array)} nolog
* @return {RegExp}
* @api private
*
* syntax
* 1. String
* 1.1 "\\.gif"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.gif?fuga
* LOGGING http://example.com/hoge.agif
* 1.2 in "\\.gif|\\.jpg$"
* NOT LOGGING http://example.com/hoge.gif and
* http://example.com/hoge.gif?fuga and http://example.com/hoge.jpg?fuga
* LOGGING http://example.com/hoge.agif,
* http://example.com/hoge.ajpg and http://example.com/hoge.jpg?hoge
* 1.3 in "\\.(gif|jpe?g|png)$"
* NOT LOGGING http://example.com/hoge.gif and http://example.com/hoge.jpeg
* LOGGING http://example.com/hoge.gif?uid=2 and http://example.com/hoge.jpg?pid=3
* 2. RegExp
* 2.1 in /\.(gif|jpe?g|png)$/
* SAME AS 1.3
* 3. Array
* 3.1 ["\\.jpg$", "\\.png", "\\.gif"]
* SAME AS "\\.jpg|\\.png|\\.gif"
*/
function createNoLogCondition(nolog) {
let regexp = null;
@@ -147,40 +157,40 @@ function createNoLogCondition(nolog) {
regexp = nolog;
}
if (typeof nolog === 'string') {
if (typeof nolog === "string") {
regexp = new RegExp(nolog);
}
if (Array.isArray(nolog)) {
// convert to strings
const regexpsAsStrings = nolog.map(reg => (reg.source ? reg.source : reg));
regexp = new RegExp(regexpsAsStrings.join('|'));
regexp = new RegExp(regexpsAsStrings.join("|"));
}
return regexp;
}
/**
* Allows users to define rules around status codes to assign them to a specific
* logging level.
* There are two types of rules:
* - RANGE: matches a code within a certain range
* E.g. { 'from': 200, 'to': 299, 'level': 'info' }
* - CONTAINS: matches a code to a set of expected codes
* E.g. { 'codes': [200, 203], 'level': 'debug' }
* Note*: Rules are respected only in order of prescendence.
*
* @param {Number} statusCode
* @param {Level} currentLevel
* @param {Object} ruleSet
* @return {Level}
* @api private
*/
* Allows users to define rules around status codes to assign them to a specific
* logging level.
* There are two types of rules:
* - RANGE: matches a code within a certain range
* E.g. { 'from': 200, 'to': 299, 'level': 'info' }
* - CONTAINS: matches a code to a set of expected codes
* E.g. { 'codes': [200, 203], 'level': 'debug' }
* Note*: Rules are respected only in order of prescendence.
*
* @param {Number} statusCode
* @param {Level} currentLevel
* @param {Object} ruleSet
* @return {Level}
* @api private
*/
function matchRules(statusCode, currentLevel, ruleSet) {
let level = currentLevel;
if (ruleSet) {
const matchedRule = ruleSet.find((rule) => {
const matchedRule = ruleSet.find(rule => {
let ruleMatched = false;
if (rule.from && rule.to) {
ruleMatched = statusCode >= rule.from && statusCode <= rule.to;
@@ -197,38 +207,38 @@ function matchRules(statusCode, currentLevel, ruleSet) {
}
/**
* Log requests with the given `options` or a `format` string.
*
* Options:
*
* - `format` Format string, see below for tokens
* - `level` A log4js levels instance. Supports also 'auto'
* - `nolog` A string or RegExp to exclude target logs
* - `statusRules` A array of rules for setting specific logging levels base on status codes
* - `context` Whether to add a response of express to the context
*
* Tokens:
*
* - `:req[header]` ex: `:req[Accept]`
* - `:res[header]` ex: `:res[Content-Length]`
* - `:http-version`
* - `:response-time`
* - `:remote-addr`
* - `:date`
* - `:method`
* - `:url`
* - `:referrer`
* - `:user-agent`
* - `:status`
*
* @return {Function}
* @param logger4js
* @param options
* @api public
*/
* Log requests with the given `options` or a `format` string.
*
* Options:
*
* - `format` Format string, see below for tokens
* - `level` A log4js levels instance. Supports also 'auto'
* - `nolog` A string or RegExp to exclude target logs
* - `statusRules` A array of rules for setting specific logging levels base on status codes
* - `context` Whether to add a response of express to the context
*
* Tokens:
*
* - `:req[header]` ex: `:req[Accept]`
* - `:res[header]` ex: `:res[Content-Length]`
* - `:http-version`
* - `:response-time`
* - `:remote-addr`
* - `:date`
* - `:method`
* - `:url`
* - `:referrer`
* - `:user-agent`
* - `:status`
*
* @return {Function}
* @param logger4js
* @param options
* @api public
*/
module.exports = function getLogger(logger4js, options) {
/* eslint no-underscore-dangle:0 */
if (typeof options === 'string' || typeof options === 'function') {
if (typeof options === "string" || typeof options === "function") {
options = { format: options };
} else {
options = options || {};
@@ -246,9 +256,9 @@ module.exports = function getLogger(logger4js, options) {
// nologs
if (nolog && nolog.test(req.originalUrl)) return next();
if (thisLogger.isLevelEnabled(level) || options.level === 'auto') {
if (thisLogger.isLevelEnabled(level) || options.level === "auto") {
const start = new Date();
const writeHead = res.writeHead;
const { writeHead } = res;
// flag as logging
req._logging = true;
@@ -263,10 +273,10 @@ module.exports = function getLogger(logger4js, options) {
};
// hook on end request to emit the log entry of the HTTP request.
res.on('finish', () => {
res.on("finish", () => {
res.responseTime = new Date() - start;
// status code response level handling
if (res.statusCode && options.level === 'auto') {
if (res.statusCode && options.level === "auto") {
level = levels.INFO;
if (res.statusCode >= 300) level = levels.WARN;
if (res.statusCode >= 400) level = levels.ERROR;
@@ -275,14 +285,14 @@ module.exports = function getLogger(logger4js, options) {
const combinedTokens = assembleTokens(req, res, options.tokens || []);
if (options.context) thisLogger.addContext('res', res);
if (typeof fmt === 'function') {
if (options.context) thisLogger.addContext("res", res);
if (typeof fmt === "function") {
const line = fmt(req, res, str => format(str, combinedTokens));
if (line) thisLogger.log(level, line);
} else {
thisLogger.log(level, format(fmt, combinedTokens));
}
if (options.context) thisLogger.removeContext('res');
if (options.context) thisLogger.removeContext("res");
});
}
+36 -36
View File
@@ -1,12 +1,8 @@
'use strict';
const dateFormat = require('date-format');
const os = require('os');
const util = require('util');
const path = require('path');
const eol = os.EOL || '\n';
const styles = {
// styles
bold: [1, 22],
@@ -71,10 +67,7 @@ function basicLayout(loggingEvent) {
* same as basicLayout, but with colours.
*/
function colouredLayout(loggingEvent) {
return timestampLevelAndCategory(
loggingEvent,
loggingEvent.level.colour
) + util.format(...loggingEvent.data);
return timestampLevelAndCategory(loggingEvent, loggingEvent.level.colour) + util.format(...loggingEvent.data);
}
function messagePassThroughLayout(loggingEvent) {
@@ -89,6 +82,12 @@ function dummyLayout(loggingEvent) {
* PatternLayout
* Format for specifiers is %[padding].[truncation][field]{[format]}
* e.g. %5.10p - left pad the log level by 5 characters, up to a max of 10
* both padding and truncation can be negative.
* Negative truncation = trunc from end of string
* Positive truncation = trunc from start of string
* Negative padding = pad right
* Positive padding = pad left
*
* Fields can be any of:
* - %r time in toLocaleTimeString format
* - %p log level
@@ -124,7 +123,7 @@ function dummyLayout(loggingEvent) {
*/
function patternLayout(pattern, tokens) {
const TTCC_CONVERSION_PATTERN = '%r %p %c - %m%n';
const regex = /%(-?[0-9]+)?(\.?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;
const regex = /%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;
pattern = pattern || TTCC_CONVERSION_PATTERN;
@@ -168,7 +167,7 @@ function patternLayout(pattern, tokens) {
}
function endOfLine() {
return eol;
return os.EOL;
}
function logLevel(loggingEvent) {
@@ -234,11 +233,11 @@ function patternLayout(pattern, tokens) {
}
function lineNumber(loggingEvent) {
return loggingEvent.lineNumber || '';
return loggingEvent.lineNumber ? `${loggingEvent.lineNumber}` : '';
}
function columnNumber(loggingEvent) {
return loggingEvent.columnNumber || '';
return loggingEvent.columnNumber ? `${loggingEvent.columnNumber}` : '';
}
function callStack(loggingEvent) {
@@ -247,24 +246,24 @@ function patternLayout(pattern, tokens) {
/* eslint quote-props:0 */
const replacers = {
'c': categoryName,
'd': formatAsDate,
'h': hostname,
'm': formatMessage,
'n': endOfLine,
'p': logLevel,
'r': startTime,
c: categoryName,
d: formatAsDate,
h: hostname,
m: formatMessage,
n: endOfLine,
p: logLevel,
r: startTime,
'[': startColour,
']': endColour,
'y': clusterInfo,
'z': pid,
y: clusterInfo,
z: pid,
'%': percent,
'x': userDefined,
'X': contextDefined,
'f': fileName,
'l': lineNumber,
'o': columnNumber,
's': callStack,
x: userDefined,
X: contextDefined,
f: fileName,
l: lineNumber,
o: columnNumber,
s: callStack
};
function replaceToken(conversionCharacter, loggingEvent, specifier) {
@@ -275,7 +274,8 @@ function patternLayout(pattern, tokens) {
let len;
if (truncation) {
len = parseInt(truncation.substr(1), 10);
return toTruncate.substring(0, len);
// negative truncate length means truncate from end of string
return len > 0 ? toTruncate.slice(0, len) : toTruncate.slice(len);
}
return toTruncate;
@@ -338,22 +338,22 @@ function patternLayout(pattern, tokens) {
}
const layoutMakers = {
messagePassThrough: function () {
messagePassThrough () {
return messagePassThroughLayout;
},
basic: function () {
basic () {
return basicLayout;
},
colored: function () {
colored () {
return colouredLayout;
},
coloured: function () {
coloured () {
return colouredLayout;
},
pattern: function (config) {
pattern (config) {
return patternLayout(config && config.pattern, config && config.tokens);
},
dummy: function () {
dummy () {
return dummyLayout;
}
};
@@ -365,10 +365,10 @@ module.exports = {
colouredLayout,
coloredLayout: colouredLayout,
dummyLayout,
addLayout: function (name, serializerGenerator) {
addLayout (name, serializerGenerator) {
layoutMakers[name] = serializerGenerator;
},
layout: function (name, config) {
layout (name, config) {
return layoutMakers[name] && layoutMakers[name](config);
}
};
+3 -7
View File
@@ -1,4 +1,4 @@
'use strict';
const configuration = require('./configuration');
@@ -21,7 +21,7 @@ class Level {
/**
* converts given String to corresponding Level
* @param {Level|String} sArg -- String value of Level OR Log4js.Level
* @param {(Level|string)} sArg -- String value of Level OR Log4js.Level
* @param {Level} [defaultLevel] -- default Level, if no String representation
* @return {Level}
*/
@@ -39,11 +39,7 @@ class Level {
sArg = sArg.levelStr;
}
if (typeof sArg === 'string') {
return Level[sArg.toUpperCase()] || defaultLevel;
}
return Level.getLevel(sArg.toString());
return Level[sArg.toString().toUpperCase()] || defaultLevel;
}
static addLevels(customLevels) {
+44 -34
View File
@@ -1,5 +1,3 @@
'use strict';
/**
* @fileoverview log4js is a library to log in JavaScript in similar manner
* than in log4j for Java (but not really).
@@ -20,41 +18,47 @@
* @since 2005-05-20
* Website: http://log4js.berlios.de
*/
const debug = require('debug')('log4js:main');
const fs = require('fs');
const deepClone = require('rfdc')({ proto: true });
const configuration = require('./configuration');
const layouts = require('./layouts');
const levels = require('./levels');
const appenders = require('./appenders');
const categories = require('./categories');
const Logger = require('./logger');
const clustering = require('./clustering');
const connectLogger = require('./connect-logger');
const debug = require("debug")("log4js:main");
const fs = require("fs");
const deepClone = require("rfdc")({ proto: true });
const configuration = require("./configuration");
const layouts = require("./layouts");
const levels = require("./levels");
const appenders = require("./appenders");
const categories = require("./categories");
const Logger = require("./logger");
const clustering = require("./clustering");
const connectLogger = require("./connect-logger");
let enabled = false;
function sendLogEventToAppender(logEvent) {
if (!enabled) return;
debug('Received log event ', logEvent);
const categoryAppenders = categories.appendersForCategory(logEvent.categoryName);
categoryAppenders.forEach((appender) => {
debug("Received log event ", logEvent);
const categoryAppenders = categories.appendersForCategory(
logEvent.categoryName
);
categoryAppenders.forEach(appender => {
appender(logEvent);
});
}
function loadConfigurationFile(filename) {
if (filename) {
debug(`Loading configuration from ${filename}`);
return JSON.parse(fs.readFileSync(filename, 'utf8'));
debug(`Loading configuration from ${filename}`);
try {
return JSON.parse(fs.readFileSync(filename, "utf8"));
} catch (e) {
throw new Error(
`Problem reading config from file "${filename}". Error was ${e.message}`,
e
);
}
return filename;
}
function configure(configurationFileOrObject) {
let configObject = configurationFileOrObject;
if (typeof configObject === 'string') {
if (typeof configObject === "string") {
configObject = loadConfigurationFile(configurationFileOrObject);
}
debug(`Configuration is ${configObject}`);
@@ -78,14 +82,17 @@ function configure(configurationFileOrObject) {
* as the first argument.
*/
function shutdown(cb) {
debug('Shutdown called. Disabling all log writing.');
debug("Shutdown called. Disabling all log writing.");
// First, disable all writing to appenders. This prevents appenders from
// not being able to be drained because of run-away log writes.
enabled = false;
// Call each of the shutdown functions in parallel
const appendersToCheck = Array.from(appenders.values());
const shutdownFunctions = appendersToCheck.reduceRight((accum, next) => (next.shutdown ? accum + 1 : accum), 0);
const shutdownFunctions = appendersToCheck.reduceRight(
(accum, next) => (next.shutdown ? accum + 1 : accum),
0
);
let completed = 0;
let error;
@@ -95,14 +102,16 @@ function shutdown(cb) {
completed += 1;
debug(`Appender shutdowns complete: ${completed} / ${shutdownFunctions}`);
if (completed >= shutdownFunctions) {
debug('All shutdown functions completed.');
cb(error);
debug("All shutdown functions completed.");
if (cb) {
cb(error);
}
}
}
if (shutdownFunctions === 0) {
debug('No appenders with shutdown functions found.');
return cb();
debug("No appenders with shutdown functions found.");
return cb !== undefined && cb();
}
appendersToCheck.filter(a => a.shutdown).forEach(a => a.shutdown(complete));
@@ -118,15 +127,16 @@ function shutdown(cb) {
*/
function getLogger(category) {
if (!enabled) {
configure(process.env.LOG4JS_CONFIG || {
appenders: { out: { type: 'stdout' } },
categories: { default: { appenders: ['out'], level: 'OFF' } }
});
configure(
process.env.LOG4JS_CONFIG || {
appenders: { out: { type: "stdout" } },
categories: { default: { appenders: ["out"], level: "OFF" } }
}
);
}
return new Logger(category || 'default');
return new Logger(category || "default");
}
/**
* @name log4js
* @namespace Log4js
@@ -140,7 +150,7 @@ const log4js = {
shutdown,
connectLogger,
levels,
addLayout: layouts.addLayout,
addLayout: layouts.addLayout
};
module.exports = log4js;
+24 -19
View File
@@ -1,17 +1,14 @@
/* eslint no-underscore-dangle:0 */
'use strict';
const debug = require('debug')('log4js:logger');
const LoggingEvent = require('./LoggingEvent');
const levels = require('./levels');
const clustering = require('./clustering');
const categories = require('./categories');
const configuration = require('./configuration');
const debug = require("debug")("log4js:logger");
const LoggingEvent = require("./LoggingEvent");
const levels = require("./levels");
const clustering = require("./clustering");
const categories = require("./categories");
const configuration = require("./configuration");
const stackReg = /at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;
function defaultParseCallStack(data, skipIdx = 4) {
const stacklines = data.stack.split('\n').slice(skipIdx);
const stacklines = data.stack.split("\n").slice(skipIdx);
const lineMatch = stackReg.exec(stacklines[0]);
if (lineMatch && lineMatch.length === 6) {
return {
@@ -19,7 +16,7 @@ function defaultParseCallStack(data, skipIdx = 4) {
fileName: lineMatch[2],
lineNumber: parseInt(lineMatch[3], 10),
columnNumber: parseInt(lineMatch[4], 10),
callStack: stacklines.join('\n'),
callStack: stacklines.join("\n")
};
}
return null;
@@ -40,7 +37,7 @@ function defaultParseCallStack(data, skipIdx = 4) {
class Logger {
constructor(name) {
if (!name) {
throw new Error('No category provided.');
throw new Error("No category provided.");
}
this.category = name;
this.context = {};
@@ -49,11 +46,17 @@ class Logger {
}
get level() {
return levels.getLevel(categories.getLevelForCategory(this.category), levels.TRACE);
return levels.getLevel(
categories.getLevelForCategory(this.category),
levels.TRACE
);
}
set level(level) {
categories.setLevelForCategory(this.category, levels.getLevel(level, this.level));
categories.setLevelForCategory(
this.category,
levels.getLevel(level, this.level)
);
}
get useCallStack() {
@@ -61,7 +64,7 @@ class Logger {
}
set useCallStack(bool) {
categories.setEnableCallStackForCategory(this.category, (bool === true));
categories.setEnableCallStackForCategory(this.category, bool === true);
}
log(level, ...args) {
@@ -82,7 +85,7 @@ class Logger {
level,
data,
this.context,
(this.useCallStack) && this.parseCallStack(new Error())
this.useCallStack && this.parseCallStack(new Error())
);
clustering.send(loggingEvent);
}
@@ -108,14 +111,16 @@ function addLevelMethods(target) {
const level = levels.getLevel(target);
const levelStrLower = level.toString().toLowerCase();
const levelMethod = levelStrLower.replace(/_([a-z])/g, g => g[1].toUpperCase());
const levelMethod = levelStrLower.replace(/_([a-z])/g, g =>
g[1].toUpperCase()
);
const isLevelMethod = levelMethod[0].toUpperCase() + levelMethod.slice(1);
Logger.prototype[`is${isLevelMethod}Enabled`] = function () {
Logger.prototype[`is${isLevelMethod}Enabled`] = function() {
return this.isLevelEnabled(level);
};
Logger.prototype[levelMethod] = function (...args) {
Logger.prototype[levelMethod] = function(...args) {
this.log(level, ...args);
};
}