diff options
Diffstat (limited to 'server/controllers')
-rw-r--r-- | server/controllers/api/server/logs.ts | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/server/controllers/api/server/logs.ts b/server/controllers/api/server/logs.ts index dfd5491aa..8aa4b7190 100644 --- a/server/controllers/api/server/logs.ts +++ b/server/controllers/api/server/logs.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import express from 'express' | 1 | import express from 'express' |
2 | import { readdir, readFile } from 'fs-extra' | 2 | import { readdir, readFile } from 'fs-extra' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { isArray } from '@server/helpers/custom-validators/misc' | ||
4 | import { logger, mtimeSortFilesDesc } from '@server/helpers/logger' | 5 | import { logger, mtimeSortFilesDesc } from '@server/helpers/logger' |
5 | import { LogLevel } from '../../../../shared/models/server/log-level.type' | 6 | import { LogLevel } from '../../../../shared/models/server/log-level.type' |
6 | import { UserRight } from '../../../../shared/models/users' | 7 | import { UserRight } from '../../../../shared/models/users' |
@@ -51,20 +52,27 @@ async function getLogs (req: express.Request, res: express.Response) { | |||
51 | startDateQuery: req.query.startDate, | 52 | startDateQuery: req.query.startDate, |
52 | endDateQuery: req.query.endDate, | 53 | endDateQuery: req.query.endDate, |
53 | level: req.query.level || 'info', | 54 | level: req.query.level || 'info', |
55 | tagsOneOf: req.query.tagsOneOf, | ||
54 | nameFilter: logNameFilter | 56 | nameFilter: logNameFilter |
55 | }) | 57 | }) |
56 | 58 | ||
57 | return res.json(output).end() | 59 | return res.json(output) |
58 | } | 60 | } |
59 | 61 | ||
60 | async function generateOutput (options: { | 62 | async function generateOutput (options: { |
61 | startDateQuery: string | 63 | startDateQuery: string |
62 | endDateQuery?: string | 64 | endDateQuery?: string |
65 | |||
63 | level: LogLevel | 66 | level: LogLevel |
64 | nameFilter: RegExp | 67 | nameFilter: RegExp |
68 | tagsOneOf?: string[] | ||
65 | }) { | 69 | }) { |
66 | const { startDateQuery, level, nameFilter } = options | 70 | const { startDateQuery, level, nameFilter } = options |
67 | 71 | ||
72 | const tagsOneOf = Array.isArray(options.tagsOneOf) && options.tagsOneOf.length !== 0 | ||
73 | ? new Set(options.tagsOneOf) | ||
74 | : undefined | ||
75 | |||
68 | const logFiles = await readdir(CONFIG.STORAGE.LOG_DIR) | 76 | const logFiles = await readdir(CONFIG.STORAGE.LOG_DIR) |
69 | const sortedLogFiles = await mtimeSortFilesDesc(logFiles, CONFIG.STORAGE.LOG_DIR) | 77 | const sortedLogFiles = await mtimeSortFilesDesc(logFiles, CONFIG.STORAGE.LOG_DIR) |
70 | let currentSize = 0 | 78 | let currentSize = 0 |
@@ -80,7 +88,7 @@ async function generateOutput (options: { | |||
80 | const path = join(CONFIG.STORAGE.LOG_DIR, meta.file) | 88 | const path = join(CONFIG.STORAGE.LOG_DIR, meta.file) |
81 | logger.debug('Opening %s to fetch logs.', path) | 89 | logger.debug('Opening %s to fetch logs.', path) |
82 | 90 | ||
83 | const result = await getOutputFromFile(path, startDate, endDate, level, currentSize) | 91 | const result = await getOutputFromFile({ path, startDate, endDate, level, currentSize, tagsOneOf }) |
84 | if (!result.output) break | 92 | if (!result.output) break |
85 | 93 | ||
86 | output = result.output.concat(output) | 94 | output = result.output.concat(output) |
@@ -92,9 +100,20 @@ async function generateOutput (options: { | |||
92 | return output | 100 | return output |
93 | } | 101 | } |
94 | 102 | ||
95 | async function getOutputFromFile (path: string, startDate: Date, endDate: Date, level: LogLevel, currentSize: number) { | 103 | async function getOutputFromFile (options: { |
104 | path: string | ||
105 | startDate: Date | ||
106 | endDate: Date | ||
107 | level: LogLevel | ||
108 | currentSize: number | ||
109 | tagsOneOf: Set<string> | ||
110 | }) { | ||
111 | const { path, startDate, endDate, level, tagsOneOf } = options | ||
112 | |||
96 | const startTime = startDate.getTime() | 113 | const startTime = startDate.getTime() |
97 | const endTime = endDate.getTime() | 114 | const endTime = endDate.getTime() |
115 | let currentSize = options.currentSize | ||
116 | |||
98 | let logTime: number | 117 | let logTime: number |
99 | 118 | ||
100 | const logsLevel: { [ id in LogLevel ]: number } = { | 119 | const logsLevel: { [ id in LogLevel ]: number } = { |
@@ -121,7 +140,12 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date, | |||
121 | } | 140 | } |
122 | 141 | ||
123 | logTime = new Date(log.timestamp).getTime() | 142 | logTime = new Date(log.timestamp).getTime() |
124 | if (logTime >= startTime && logTime <= endTime && logsLevel[log.level] >= logsLevel[level]) { | 143 | if ( |
144 | logTime >= startTime && | ||
145 | logTime <= endTime && | ||
146 | logsLevel[log.level] >= logsLevel[level] && | ||
147 | (!tagsOneOf || lineHasTag(log, tagsOneOf)) | ||
148 | ) { | ||
125 | output.push(log) | 149 | output.push(log) |
126 | 150 | ||
127 | currentSize += line.length | 151 | currentSize += line.length |
@@ -135,6 +159,16 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date, | |||
135 | return { currentSize, output: output.reverse(), logTime } | 159 | return { currentSize, output: output.reverse(), logTime } |
136 | } | 160 | } |
137 | 161 | ||
162 | function lineHasTag (line: { tags?: string }, tagsOneOf: Set<string>) { | ||
163 | if (!isArray(line.tags)) return false | ||
164 | |||
165 | for (const lineTag of line.tags) { | ||
166 | if (tagsOneOf.has(lineTag)) return true | ||
167 | } | ||
168 | |||
169 | return false | ||
170 | } | ||
171 | |||
138 | function generateLogNameFilter (baseName: string) { | 172 | function generateLogNameFilter (baseName: string) { |
139 | return new RegExp('^' + baseName.replace(/\.log$/, '') + '\\d*.log$') | 173 | return new RegExp('^' + baseName.replace(/\.log$/, '') + '\\d*.log$') |
140 | } | 174 | } |