mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 04:22:33 +08:00
fix: 修正日志样式
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"alova": "^3.3.4",
|
||||
"echarts": "^6.0.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"install": "^0.13.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"luxon": "^3.7.2",
|
||||
|
||||
3
web/pnpm-lock.yaml
generated
3
web/pnpm-lock.yaml
generated
@@ -50,6 +50,9 @@ importers:
|
||||
echarts:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
highlight.js:
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1
|
||||
install:
|
||||
specifier: ^0.13.0
|
||||
version: 0.13.0
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
import systemdlog from '@/utils/hljs/systemdlog'
|
||||
import hljs from 'highlight.js/lib/core'
|
||||
import log from 'highlight.js/lib/languages/accesslog'
|
||||
|
||||
import { useThemeStore } from '@/store'
|
||||
|
||||
hljs.registerLanguage('accesslog', log)
|
||||
hljs.registerLanguage('systemdlog', systemdlog)
|
||||
|
||||
const themeStore = useThemeStore()
|
||||
|
||||
watch(
|
||||
@@ -29,6 +36,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<n-config-provider
|
||||
:hljs="hljs"
|
||||
:theme="themeStore.naiveTheme"
|
||||
:locale="themeStore.naiveLocale"
|
||||
:date-locale="themeStore.naiveDateLocale"
|
||||
|
||||
@@ -12,6 +12,11 @@ const props = defineProps({
|
||||
service: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'systemdlog'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -82,7 +87,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-log ref="logRef" :log="log" trim :rows="40" />
|
||||
<n-log ref="logRef" :log="log" trim :rows="40" :language="props.language" />
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -9,6 +9,11 @@ const props = defineProps({
|
||||
path: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'systemdlog'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -72,7 +77,7 @@ defineExpose({
|
||||
@close="handleClose"
|
||||
@mask-click="handleClose"
|
||||
>
|
||||
<n-log ref="logRef" :log="log" trim :rows="40" />
|
||||
<n-log ref="logRef" :log="log" trim :rows="40" :language="props.language" />
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
|
||||
167
web/src/utils/hljs/systemdlog.ts
Normal file
167
web/src/utils/hljs/systemdlog.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
Language: systemd Journal (journalctl)
|
||||
Description: systemd/journald logs (journalctl -o short / short-iso)
|
||||
Category: system, logs
|
||||
*/
|
||||
|
||||
/** @type {import('highlight.js').LanguageFn} */
|
||||
export default function systemdJournal(hljs: any) {
|
||||
const regex = hljs.regex
|
||||
|
||||
// Month names for "short" format
|
||||
const MONTH = '(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'
|
||||
|
||||
// journalctl -o short:
|
||||
// Jan 13 10:22:33 ...
|
||||
const TS_SHORT = new RegExp(`^${MONTH}\\s+\\d{1,2}\\s+\\d{2}:\\d{2}:\\d{2}`)
|
||||
|
||||
// journalctl -o short-iso:
|
||||
// 2026-01-13T10:22:33+0800 ...
|
||||
// 2026-01-13 10:22:33 ...
|
||||
const TS_ISO = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?/
|
||||
|
||||
const HOST = /[A-Za-z0-9][A-Za-z0-9_.-]*/
|
||||
const IDENT = /[A-Za-z_][A-Za-z0-9_.-]*(?:\/[A-Za-z0-9_.-]+)*/ // e.g. systemd, sshd, foo/bar
|
||||
const PID_OPT = /(?:\[\d+\])?/
|
||||
|
||||
const UNIT = /\b[\w.-]+?\.(?:service|socket|target|timer|mount|device|path|slice|scope)\b/
|
||||
|
||||
const PRIORITY_WORDS = [
|
||||
'emerg',
|
||||
'alert',
|
||||
'crit',
|
||||
'critical',
|
||||
'err',
|
||||
'error',
|
||||
'warn',
|
||||
'warning',
|
||||
'notice',
|
||||
'info',
|
||||
'debug',
|
||||
'panic',
|
||||
// systemd/journal 常见状态词
|
||||
'failed',
|
||||
'failure',
|
||||
'timeout',
|
||||
'timed',
|
||||
'denied',
|
||||
'refused',
|
||||
'segfault'
|
||||
]
|
||||
|
||||
const SYSTEMD_VERBS = [
|
||||
'starting',
|
||||
'started',
|
||||
'stopping',
|
||||
'stopped',
|
||||
'reloading',
|
||||
'reloaded',
|
||||
'restarting',
|
||||
'restarted',
|
||||
'activating',
|
||||
'activated',
|
||||
'deactivating',
|
||||
'deactivated',
|
||||
'mounted',
|
||||
'mounting',
|
||||
'unmounted',
|
||||
'unmounting',
|
||||
'listening',
|
||||
'triggered',
|
||||
'queued',
|
||||
'succeeded',
|
||||
'success'
|
||||
]
|
||||
|
||||
// Prefix: "<timestamp> <host> <ident>[pid]: "
|
||||
// Example:
|
||||
// Jan 13 10:22:33 host systemd[1]:
|
||||
// 2026-01-13T10:22:33+0800 host sshd[1234]:
|
||||
const PREFIX = {
|
||||
begin: [regex.either(TS_ISO, TS_SHORT), /\s+/, HOST, /\s+/, IDENT, PID_OPT],
|
||||
beginScope: {
|
||||
1: 'meta', // timestamp
|
||||
3: 'title', // hostname
|
||||
5: 'symbol', // identifier
|
||||
6: 'number' // [pid]
|
||||
},
|
||||
end: /: /,
|
||||
endScope: 'punctuation',
|
||||
relevance: 10
|
||||
}
|
||||
|
||||
const SEVERITY = {
|
||||
match: new RegExp(`\\b(?:${PRIORITY_WORDS.join('|')})\\b`, 'i'),
|
||||
scope: 'keyword',
|
||||
relevance: 2
|
||||
}
|
||||
|
||||
const STATUS_VERB = {
|
||||
match: new RegExp(`\\b(?:${SYSTEMD_VERBS.join('|')})\\b`, 'i'),
|
||||
scope: 'built_in',
|
||||
relevance: 1
|
||||
}
|
||||
|
||||
// key=value(如:code=exited status=1/FAILURE UNIT=foo.service)
|
||||
const KEY_VALUE = {
|
||||
begin: /\b[\w.-]+=/,
|
||||
scope: 'attr',
|
||||
relevance: 0
|
||||
}
|
||||
|
||||
// kernel/journal 常见的 monotonic timestamp: "[ 123.456]"
|
||||
const MONOTONIC = {
|
||||
match: /\[\s*\d+(?:\.\d+)?\]/,
|
||||
scope: 'meta',
|
||||
relevance: 0
|
||||
}
|
||||
|
||||
const DQUOTE = {
|
||||
scope: 'string',
|
||||
begin: /"/,
|
||||
end: /"/,
|
||||
illegal: /\n/,
|
||||
relevance: 0
|
||||
}
|
||||
|
||||
const SQUOTE = {
|
||||
scope: 'string',
|
||||
begin: /'/,
|
||||
end: /'/,
|
||||
illegal: /\n/,
|
||||
relevance: 0
|
||||
}
|
||||
|
||||
const PATH = {
|
||||
match: /(?:\/[^\s"'():\[\]]+)+/,
|
||||
scope: 'string',
|
||||
relevance: 0
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'systemd Journal',
|
||||
aliases: ['journalctl', 'journald', 'systemdlog', 'systemd-journal', 'systemd'],
|
||||
case_insensitive: true,
|
||||
contains: [
|
||||
PREFIX,
|
||||
|
||||
// unit names in message body
|
||||
{ match: UNIT, scope: 'title', relevance: 3 },
|
||||
|
||||
// severity/status words
|
||||
SEVERITY,
|
||||
STATUS_VERB,
|
||||
|
||||
MONOTONIC,
|
||||
KEY_VALUE,
|
||||
|
||||
// numbers (exit codes, pids, etc.)
|
||||
hljs.NUMBER_MODE,
|
||||
|
||||
// strings/paths
|
||||
DQUOTE,
|
||||
SQUOTE,
|
||||
PATH
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -912,7 +912,7 @@ const updateTimeoutUnit = (proxy: any, unit: string) => {
|
||||
{{ $gettext('Are you sure you want to clear?') }}
|
||||
</n-popconfirm>
|
||||
</n-flex>
|
||||
<realtime-log :path="setting.access_log" />
|
||||
<realtime-log :path="setting.access_log" language="accesslog" />
|
||||
</n-flex>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="error_log" :tab="$gettext('Error Log')">
|
||||
@@ -924,7 +924,7 @@ const updateTimeoutUnit = (proxy: any, unit: string) => {
|
||||
{{ $gettext('view') }}.
|
||||
</n-alert>
|
||||
</n-flex>
|
||||
<realtime-log :path="setting.error_log" />
|
||||
<realtime-log :path="setting.error_log" language="accesslog" />
|
||||
</n-flex>
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
|
||||
Reference in New Issue
Block a user