mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-06 06:58:21 +00:00
quick log rotation (#2432)
This commit is contained in:
parent
8b46463f95
commit
3f41c643b9
2 changed files with 110 additions and 2 deletions
108
emain/log.ts
108
emain/log.ts
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2025, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { format } from "util";
|
||||
import winston from "winston";
|
||||
|
|
@ -8,6 +9,99 @@ import { getWaveDataDir, isDev } from "./platform";
|
|||
|
||||
const oldConsoleLog = console.log;
|
||||
|
||||
function findHighestLogNumber(logsDir: string): number {
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
return 0;
|
||||
}
|
||||
const files = fs.readdirSync(logsDir);
|
||||
let maxNum = 0;
|
||||
for (const file of files) {
|
||||
const match = file.match(/^waveapp\.(\d+)\.log$/);
|
||||
if (match) {
|
||||
const num = parseInt(match[1], 10);
|
||||
if (num > maxNum) {
|
||||
maxNum = num;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxNum;
|
||||
}
|
||||
|
||||
function pruneOldLogs(logsDir: string): { pruned: string[]; error: any } {
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
return { pruned: [], error: null };
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(logsDir);
|
||||
const logFiles: { name: string; num: number }[] = [];
|
||||
|
||||
for (const file of files) {
|
||||
const match = file.match(/^waveapp\.(\d+)\.log$/);
|
||||
if (match) {
|
||||
logFiles.push({ name: file, num: parseInt(match[1], 10) });
|
||||
}
|
||||
}
|
||||
|
||||
if (logFiles.length <= 5) {
|
||||
return { pruned: [], error: null };
|
||||
}
|
||||
|
||||
logFiles.sort((a, b) => b.num - a.num);
|
||||
const toDelete = logFiles.slice(5);
|
||||
const pruned: string[] = [];
|
||||
let firstError: any = null;
|
||||
|
||||
for (const logFile of toDelete) {
|
||||
try {
|
||||
fs.unlinkSync(path.join(logsDir, logFile.name));
|
||||
pruned.push(logFile.name);
|
||||
} catch (e) {
|
||||
if (firstError == null) {
|
||||
firstError = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { pruned, error: firstError };
|
||||
}
|
||||
|
||||
function rotateLogIfNeeded(): string | null {
|
||||
const waveDataDir = getWaveDataDir();
|
||||
const logFile = path.join(waveDataDir, "waveapp.log");
|
||||
const logsDir = path.join(waveDataDir, "logs");
|
||||
|
||||
if (!fs.existsSync(logsDir)) {
|
||||
fs.mkdirSync(logsDir, { recursive: true });
|
||||
}
|
||||
|
||||
if (!fs.existsSync(logFile)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const stats = fs.statSync(logFile);
|
||||
if (stats.size > 10 * 1024 * 1024) {
|
||||
const nextNum = findHighestLogNumber(logsDir) + 1;
|
||||
const rotatedPath = path.join(logsDir, `waveapp.${nextNum}.log`);
|
||||
fs.renameSync(logFile, rotatedPath);
|
||||
return rotatedPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
let logRotateError: any = null;
|
||||
let rotatedPath: string | null = null;
|
||||
let prunedFiles: string[] = [];
|
||||
let pruneError: any = null;
|
||||
try {
|
||||
rotatedPath = rotateLogIfNeeded();
|
||||
const logsDir = path.join(getWaveDataDir(), "logs");
|
||||
const pruneResult = pruneOldLogs(logsDir);
|
||||
prunedFiles = pruneResult.pruned;
|
||||
pruneError = pruneResult.error;
|
||||
} catch (e) {
|
||||
logRotateError = e;
|
||||
}
|
||||
|
||||
const loggerTransports: winston.transport[] = [
|
||||
new winston.transports.File({ filename: path.join(getWaveDataDir(), "waveapp.log"), level: "info" }),
|
||||
];
|
||||
|
|
@ -23,6 +117,7 @@ const loggerConfig = {
|
|||
transports: loggerTransports,
|
||||
};
|
||||
const logger = winston.createLogger(loggerConfig);
|
||||
|
||||
function log(...msg: any[]) {
|
||||
try {
|
||||
logger.info(format(...msg));
|
||||
|
|
@ -31,4 +126,17 @@ function log(...msg: any[]) {
|
|||
}
|
||||
}
|
||||
|
||||
if (logRotateError != null) {
|
||||
log("error rotating/pruning logs (non-fatal):", logRotateError);
|
||||
}
|
||||
if (rotatedPath != null) {
|
||||
log("rotated old log file to:", rotatedPath);
|
||||
}
|
||||
if (prunedFiles.length > 0) {
|
||||
log("pruned old log files:", prunedFiles.join(", "));
|
||||
}
|
||||
if (pruneError != null) {
|
||||
log("error pruning some log files (non-fatal):", pruneError);
|
||||
}
|
||||
|
||||
export { log };
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "waveterm",
|
||||
"version": "0.12.0-beta.1",
|
||||
"version": "0.12.0-beta.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "waveterm",
|
||||
"version": "0.12.0-beta.1",
|
||||
"version": "0.12.0-beta.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"workspaces": [
|
||||
|
|
|
|||
Loading…
Reference in a new issue