UNPKG

@eggjs/logrotator

Version:
74 lines 6.41 kB
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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