/
RotatingFileTransport.ts
89 lines (70 loc) 路 2.26 KB
/
RotatingFileTransport.ts
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
81
82
83
84
85
86
87
88
89
import type { Blueprint, Schemas } from '@boost/common/optimal';
import type { Rotation } from '../types';
import { FileTransport, type FileTransportOptions } from './FileTransport';
const DAYS_IN_WEEK = 7;
export interface RotatingFileTransportOptions extends FileTransportOptions {
/** Period in which to rotate files. Will append a timestamp to the rotated log file. */
rotation: Rotation;
}
export class RotatingFileTransport extends FileTransport<RotatingFileTransportOptions> {
protected lastTimestamp: string = this.formatTimestamp(Date.now());
override blueprint(schemas: Schemas): Blueprint<RotatingFileTransportOptions> {
const { string } = schemas;
return {
...super.blueprint(schemas),
rotation: string().oneOf(['hourly', 'daily', 'weekly', 'monthly']),
};
}
/**
* Format a `Date` object into a format used within the log file name.
*/
formatTimestamp(ms: number): string {
const { rotation } = this.options;
const date = new Date(ms);
let timestamp = `${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, '0')}`;
if (rotation === 'monthly') {
return timestamp;
}
// Special case, calculate the week manually and return,
// but do not append so other rotations inherit!
if (rotation === 'weekly') {
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1).getDay();
const offsetDate = date.getDate() + firstDay - 1;
timestamp += `.W${Math.floor(offsetDate / DAYS_IN_WEEK) + 1}`;
return timestamp;
}
timestamp += String(date.getDate()).padStart(2, '0');
if (rotation === 'daily') {
return timestamp;
}
timestamp += `.${String(date.getHours()).padStart(2, '0')}`;
return timestamp;
}
/**
* @inheritDoc
*/
protected override checkIfNeedsRotation() {
if (
this.lastSize > this.options.maxSize ||
this.formatTimestamp(Date.now()) !== this.lastTimestamp
) {
this.closeStreamAndRotateFile();
}
}
/**
* @inheritDoc
*/
protected override getRotatedFileName(): string {
const name = this.path.name(true);
const ext = this.path.ext(true);
return `${name}-${this.lastTimestamp}.${ext}`;
}
/**
* @inheritDoc
*/
protected override rotateFile() {
super.rotateFile();
// Update timestamp to the new format
this.lastTimestamp = this.formatTimestamp(Date.now());
}
}