kaven-utils
Version:
Utils for Node.js.
98 lines (97 loc) • 3.17 kB
JavaScript
/********************************************************************
* @author: Kaven
* @email: kaven@wuwenkai.com
* @website: http://blog.kaven.xyz
* @file: [Kaven-Utils] /src/logger/FileLogger.ts
* @create: 2025-06-19 17:39:49.430
* @modify: 2025-10-24 14:43:06.729
* @version: 6.1.2
* @times: 25
* @lines: 123
* @copyright: Copyright © 2025 Kaven. All Rights Reserved.
* @description: [description]
* @license: [license]
********************************************************************/
import { LogLevel, LogType, StartTimer, StripAnsi } from "kaven-basic";
import { createWriteStream } from "node:fs";
import { EOL } from "node:os";
import { dirname } from "node:path";
import { MakeDirectorySync } from "../KavenUtility.FileSystem.js";
import { ResetLogFileIf } from "../KavenUtility.js";
export class FileLogger {
file;
stream;
timer;
Type = LogType.File;
Options = {};
Levels;
constructor(file, options) {
if (!file) {
throw new Error("The file cannot be empty.");
}
this.file = file;
this.Options = options ?? {};
if (this.Options.ResetSizeInBytes === undefined) {
this.Options.ResetSizeInBytes = 5 * 1024 * 1024;
}
if (this.Options.ResetInterval === undefined) {
this.Options.ResetInterval = { hours: 1 };
}
this.Levels = options?.Levels ?? Object.values(LogLevel).filter(value => typeof value === "number");
}
Write(data, _level) {
if (this.Options.StripAnsi === true) {
data = StripAnsi(data);
}
this.stream?.write(data + EOL, "utf8");
}
Start(logger) {
MakeDirectorySync(dirname(this.file));
this.stream = createWriteStream(this.file, { flags: "a" });
logger?.Info(`Start logger: ${this.file}`);
if (this.Options.ResetInterval) {
this.timer = StartTimer(async () => {
await this.ResetIfNecessary();
}, this.Options.ResetInterval);
logger?.Info(`Next log reset date: ${this.timer.NextInvocationDateTime}`);
}
}
async Restart() {
await this.Stop();
this.Start();
}
async ResetIfNecessary() {
await ResetLogFileIf(this.Options.ResetSizeInBytes, this.file);
}
async Stop(logger) {
if (this.timer) {
this.timer.Stop();
this.timer = undefined;
}
if (this.stream === undefined) {
return;
}
await new Promise((resolve) => {
if (this.stream) {
this.stream.close(err => {
if (err) {
logger?.Error(err);
}
this.stream = undefined;
resolve();
});
}
else {
resolve();
}
});
}
async Dispose() {
await this.Stop();
}
static StartNew(file, options) {
const logger = new FileLogger(file, options);
logger.Start();
return logger;
}
}