galactic-bot/middleware/logger/transports/FileExtension.js

118 lines
3.6 KiB
JavaScript
Raw Normal View History

2020-04-14 17:05:37 +02:00
/* eslint-disable no-control-regex */
2020-04-14 05:25:17 +02:00
const { transports: { File }} = require('winston');
const debug = require('diagnostics')('winston:file');
const { MESSAGE } = require('triple-beam');
const moment = require('moment');
2020-04-14 17:05:37 +02:00
const regex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
2020-04-14 05:25:17 +02:00
class FileExtension extends File {
constructor(opts) {
super(opts);
}
log(info, callback = () => {}) {
// Remark: (jcrugzz) What is necessary about this callback(null, true) now
// when thinking about 3.x? Should silent be handled in the base
// TransportStream _write method?
if (this.silent) {
2020-04-14 17:05:37 +02:00
callback();
return true;
2020-04-14 05:25:17 +02:00
}
// Output stream buffer is full and has asked us to wait for the drain event
if (this._drain) {
2020-04-14 17:05:37 +02:00
this._stream.once('drain', () => {
this._drain = false;
this.log(info, callback);
});
return;
2020-04-14 05:25:17 +02:00
}
if (this._rotate) {
2020-04-14 17:05:37 +02:00
this._stream.once('rotate', () => {
this._rotate = false;
this.log(info, callback);
});
return;
2020-04-14 05:25:17 +02:00
}
// Grab the raw string and append the expected EOL.
2020-04-14 17:05:37 +02:00
const output = `${info[MESSAGE]}${this.eol}`.replace(regex, '');
2020-04-14 05:25:17 +02:00
const bytes = Buffer.byteLength(output);
// After we have written to the PassThrough check to see if we need
// to rotate to the next file.
//
// Remark: This gets called too early and does not depict when data
// has been actually flushed to disk.
function logged() {
2020-04-14 17:05:37 +02:00
this._size += bytes;
this._pendingSize -= bytes;
2020-04-14 05:25:17 +02:00
2020-04-14 17:05:37 +02:00
debug('logged %s %s', this._size, output);
this.emit('logged', info);
2020-04-14 05:25:17 +02:00
2020-04-14 17:05:37 +02:00
// Do not attempt to rotate files while opening
if (this._opening) {
return;
}
2020-04-14 05:25:17 +02:00
2020-04-14 17:05:37 +02:00
// Check to see if we need to end the stream and create a new one.
if (!this._needsNewFile()) {
return;
}
2020-04-14 05:25:17 +02:00
2020-04-14 17:05:37 +02:00
// End the current stream, ensure it flushes and create a new one.
// This could potentially be optimized to not run a stat call but its
// the safest way since we are supporting `maxFiles`.
this._rotate = true;
this._endStream(() => this._rotateFile());
2020-04-14 05:25:17 +02:00
}
// Keep track of the pending bytes being written while files are opening
// in order to properly rotate the PassThrough this._stream when the file
// eventually does open.
this._pendingSize += bytes;
if (this._opening
&& !this.rotatedWhileOpening
&& this._needsNewFile(this._size + this._pendingSize)) {
2020-04-14 17:05:37 +02:00
this.rotatedWhileOpening = true;
2020-04-14 05:25:17 +02:00
}
const written = this._stream.write(output, logged.bind(this));
if (!written) {
2020-04-14 17:05:37 +02:00
this._drain = true;
this._stream.once('drain', () => {
this._drain = false;
callback();
});
2020-04-14 05:25:17 +02:00
} else {
2020-04-14 17:05:37 +02:00
callback(); // eslint-disable-line callback-return
2020-04-14 05:25:17 +02:00
}
debug('written', written, this._drain);
this.finishIfEnding();
return written;
2020-04-14 17:05:37 +02:00
}
2020-04-14 05:25:17 +02:00
get date() {
return moment().format("MM-DD-YYYY hh:mm:ss");
}
}
module.exports = FileExtension;
const Constants = {
Colors: {
error: 'red',
warn: 'yellow',
info: 'blue',
verbose: 'cyan',
debug: 'magenta',
silly: 'magentaBright'
}
};