peertube-plugin-livechat/server/lib/prosody/logrotate.ts

96 lines
2.7 KiB
TypeScript

import type { RegisterServerOptions } from '@peertube/peertube-types'
import type { ProsodyFilePaths } from './config/paths'
import { debugNumericParameter } from '../debug'
import { reloadProsody } from './ctl'
type Rotate = (file: string, options: {
count?: number
compress?: boolean
}, cb: Function) => void
const rotate: Rotate = require('log-rotate')
interface ProsodyLogRotate {
timer: NodeJS.Timeout
lastRotation: number
}
let logRotate: ProsodyLogRotate | undefined
async function _rotate (options: RegisterServerOptions, path: string): Promise<void> {
const p = new Promise<void>((resolve) => {
// I dont use compress.
// I guess that this could cause log losses, because the prosody reload will not happen immediatly.
rotate(path, { count: 14, compress: false }, (err: any) => {
if (err) {
options.peertubeHelpers.logger.error('Failed to rotate file ' + path, err)
return resolve()
}
return resolve()
})
})
return p
}
function startProsodyLogRotate (options: RegisterServerOptions, paths: ProsodyFilePaths): void {
const logger = options.peertubeHelpers.logger
// check every hour
const checkInterval = debugNumericParameter(options, 'logRotateCheckInterval', 60 * 1000, 60 * 60 * 1000)
// rotate every 24hour
const rotateEvery = debugNumericParameter(options, 'logRotateEvery', 2 * 60 * 1000, 24 * 60 * 60 * 1000)
// TODO: also rotate when file is too big
if (logRotate) {
stopProsodyLogRotate(options)
}
logger.info('Starting Prosody log rotation')
const timer = setInterval(() => {
logger.debug('Checking if Prosody logs need to be rotated')
if (!logRotate) {
logger.error('Seems that we dont need to rotate Prosody logs, but the timer was called.')
return
}
if (logRotate.lastRotation + rotateEvery - 1000 > Date.now()) {
// minus 1000 to not miss next check
logger.debug('To soon to rotate.')
return
}
logger.info('Rotating Prosody log files.')
logRotate.lastRotation = Date.now()
const p = Promise.all([
_rotate(options, paths.log),
_rotate(options, paths.error)
])
p.then(() => {
reloadProsody(options).then(() => {
logger.debug('Prosody reloaded')
}, () => {
logger.error('Prosody failed to reload')
})
}, (err) => {
logger.error('Failed rotating logs', err)
})
}, checkInterval)
logRotate = {
timer: timer,
lastRotation: Date.now()
}
}
function stopProsodyLogRotate (options: RegisterServerOptions): void {
const logger = options.peertubeHelpers.logger
if (logRotate === undefined) {
return
}
logger.info('Stoping Prosody log rotation')
clearInterval(logRotate.timer)
}
export {
startProsodyLogRotate,
stopProsodyLogRotate
}