2022-01-11 00:29:33 +00:00
|
|
|
import type { RegisterServerOptions } from '@peertube/peertube-types'
|
2021-05-12 12:59:52 +00:00
|
|
|
import type { ProsodyFilePaths } from './config/paths'
|
2023-05-23 10:39:05 +00:00
|
|
|
import { debugNumericParameter } from '../debug'
|
2023-04-13 15:00:34 +00:00
|
|
|
import { reloadProsody } from './ctl'
|
2021-05-12 12:59:52 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-04-13 15:00:34 +00:00
|
|
|
function startProsodyLogRotate (options: RegisterServerOptions, paths: ProsodyFilePaths): void {
|
2021-05-12 12:59:52 +00:00
|
|
|
const logger = options.peertubeHelpers.logger
|
2023-05-23 10:39:05 +00:00
|
|
|
// 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)
|
2021-05-12 12:59:52 +00:00
|
|
|
// 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(() => {
|
2023-04-13 15:00:34 +00:00
|
|
|
reloadProsody(options).then(() => {
|
2021-05-12 12:59:52 +00:00
|
|
|
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
|
|
|
|
}
|