admin/logs: console
Massimo Melina committed
Jul 16, 2023 at 20:04 UTC
dd7e3fde6250bd64aea4f5e88c54c9d51c6acbcc
5 files changed
+50
-5
admin/src/LogsPage.ts
+21
-1
@@ -31,7 +31,27 @@ function LogFile({ file }: { file: string }) {
31
showLastButton: true,
32
}
33
},
34
- columns: [
34
+ columns: file === 'console' ? [
35
+ {
36
+ field: 'ts',
37
+ headerName: "Timestamp",
38
+ type: 'dateTime',
39
+ width: 90,
40
+ valueGetter: ({ value }) => new Date(value as string),
41
+ renderCell: ({ value }) => h(Box, {}, value.toLocaleDateString(), h('br'), value.toLocaleTimeString())
42
+ },
43
+ {
44
+ field: 'k',
45
+ headerName: "Level",
46
+ hideUnder: 'sm',
47
+ },
48
+ {
49
+ field: 'msg',
50
+ headerName: "Message",
51
+ flex: 1,
52
+ mergeRender: { other: 'k', override: { valueFormatter: ({ value }) => value !== 'log' && value } }
53
+ }
54
+ ] : [
55
{
56
field: 'ip',
57
headerName: "Address",
admin/src/OptionsPage.ts
+3
-2
@@ -35,8 +35,9 @@ subscribe(state, (ops) => {
35
})
36
37
export const logLabels = {
38
- log: "Access log file",
39
- error_log: "Access error log file"
38
+ log: "Access",
39
+ error_log: "Access error",
40
+ console: "Console",
41
}
42
43
const NetmaskField = StringField
src/adminApis.ts
+13
-2
@@ -18,7 +18,7 @@ import pluginsApis from './api.plugins'
18
import monitorApis from './api.monitor'
19
import langApis from './api.lang'
20
import { getConnections } from './connections'
21
-import { debounceAsync, isLocalHost, makeNetMatcher, onOff, waitFor } from './misc'
21
+import { debounceAsync, isLocalHost, makeNetMatcher, onOff, wait, waitFor } from './misc'
22
import events from './events'
23
import { accountCanLoginAdmin, accountsConfig, getFromAccount } from './perm'
24
import Koa from 'koa'
@@ -32,6 +32,7 @@ import { promisify } from 'util'
32
import { customHtmlSections, customHtmlState, saveCustomHtml } from './customHtml'
33
import _ from 'lodash'
34
import { getUpdate, localUpdateAvailable, update, updateSupported } from './update'
35
+import { consoleLog } from './consoleLog'
36
37
export const adminApis: ApiHandlers = {
38
@@ -110,7 +111,17 @@ export const adminApis: ApiHandlers = {
111
async get_log({ file='log' }, ctx) {
112
return new SendListReadable({
113
bufferTime: 10,
113
- doAtStart(list) {
114
+ async doAtStart(list) {
115
+ if (file === 'console') {
116
+ for (const chunk of _.chunk(consoleLog, 1000)) { // avoid occupying the thread too long
117
+ for (const x of chunk)
118
+ list.add(x)
119
+ await wait(0)
120
+ }
121
+ list.ready()
122
+ events.on('console', x => list.add(x))
123
+ return
124
+ }
125
const logger = loggers.find(l => l.name === file)
126
if (!logger)
127
return list.error(HTTP_NOT_FOUND, true)
src/consoleLog.ts
new
+12
@@ -0,0 +1,12 @@
1
+import events from './events'
2
+
3
+export const consoleLog: Array<{ ts: Date, k: string, msg: string }> = []
4
+for (const k of ['log','warn','error']) {
5
+ const original = console[k as 'log']
6
+ console[k as 'log'] = (...args: any[]) => {
7
+ const rec = { ts: new Date(), k, msg: args.join(' ') }
8
+ consoleLog.push(rec)
9
+ events.emit('console', rec)
10
+ return original(...args)
11
+ }
12
+}
src/index.ts
+1
@@ -3,6 +3,7 @@
3
4
import Koa from 'koa'
5
import mount from 'koa-mount'
6
+import './consoleLog'
7
import { apiMiddleware } from './apiMiddleware'
8
import { API_URI, DEV } from './const'
9
import { frontEndApis } from './frontEndApis'