53 lines
1.6 KiB
JavaScript
53 lines
1.6 KiB
JavaScript
'use strict';
|
|
|
|
const stream = require('stream'),
|
|
{ StringDecoder } = require('string_decoder'),
|
|
TransformStream = stream.Transform;
|
|
|
|
class LogStream extends TransformStream {
|
|
constructor(options) {
|
|
super();
|
|
this._options = Object.assign({ source: 'unknown', format: 'json' }, options);
|
|
this._decoder = new StringDecoder();
|
|
this._soFar = '';
|
|
}
|
|
|
|
_format(line) {
|
|
if (this._options.format !== 'json') return line + '\n';
|
|
|
|
const data = line.split(' '); // logs are <ISOtimestamp> <msg>
|
|
let timestamp = (new Date(data[0])).getTime();
|
|
if (isNaN(timestamp)) timestamp = 0;
|
|
const message = line.slice(data[0].length+1);
|
|
|
|
// ignore faulty empty logs
|
|
if (!timestamp && !message) return;
|
|
|
|
return JSON.stringify({
|
|
realtimeTimestamp: timestamp * 1000,
|
|
message: message,
|
|
source: this._options.source
|
|
}) + '\n';
|
|
}
|
|
|
|
_transform(chunk, encoding, callback) {
|
|
const data = this._soFar + this._decoder.write(chunk);
|
|
let start = this._soFar.length, end = -1;
|
|
while ((end = data.indexOf('\n', start)) !== -1) {
|
|
const line = data.slice(start, end); // does not include end
|
|
this.push(this._format(line));
|
|
start = end + 1;
|
|
}
|
|
this._soFar = data.slice(start);
|
|
callback(null);
|
|
}
|
|
|
|
_flush(callback) {
|
|
const line = this._soFar + this._decoder.end();
|
|
this.push(this._format(line));
|
|
callback(null);
|
|
}
|
|
}
|
|
|
|
exports = module.exports = LogStream;
|