log4js-node/test/tap/dateFileAppender-test.js

304 lines
8.0 KiB
JavaScript

/* eslint max-classes-per-file: ["error", 3] */
const { test } = require('tap');
const path = require('path');
const fs = require('fs');
const EOL = require('os').EOL || '\n';
const format = require('date-format');
const sandbox = require('@log4js-node/sandboxed-module');
const log4js = require('../../lib/log4js');
const osDelay = process.platform === 'win32' ? 400 : 200;
function removeFile(filename) {
try {
fs.unlinkSync(path.join(__dirname, filename));
} catch (e) {
// doesn't matter
}
}
test('../../lib/appenders/dateFile', (batch) => {
batch.test('with default settings', (t) => {
const testFile = path.join(__dirname, 'date-appender-default.log');
log4js.configure({
appenders: { date: { type: 'dateFile', filename: testFile } },
categories: { default: { appenders: ['date'], level: 'DEBUG' } },
});
const logger = log4js.getLogger('default-settings');
logger.info('This should be in the file.');
t.teardown(() => {
removeFile('date-appender-default.log');
});
setTimeout(() => {
fs.readFile(testFile, 'utf8', (err, contents) => {
t.match(contents, 'This should be in the file');
t.match(
contents,
/\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}] \[INFO] default-settings - /
);
t.end();
});
}, osDelay);
});
batch.test('configure with dateFileAppender', (t) => {
log4js.configure({
appenders: {
date: {
type: 'dateFile',
filename: 'test/tap/date-file-test.log',
pattern: '-yyyy-MM-dd',
layout: { type: 'messagePassThrough' },
},
},
categories: { default: { appenders: ['date'], level: 'WARN' } },
});
const logger = log4js.getLogger('tests');
logger.info('this should not be written to the file');
logger.warn('this should be written to the file');
log4js.shutdown(() => {
fs.readFile(
path.join(__dirname, 'date-file-test.log'),
'utf8',
(err, contents) => {
t.match(contents, `this should be written to the file${EOL}`);
t.equal(
contents.indexOf('this should not be written to the file'),
-1
);
t.end();
}
);
});
t.teardown(() => {
removeFile('date-file-test.log');
});
});
batch.test('configure with options.alwaysIncludePattern', (t) => {
const options = {
appenders: {
date: {
category: 'tests',
type: 'dateFile',
filename: 'test/tap/date-file-test',
pattern: 'yyyy-MM-dd.log',
alwaysIncludePattern: true,
layout: {
type: 'messagePassThrough',
},
},
},
categories: { default: { appenders: ['date'], level: 'debug' } },
};
const thisTime = format.asString(
options.appenders.date.pattern,
new Date()
);
const testFile = `date-file-test.${thisTime}`;
const existingFile = path.join(__dirname, testFile);
fs.writeFileSync(existingFile, `this is existing data${EOL}`, 'utf8');
log4js.configure(options);
const logger = log4js.getLogger('tests');
logger.warn('this should be written to the file with the appended date');
t.teardown(() => {
removeFile(testFile);
});
// wait for filesystem to catch up
log4js.shutdown(() => {
fs.readFile(existingFile, 'utf8', (err, contents) => {
t.match(
contents,
'this is existing data',
'should not overwrite the file on open (issue #132)'
);
t.match(
contents,
'this should be written to the file with the appended date'
);
t.end();
});
});
});
batch.test('should flush logs on shutdown', (t) => {
const testFile = path.join(__dirname, 'date-appender-flush.log');
log4js.configure({
appenders: { test: { type: 'dateFile', filename: testFile } },
categories: { default: { appenders: ['test'], level: 'trace' } },
});
const logger = log4js.getLogger('default-settings');
logger.info('1');
logger.info('2');
logger.info('3');
t.teardown(() => {
removeFile('date-appender-flush.log');
});
log4js.shutdown(() => {
fs.readFile(testFile, 'utf8', (err, fileContents) => {
// 3 lines of output, plus the trailing newline.
t.equal(fileContents.split(EOL).length, 4);
t.match(
fileContents,
/\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}] \[INFO] default-settings - /
);
t.end();
});
});
});
batch.test('should map maxLogSize to maxSize', (t) => {
const fakeStreamroller = {};
class DateRollingFileStream {
constructor(filename, pattern, options) {
fakeStreamroller.filename = filename;
fakeStreamroller.pattern = pattern;
fakeStreamroller.options = options;
}
on() {} // eslint-disable-line class-methods-use-this
}
fakeStreamroller.DateRollingFileStream = DateRollingFileStream;
const dateFileAppenderModule = sandbox.require(
'../../lib/appenders/dateFile',
{
requires: { streamroller: fakeStreamroller },
}
);
dateFileAppenderModule.configure(
{
filename: 'cheese.log',
pattern: 'yyyy',
maxLogSize: 100,
},
{ basicLayout: () => {} }
);
t.equal(fakeStreamroller.options.maxSize, 100);
t.end();
});
batch.test('handling of writer.writable', (t) => {
const output = [];
let writable = true;
const DateRollingFileStream = class {
write(loggingEvent) {
output.push(loggingEvent);
this.written = true;
return true;
}
// eslint-disable-next-line class-methods-use-this
on() {}
// eslint-disable-next-line class-methods-use-this
get writable() {
return writable;
}
};
const dateFileAppender = sandbox.require('../../lib/appenders/dateFile', {
requires: {
streamroller: {
DateRollingFileStream,
},
},
});
const appender = dateFileAppender.configure(
{ filename: 'test1.log', maxLogSize: 100 },
{
basicLayout(loggingEvent) {
return loggingEvent.data;
},
}
);
t.test('should log when writer.writable=true', (assert) => {
writable = true;
appender({ data: 'something to log' });
assert.ok(output.length, 1);
assert.match(output[output.length - 1], 'something to log');
assert.end();
});
t.test('should not log when writer.writable=false', (assert) => {
writable = false;
appender({ data: 'this should not be logged' });
assert.ok(output.length, 1);
assert.notMatch(output[output.length - 1], 'this should not be logged');
assert.end();
});
t.end();
});
batch.test('when underlying stream errors', (t) => {
let consoleArgs;
let errorHandler;
const DateRollingFileStream = class {
end() {
this.ended = true;
}
on(evt, cb) {
if (evt === 'error') {
this.errored = true;
errorHandler = cb;
}
}
write() {
this.written = true;
return true;
}
};
const dateFileAppender = sandbox.require('../../lib/appenders/dateFile', {
globals: {
console: {
error(...args) {
consoleArgs = args;
},
},
},
requires: {
streamroller: {
DateRollingFileStream,
},
},
});
dateFileAppender.configure(
{ filename: 'test1.log', maxLogSize: 100 },
{ basicLayout() {} }
);
errorHandler({ error: 'aargh' });
t.test('should log the error to console.error', (assert) => {
assert.ok(consoleArgs);
assert.equal(
consoleArgs[0],
'log4js.dateFileAppender - Writing to file %s, error happened '
);
assert.equal(consoleArgs[1], 'test1.log');
assert.equal(consoleArgs[2].error, 'aargh');
assert.end();
});
t.end();
});
batch.end();
});