Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding function(req, res) support to connectLogger options->nol… #1279

Merged
merged 2 commits into from Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 14 additions & 2 deletions docs/connect-logger.md
Expand Up @@ -30,7 +30,7 @@ The log4js.connectLogger supports the passing of an options object that can be u

- log level
- log format string or function (the same as the connect/express logger)
- nolog expressions (represented as a string, regexp, or array)
- nolog expressions (represented as a string, regexp, array, or function(req, res))
- status code rulesets

For example:
Expand Down Expand Up @@ -97,7 +97,7 @@ app.use(
);
```

The log4js.connectLogger also supports a nolog option where you can specify a string, regexp, or array to omit certain log messages. Example of 1.2 below.
The log4js.connectLogger also supports a nolog option where you can specify a string, regexp, array, or function(req, res) to omit certain log messages. Example of 1.2 below.

```javascript
app.use(
Expand All @@ -109,6 +109,18 @@ app.use(
);
```

or

```javascript
app.use(
log4js.connectLogger(logger, {
level: "auto",
format: ":method :url",
nolog: (req, res) => res.statusCode < 400,
})
);
```

The log4js.connectLogger can add a response of express to context if `context` flag is set to `true`.
Application can use it in layouts or appenders.

Expand Down
10 changes: 7 additions & 3 deletions lib/connect-logger.js
Expand Up @@ -215,7 +215,7 @@ function matchRules(statusCode, currentLevel, ruleSet) {
*
* - `format` Format string, see below for tokens
* - `level` A log4js levels instance. Supports also 'auto'
* - `nolog` A string or RegExp to exclude target logs
* - `nolog` A string or RegExp to exclude target logs or function(req, res): boolean
* - `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
*
Expand Down Expand Up @@ -248,14 +248,18 @@ module.exports = function getLogger(logger4js, options) {
const thisLogger = logger4js;
let level = levels.getLevel(options.level, levels.INFO);
const fmt = options.format || DEFAULT_FORMAT;
const nolog = createNoLogCondition(options.nolog);

return (req, res, next) => {
// mount safety
if (req._logging) return next();

// nologs
if (nolog && nolog.test(req.originalUrl)) return next();
if (typeof options.nolog === 'function') {
if (options.nolog(req, res) === true) return next();
} else {
const nolog = createNoLogCondition(options.nolog);
if (nolog && nolog.test(req.originalUrl)) return next();
}

if (thisLogger.isLevelEnabled(level) || options.level === 'auto') {
const start = new Date();
Expand Down
38 changes: 38 additions & 0 deletions test/tap/connect-nolog-test.js
Expand Up @@ -346,5 +346,43 @@ test('log4js connect logger', (batch) => {
t.end();
});

batch.test('nolog function', (t) => {
const ml = new MockLogger();
const cl = clm(ml, { nolog: (_req, res) => res.statusCode < 400 });

t.beforeEach(() => {
ml.messages = [];
});

t.test('check unmatch function return (statusCode < 400)', (assert) => {
const { messages } = ml;
const req = new MockRequest('my.remote.addr', 'GET', 'http://url/log');
const res = new MockResponse(500);
cl(req, res, () => {});
res.end('chunk', 'encoding');

assert.equal(messages.length, 1);
assert.ok(levels.INFO.isEqualTo(messages[0].level));
assert.match(messages[0].message, 'GET');
assert.match(messages[0].message, 'http://url');
assert.match(messages[0].message, 'my.remote.addr');
assert.match(messages[0].message, '500');
assert.end();
});

t.test('check match function return (statusCode >= 400)', (assert) => {
const { messages } = ml;
const req = new MockRequest('my.remote.addr', 'GET', 'http://url/nolog');
const res = new MockResponse(200);
cl(req, res, () => {});
res.end('chunk', 'encoding');

assert.equal(messages.length, 0);
assert.end();
});

t.end();
});

batch.end();
});