bifocal/node_modules/@tryghost/bunyan-rotating-filestream/index.js

81 lines
2.5 KiB
JavaScript

const WriteQueue = require('./lib/writeQueue');
const PeriodTrigger = require('./lib/periodTrigger');
const ThresholdTrigger = require('./lib/thresholdTrigger');
const FileRotator = require('./lib/fileRotator');
const {BytesWritten, Rotate, NewFile} = require('./lib/customEvents');
const fileStreams = [];
class RotatingFileStream {
constructor(config) {
if (typeof config.path !== 'string') {
throw new Error('Must provide a string for path');
}
if (fileStreams.indexOf(config.path) >= 0) {
throw new Error('Rotating log already exists for path: ', config.path);
}
fileStreams.push(config.path);
this._path = config.path;
this._rotator = new FileRotator(config);
this._queue = new WriteQueue();
this._triggers = [];
if (config.period) {
const periodTrigger = new PeriodTrigger(config.period, config.rotateExisting);
this._triggers.push(periodTrigger);
}
if (config.threshold) {
const thresholdTrigger = new ThresholdTrigger(config.threshold);
this._queue.on(BytesWritten, bytes => thresholdTrigger.updateWritten(bytes));
this._triggers.push(thresholdTrigger);
}
this._rotatingLock = false;
this._triggers.forEach((trigger) => {
trigger.on(Rotate, () => {
this._rotate();
});
});
this._rotator.on(NewFile, (fileInfo) => {
this._queue.setFileHandle(this._rotator.getCurrentHandle());
this._triggers.forEach(trigger => trigger.newFile(fileInfo));
});
this._initialised = this._rotator.initialise();
}
async _rotate() {
if (this._rotatingLock) {
// Already rotating
return;
}
this._rotatingLock = true;
await this._queue.pause();
const nextFileHandle = await this._rotator.rotate();
this._queue.setFileHandle(nextFileHandle);
this._rotatingLock = false;
}
async write(data) {
this._queue.push(data);
}
async end() {
await this._initialised;
await this._queue.shutdown();
await this._rotator.shutdown();
this._triggers.forEach(trigger => trigger.shutdown());
const fileStreamIndex = fileStreams.indexOf(this._path);
if (fileStreamIndex >= 0) {
fileStreams.splice(fileStreamIndex, 1);
}
}
destroy() {
this.end();
}
destroySoon() {
this.end();
}
}
module.exports = RotatingFileStream;