diff options
author | Chocobozzz <me@florianbigard.com> | 2019-12-11 14:14:01 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-12-11 14:14:01 +0100 |
commit | 566c125d6eee3bd907404523d94e1e0b5e403a46 (patch) | |
tree | c477cdd2ba745015d80052968c37927b1bca1254 /server/controllers/api | |
parent | 92e0f42e8ce5f1ab5e4023900b8194627231a11b (diff) | |
download | PeerTube-566c125d6eee3bd907404523d94e1e0b5e403a46.tar.gz PeerTube-566c125d6eee3bd907404523d94e1e0b5e403a46.tar.zst PeerTube-566c125d6eee3bd907404523d94e1e0b5e403a46.zip |
Serve audit logs to client
Diffstat (limited to 'server/controllers/api')
-rw-r--r-- | server/controllers/api/server/logs.ts | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/server/controllers/api/server/logs.ts b/server/controllers/api/server/logs.ts index e9d1f2efd..a0ca21cd5 100644 --- a/server/controllers/api/server/logs.ts +++ b/server/controllers/api/server/logs.ts | |||
@@ -3,11 +3,12 @@ import { UserRight } from '../../../../shared/models/users' | |||
3 | import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares' | 3 | import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares' |
4 | import { mtimeSortFilesDesc } from '../../../../shared/core-utils/logs/logs' | 4 | import { mtimeSortFilesDesc } from '../../../../shared/core-utils/logs/logs' |
5 | import { readdir, readFile } from 'fs-extra' | 5 | import { readdir, readFile } from 'fs-extra' |
6 | import { MAX_LOGS_OUTPUT_CHARACTERS } from '../../../initializers/constants' | 6 | import { AUDIT_LOG_FILENAME, MAX_LOGS_OUTPUT_CHARACTERS, LOG_FILENAME } from '../../../initializers/constants' |
7 | import { join } from 'path' | 7 | import { join } from 'path' |
8 | import { getLogsValidator } from '../../../middlewares/validators/logs' | 8 | import { getAuditLogsValidator, getLogsValidator } from '../../../middlewares/validators/logs' |
9 | import { LogLevel } from '../../../../shared/models/server/log-level.type' | 9 | import { LogLevel } from '../../../../shared/models/server/log-level.type' |
10 | import { CONFIG } from '../../../initializers/config' | 10 | import { CONFIG } from '../../../initializers/config' |
11 | import { logger } from '@server/helpers/logger' | ||
11 | 12 | ||
12 | const logsRouter = express.Router() | 13 | const logsRouter = express.Router() |
13 | 14 | ||
@@ -18,6 +19,13 @@ logsRouter.get('/logs', | |||
18 | asyncMiddleware(getLogs) | 19 | asyncMiddleware(getLogs) |
19 | ) | 20 | ) |
20 | 21 | ||
22 | logsRouter.get('/audit-logs', | ||
23 | authenticate, | ||
24 | ensureUserHasRight(UserRight.MANAGE_LOGS), | ||
25 | getAuditLogsValidator, | ||
26 | asyncMiddleware(getAuditLogs) | ||
27 | ) | ||
28 | |||
21 | // --------------------------------------------------------------------------- | 29 | // --------------------------------------------------------------------------- |
22 | 30 | ||
23 | export { | 31 | export { |
@@ -26,18 +34,50 @@ export { | |||
26 | 34 | ||
27 | // --------------------------------------------------------------------------- | 35 | // --------------------------------------------------------------------------- |
28 | 36 | ||
37 | const auditLogNameFilter = generateLogNameFilter(AUDIT_LOG_FILENAME) | ||
38 | async function getAuditLogs (req: express.Request, res: express.Response) { | ||
39 | const output = await generateOutput({ | ||
40 | startDateQuery: req.query.startDate, | ||
41 | endDateQuery: req.query.endDate, | ||
42 | level: 'audit', | ||
43 | nameFilter: auditLogNameFilter | ||
44 | }) | ||
45 | |||
46 | return res.json(output).end() | ||
47 | } | ||
48 | |||
49 | const logNameFilter = generateLogNameFilter(LOG_FILENAME) | ||
29 | async function getLogs (req: express.Request, res: express.Response) { | 50 | async function getLogs (req: express.Request, res: express.Response) { |
51 | const output = await generateOutput({ | ||
52 | startDateQuery: req.query.startDate, | ||
53 | endDateQuery: req.query.endDate, | ||
54 | level: req.query.level || 'info', | ||
55 | nameFilter: logNameFilter | ||
56 | }) | ||
57 | |||
58 | return res.json(output).end() | ||
59 | } | ||
60 | |||
61 | async function generateOutput (options: { | ||
62 | startDateQuery: string, | ||
63 | endDateQuery?: string, | ||
64 | level: LogLevel, | ||
65 | nameFilter: RegExp | ||
66 | }) { | ||
67 | const { startDateQuery, level, nameFilter } = options | ||
68 | |||
30 | const logFiles = await readdir(CONFIG.STORAGE.LOG_DIR) | 69 | const logFiles = await readdir(CONFIG.STORAGE.LOG_DIR) |
31 | const sortedLogFiles = await mtimeSortFilesDesc(logFiles, CONFIG.STORAGE.LOG_DIR) | 70 | const sortedLogFiles = await mtimeSortFilesDesc(logFiles, CONFIG.STORAGE.LOG_DIR) |
32 | let currentSize = 0 | 71 | let currentSize = 0 |
33 | 72 | ||
34 | const startDate = new Date(req.query.startDate) | 73 | const startDate = new Date(startDateQuery) |
35 | const endDate = req.query.endDate ? new Date(req.query.endDate) : new Date() | 74 | const endDate = options.endDateQuery ? new Date(options.endDateQuery) : new Date() |
36 | const level: LogLevel = req.query.level || 'info' | ||
37 | 75 | ||
38 | let output: string[] = [] | 76 | let output: string[] = [] |
39 | 77 | ||
40 | for (const meta of sortedLogFiles) { | 78 | for (const meta of sortedLogFiles) { |
79 | if (nameFilter.exec(meta.file) === null) continue | ||
80 | |||
41 | const path = join(CONFIG.STORAGE.LOG_DIR, meta.file) | 81 | const path = join(CONFIG.STORAGE.LOG_DIR, meta.file) |
42 | 82 | ||
43 | const result = await getOutputFromFile(path, startDate, endDate, level, currentSize) | 83 | const result = await getOutputFromFile(path, startDate, endDate, level, currentSize) |
@@ -49,7 +89,7 @@ async function getLogs (req: express.Request, res: express.Response) { | |||
49 | if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS || (result.logTime && result.logTime < startDate.getTime())) break | 89 | if (currentSize > MAX_LOGS_OUTPUT_CHARACTERS || (result.logTime && result.logTime < startDate.getTime())) break |
50 | } | 90 | } |
51 | 91 | ||
52 | return res.json(output).end() | 92 | return output |
53 | } | 93 | } |
54 | 94 | ||
55 | async function getOutputFromFile (path: string, startDate: Date, endDate: Date, level: LogLevel, currentSize: number) { | 95 | async function getOutputFromFile (path: string, startDate: Date, endDate: Date, level: LogLevel, currentSize: number) { |
@@ -58,6 +98,7 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date, | |||
58 | let logTime: number | 98 | let logTime: number |
59 | 99 | ||
60 | const logsLevel: { [ id in LogLevel ]: number } = { | 100 | const logsLevel: { [ id in LogLevel ]: number } = { |
101 | audit: -1, | ||
61 | debug: 0, | 102 | debug: 0, |
62 | info: 1, | 103 | info: 1, |
63 | warn: 2, | 104 | warn: 2, |
@@ -93,3 +134,7 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date, | |||
93 | 134 | ||
94 | return { currentSize, output: output.reverse(), logTime } | 135 | return { currentSize, output: output.reverse(), logTime } |
95 | } | 136 | } |
137 | |||
138 | function generateLogNameFilter (baseName: string) { | ||
139 | return new RegExp('^' + baseName.replace(/\.log$/, '') + '\d*.log$') | ||
140 | } | ||