PeerTube/server/controllers/api/server/logs.ts

95 lines
2.8 KiB
TypeScript
Raw Normal View History

2019-04-10 15:26:33 +02:00
import * as express from 'express'
import { UserRight } from '../../../../shared/models/users'
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares'
import { mtimeSortFilesDesc } from '../../../../shared/utils/logs/logs'
2019-04-11 10:05:43 +02:00
import { readdir, readFile } from 'fs-extra'
2019-04-10 15:26:33 +02:00
import { CONFIG, MAX_LOGS_OUTPUT_CHARACTERS } from '../../../initializers'
import { join } from 'path'
import { getLogsValidator } from '../../../middlewares/validators/logs'
import { LogLevel } from '../../../../shared/models/server/log-level.type'
const logsRouter = express.Router()
logsRouter.get('/logs',
authenticate,
ensureUserHasRight(UserRight.MANAGE_LOGS),
getLogsValidator,
asyncMiddleware(getLogs)
)
// ---------------------------------------------------------------------------
export {
logsRouter
}
// ---------------------------------------------------------------------------
async function getLogs (req: express.Request, res: express.Response) {
const logFiles = await readdir(CONFIG.STORAGE.LOG_DIR)
const sortedLogFiles = await mtimeSortFilesDesc(logFiles, CONFIG.STORAGE.LOG_DIR)
let currentSize = 0
const startDate = new Date(req.query.startDate)
const endDate = req.query.endDate ? new Date(req.query.endDate) : new Date()
const level: LogLevel = req.query.level || 'info'
2019-04-11 10:05:43 +02:00
let output: string[] = []
2019-04-10 15:26:33 +02:00
for (const meta of sortedLogFiles) {
const path = join(CONFIG.STORAGE.LOG_DIR, meta.file)
const result = await getOutputFromFile(path, startDate, endDate, level, currentSize)
if (!result.output) break
2019-04-11 10:05:43 +02:00
output = result.output.concat(output)
2019-04-10 15:26:33 +02:00
currentSize = result.currentSize
2019-04-11 10:05:43 +02:00
if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS || (result.logTime && result.logTime < startDate.getTime())) break
2019-04-10 15:26:33 +02:00
}
return res.json(output).end()
}
2019-04-11 10:05:43 +02:00
async function getOutputFromFile (path: string, startDate: Date, endDate: Date, level: LogLevel, currentSize: number) {
2019-04-10 15:26:33 +02:00
const startTime = startDate.getTime()
const endTime = endDate.getTime()
2019-04-11 10:05:43 +02:00
let logTime: number
2019-04-10 15:26:33 +02:00
const logsLevel: { [ id in LogLevel ]: number } = {
debug: 0,
info: 1,
warn: 2,
error: 3
}
2019-04-11 10:05:43 +02:00
const content = await readFile(path)
const lines = content.toString().split('\n')
const output: any[] = []
2019-04-10 15:26:33 +02:00
2019-04-11 10:05:43 +02:00
for (let i = lines.length - 1; i >= 0; i--) {
const line = lines[ i ]
let log: any
2019-04-10 15:26:33 +02:00
2019-04-11 10:05:43 +02:00
try {
log = JSON.parse(line)
} catch {
// Maybe there a multiple \n at the end of the file
continue
}
2019-04-10 15:26:33 +02:00
2019-04-11 10:05:43 +02:00
logTime = new Date(log.timestamp).getTime()
if (logTime >= startTime && logTime <= endTime && logsLevel[ log.level ] >= logsLevel[ level ]) {
output.push(log)
2019-04-10 15:26:33 +02:00
2019-04-11 10:05:43 +02:00
currentSize += line.length
2019-04-10 15:26:33 +02:00
2019-04-11 10:05:43 +02:00
if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS) break
} else if (logTime < startTime) {
break
}
}
2019-04-10 15:26:33 +02:00
2019-04-11 10:05:43 +02:00
return { currentSize, output: output.reverse(), logTime }
2019-04-10 15:26:33 +02:00
}