-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
80 lines (72 loc) · 2.55 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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;