aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'server/controllers')
-rw-r--r--server/controllers/api/server/logs.ts52
1 files changed, 28 insertions, 24 deletions
diff --git a/server/controllers/api/server/logs.ts b/server/controllers/api/server/logs.ts
index c551c67e3..5fa3c8787 100644
--- a/server/controllers/api/server/logs.ts
+++ b/server/controllers/api/server/logs.ts
@@ -2,10 +2,8 @@ import * as express from 'express'
2import { UserRight } from '../../../../shared/models/users' 2import { UserRight } from '../../../../shared/models/users'
3import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares' 3import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares'
4import { mtimeSortFilesDesc } from '../../../../shared/utils/logs/logs' 4import { mtimeSortFilesDesc } from '../../../../shared/utils/logs/logs'
5import { readdir } from 'fs-extra' 5import { readdir, readFile } from 'fs-extra'
6import { CONFIG, MAX_LOGS_OUTPUT_CHARACTERS } from '../../../initializers' 6import { CONFIG, MAX_LOGS_OUTPUT_CHARACTERS } from '../../../initializers'
7import { createInterface } from 'readline'
8import { createReadStream } from 'fs'
9import { join } from 'path' 7import { join } from 'path'
10import { getLogsValidator } from '../../../middlewares/validators/logs' 8import { getLogsValidator } from '../../../middlewares/validators/logs'
11import { LogLevel } from '../../../../shared/models/server/log-level.type' 9import { LogLevel } from '../../../../shared/models/server/log-level.type'
@@ -36,7 +34,7 @@ async function getLogs (req: express.Request, res: express.Response) {
36 const endDate = req.query.endDate ? new Date(req.query.endDate) : new Date() 34 const endDate = req.query.endDate ? new Date(req.query.endDate) : new Date()
37 const level: LogLevel = req.query.level || 'info' 35 const level: LogLevel = req.query.level || 'info'
38 36
39 let output = '' 37 let output: string[] = []
40 38
41 for (const meta of sortedLogFiles) { 39 for (const meta of sortedLogFiles) {
42 const path = join(CONFIG.STORAGE.LOG_DIR, meta.file) 40 const path = join(CONFIG.STORAGE.LOG_DIR, meta.file)
@@ -44,18 +42,19 @@ async function getLogs (req: express.Request, res: express.Response) {
44 const result = await getOutputFromFile(path, startDate, endDate, level, currentSize) 42 const result = await getOutputFromFile(path, startDate, endDate, level, currentSize)
45 if (!result.output) break 43 if (!result.output) break
46 44
47 output = output + result.output 45 output = result.output.concat(output)
48 currentSize = result.currentSize 46 currentSize = result.currentSize
49 47
50 if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS) break 48 if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS || (result.logTime && result.logTime < startDate.getTime())) break
51 } 49 }
52 50
53 return res.json(output).end() 51 return res.json(output).end()
54} 52}
55 53
56function getOutputFromFile (path: string, startDate: Date, endDate: Date, level: LogLevel, currentSize: number) { 54async function getOutputFromFile (path: string, startDate: Date, endDate: Date, level: LogLevel, currentSize: number) {
57 const startTime = startDate.getTime() 55 const startTime = startDate.getTime()
58 const endTime = endDate.getTime() 56 const endTime = endDate.getTime()
57 let logTime: number
59 58
60 const logsLevel: { [ id in LogLevel ]: number } = { 59 const logsLevel: { [ id in LogLevel ]: number } = {
61 debug: 0, 60 debug: 0,
@@ -64,27 +63,32 @@ function getOutputFromFile (path: string, startDate: Date, endDate: Date, level:
64 error: 3 63 error: 3
65 } 64 }
66 65
67 return new Promise<{ output: string, currentSize: number }>(res => { 66 const content = await readFile(path)
68 const stream = createReadStream(path) 67 const lines = content.toString().split('\n')
69 let output = '' 68 const output: any[] = []
70 69
71 stream.once('close', () => res({ output, currentSize })) 70 for (let i = lines.length - 1; i >= 0; i--) {
71 const line = lines[ i ]
72 let log: any
72 73
73 const rl = createInterface({ 74 try {
74 input: stream 75 log = JSON.parse(line)
75 }) 76 } catch {
77 // Maybe there a multiple \n at the end of the file
78 continue
79 }
76 80
77 rl.on('line', line => { 81 logTime = new Date(log.timestamp).getTime()
78 const log = JSON.parse(line) 82 if (logTime >= startTime && logTime <= endTime && logsLevel[ log.level ] >= logsLevel[ level ]) {
83 output.push(log)
79 84
80 const logTime = new Date(log.timestamp).getTime() 85 currentSize += line.length
81 if (logTime >= startTime && logTime <= endTime && logsLevel[log.level] >= logsLevel[level]) {
82 output += line
83 86
84 currentSize += line.length 87 if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS) break
88 } else if (logTime < startTime) {
89 break
90 }
91 }
85 92
86 if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS) stream.close() 93 return { currentSize, output: output.reverse(), logTime }
87 }
88 })
89 })
90} 94}