monitor/core/modules/Logger/LoggerBase.ts
2025-04-16 22:30:27 +07:00

80 lines
2.7 KiB
TypeScript

const modulename = 'Logger:Base';
import fs from 'node:fs';
import path from 'node:path';
import * as rfs from 'rotating-file-stream';
import { cloneDeep, defaultsDeep } from 'lodash-es';
import consoleFactory from '@lib/console';
import { getLogSizes, getLogDivider } from './loggerUtils';
import { getTimeFilename } from '@lib/misc';
const console = consoleFactory(modulename);
/**
* Default class for logger instances.
* Implements log-rotate, listLogFiles() and getLogFile()
*/
export class LoggerBase {
lrStream: rfs.RotatingFileStream;
lrErrors = 0;
public activeFilePath: string;
private lrLastError: string | undefined;
private basePath: string;
private logNameRegex: RegExp;
constructor(
basePath: string,
logName: string,
lrDefaultOptions: rfs.Options,
lrProfileConfig: rfs.Options | false = false
) {
//Sanity check
if (!basePath || !logName) throw new Error('Missing constructor parameters');
this.basePath = basePath;
this.activeFilePath = path.join(basePath, `${logName}.log`);
this.logNameRegex = new RegExp(`^${logName}(_\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}(_\\d+)?)?.log$`);
//If disabled
if (lrProfileConfig === false) {
console.warn('persistent logging disabled for:', logName);
this.lrStream = {
write: () => { },
} as any as rfs.RotatingFileStream;
return;
}
//Setting log rotate up
const lrOptions = cloneDeep(lrProfileConfig);
if (typeof lrProfileConfig === 'object') {
defaultsDeep(lrOptions, lrDefaultOptions);
}
const filenameGenerator: rfs.Generator = (time, index) => {
return time
? `${logName}_${getTimeFilename(time)}_${index}.log`
: `${logName}.log`;
};
this.lrStream = rfs.createStream(filenameGenerator, lrOptions);
this.lrStream.on('rotated', (filename) => {
this.lrStream.write(getLogDivider('Log Rotated'));
console.verbose.log(`Rotated file ${filename}`);
});
this.lrStream.on('error', (error) => {
if ((error as any).code !== 'ERR_STREAM_DESTROYED') {
console.verbose.error(error, logName);
this.lrErrors++;
this.lrLastError = error.message;
}
});
}
listLogFiles() {
return getLogSizes(this.basePath, this.logNameRegex);
}
getLogFile(fileName: string) {
if (!this.logNameRegex.test(fileName)) throw new Error('fileName doesn\'t match regex');
return fs.createReadStream(path.join(this.basePath, fileName));
}
};