feat(logging): enhance debug logging and cleanup capabilities with new configuration options
All checks were successful
Publish FaceAI Container / publish (push) Successful in 19m7s
All checks were successful
Publish FaceAI Container / publish (push) Successful in 19m7s
This commit is contained in:
parent
a95ae56134
commit
9860aad646
8 changed files with 212 additions and 13 deletions
|
|
@ -1,10 +1,11 @@
|
|||
import fs from 'node:fs';
|
||||
import fsp from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
const [, , logPath, ...commandArgs] = process.argv;
|
||||
const maxBytes = Number(process.env.FACEAI_SERVICE_LOG_MAX_BYTES || 20 * 1024 * 1024);
|
||||
const maxFiles = Math.max(1, Number(process.env.FACEAI_SERVICE_LOG_MAX_FILES || 5));
|
||||
|
||||
if (!logPath || commandArgs.length === 0) {
|
||||
process.stderr.write('Usage: node docker/run-with-log-file.mjs <log-path> <command> [args...]\n');
|
||||
|
|
@ -12,8 +13,60 @@ if (!logPath || commandArgs.length === 0) {
|
|||
}
|
||||
|
||||
await fsp.mkdir(path.dirname(logPath), { recursive: true });
|
||||
let currentSize = await fsp.stat(logPath).then((stats) => stats.size).catch(() => 0);
|
||||
let writeQueue = Promise.resolve();
|
||||
|
||||
async function pathExists(targetPath) {
|
||||
try {
|
||||
await fsp.access(targetPath);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function rotateLogFile() {
|
||||
if (!Number.isFinite(maxBytes) || maxBytes <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await fsp.rm(`${logPath}.${maxFiles}`, { force: true }).catch(() => {});
|
||||
|
||||
for (let index = maxFiles - 1; index >= 1; index -= 1) {
|
||||
const sourcePath = `${logPath}.${index}`;
|
||||
const destinationPath = `${logPath}.${index + 1}`;
|
||||
|
||||
if (await pathExists(sourcePath)) {
|
||||
await fsp.rename(sourcePath, destinationPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (await pathExists(logPath)) {
|
||||
await fsp.rename(logPath, `${logPath}.1`);
|
||||
}
|
||||
|
||||
currentSize = 0;
|
||||
}
|
||||
|
||||
async function appendChunkToLog(chunk) {
|
||||
const chunkSize = Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk);
|
||||
|
||||
if (Number.isFinite(maxBytes) && maxBytes > 0 && currentSize > 0 && currentSize + chunkSize > maxBytes) {
|
||||
await rotateLogFile();
|
||||
}
|
||||
|
||||
await fsp.appendFile(logPath, chunk);
|
||||
currentSize += chunkSize;
|
||||
}
|
||||
|
||||
function queueChunkWrite(chunk) {
|
||||
writeQueue = writeQueue
|
||||
.then(() => appendChunkToLog(chunk))
|
||||
.catch((error) => {
|
||||
process.stderr.write(`${error.stack || error.message}\n`);
|
||||
});
|
||||
}
|
||||
|
||||
const logStream = fs.createWriteStream(logPath, { flags: 'a' });
|
||||
const child = spawn(commandArgs[0], commandArgs.slice(1), {
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
|
|
@ -22,7 +75,7 @@ const child = spawn(commandArgs[0], commandArgs.slice(1), {
|
|||
|
||||
function writeChunk(target, chunk) {
|
||||
target.write(chunk);
|
||||
logStream.write(chunk);
|
||||
queueChunkWrite(chunk);
|
||||
}
|
||||
|
||||
child.stdout.on('data', (chunk) => {
|
||||
|
|
@ -36,18 +89,18 @@ child.stderr.on('data', (chunk) => {
|
|||
child.on('error', (error) => {
|
||||
const message = `${error.stack || error.message}\n`;
|
||||
writeChunk(process.stderr, message);
|
||||
logStream.end(() => {
|
||||
writeQueue.finally(() => {
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
logStream.end(() => {
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal);
|
||||
return;
|
||||
}
|
||||
child.on('close', async (code, signal) => {
|
||||
await writeQueue;
|
||||
|
||||
process.exit(code ?? 1);
|
||||
});
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal);
|
||||
return;
|
||||
}
|
||||
|
||||
process.exit(code ?? 1);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue