mirror of
https://github.com/log4js-node/log4js-node.git
synced 2025-12-08 19:26:01 +00:00
As class inheritance inside stream/*.js, standalone refactor don't work. So streams/*.js are refactored in batch. One thing worth mentioning is that, the old inherit-style will call the parent constructor at the end of child constructor for some code initialization. However, with ES6 class syntax, the call of `super` must be afore every statement with this. So, some code initializing logic are reordered to suit the ES6 syntax and the tests.
96 lines
2.9 KiB
JavaScript
96 lines
2.9 KiB
JavaScript
'use strict';
|
|
|
|
const BaseRollingFileStream = require('./BaseRollingFileStream');
|
|
const debug = require('../debug')('DateRollingFileStream');
|
|
const format = require('../date_format');
|
|
const fs = require('fs');
|
|
|
|
function findTimestampFromFileIfExists(filename, now) {
|
|
return fs.existsSync(filename) ? fs.statSync(filename).mtime : new Date(now());
|
|
}
|
|
|
|
class DateRollingFileStream extends BaseRollingFileStream {
|
|
constructor(filename, pattern, options, now) {
|
|
debug(`Now is ${now}`);
|
|
|
|
if (pattern && typeof(pattern) === 'object') {
|
|
now = options;
|
|
options = pattern;
|
|
pattern = null;
|
|
}
|
|
pattern = pattern || '.yyyy-MM-dd';
|
|
const thisNow = now || Date.now;
|
|
const lastTimeWeWroteSomething = format.asString(
|
|
pattern,
|
|
findTimestampFromFileIfExists(filename, thisNow)
|
|
);
|
|
const baseFilename = filename;
|
|
let alwaysIncludePattern = false;
|
|
|
|
if (options) {
|
|
if (options.alwaysIncludePattern) {
|
|
alwaysIncludePattern = true;
|
|
filename = baseFilename + lastTimeWeWroteSomething;
|
|
}
|
|
delete options.alwaysIncludePattern;
|
|
if (Object.keys(options).length === 0) {
|
|
options = null;
|
|
}
|
|
}
|
|
|
|
debug(`this.now is ${thisNow}, now is ${now}`);
|
|
|
|
super(filename, options);
|
|
|
|
this.pattern = pattern;
|
|
this.now = thisNow;
|
|
this.lastTimeWeWroteSomething = lastTimeWeWroteSomething;
|
|
this.baseFilename = baseFilename;
|
|
this.alwaysIncludePattern = alwaysIncludePattern;
|
|
}
|
|
|
|
shouldRoll() {
|
|
const lastTime = this.lastTimeWeWroteSomething;
|
|
const thisTime = format.asString(this.pattern, new Date(this.now()));
|
|
|
|
debug(`DateRollingFileStream.shouldRoll with now = ${this.now()}, thisTime = ${thisTime}, lastTime = ${lastTime}`);
|
|
|
|
this.lastTimeWeWroteSomething = thisTime;
|
|
this.previousTime = lastTime;
|
|
|
|
return thisTime !== lastTime;
|
|
}
|
|
|
|
roll(filename, callback) {
|
|
debug('Starting roll');
|
|
let newFilename;
|
|
|
|
if (this.alwaysIncludePattern) {
|
|
this.filename = this.baseFilename + this.lastTimeWeWroteSomething;
|
|
this.closeTheStream(this.openTheStream.bind(this, callback));
|
|
} else {
|
|
newFilename = this.baseFilename + this.previousTime;
|
|
this.closeTheStream(
|
|
deleteAnyExistingFile.bind(null,
|
|
renameTheCurrentFile.bind(null,
|
|
this.openTheStream.bind(this, callback))));
|
|
}
|
|
|
|
function deleteAnyExistingFile(cb) {
|
|
// on windows, you can get a EEXIST error if you rename a file to an existing file
|
|
// so, we'll try to delete the file we're renaming to first
|
|
fs.unlink(newFilename, err => {
|
|
// ignore err: if we could not delete, it's most likely that it doesn't exist
|
|
cb(err);
|
|
});
|
|
}
|
|
|
|
function renameTheCurrentFile(cb) {
|
|
debug(`Renaming the ${filename} -> ${newFilename}`);
|
|
fs.rename(filename, newFilename, cb);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = DateRollingFileStream;
|