Files
Havline/web/src/utils/logDisplay.ts
T
mrlee 278f8267b7 chore: 初始提交 Fonu 1.0.2
- 公网反代:Nginx 状态卡片(版本 / 运行状态 / 配置校验 / 端口监听)
- 部署设置第一、二梯队(HTTPS 开关、安全头、限流、连接数、仅中国大陆 IP)
- 隧道检测兼容 frps v0.68 / v0.71(V2 与旧版端点)
- 恢复被清空的 internal/frp/store.go、internal/api/ddns_handler.go、web/src/views/DdnsView.vue
2026-09-23 09:40:59 +08:00

166 lines
4.2 KiB
TypeScript

import type { SystemLogEntry } from '../api/types'
import { formatLogTime } from './format'
export type LogTagType = 'success' | 'info' | 'warning' | 'error' | 'default'
export interface DisplaySystemLogEntry extends SystemLogEntry {
displayLevel: string
displayModule: string
}
const SYSTEM_LEVEL_LABELS: Record<string, string> = {
INFO: '信息',
WARN: '警告',
ERROR: '错误',
DEBUG: '调试',
}
const SYSTEM_MODULE_LABELS: Record<string, string> = {
SYSTEM: '系统',
NGINX: 'Nginx',
DDNS: '域名解析',
ACME: '证书',
CERT: '证书',
CHINA_CIDR: '中国 IP 段',
API: 'API',
HTTP: 'HTTP',
FRP: '内网穿透',
}
export function systemLevelLabel(level: string): string {
const upper = level.trim().toUpperCase()
return SYSTEM_LEVEL_LABELS[upper] ?? level
}
export function systemModuleLabel(module: string): string {
const trimmed = module.trim()
if (!trimmed) return '系统'
const upper = trimmed.toUpperCase()
return SYSTEM_MODULE_LABELS[upper] ?? trimmed
}
export function displaySystemLog(entry: SystemLogEntry): DisplaySystemLogEntry {
const message = entry.message.trim()
const msgLower = message.toLowerCase()
let level = entry.level.trim().toUpperCase()
let displayModule = systemModuleLabel(entry.module)
if (
level === 'INFO' &&
(msgLower.includes('server error') ||
msgLower.includes(' failed') ||
msgLower.startsWith('error') ||
msgLower.includes('bind:'))
) {
level = 'ERROR'
}
return {
...entry,
displayLevel: systemLevelLabel(level),
displayModule,
}
}
export interface ParsedNginxError {
time: string
level: string
message: string
raw: string
}
export function parseNginxErrorLine(line: string): ParsedNginxError {
const raw = line.trim()
const match = raw.match(/^(\d{4}[-/]\d{2}[-/]\d{2} \d{2}:\d{2}:\d{2})\s+\[([^\]]+)\]\s+(.+)$/)
if (!match) {
return { time: '', level: 'unknown', message: raw, raw }
}
return {
time: formatLogTime(match[1]),
level: match[2].toLowerCase(),
message: match[3],
raw,
}
}
export function nginxLevelTagType(level: string): LogTagType {
switch (level.toLowerCase()) {
case 'emerg':
case 'alert':
case 'crit':
case 'error':
return 'error'
case 'warn':
case 'warning':
return 'warning'
case 'notice':
case 'info':
return 'info'
default:
return 'default'
}
}
export function systemLevelTagType(level: string): LogTagType {
const upper = level.trim().toUpperCase()
if (upper === 'ERROR' || level === '错误') return 'error'
if (upper === 'WARN' || level === '警告') return 'warning'
if (upper === 'INFO' || level === '信息') return 'info'
return 'default'
}
export function systemModuleTagType(module: string): LogTagType {
const upper = module.trim().toUpperCase()
switch (upper) {
case 'NGINX':
case 'Nginx':
return 'warning'
case 'SYSTEM':
case '系统':
return 'success'
case 'CHINA_CIDR':
case '中国 IP 段':
return 'info'
case 'DDNS':
case '域名解析':
return 'info'
case 'CERT':
case 'ACME':
case '证书':
return 'warning'
default:
return 'default'
}
}
export function latencyClass(seconds: number): string {
const ms = seconds * 1000
if (ms >= 3000) return 'log-duration log-duration--critical'
if (ms >= 1000) return 'log-duration log-duration--slow'
return 'log-duration'
}
export function streamLineClass(line: string): string {
const parsed = parseNginxErrorLine(line)
if (parsed.level !== 'unknown') {
const type = nginxLevelTagType(parsed.level)
if (type === 'error') return 'level-error'
if (type === 'warning') return 'level-warn'
if (type === 'info') return 'level-info'
}
const lower = line.toLowerCase()
if (lower.includes('[error]') || lower.includes(' emerg ') || lower.includes(' alert ') || lower.includes(' crit ')) {
return 'level-error'
}
if (lower.includes('[warn]') || lower.includes(' warning ')) return 'level-warn'
const statusMatch = line.match(/\s(\d{3})\s+\d/)
if (statusMatch) {
const code = Number(statusMatch[1])
if (code >= 500) return 'level-error'
if (code >= 400) return 'level-warn'
}
return ''
}