Prosody log rotation every 24 hour.
This commit is contained in:
parent
c5bcf611d3
commit
4cf9ab51aa
@ -8,6 +8,7 @@
|
|||||||
* Starting with Peertube 3.2.0, builtin prosody save room history on server. So when a user connects, he can get previously send messages.
|
* Starting with Peertube 3.2.0, builtin prosody save room history on server. So when a user connects, he can get previously send messages.
|
||||||
* Starting with Peertube 3.2.0, builtin prosody also activate mod_muc_moderation, enabling moderators to moderate messages.
|
* Starting with Peertube 3.2.0, builtin prosody also activate mod_muc_moderation, enabling moderators to moderate messages.
|
||||||
* Prosody log level will be the same as the Peertube's one.
|
* Prosody log level will be the same as the Peertube's one.
|
||||||
|
* Prosody log rotation every 24 hour.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ This roadmap is given as an indication. It will be updated as we go along accord
|
|||||||
[x] | [x] | Common | Chat should not be displayed in playlists | v2.2.0
|
[x] | [x] | Common | Chat should not be displayed in playlists | v2.2.0
|
||||||
[x] | [x] | Builtin Prosody | Do not use a temp folder, use the one provided by Peertube>=3.2.0. | Not Released Yet
|
[x] | [x] | Builtin Prosody | Do not use a temp folder, use the one provided by Peertube>=3.2.0. | Not Released Yet
|
||||||
[x] | [ ] | Builtin Prosody | Use Peertube log level for prosody. | Not Released Yet
|
[x] | [ ] | Builtin Prosody | Use Peertube log level for prosody. | Not Released Yet
|
||||||
[ ] | [x] | Builtin Prosody | Rotate prosody logs.
|
[ ] | [x] | Builtin Prosody | Rotate prosody logs. | Not Released Yet
|
||||||
[x] | [x] | Builtin Prosody | Data Persistence | Not Released Yet
|
[x] | [x] | Builtin Prosody | Data Persistence | Not Released Yet
|
||||||
[ ] | [x] | Common | Add a checkbox per video to activate livechat. Only on lives.
|
[ ] | [x] | Common | Add a checkbox per video to activate livechat. Only on lives.
|
||||||
[ ] | [x] | Builtin Prosody | Docker: check how to install and use Prosody on docker installations. Do the documentation.
|
[ ] | [x] | Builtin Prosody | Docker: check how to install and use Prosody on docker installations. Do the documentation.
|
||||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -3620,6 +3620,11 @@
|
|||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"log-rotate": {
|
||||||
|
"version": "0.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/log-rotate/-/log-rotate-0.2.8.tgz",
|
||||||
|
"integrity": "sha512-r9I3eKh2EH+jjbg+tqvACtBjmCdyyyKQsElVF+a/tYCQDOmHQxTvlDEB6GFn2UAZcsF13LTV814bhXspWMu96g=="
|
||||||
|
},
|
||||||
"logform": {
|
"logform": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz",
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
"async": "^3.2.0",
|
"async": "^3.2.0",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"decache": "^4.6.0",
|
"decache": "^4.6.0",
|
||||||
"express-http-proxy": "^1.6.2"
|
"express-http-proxy": "^1.6.2",
|
||||||
|
"log-rotate": "^0.2.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@purtuga/esm-webpack-plugin": "^1.1.1",
|
"@purtuga/esm-webpack-plugin": "^1.1.1",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { getProsodyConfig, getProsodyFilePaths, writeProsodyConfig } from './config'
|
import { getProsodyConfig, getProsodyFilePaths, writeProsodyConfig } from './config'
|
||||||
|
import { startProsodyLogRotate, stopProsodyLogRotate } from './logrotate'
|
||||||
import { changeHttpBindRoute } from '../routers/webchat'
|
import { changeHttpBindRoute } from '../routers/webchat'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as child_process from 'child_process'
|
import * as child_process from 'child_process'
|
||||||
@ -58,6 +59,15 @@ async function getProsodyAbout (options: RegisterServerOptions): Promise<string>
|
|||||||
return ctl.message
|
return ctl.message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function reloadProsody (options: RegisterServerOptions): Promise<boolean> {
|
||||||
|
const reload = await prosodyCtl(options, 'reload')
|
||||||
|
if (reload.code) {
|
||||||
|
options.peertubeHelpers.logger.error('reloadProsody failed: ' + JSON.stringify(reload))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
interface ProsodyRunning {
|
interface ProsodyRunning {
|
||||||
ok: boolean
|
ok: boolean
|
||||||
messages: string[]
|
messages: string[]
|
||||||
@ -208,9 +218,10 @@ async function ensureProsodyRunning (options: RegisterServerOptions): Promise<vo
|
|||||||
}
|
}
|
||||||
if (!processStarted) {
|
if (!processStarted) {
|
||||||
logger.error('It seems that the Prosody process is not up')
|
logger.error('It seems that the Prosody process is not up')
|
||||||
} else {
|
return
|
||||||
logger.info('Prosody is running')
|
|
||||||
}
|
}
|
||||||
|
logger.info('Prosody is running')
|
||||||
|
startProsodyLogRotate(options, filePaths, reloadProsody)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureProsodyNotRunning (options: RegisterServerOptions): Promise<void> {
|
async function ensureProsodyNotRunning (options: RegisterServerOptions): Promise<void> {
|
||||||
@ -218,6 +229,8 @@ async function ensureProsodyNotRunning (options: RegisterServerOptions): Promise
|
|||||||
const logger = peertubeHelpers.logger
|
const logger = peertubeHelpers.logger
|
||||||
logger.info('Checking if Prosody is running, and shutting it down if so')
|
logger.info('Checking if Prosody is running, and shutting it down if so')
|
||||||
|
|
||||||
|
stopProsodyLogRotate(options)
|
||||||
|
|
||||||
// NB: this function is called on plugin unregister, even if prosody is not used
|
// NB: this function is called on plugin unregister, even if prosody is not used
|
||||||
// so we must avoid creating the working dir now
|
// so we must avoid creating the working dir now
|
||||||
const filePaths = await getProsodyFilePaths(options)
|
const filePaths = await getProsodyFilePaths(options)
|
||||||
|
91
server/lib/prosody/logrotate.ts
Normal file
91
server/lib/prosody/logrotate.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import type { ProsodyFilePaths } from './config/paths'
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
type ReloadProsody = (options: RegisterServerOptions) => Promise<boolean>
|
||||||
|
|
||||||
|
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, reload: ReloadProsody): void {
|
||||||
|
const logger = options.peertubeHelpers.logger
|
||||||
|
const checkInterval = process.env.NODE_ENV === 'test' ? 60 * 1000 : 60 * 60 * 1000 // check every hour
|
||||||
|
const rotateEvery = process.env.NODE_ENV === 'test' ? 2 * 60 * 1000 : 24 * 60 * 60 * 1000 // rotate every 24hour
|
||||||
|
// 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(() => {
|
||||||
|
reload(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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user