@eggjs/logrotator
Version:
logrotator for egg
74 lines • 6.41 kB
JavaScript
import assert from 'node:assert';
import { createWriteStream, createReadStream } from 'node:fs';
import fs from 'node:fs/promises';
import { pipeline } from 'node:stream/promises';
import { createGzip } from 'node:zlib';
import { debuglog } from 'node:util';
import { exists } from 'utility';
const debug = debuglog('@eggjs/logrotator/lib/rotator');
export class LogRotator {
options;
app;
logger;
constructor(options) {
this.options = options;
assert(this.options.app, 'options.app is required');
this.app = this.options.app;
this.logger = this.app.coreLogger;
}
async rotate() {
const files = await this.getRotateFiles();
assert(files instanceof Map, 'getRotateFiles should return a Map');
const rotatedFiles = [];
for (const file of files.values()) {
try {
debug('rename from %s to %s', file.srcPath, file.targetPath);
await renameOrDelete(file.srcPath, file.targetPath, this.app.config.logrotator.gzip);
rotatedFiles.push(`${file.srcPath} -> ${file.targetPath}`);
}
catch (e) {
const err = e;
err.message =
`[@eggjs/logrotator] rename ${file.srcPath}, found exception: ` +
err.message;
this.logger.error(err);
}
}
if (rotatedFiles.length > 0) {
// tell every one to reload logger
this.logger.info('[@eggjs/logrotator] broadcast log-reload');
this.app.messenger.sendToApp('log-reload');
this.app.messenger.sendToAgent('log-reload');
}
this.logger.info('[@eggjs/logrotator] rotate files success by %s, files %j', this.constructor.name, rotatedFiles);
}
}
// rename from srcPath to targetPath, for example foo.log.1 > foo.log.2
// if gzip is true, then use gzip to compress the file, and delete the src file, for example foo.log.1 -> foo.log.2.gz
async function renameOrDelete(srcPath, targetPath, gzip) {
if (srcPath === targetPath) {
return;
}
const srcExists = await exists(srcPath);
if (!srcExists) {
return;
}
const targetExists = await exists(targetPath);
// if target file exists, then throw
// because the target file always be renamed first.
if (targetExists) {
const err = new Error(`targetFile ${targetPath} exists!!!`);
throw err;
}
// if gzip is true, then use gzip
if (gzip === true) {
const tmpPath = `${targetPath}.tmp`;
await fs.rename(srcPath, tmpPath);
await pipeline(createReadStream(tmpPath), createGzip(), createWriteStream(targetPath));
await fs.unlink(tmpPath);
}
else {
await fs.rename(srcPath, targetPath);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm90YXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvcm90YXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlELE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFckMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUdqQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsK0JBQStCLENBQUMsQ0FBQztBQVd4RCxNQUFNLE9BQWdCLFVBQVU7SUFDWCxPQUFPLENBQWlCO0lBQ3hCLEdBQUcsQ0FBVTtJQUNiLE1BQU0sQ0FBd0I7SUFFakQsWUFBWSxPQUF1QjtRQUNqQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUseUJBQXlCLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQzVCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7SUFDcEMsQ0FBQztJQUlELEtBQUssQ0FBQyxNQUFNO1FBQ1YsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDMUMsTUFBTSxDQUFDLEtBQUssWUFBWSxHQUFHLEVBQUUsb0NBQW9DLENBQUMsQ0FBQztRQUNuRSxNQUFNLFlBQVksR0FBYSxF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