mirror of
https://github.com/rnvm9wjdtj-bot/myaps_api.git
synced 2026-06-02 05:54:40 +00:00
优化语言补丁的命名空间,优化历史日志的查询性能
This commit is contained in:
+154
-30
@@ -4,6 +4,20 @@
|
||||
提供监控相关的 API 端点
|
||||
"""
|
||||
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from fastapi import APIRouter, HTTPException, WebSocket
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from typing import Dict, Any, List, Optional
|
||||
from tortoise import Tortoise
|
||||
from .service import monitor_service
|
||||
from .log_stream_service import log_stream_service
|
||||
from .storage import request_storage, outbound_request_storage, system_log_storage
|
||||
from .models import APIRequest, OutboundAPIRequest, SystemLog
|
||||
from core.settings import TIMEZONE
|
||||
from globalobjects import logger as log_config
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
@@ -1030,6 +1044,8 @@ async def get_history_by_time_range(
|
||||
http_requests = await request_storage.get_requests_with_filters(
|
||||
utc_start, utc_end, limit, filter_params
|
||||
)
|
||||
print(f"[DEBUG] HTTP查询: page={page}, page_size={page_size}, 返回{len(http_requests)}条")
|
||||
# 列表查询只返回基本字段,不返回request_body/response_body大字段(详情时懒加载)
|
||||
result["http_requests"] = [{
|
||||
"id": req.id,
|
||||
"timestamp": req.timestamp.isoformat(),
|
||||
@@ -1042,11 +1058,8 @@ async def get_history_by_time_range(
|
||||
"user_agent": req.user_agent,
|
||||
"is_slow": req.is_slow,
|
||||
"is_error": req.is_error,
|
||||
"error_message": req.error_message,
|
||||
"request_body": req.request_body,
|
||||
"response_body": req.response_body,
|
||||
"request_headers": getattr(req, 'request_headers', None),
|
||||
"response_headers": getattr(req, 'response_headers', None)
|
||||
"error_message": req.error_message
|
||||
# 不返回: request_body, response_body, request_headers, response_headers
|
||||
} for req in http_requests]
|
||||
|
||||
# 查询发送请求
|
||||
@@ -1054,6 +1067,8 @@ async def get_history_by_time_range(
|
||||
outbound_requests = await outbound_request_storage.get_requests_with_filters(
|
||||
utc_start, utc_end, limit, filter_params
|
||||
)
|
||||
print(f"[DEBUG] Outbound查询: page={page}, page_size={page_size}, 返回{len(outbound_requests)}条")
|
||||
# 列表查询只返回基本字段,不返回request_body/response_body大字段
|
||||
result["outbound_requests"] = [{
|
||||
"id": req.id,
|
||||
"timestamp": req.timestamp.isoformat(),
|
||||
@@ -1064,11 +1079,8 @@ async def get_history_by_time_range(
|
||||
"module": req.module,
|
||||
"is_slow": req.is_slow,
|
||||
"is_error": req.is_error,
|
||||
"error_message": req.error_message,
|
||||
"request_body": req.request_body,
|
||||
"response_body": req.response_body,
|
||||
"request_headers": req.request_headers,
|
||||
"response_headers": req.response_headers
|
||||
"error_message": req.error_message
|
||||
# 不返回: request_body, response_body, request_headers, response_headers
|
||||
} for req in outbound_requests]
|
||||
|
||||
# 查询系统日志
|
||||
@@ -1076,6 +1088,8 @@ async def get_history_by_time_range(
|
||||
logs = await system_log_storage.get_logs_with_filters(
|
||||
utc_start, utc_end, level, limit, filter_params
|
||||
)
|
||||
print(f"[DEBUG] Logs查询: page={page}, page_size={page_size}, 返回{len(logs)}条")
|
||||
# 列表查询不返回stack_trace大字段(详情时懒加载)
|
||||
result["logs"] = [{
|
||||
"id": log.id,
|
||||
"timestamp": log.timestamp.isoformat(),
|
||||
@@ -1083,18 +1097,25 @@ async def get_history_by_time_range(
|
||||
"module": log.module,
|
||||
"function": log.function,
|
||||
"line_number": log.line_number,
|
||||
"message": log.message,
|
||||
"stack_trace": log.stack_trace
|
||||
"message": log.message[:500] if log.message else None # 截断message,避免超长日志
|
||||
# 不返回: stack_trace
|
||||
} for log in logs]
|
||||
|
||||
# 计算分页元数据
|
||||
# 统计总数(用于结果摘要显示)- 只执行一次count
|
||||
result["stats"] = {
|
||||
"http_count": await request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_http else 0,
|
||||
"outbound_count": await outbound_request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_outbound else 0,
|
||||
"logs_count": await system_log_storage.count_logs_with_filters(utc_start, utc_end, level, filter_params) if should_query_logs else 0
|
||||
}
|
||||
|
||||
# 计算分页元数据(复用stats的count结果)
|
||||
total_count = 0
|
||||
if should_query_http:
|
||||
total_count = await request_storage.count_requests_with_filters(utc_start, utc_end, filter_params)
|
||||
total_count = result["stats"]["http_count"]
|
||||
elif should_query_outbound:
|
||||
total_count = await outbound_request_storage.count_requests_with_filters(utc_start, utc_end, filter_params)
|
||||
total_count = result["stats"]["outbound_count"]
|
||||
elif should_query_logs:
|
||||
total_count = await system_log_storage.count_logs_with_filters(utc_start, utc_end, level, filter_params)
|
||||
total_count = result["stats"]["logs_count"]
|
||||
|
||||
if total_count > 0:
|
||||
total_pages = (total_count + page_size - 1) // page_size
|
||||
@@ -1109,21 +1130,36 @@ async def get_history_by_time_range(
|
||||
"end_index": min(page * page_size, total_count)
|
||||
}
|
||||
|
||||
# 统计总数(用于结果摘要显示)
|
||||
result["stats"] = {
|
||||
"http_count": await request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_http else 0,
|
||||
"outbound_count": await outbound_request_storage.count_requests_with_filters(utc_start, utc_end, filter_params) if should_query_outbound else 0,
|
||||
"logs_count": await system_log_storage.count_logs_with_filters(utc_start, utc_end, level, filter_params) if should_query_logs else 0
|
||||
}
|
||||
|
||||
# 统计日志级别分布(仅查询系统日志时)
|
||||
# 统计日志级别分布(仅查询系统日志时)- 优化:使用GROUP BY聚合,避免查询所有记录
|
||||
if should_query_logs and result["stats"]["logs_count"] > 0:
|
||||
level_stats = {}
|
||||
for lv in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
|
||||
count = await system_log_storage.count_logs_with_filters(utc_start, utc_end, lv, filter_params)
|
||||
if count > 0:
|
||||
level_stats[lv] = count
|
||||
result["stats"]["level_distribution"] = level_stats
|
||||
try:
|
||||
# 使用原生SQL的GROUP BY聚合,性能最优
|
||||
from .models import SystemLog
|
||||
from tortoise import connections
|
||||
|
||||
conn = connections.get("default")
|
||||
|
||||
# 构建SQL查询
|
||||
sql = "SELECT level, COUNT(*) as count FROM system_logs WHERE 1=1"
|
||||
params = []
|
||||
|
||||
if utc_start and utc_end:
|
||||
sql += " AND timestamp >= $1 AND timestamp <= $2"
|
||||
params.extend([utc_start, utc_end])
|
||||
|
||||
if filter_params and filter_params.get('module'):
|
||||
sql += f" AND module IN ({','.join(['$'+str(i+3) for i in range(len(filter_params['module']))])})"
|
||||
params.extend(filter_params['module'])
|
||||
|
||||
sql += " GROUP BY level"
|
||||
|
||||
# 执行查询
|
||||
rows = await conn.execute_query(sql, params)
|
||||
level_stats = {row['level']: row['count'] for row in rows[1] if row.get('level')}
|
||||
result["stats"]["level_distribution"] = level_stats
|
||||
except Exception as e:
|
||||
print(f"统计级别分布失败: {e}")
|
||||
result["stats"]["level_distribution"] = {}
|
||||
|
||||
return result
|
||||
|
||||
@@ -1576,3 +1612,91 @@ async def export_history_data(
|
||||
media_type="application/json",
|
||||
headers={"Content-Disposition": f"attachment; filename={filename}"}
|
||||
)
|
||||
|
||||
|
||||
# ========== 详情懒加载端点 ==========
|
||||
|
||||
@router.get("/history/outbound/{request_id}")
|
||||
async def get_outbound_request_detail(request_id: int):
|
||||
"""
|
||||
获取发送请求详情(懒加载,包含request_body、response_body等大字段)
|
||||
"""
|
||||
try:
|
||||
req = await OutboundAPIRequest.get_or_none(id=request_id)
|
||||
if not req:
|
||||
raise HTTPException(status_code=404, detail="请求不存在")
|
||||
|
||||
return {
|
||||
"id": req.id,
|
||||
"timestamp": req.timestamp.isoformat(),
|
||||
"method": req.method,
|
||||
"url": req.url,
|
||||
"status_code": req.status_code,
|
||||
"duration": req.duration * 1000,
|
||||
"module": req.module,
|
||||
"is_slow": req.is_slow,
|
||||
"is_error": req.is_error,
|
||||
"error_message": req.error_message,
|
||||
"request_body": req.request_body,
|
||||
"response_body": req.response_body,
|
||||
"request_headers": req.request_headers,
|
||||
"response_headers": req.response_headers
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"查询详情失败: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/history/http/{request_id}")
|
||||
async def get_http_request_detail(request_id: int):
|
||||
"""
|
||||
获取HTTP请求详情(懒加载,包含request_body、response_body等大字段)
|
||||
"""
|
||||
try:
|
||||
req = await APIRequest.get_or_none(id=request_id)
|
||||
if not req:
|
||||
raise HTTPException(status_code=404, detail="请求不存在")
|
||||
|
||||
return {
|
||||
"id": req.id,
|
||||
"timestamp": req.timestamp.isoformat(),
|
||||
"method": req.method,
|
||||
"path": req.path,
|
||||
"query_params": req.query_params,
|
||||
"status_code": req.status_code,
|
||||
"duration": req.response_time,
|
||||
"client_ip": req.client_ip,
|
||||
"user_agent": req.user_agent,
|
||||
"is_slow": req.is_slow,
|
||||
"is_error": req.is_error,
|
||||
"error_message": req.error_message,
|
||||
"request_body": req.request_body,
|
||||
"response_body": req.response_body,
|
||||
"request_headers": getattr(req, 'request_headers', None),
|
||||
"response_headers": getattr(req, 'response_headers', None)
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"查询详情失败: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/history/log/{log_id}")
|
||||
async def get_log_detail(log_id: int):
|
||||
"""
|
||||
获取系统日志详情(懒加载,包含stack_trace等大字段)
|
||||
"""
|
||||
try:
|
||||
log = await SystemLog.get_or_none(id=log_id)
|
||||
if not log:
|
||||
raise HTTPException(status_code=404, detail="日志不存在")
|
||||
|
||||
return {
|
||||
"id": log.id,
|
||||
"timestamp": log.timestamp.isoformat(),
|
||||
"level": log.level,
|
||||
"module": log.module,
|
||||
"function": log.function,
|
||||
"line_number": log.line_number,
|
||||
"message": log.message,
|
||||
"stack_trace": log.stack_trace
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"查询详情失败: {str(e)}")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+431
-414
@@ -4,497 +4,507 @@
|
||||
*/
|
||||
window.__i18n_de_DE__ = {
|
||||
// ============ Seitentitel ============
|
||||
'page.title': 'MyAPI Systemüberwachung',
|
||||
'page.live_logs': 'Echtzeit-Logs - Systemüberwachung',
|
||||
'page.history_logs': 'Protokollverlauf - Systemüberwachung',
|
||||
'monitor.page.title': 'MyAPI Systemüberwachung',
|
||||
'monitor.page.live_logs': 'Echtzeit-Logs - Systemüberwachung',
|
||||
'monitor.page.history_logs': 'Protokollverlauf - Systemüberwachung',
|
||||
|
||||
// ============ Navigation ============
|
||||
'nav.overview': '📊 Übersicht',
|
||||
'nav.database': '🗃️ Datenbank',
|
||||
'nav.events': '☎️ Ereignisse',
|
||||
'nav.scheduler': '⏰ Planer',
|
||||
'nav.http_requests': '📥 HTTP-Anfragen',
|
||||
'nav.outbound_requests': '📤 Ausgehend',
|
||||
'nav.logs': '📋 Protokolle',
|
||||
'monitor.nav.overview': '📊 Übersicht',
|
||||
'monitor.nav.database': '🗃️ Datenbank',
|
||||
'monitor.nav.events': '☎️ Ereignisse',
|
||||
'monitor.nav.scheduler': '⏰ Planer',
|
||||
'monitor.nav.http_requests': '📥 HTTP-Anfragen',
|
||||
'monitor.nav.outbound_requests': '📤 Ausgehend',
|
||||
'monitor.nav.logs': '📋 Protokolle',
|
||||
|
||||
// ============ Tabs ============
|
||||
'tab.overview': 'Übersicht',
|
||||
'tab.database': 'Datenbank',
|
||||
'tab.events': 'Ereignisse',
|
||||
'tab.scheduler': 'Planer',
|
||||
'tab.http': 'HTTP-Anfragen',
|
||||
'tab.outbound': 'Ausgehend',
|
||||
'tab.logs': 'Systemprotokolle',
|
||||
'tab.timeline': 'Zeitachse',
|
||||
'tab.chart': 'Diagramme',
|
||||
'monitor.tab.overview': 'Übersicht',
|
||||
'monitor.tab.database': 'Datenbank',
|
||||
'monitor.tab.events': 'Ereignisse',
|
||||
'monitor.tab.scheduler': 'Planer',
|
||||
'monitor.tab.http': 'HTTP-Anfragen',
|
||||
'monitor.tab.outbound': 'Ausgehend',
|
||||
'monitor.tab.logs': 'Systemprotokolle',
|
||||
'monitor.tab.timeline': 'Zeitachse',
|
||||
'monitor.tab.chart': 'Diagramme',
|
||||
|
||||
// ============ Karten ============
|
||||
'card.resource': 'Ressourcennutzung',
|
||||
'card.db_status': 'Datenbankstatus',
|
||||
'card.db_connections': 'Datenbankverbindungen',
|
||||
'card.event_helpers': 'Ereignis-Helfer',
|
||||
'card.scheduler': 'Aufgabenplaner',
|
||||
'card.api_requests': 'HTTP-Anfragen',
|
||||
'card.outbound_requests': 'Ausgehende Anfragen',
|
||||
'card.redis': 'Redis-Status',
|
||||
'card.event_listener': 'Ereignis-Listener',
|
||||
'card.recent_alerts': 'Aktuelle Warnungen',
|
||||
'card.mysql': 'MySQL',
|
||||
'card.http_requests_log': 'HTTP-Anfragedatensätze',
|
||||
'card.scheduler_detail': 'Planer-Details',
|
||||
'card.outbound_requests_log': 'Ausgehende Anfragedatensätze',
|
||||
'card.callback_tracker': 'Callback-Tracker',
|
||||
'card.event_deduplicator': 'Ereignis-Deduplikator',
|
||||
'monitor.card.resource': 'Ressourcennutzung',
|
||||
'monitor.card.db_status': 'Datenbankstatus',
|
||||
'monitor.card.db_connections': 'Datenbankverbindungen',
|
||||
'monitor.card.event_helpers': 'Ereignis-Helfer',
|
||||
'monitor.card.scheduler': 'Aufgabenplaner',
|
||||
'monitor.card.api_requests': 'HTTP-Anfragen',
|
||||
'monitor.card.outbound_requests': 'Ausgehende Anfragen',
|
||||
'monitor.card.redis': 'Redis-Status',
|
||||
'monitor.card.event_listener': 'Ereignis-Listener',
|
||||
'monitor.card.recent_alerts': 'Aktuelle Warnungen',
|
||||
'monitor.card.mysql': 'MySQL',
|
||||
'monitor.card.http_requests_log': 'HTTP-Anfragedatensätze',
|
||||
'monitor.card.scheduler_detail': 'Planer-Details',
|
||||
'monitor.card.outbound_requests_log': 'Ausgehende Anfragedatensätze',
|
||||
'monitor.card.callback_tracker': 'Callback-Tracker',
|
||||
'monitor.card.event_deduplicator': 'Ereignis-Deduplikator',
|
||||
|
||||
// ============ Kennzahlen ============
|
||||
'metric.cpu': 'CPU-Auslastung',
|
||||
'metric.memory': 'Speichernutzung',
|
||||
'metric.threads': 'Threads',
|
||||
'metric.uptime': 'Laufzeit',
|
||||
'metric.total_connections': 'Verbindungen',
|
||||
'metric.healthy': 'Gesund',
|
||||
'metric.unhealthy': 'Fehlerhaft',
|
||||
'metric.degraded': 'Eingeschränkt',
|
||||
'metric.total': 'Gesamt',
|
||||
'metric.success': 'Erfolg',
|
||||
'metric.failed': 'Fehler',
|
||||
'metric.pending': 'Ausstehend',
|
||||
'metric.active': 'Aktiv',
|
||||
'metric.idle': 'Inaktiv',
|
||||
'metric.unknown': 'Unbekannt',
|
||||
'metric.warning': 'Warnung',
|
||||
'metric.events_received': 'Empfangene Ereignisse',
|
||||
'metric.events_processed': 'Verarbeitete Ereignisse',
|
||||
'metric.events_failed': 'Fehlgeschlagene Ereignisse',
|
||||
'metric.jobs_running': 'Laufende Aufgaben',
|
||||
'metric.jobs_pending': 'Ausstehende Aufgaben',
|
||||
'metric.requests_total': 'Anfragen Gesamt',
|
||||
'metric.requests_slow': 'Langsame Anfragen',
|
||||
'metric.requests_error': 'Fehlerhafte Anfragen',
|
||||
'metric.error_rate': 'Fehlerquote',
|
||||
'metric.avg_time': 'Durchschn. Antwort',
|
||||
'metric.connection_status': 'Verbindungsstatus',
|
||||
'metric.host': 'Host',
|
||||
'metric.port': 'Port',
|
||||
'metric.database': 'Datenbank',
|
||||
'metric.used_connections': 'Verwendete Verbindungen',
|
||||
'metric.max_connections': 'Max. Verbindungen',
|
||||
'metric.connection_usage': 'Verbindungsnutzung',
|
||||
'metric.buffer_size': 'Puffergröße',
|
||||
'metric.buffer_threshold': 'Pufferschwellwert',
|
||||
'metric.buffer_usage': 'Puffernutzung',
|
||||
'metric.events_interrupted': 'Unterbrochen',
|
||||
'metric.overall_success_rate': 'Gesamterfolgsquote',
|
||||
'metric.active_event_types': 'Aktive Ereignistypen',
|
||||
'metric.backpressure_status': 'Rückstau-Status',
|
||||
'metric.backpressure_pending': 'Ausstehende Ereignisse',
|
||||
'metric.backpressure_usage': 'Rückstau-Nutzung',
|
||||
'metric.event_loop_status': 'Ereignisschleifen-Status',
|
||||
'metric.pending_callbacks': 'Ausstehende Callbacks',
|
||||
'metric.max_retries': 'Max. Wiederholungen',
|
||||
'metric.pending_retries': 'Ausstehende Wiederholungen',
|
||||
'metric.total_entries': 'Gesamteinträge',
|
||||
'metric.active_items': 'Aktive Elemente',
|
||||
'metric.ttl_seconds': 'TTL (Sekunden)',
|
||||
'metric.max_entries': 'Max. Einträge',
|
||||
'metric.dl_total': 'DL-Gesamt',
|
||||
'metric.recent_dl': 'Aktuelle DL',
|
||||
'metric.process_success_rate': 'Verarbeitungserfolgsquote',
|
||||
'metric.scheduler_status': 'Planer-Status',
|
||||
'metric.job_count': 'Aufgabenanzahl',
|
||||
'metric.pending_events': 'Ausstehende Ereignisse',
|
||||
'metric.total_events': 'Gesamtereignisse',
|
||||
'metric.file_size': 'Dateigröße',
|
||||
'metric.running_status': 'Betriebsstatus',
|
||||
'monitor.metric.cpu': 'CPU-Auslastung',
|
||||
'monitor.metric.memory': 'Speichernutzung',
|
||||
'monitor.metric.threads': 'Threads',
|
||||
'monitor.metric.uptime': 'Laufzeit',
|
||||
'monitor.metric.total_connections': 'Verbindungen',
|
||||
'monitor.metric.healthy': 'Gesund',
|
||||
'monitor.metric.unhealthy': 'Fehlerhaft',
|
||||
'monitor.metric.degraded': 'Eingeschränkt',
|
||||
'monitor.metric.total': 'Gesamt',
|
||||
'monitor.metric.success': 'Erfolg',
|
||||
'monitor.metric.failed': 'Fehler',
|
||||
'monitor.metric.pending': 'Ausstehend',
|
||||
'monitor.metric.active': 'Aktiv',
|
||||
'monitor.metric.idle': 'Inaktiv',
|
||||
'monitor.metric.unknown': 'Unbekannt',
|
||||
'monitor.metric.warning': 'Warnung',
|
||||
'monitor.metric.events_received': 'Empfangene Ereignisse',
|
||||
'monitor.metric.events_processed': 'Verarbeitete Ereignisse',
|
||||
'monitor.metric.events_failed': 'Fehlgeschlagene Ereignisse',
|
||||
'monitor.metric.jobs_running': 'Laufende Aufgaben',
|
||||
'monitor.metric.jobs_pending': 'Ausstehende Aufgaben',
|
||||
'monitor.metric.requests_total': 'Anfragen Gesamt',
|
||||
'monitor.metric.requests_slow': 'Langsame Anfragen',
|
||||
'monitor.metric.requests_error': 'Fehlerhafte Anfragen',
|
||||
'monitor.metric.error_rate': 'Fehlerquote',
|
||||
'monitor.metric.avg_time': 'Durchschn. Antwort',
|
||||
'monitor.metric.connection_status': 'Verbindungsstatus',
|
||||
'monitor.metric.host': 'Host',
|
||||
'monitor.metric.port': 'Port',
|
||||
'monitor.metric.database': 'Datenbank',
|
||||
'monitor.metric.used_connections': 'Verwendete Verbindungen',
|
||||
'monitor.metric.max_connections': 'Max. Verbindungen',
|
||||
'monitor.metric.connection_usage': 'Verbindungsnutzung',
|
||||
'monitor.metric.buffer_size': 'Puffergröße',
|
||||
'monitor.metric.buffer_threshold': 'Pufferschwellwert',
|
||||
'monitor.metric.buffer_usage': 'Puffernutzung',
|
||||
'monitor.metric.events_interrupted': 'Unterbrochen',
|
||||
'monitor.metric.overall_success_rate': 'Gesamterfolgsquote',
|
||||
'monitor.metric.active_event_types': 'Aktive Ereignistypen',
|
||||
'monitor.metric.backpressure_status': 'Rückstau-Status',
|
||||
'monitor.metric.backpressure_pending': 'Ausstehende Ereignisse',
|
||||
'monitor.metric.backpressure_usage': 'Rückstau-Nutzung',
|
||||
'monitor.metric.event_loop_status': 'Ereignisschleifen-Status',
|
||||
'monitor.metric.pending_callbacks': 'Ausstehende Callbacks',
|
||||
'monitor.metric.max_retries': 'Max. Wiederholungen',
|
||||
'monitor.metric.pending_retries': 'Ausstehende Wiederholungen',
|
||||
'monitor.metric.total_entries': 'Gesamteinträge',
|
||||
'monitor.metric.active_items': 'Aktive Elemente',
|
||||
'monitor.metric.ttl_seconds': 'TTL (Sekunden)',
|
||||
'monitor.metric.max_entries': 'Max. Einträge',
|
||||
'monitor.metric.dl_total': 'DL-Gesamt',
|
||||
'monitor.metric.recent_dl': 'Aktuelle DL',
|
||||
'monitor.metric.process_success_rate': 'Verarbeitungserfolgsquote',
|
||||
'monitor.metric.scheduler_status': 'Planer-Status',
|
||||
'monitor.metric.job_count': 'Aufgabenanzahl',
|
||||
'monitor.metric.pending_events': 'Ausstehende Ereignisse',
|
||||
'monitor.metric.total_events': 'Gesamtereignisse',
|
||||
'monitor.metric.file_size': 'Dateigröße',
|
||||
'monitor.metric.running_status': 'Betriebsstatus',
|
||||
|
||||
// ============ Status ============
|
||||
'status.healthy': '● System gesund',
|
||||
'status.unhealthy': '● System fehlerhaft',
|
||||
'status.degraded': '● System eingeschränkt',
|
||||
'status.running': 'Läuft',
|
||||
'status.checking': 'Prüfe',
|
||||
'status.stopped': 'Gestoppt',
|
||||
'status.loading': 'Laden...',
|
||||
'status.querying': 'Abfrage...',
|
||||
'status.exporting': 'Exportiere...',
|
||||
'status.no_data': 'Keine Daten',
|
||||
'status.connected': 'Verbunden',
|
||||
'status.connecting': 'Verbinde...',
|
||||
'status.disconnected': 'Getrennt',
|
||||
'status.reconnecting': 'Verbinde neu...',
|
||||
'status.paused': 'Pausiert',
|
||||
'status.enabled': 'Aktiviert',
|
||||
'status.disabled': 'Deaktiviert',
|
||||
'status.no_db_connections': 'Keine Datenbankverbindungen',
|
||||
'status.no_scheduler': 'Keine geplanten Aufgaben',
|
||||
'status.no_http_requests': 'Keine HTTP-Anfragen',
|
||||
'status.no_alerts': 'Keine Warnungen',
|
||||
'status.no_logs': 'Keine Protokolle',
|
||||
'status.no_events': 'Keine Ereignisstatistiken',
|
||||
'status.no_api_requests': 'Keine API-Anfragedatensätze',
|
||||
'status.no_outbound_requests': 'Keine ausgehenden Anfragedatensätze',
|
||||
'status.no_dead_letters': 'Keine DL',
|
||||
'status.partial_warnings': '● Teilweise Warnungen',
|
||||
'status.monitoring': 'Überwachung',
|
||||
'monitor.status.healthy': '● System gesund',
|
||||
'monitor.status.unhealthy': '● System fehlerhaft',
|
||||
'monitor.status.degraded': '● System eingeschränkt',
|
||||
'monitor.status.running': 'Läuft',
|
||||
'monitor.status.checking': 'Prüfe',
|
||||
'monitor.status.stopped': 'Gestoppt',
|
||||
'monitor.status.loading': 'Laden...',
|
||||
'monitor.status.querying': 'Abfrage...',
|
||||
'monitor.status.exporting': 'Exportiere...',
|
||||
'monitor.status.no_data': 'Keine Daten',
|
||||
'monitor.status.connected': 'Verbunden',
|
||||
'monitor.status.connecting': 'Verbinde...',
|
||||
'monitor.status.disconnected': 'Getrennt',
|
||||
'monitor.status.reconnecting': 'Verbinde neu...',
|
||||
'monitor.status.paused': 'Pausiert',
|
||||
'monitor.status.enabled': 'Aktiviert',
|
||||
'monitor.status.disabled': 'Deaktiviert',
|
||||
'monitor.status.no_db_connections': 'Keine Datenbankverbindungen',
|
||||
'monitor.status.no_scheduler': 'Keine geplanten Aufgaben',
|
||||
'monitor.status.no_http_requests': 'Keine HTTP-Anfragen',
|
||||
'monitor.status.no_alerts': 'Keine Warnungen',
|
||||
'monitor.status.no_logs': 'Keine Protokolle',
|
||||
'monitor.status.no_events': 'Keine Ereignisstatistiken',
|
||||
'monitor.status.no_api_requests': 'Keine API-Anfragedatensätze',
|
||||
'monitor.status.no_outbound_requests': 'Keine ausgehenden Anfragedatensätze',
|
||||
'monitor.status.no_dead_letters': 'Keine DL',
|
||||
'monitor.status.partial_warnings': '● Teilweise Warnungen',
|
||||
'monitor.status.monitoring': 'Überwachung',
|
||||
|
||||
// ============ Schaltflächen ============
|
||||
'btn.query': 'Abfrage',
|
||||
'btn.reset': 'Zurücksetzen',
|
||||
'btn.refresh': 'Aktualisieren',
|
||||
'btn.export': 'Exportieren',
|
||||
'btn.export_csv': 'CSV Export',
|
||||
'btn.export_json': 'JSON Export',
|
||||
'btn.detail': 'Details',
|
||||
'btn.pause': 'Pause',
|
||||
'btn.resume': 'Fortsetzen',
|
||||
'btn.clear': 'Löschen',
|
||||
'btn.save': 'Speichern',
|
||||
'btn.delete': 'Löschen',
|
||||
'btn.close': 'Schließen',
|
||||
'btn.confirm': 'Bestätigen',
|
||||
'btn.cancel': 'Abbrechen',
|
||||
'btn.test': 'Testen',
|
||||
'btn.apply': 'Anwenden',
|
||||
'btn.filter': 'Filtern',
|
||||
'btn.clear_all': 'Alle löschen',
|
||||
'btn.realtime_on': 'Echtzeit: AN',
|
||||
'btn.realtime_off': 'Echtzeit: AUS',
|
||||
'btn.precise_locate': '± 60s',
|
||||
'btn.precise_cancel': '± 60s - Klick zum Abbrechen',
|
||||
'btn.reset_stats': 'Statistik zurücksetzen',
|
||||
'btn.flush_all': 'Alle leeren',
|
||||
'btn.new_window': 'Neues Fenster',
|
||||
'btn.auto_scroll': 'Auto-Scroll',
|
||||
'btn.live_logs': 'Echtzeit-Protokolle',
|
||||
'btn.history_query': 'Verlaufsanfrage',
|
||||
'btn.mark_all_read': 'Alle als gelesen markieren',
|
||||
'btn.clear_read_status': 'Lesestatus löschen',
|
||||
'monitor.btn.query': 'Abfrage',
|
||||
'monitor.btn.reset': 'Zurücksetzen',
|
||||
'monitor.btn.refresh': 'Aktualisieren',
|
||||
'monitor.btn.export': 'Exportieren',
|
||||
'monitor.btn.export_csv': 'CSV Export',
|
||||
'monitor.btn.export_json': 'JSON Export',
|
||||
'monitor.btn.detail': 'Details',
|
||||
'monitor.btn.pause': 'Pause',
|
||||
'monitor.btn.resume': 'Fortsetzen',
|
||||
'monitor.btn.clear': 'Löschen',
|
||||
'monitor.btn.save': 'Speichern',
|
||||
'monitor.btn.delete': 'Löschen',
|
||||
'monitor.btn.close': 'Schließen',
|
||||
'monitor.btn.confirm': 'Bestätigen',
|
||||
'monitor.btn.cancel': 'Abbrechen',
|
||||
'monitor.btn.test': 'Testen',
|
||||
'monitor.btn.apply': 'Anwenden',
|
||||
'monitor.btn.filter': 'Filtern',
|
||||
'monitor.btn.clear_all': 'Alle löschen',
|
||||
'monitor.btn.realtime_on': 'Echtzeit: AN',
|
||||
'monitor.btn.realtime_off': 'Echtzeit: AUS',
|
||||
'monitor.btn.precise_locate': '± 60s',
|
||||
'monitor.btn.precise_cancel': '± 60s - Klick zum Abbrechen',
|
||||
'monitor.btn.reset_stats': 'Statistik zurücksetzen',
|
||||
'monitor.btn.flush_all': 'Alle leeren',
|
||||
'monitor.btn.new_window': 'Neues Fenster',
|
||||
'monitor.btn.auto_scroll': 'Auto-Scroll',
|
||||
'monitor.btn.live_logs': 'Echtzeit-Protokolle',
|
||||
'monitor.btn.history_query': 'Verlaufsanfrage',
|
||||
'monitor.btn.mark_all_read': 'Alle als gelesen markieren',
|
||||
'monitor.btn.clear_read_status': 'Lesestatus löschen',
|
||||
|
||||
// ============ Tabellenspalten ============
|
||||
'col.index': '#',
|
||||
'col.time': 'Zeit',
|
||||
'col.level': 'Stufe',
|
||||
'col.module': 'Modul',
|
||||
'col.message': 'Nachricht',
|
||||
'col.method': 'Methode',
|
||||
'col.path': 'Pfad',
|
||||
'col.url': 'URL',
|
||||
'col.status': 'Status',
|
||||
'col.duration': 'Dauer',
|
||||
'col.client_ip': 'Client-IP',
|
||||
'col.source': 'Quelle',
|
||||
'col.function': 'Funktion',
|
||||
'col.line': 'Zeile',
|
||||
'col.operation': 'Aktion',
|
||||
'col.count': 'Anzahl',
|
||||
'col.avg_time': 'Durchschn. Zeit',
|
||||
'col.max_time': 'Max. Zeit',
|
||||
'col.db_name': 'DB-Name',
|
||||
'col.last_check': 'Letzte Prüfung',
|
||||
'col.current_connections': 'Aktuell',
|
||||
'col.max_connections': 'Max',
|
||||
'col.min_connections': 'Min',
|
||||
'col.idle_connections': 'Inaktiv',
|
||||
'col.used_connections': 'Verwendet',
|
||||
'col.usage': 'Nutzung',
|
||||
'col.processed_records': 'Verarbeitet',
|
||||
'col.timestamp': 'Zeitstempel',
|
||||
'col.query_params': 'Abfrageparameter',
|
||||
'col.error_message': 'Fehlermeldung',
|
||||
'col.url': 'URL',
|
||||
'col.is_read': 'Gelesen',
|
||||
'col.description': 'Beschreibung',
|
||||
'col.total_received': 'Gesamt empfangen',
|
||||
'col.pending': 'Ausstehend',
|
||||
'col.processed': 'Verarbeitet',
|
||||
'col.interrupted': 'Unterbrochen',
|
||||
'col.completion_rate': 'Abschlussrate',
|
||||
'col.avg_latency': 'Durchschn. Latenz',
|
||||
'col.last_action': 'Letzte Aktion',
|
||||
'col.id': 'ID',
|
||||
'col.event_type': 'Ereignistyp',
|
||||
'col.table': 'Tabelle',
|
||||
'monitor.col.index': '#',
|
||||
'monitor.col.time': 'Zeit',
|
||||
'monitor.col.level': 'Stufe',
|
||||
'monitor.col.module': 'Modul',
|
||||
'monitor.col.message': 'Nachricht',
|
||||
'monitor.col.method': 'Methode',
|
||||
'monitor.col.path': 'Pfad',
|
||||
'monitor.col.url': 'URL',
|
||||
'monitor.col.status': 'Status',
|
||||
'monitor.col.duration': 'Dauer',
|
||||
'monitor.col.client_ip': 'Client-IP',
|
||||
'monitor.col.source': 'Quelle',
|
||||
'monitor.col.function': 'Funktion',
|
||||
'monitor.col.line': 'Zeile',
|
||||
'monitor.col.operation': 'Aktion',
|
||||
'monitor.col.count': 'Anzahl',
|
||||
'monitor.col.avg_time': 'Durchschn. Zeit',
|
||||
'monitor.col.max_time': 'Max. Zeit',
|
||||
'monitor.col.db_name': 'DB-Name',
|
||||
'monitor.col.last_check': 'Letzte Prüfung',
|
||||
'monitor.col.current_connections': 'Aktuell',
|
||||
'monitor.col.max_connections': 'Max',
|
||||
'monitor.col.min_connections': 'Min',
|
||||
'monitor.col.idle_connections': 'Inaktiv',
|
||||
'monitor.col.used_connections': 'Verwendet',
|
||||
'monitor.col.usage': 'Nutzung',
|
||||
'monitor.col.processed_records': 'Verarbeitet',
|
||||
'monitor.col.timestamp': 'Zeitstempel',
|
||||
'monitor.col.query_params': 'Abfrageparameter',
|
||||
'monitor.col.error_message': 'Fehlermeldung',
|
||||
'monitor.col.url': 'URL',
|
||||
'monitor.col.is_read': 'Gelesen',
|
||||
'monitor.col.description': 'Beschreibung',
|
||||
'monitor.col.total_received': 'Gesamt empfangen',
|
||||
'monitor.col.pending': 'Ausstehend',
|
||||
'monitor.col.processed': 'Verarbeitet',
|
||||
'monitor.col.interrupted': 'Unterbrochen',
|
||||
'monitor.col.completion_rate': 'Abschlussrate',
|
||||
'monitor.col.avg_latency': 'Durchschn. Latenz',
|
||||
'monitor.col.last_action': 'Letzte Aktion',
|
||||
'monitor.col.id': 'ID',
|
||||
'monitor.col.event_type': 'Ereignistyp',
|
||||
'monitor.col.table': 'Tabelle',
|
||||
|
||||
// ============ Schnellzeit ============
|
||||
'time.start_time': 'Startzeit',
|
||||
'time.end_time': 'Endzeit',
|
||||
'time.last_10m': 'Letzte 10 Min',
|
||||
'time.last_30m': 'Letzte 30 Min',
|
||||
'time.last_1h': 'Letzte Stunde',
|
||||
'time.last_6h': 'Letzte 6 Stunden',
|
||||
'time.last_24h': 'Letzte 24 Stunden',
|
||||
'time.range': 'Zeitbereich',
|
||||
'monitor.time.start_time': 'Startzeit',
|
||||
'monitor.time.end_time': 'Endzeit',
|
||||
'monitor.time.last_10m': 'Letzte 10 Min',
|
||||
'monitor.time.last_30m': 'Letzte 30 Min',
|
||||
'monitor.time.last_1h': 'Letzte Stunde',
|
||||
'monitor.time.last_6h': 'Letzte 6 Stunden',
|
||||
'monitor.time.last_24h': 'Letzte 24 Stunden',
|
||||
'monitor.time.range': 'Zeitbereich',
|
||||
|
||||
// ============ Filter ============
|
||||
'filter.level': 'Alle Stufen',
|
||||
'filter.type': 'Alle Typen',
|
||||
'filter.module': 'Modul',
|
||||
'filter.keyword': 'Schlüsselwort',
|
||||
'filter.method': 'Methode',
|
||||
'filter.client_ip': 'Client-IP',
|
||||
'filter.status_range': 'Statusbereich',
|
||||
'filter.duration_range': 'Dauerbereich',
|
||||
'filter.advanced': 'Erweiterte Filter',
|
||||
'filter.collapse': 'Einklappen',
|
||||
'filter.expand': 'Ausklappen',
|
||||
'filter.clear': 'Löschen',
|
||||
'filter.active': 'Aktive Filter',
|
||||
'filter.module_placeholder': 'Modulname eingeben',
|
||||
'filter.keyword_placeholder': 'Schlüsselwort eingeben',
|
||||
'filter.ip_placeholder': 'Client-IP eingeben',
|
||||
'filter.status_placeholder': 'z.B.: 400-499',
|
||||
'filter.duration_placeholder': 'z.B.: >1000',
|
||||
'filter.all_logs': 'Alle Protokolle',
|
||||
'monitor.filter.level': 'Alle Stufen',
|
||||
'monitor.filter.type': 'Alle Typen',
|
||||
'monitor.filter.module': 'Modul',
|
||||
'monitor.filter.keyword': 'Schlüsselwort',
|
||||
'monitor.filter.method': 'Methode',
|
||||
'monitor.filter.client_ip': 'Client-IP',
|
||||
'monitor.filter.status_range': 'Statusbereich',
|
||||
'monitor.filter.duration_range': 'Dauerbereich',
|
||||
'monitor.filter.advanced': 'Erweiterte Filter',
|
||||
'monitor.filter.collapse': 'Einklappen',
|
||||
'monitor.filter.expand': 'Ausklappen',
|
||||
'monitor.filter.clear': 'Löschen',
|
||||
'monitor.filter.active': 'Aktive Filter',
|
||||
'monitor.filter.module_placeholder': 'Modulname eingeben',
|
||||
'monitor.filter.keyword_placeholder': 'Schlüsselwort eingeben',
|
||||
'monitor.filter.ip_placeholder': 'Client-IP eingeben',
|
||||
'monitor.filter.status_placeholder': 'z.B.: 400-499',
|
||||
'monitor.filter.duration_placeholder': 'z.B.: >1000',
|
||||
'monitor.filter.all_logs': 'Alle Protokolle',
|
||||
|
||||
// ============ Diagramme ============
|
||||
'chart.request_trend': '📊 Anfragentrend',
|
||||
'chart.level_distribution': '📊 Protokollstufen-Verteilung',
|
||||
'chart.status_distribution': '📈 Statuscode-Verteilung',
|
||||
'chart.slow_requests': '⏱️ Langsame Anfragen TOP10',
|
||||
'chart.total_requests': 'Anfragen Gesamt',
|
||||
'chart.error_count': 'Fehler',
|
||||
'chart.slow_count': 'Langsame Anfragen',
|
||||
'chart.log_count': 'Protokolle Gesamt',
|
||||
'chart.no_slow': '✅ Keine langsamen Anfragen',
|
||||
'chart.query_required': 'Bitte zuerst Abfrage ausführen',
|
||||
'chart.load_failed': '❌ Diagramm-Daten laden fehlgeschlagen, bitte erneut versuchen',
|
||||
'chart.redis_connections': 'Redis Verbindungspool-Nutzung',
|
||||
'chart.redis_buffer': 'Redis Puffergrößen-Änderungen',
|
||||
'chart.cpu': 'CPU',
|
||||
'chart.memory': 'Speicher',
|
||||
'chart.upload': 'Upload',
|
||||
'chart.download': 'Download',
|
||||
'chart.cpu_memory_axis': 'CPU / Speicher (%)',
|
||||
'chart.network_axis': 'Netzwerk-Upload / Download (KB/s)',
|
||||
'chart.used_connections': 'Verwendete Verbindungen',
|
||||
'chart.buffer_size_mb': 'Puffergröße (MB)',
|
||||
'monitor.chart.request_trend': '📊 Anfragentrend',
|
||||
'monitor.chart.level_distribution': '📊 Protokollstufen-Verteilung',
|
||||
'monitor.chart.status_distribution': '📈 Statuscode-Verteilung',
|
||||
'monitor.chart.slow_requests': '⏱️ Langsame Anfragen TOP10',
|
||||
'monitor.chart.total_requests': 'Anfragen Gesamt',
|
||||
'monitor.chart.error_count': 'Fehler',
|
||||
'monitor.chart.slow_count': 'Langsame Anfragen',
|
||||
'monitor.chart.log_count': 'Protokolle Gesamt',
|
||||
'monitor.chart.no_slow': '✅ Keine langsamen Anfragen',
|
||||
'monitor.chart.query_required': 'Bitte zuerst Abfrage ausführen',
|
||||
'monitor.chart.load_failed': '❌ Diagramm-Daten laden fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.chart.no_data': 'Keine Daten',
|
||||
'monitor.chart.no_trend': 'Keine Trenddaten',
|
||||
'monitor.chart.redis_connections': 'Redis Verbindungspool-Nutzung',
|
||||
'monitor.chart.redis_buffer': 'Redis Puffergrößen-Änderungen',
|
||||
'monitor.chart.cpu': 'CPU',
|
||||
'monitor.chart.memory': 'Speicher',
|
||||
'monitor.chart.upload': 'Upload',
|
||||
'monitor.chart.download': 'Download',
|
||||
'monitor.chart.cpu_memory_axis': 'CPU / Speicher (%)',
|
||||
'monitor.chart.network_axis': 'Netzwerk-Upload / Download (KB/s)',
|
||||
'monitor.chart.used_connections': 'Verwendete Verbindungen',
|
||||
'monitor.chart.buffer_size_mb': 'Puffergröße (MB)',
|
||||
|
||||
// ============ Fehler ============
|
||||
'error.time_range_invalid': 'Startzeit kann nicht größer als Endzeit sein',
|
||||
'error.time_range_required': 'Bitte Startzeit und Endzeit auswählen',
|
||||
'error.query_failed': 'Abfrage fehlgeschlagen, bitte erneut versuchen',
|
||||
'error.export_failed': 'Export fehlgeschlagen, bitte erneut versuchen',
|
||||
'error.connection_failed': 'Verbindung fehlgeschlagen, bitte Seite aktualisieren',
|
||||
'error.max_templates': 'Maximal 10 Vorlagen erlaubt, bitte zuerst einige löschen',
|
||||
'error.auto_pause': 'Echtzeit-Verfolgung automatisch pausiert (über 10 Minuten)',
|
||||
'error.load_failed': 'Laden fehlgeschlagen, bitte erneut versuchen',
|
||||
'error.invalid_params': 'Ungültige Parameter',
|
||||
'error.clear_dl_failed': 'DeadLetter-Warteschlange löschen fehlgeschlagen',
|
||||
'monitor.error.time_range_invalid': 'Startzeit kann nicht größer als Endzeit sein',
|
||||
'monitor.error.time_range_required': 'Bitte Startzeit und Endzeit auswählen',
|
||||
'monitor.error.query_failed': 'Abfrage fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.error.export_failed': 'Export fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.error.connection_failed': 'Verbindung fehlgeschlagen, bitte Seite aktualisieren',
|
||||
'monitor.error.max_templates': 'Maximal 10 Vorlagen erlaubt, bitte zuerst einige löschen',
|
||||
'monitor.error.auto_pause': 'Echtzeit-Verfolgung automatisch pausiert (über 10 Minuten)',
|
||||
'monitor.error.load_failed': 'Laden fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.error.invalid_params': 'Ungültige Parameter',
|
||||
'monitor.error.clear_dl_failed': 'DeadLetter-Warteschlange löschen fehlgeschlagen',
|
||||
|
||||
// ============ Erfolg ============
|
||||
'success.query_complete': 'Abfrage abgeschlossen',
|
||||
'success.export_complete': 'Export abgeschlossen',
|
||||
'success.template_saved': 'Vorlage "{name}" gespeichert',
|
||||
'success.logs_cleared': 'Protokolle gelöscht',
|
||||
'success.operation_success': 'Operation erfolgreich',
|
||||
'success.dl_cleared': 'DeadLetter-Warteschlange gelöscht',
|
||||
'monitor.success.query_complete': 'Abfrage abgeschlossen',
|
||||
'monitor.success.export_complete': 'Export abgeschlossen',
|
||||
'monitor.success.template_saved': 'Vorlage "{name}" gespeichert',
|
||||
'monitor.success.logs_cleared': 'Protokolle gelöscht',
|
||||
'monitor.success.operation_success': 'Operation erfolgreich',
|
||||
'monitor.success.dl_cleared': 'DeadLetter-Warteschlange gelöscht',
|
||||
|
||||
// ============ Zeitachse ============
|
||||
'timeline.title': 'Zeitachse',
|
||||
'timeline.no_data': 'Keine Daten, bitte zuerst Abfrage ausführen',
|
||||
'timeline.anomaly_detected': '⚠️ {count} Anomalien erkannt',
|
||||
'timeline.error_burst': '{count} aufeinanderfolgende FEHLER-Protokolle',
|
||||
'timeline.slow_anomaly': 'Langsame Anfrage Anomalie ({duration}ms > durchschn. {avg}ms×3)',
|
||||
'timeline.duplicate_error': 'Duplizierter Fehler "{msg}" {count} mal aufgetreten',
|
||||
'timeline.http_request': 'HTTP-Anfrage',
|
||||
'timeline.outbound_request': 'Ausgehende Anfrage',
|
||||
'timeline.system_log': 'Systemprotokoll',
|
||||
'monitor.timeline.title': 'Zeitachse',
|
||||
'monitor.timeline.no_data': 'Keine Daten, bitte zuerst Abfrage ausführen',
|
||||
'monitor.timeline.anomaly_detected': '⚠️ {count} Anomalien erkannt',
|
||||
'monitor.timeline.error_burst': '{count} aufeinanderfolgende FEHLER-Protokolle',
|
||||
'monitor.timeline.slow_anomaly': 'Langsame Anfrage Anomalie ({duration}ms > durchschn. {avg}ms×3)',
|
||||
'monitor.timeline.duplicate_error': 'Duplizierter Fehler "{msg}" {count} mal aufgetreten',
|
||||
'monitor.timeline.http_request': 'HTTP-Anfrage',
|
||||
'monitor.timeline.outbound_request': 'Ausgehende Anfrage',
|
||||
'monitor.timeline.system_log': 'Systemprotokoll',
|
||||
'monitor.timeline.summary_title': '📊 Timeline-Statistiken',
|
||||
'monitor.timeline.total_events': 'Gesamtereignisse',
|
||||
'monitor.timeline.http_requests': 'HTTP-Anfragen',
|
||||
'monitor.timeline.outbound_requests': 'Ausgehende Anfragen',
|
||||
'monitor.timeline.system_logs': 'Systemprotokolle',
|
||||
'monitor.timeline.errors': 'Fehler',
|
||||
'monitor.timeline.warnings': 'Warnungen',
|
||||
'monitor.timeline.slow_requests': 'Langsame Anfragen',
|
||||
|
||||
// ============ Paginierung ============
|
||||
'pagination.page': 'Seite',
|
||||
'pagination.of': 'von',
|
||||
'pagination.items': 'Einträge',
|
||||
'pagination.showing': 'Anzeigen',
|
||||
'pagination.per_page': 'Pro Seite',
|
||||
'pagination.first': 'Erste',
|
||||
'pagination.last': 'Letzte',
|
||||
'pagination.prev': 'Vorherige',
|
||||
'pagination.next': 'Nächste',
|
||||
'pagination.go_to': 'Gehe zu',
|
||||
'monitor.pagination.page': 'Seite',
|
||||
'monitor.pagination.of': 'von',
|
||||
'monitor.pagination.items': 'Einträge',
|
||||
'monitor.pagination.showing': 'Anzeigen',
|
||||
'monitor.pagination.per_page': 'Pro Seite',
|
||||
'monitor.pagination.first': 'Erste',
|
||||
'monitor.pagination.last': 'Letzte',
|
||||
'monitor.pagination.prev': 'Vorherige',
|
||||
'monitor.pagination.next': 'Nächste',
|
||||
'monitor.pagination.go_to': 'Gehe zu',
|
||||
|
||||
// ============ Export ============
|
||||
'export.current_page': 'Aktuelle Seite exportieren',
|
||||
'export.all_data': 'Alle Daten exportieren',
|
||||
'export.format_csv': 'CSV-Format',
|
||||
'export.format_json': 'JSON-Format',
|
||||
'export.select_format': 'Format auswählen',
|
||||
'monitor.export.current_page': 'Aktuelle Seite exportieren',
|
||||
'monitor.export.all_data': 'Alle Daten exportieren',
|
||||
'monitor.export.format_csv': 'CSV-Format',
|
||||
'monitor.export.format_json': 'JSON-Format',
|
||||
'monitor.export.select_format': 'Format auswählen',
|
||||
|
||||
// ============ Vorlagen ============
|
||||
'template.saved_queries': 'Gespeicherte Abfragen...',
|
||||
'template.save': 'Abfrage speichern',
|
||||
'template.manage': 'Vorlagen verwalten',
|
||||
'template.name': 'Vorlagenname',
|
||||
'template.description': 'Beschreibung',
|
||||
'template.delete_confirm': 'Diese Vorlage löschen?',
|
||||
'template.empty': 'Keine gespeicherten Vorlagen',
|
||||
'monitor.template.saved_queries': 'Gespeicherte Abfragen...',
|
||||
'monitor.template.save': 'Abfrage speichern',
|
||||
'monitor.template.manage': 'Vorlagen verwalten',
|
||||
'monitor.template.name': 'Vorlagenname',
|
||||
'monitor.template.description': 'Beschreibung',
|
||||
'monitor.template.delete_confirm': 'Diese Vorlage löschen?',
|
||||
'monitor.template.empty': 'Keine gespeicherten Vorlagen',
|
||||
|
||||
// ============ Statistiken ============
|
||||
'stats.time_range': 'Abfragezeitbereich',
|
||||
'stats.http_requests': 'HTTP-Anfragen',
|
||||
'stats.outbound_requests': 'Ausgehende Anfragen',
|
||||
'stats.system_logs': 'Systemprotokolle',
|
||||
'stats.level_distribution': 'Stufenverteilung',
|
||||
'stats.all_time': 'Gesamte Zeit',
|
||||
'monitor.stats.time_range': 'Abfragezeitbereich',
|
||||
'monitor.stats.http_requests': 'HTTP-Anfragen',
|
||||
'monitor.stats.outbound_requests': 'Ausgehende Anfragen',
|
||||
'monitor.stats.system_logs': 'Systemprotokolle',
|
||||
'monitor.stats.level_distribution': 'Stufenverteilung',
|
||||
'monitor.stats.all_time': 'Gesamte Zeit',
|
||||
|
||||
// ============ Sonstiges ============
|
||||
'other.last_update': 'Letzte Aktualisierung',
|
||||
'other.auto_reconnect': 'Neuverbindung in 5s',
|
||||
'other.waiting_logs': 'Warte auf Protokolldaten...',
|
||||
'other.no_matching_logs': 'Keine passenden Protokolle',
|
||||
'other.precise_mode': 'Präziser Modus',
|
||||
'other.saved_queries': 'Gespeicherte Abfragen...',
|
||||
'other.all_time': 'Gesamte Zeit',
|
||||
'other.linked_query': 'Verknüpfte Abfrage',
|
||||
'other.seconds': 'Sekunden',
|
||||
'other.minutes': 'Minuten',
|
||||
'other.hours': 'Stunden',
|
||||
'other.days': 'Tage',
|
||||
'other.ms': 'ms',
|
||||
'other.times': 'mal',
|
||||
'other.view_detail': 'Details anzeigen',
|
||||
'other.copy': 'Kopieren',
|
||||
'other.expand': 'Ausklappen',
|
||||
'other.collapse': 'Einklappen',
|
||||
'other.show_internal': 'Intern anzeigen',
|
||||
'other.show_read': 'Gelesen anzeigen',
|
||||
'monitor.other.last_update': 'Letzte Aktualisierung',
|
||||
'monitor.other.auto_reconnect': 'Neuverbindung in 5s',
|
||||
'monitor.other.waiting_logs': 'Warte auf Protokolldaten...',
|
||||
'monitor.other.no_matching_logs': 'Keine passenden Protokolle',
|
||||
'monitor.other.precise_mode': 'Präziser Modus',
|
||||
'monitor.other.saved_queries': 'Gespeicherte Abfragen...',
|
||||
'monitor.other.all_time': 'Gesamte Zeit',
|
||||
'monitor.other.linked_query': 'Verknüpfte Abfrage',
|
||||
'monitor.other.seconds': 'Sekunden',
|
||||
'monitor.other.minutes': 'Minuten',
|
||||
'monitor.other.hours': 'Stunden',
|
||||
'monitor.other.days': 'Tage',
|
||||
'monitor.other.ms': 'ms',
|
||||
'monitor.other.times': 'mal',
|
||||
'monitor.other.view_detail': 'Details anzeigen',
|
||||
'monitor.other.copy': 'Kopieren',
|
||||
'monitor.other.expand': 'Ausklappen',
|
||||
'monitor.other.collapse': 'Einklappen',
|
||||
'monitor.other.show_internal': 'Intern anzeigen',
|
||||
'monitor.other.show_read': 'Gelesen anzeigen',
|
||||
|
||||
// ============ Datum ============
|
||||
'date.today': 'Heute',
|
||||
'date.yesterday': 'Gestern',
|
||||
'monitor.date.today': 'Heute',
|
||||
'monitor.date.yesterday': 'Gestern',
|
||||
|
||||
// ============ Sprache ============
|
||||
'lang.select': 'Sprache auswählen',
|
||||
'lang.zh': '中文',
|
||||
'lang.en': 'English',
|
||||
'lang.de': 'Deutsch',
|
||||
'monitor.lang.select': 'Sprache auswählen',
|
||||
'monitor.lang.zh': '中文',
|
||||
'monitor.lang.en': 'English',
|
||||
'monitor.lang.de': 'Deutsch',
|
||||
|
||||
// ============ HTTP-Methoden ============
|
||||
'method.get': 'GET',
|
||||
'method.post': 'POST',
|
||||
'method.put': 'PUT',
|
||||
'method.delete': 'DELETE',
|
||||
'method.patch': 'PATCH',
|
||||
'monitor.method.get': 'GET',
|
||||
'monitor.method.post': 'POST',
|
||||
'monitor.method.put': 'PUT',
|
||||
'monitor.method.delete': 'DELETE',
|
||||
'monitor.method.patch': 'PATCH',
|
||||
|
||||
// ============ Protokollstufen ============
|
||||
'level.debug': 'DEBUG',
|
||||
'level.info': 'INFO',
|
||||
'level.warning': 'WARNING',
|
||||
'level.error': 'ERROR',
|
||||
'level.critical': 'CRITICAL',
|
||||
'monitor.level.debug': 'DEBUG',
|
||||
'monitor.level.info': 'INFO',
|
||||
'monitor.level.warning': 'WARNING',
|
||||
'monitor.level.error': 'ERROR',
|
||||
'monitor.level.critical': 'CRITICAL',
|
||||
|
||||
// ============ Planer ============
|
||||
'scheduler.rule': 'Planungsregel',
|
||||
'scheduler.last_run': 'Letzte Ausführung',
|
||||
'scheduler.max_time': 'Max. Zeit',
|
||||
'scheduler.never_run': 'Nie ausgeführt',
|
||||
'scheduler.default': 'Standard',
|
||||
'scheduler.running': 'Läuft',
|
||||
'scheduler.not_scheduled': 'Nicht geplant',
|
||||
'monitor.scheduler.rule': 'Planungsregel',
|
||||
'monitor.scheduler.last_run': 'Letzte Ausführung',
|
||||
'monitor.scheduler.max_time': 'Max. Zeit',
|
||||
'monitor.scheduler.never_run': 'Nie ausgeführt',
|
||||
'monitor.scheduler.default': 'Standard',
|
||||
'monitor.scheduler.running': 'Läuft',
|
||||
'monitor.scheduler.not_scheduled': 'Nicht geplant',
|
||||
|
||||
// ============ Relative Zeit ============
|
||||
'time.just_now': 'Gerade eben',
|
||||
'time.minutes_ago': 'vor {n} Min.',
|
||||
'time.hours_ago': 'vor {n} Stunden',
|
||||
'time.days_ago': 'vor {n} Tagen',
|
||||
'time.day_before_yesterday': 'Vorgestern',
|
||||
'monitor.time.just_now': 'Gerade eben',
|
||||
'monitor.time.minutes_ago': 'vor {n} Min.',
|
||||
'monitor.time.hours_ago': 'vor {n} Stunden',
|
||||
'monitor.time.days_ago': 'vor {n} Tagen',
|
||||
'monitor.time.day_before_yesterday': 'Vorgestern',
|
||||
|
||||
// ============ Warnungstypen ============
|
||||
'alert.warning': 'Warnung',
|
||||
'alert.error': 'Fehler',
|
||||
'alert.critical': 'Kritisch',
|
||||
'alert.normal': 'Normal',
|
||||
'monitor.alert.warning': 'Warnung',
|
||||
'monitor.alert.error': 'Fehler',
|
||||
'monitor.alert.critical': 'Kritisch',
|
||||
'monitor.alert.normal': 'Normal',
|
||||
|
||||
// ============ Verbindungsstatus ============
|
||||
'connection.failed': 'Verbindung fehlgeschlagen',
|
||||
'connection.reconnecting': 'Verbinde neu',
|
||||
'connection.connected': 'Verbunden',
|
||||
'connection.disconnected': 'Getrennt',
|
||||
'monitor.connection.failed': 'Verbindung fehlgeschlagen',
|
||||
'monitor.connection.reconnecting': 'Verbinde neu',
|
||||
'monitor.connection.connected': 'Verbunden',
|
||||
'monitor.connection.disconnected': 'Getrennt',
|
||||
|
||||
// ============ Überwachungsstatus ============
|
||||
'monitor.paused': '● Überwachung pausiert (inaktiv)',
|
||||
'monitor.panel': 'Überwachungstafel',
|
||||
'monitor.last_update': 'Letzte Aktualisierung',
|
||||
'monitor.reset_stats_confirm': 'Alle Ereignisstatistiken zurücksetzen?',
|
||||
'monitor.monitor.paused': '● Überwachung pausiert (inaktiv)',
|
||||
'monitor.monitor.panel': 'Überwachungstafel',
|
||||
'monitor.monitor.last_update': 'Letzte Aktualisierung',
|
||||
'monitor.monitor.reset_stats_confirm': 'Alle Ereignisstatistiken zurücksetzen?',
|
||||
|
||||
// ============ Hervorhebung ============
|
||||
'highlight.on': 'Hervorgehoben',
|
||||
'highlight.off': 'Hervorheben',
|
||||
'monitor.highlight.on': 'Hervorgehoben',
|
||||
'monitor.highlight.off': 'Hervorheben',
|
||||
|
||||
// ============ Kopieren ============
|
||||
'copy.success': 'Kopiert',
|
||||
'copy.failed': 'Kopieren fehlgeschlagen, bitte manuell kopieren',
|
||||
'copy.error': 'Kopieren fehlgeschlagen',
|
||||
'monitor.copy.success': 'Kopiert',
|
||||
'monitor.copy.failed': 'Kopieren fehlgeschlagen, bitte manuell kopieren',
|
||||
'monitor.copy.error': 'Kopieren fehlgeschlagen',
|
||||
|
||||
// ============ Eingabeaufforderungen ============
|
||||
'prompt.select_date': 'Bitte Datum auswählen',
|
||||
'prompt.fetch_failed': 'Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen',
|
||||
'prompt.fetch_outbound_failed': 'Ausgehende Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen',
|
||||
'prompt.reset_failed': 'Zurücksetzen fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.prompt.select_date': 'Bitte Datum auswählen',
|
||||
'monitor.prompt.fetch_failed': 'Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.prompt.fetch_outbound_failed': 'Ausgehende Anfragedatensätze abrufen fehlgeschlagen, bitte erneut versuchen',
|
||||
'monitor.prompt.reset_failed': 'Zurücksetzen fehlgeschlagen, bitte erneut versuchen',
|
||||
|
||||
// ============ Seitentitel ============
|
||||
'page.http_requests_log': 'HTTP-Anfragedatensätze',
|
||||
'page.outbound_requests_log': 'Ausgehende Anfragedatensätze',
|
||||
'monitor.page.http_requests_log': 'HTTP-Anfragedatensätze',
|
||||
'monitor.page.outbound_requests_log': 'Ausgehende Anfragedatensätze',
|
||||
|
||||
// ============ Zeit ============
|
||||
'time.tomorrow': 'Morgen',
|
||||
'time.day_after_tomorrow': 'Übermorgen',
|
||||
'time.over_24h': 'Über 24 Stunden',
|
||||
'time.expired': 'Abgelaufen',
|
||||
'time.days_hours_later': 'In {days}T {hours}Std.',
|
||||
'time.unknown': 'Unbekannt',
|
||||
'time.month_day': '{day}.{month}.',
|
||||
'monitor.time.tomorrow': 'Morgen',
|
||||
'monitor.time.day_after_tomorrow': 'Übermorgen',
|
||||
'monitor.time.over_24h': 'Über 24 Stunden',
|
||||
'monitor.time.expired': 'Abgelaufen',
|
||||
'monitor.time.days_hours_later': 'In {days}T {hours}Std.',
|
||||
'monitor.time.unknown': 'Unbekannt',
|
||||
'monitor.time.month_day': '{day}.{month}.',
|
||||
|
||||
// ============ Aufgabentypen ============
|
||||
'task.system': 'System',
|
||||
'task.project': 'Projekt',
|
||||
'task.avg_time': 'Durchschn. Ausführungszeit',
|
||||
'monitor.task.system': 'System',
|
||||
'monitor.task.project': 'Projekt',
|
||||
'monitor.task.avg_time': 'Durchschn. Ausführungszeit',
|
||||
|
||||
// ============ Detail-Modal ============
|
||||
'modal.outbound_detail': 'Ausgehende Anfrage-Details',
|
||||
'modal.timestamp': 'Zeitstempel:',
|
||||
'modal.method': 'Methode:',
|
||||
'modal.status_code': 'Statuscode:',
|
||||
'modal.response_time': 'Antwortzeit:',
|
||||
'modal.module': 'Modul:',
|
||||
'modal.error_msg': 'Fehlermeldung:',
|
||||
'monitor.modal.outbound_detail': 'Ausgehende Anfrage-Details',
|
||||
'monitor.modal.timestamp': 'Zeitstempel:',
|
||||
'monitor.modal.method': 'Methode:',
|
||||
'monitor.modal.status_code': 'Statuscode:',
|
||||
'monitor.modal.response_time': 'Antwortzeit:',
|
||||
'monitor.modal.module': 'Modul:',
|
||||
'monitor.modal.error_msg': 'Fehlermeldung:',
|
||||
|
||||
// ============ Anfrage/Antwort-Bereiche ============
|
||||
'section.request_headers': 'Anfrage-Header',
|
||||
'section.request_body': 'Anfrage-Body',
|
||||
'section.response_headers': 'Antwort-Header',
|
||||
'section.response_body': 'Antwort-Body',
|
||||
'section.no_response': 'Keine Antwort-Body-Daten',
|
||||
'section.response_failed': 'Antwort-Body-Verarbeitung fehlgeschlagen: ',
|
||||
'section.truncated': '[Inhalt gekürzt, exportieren für vollständigen Inhalt]',
|
||||
'section.large_data_warning': '⚠️ Große Datenmenge ({count} Zeichen), kann Leistung beeinträchtigen',
|
||||
'section.showing_chars': 'Zeige erste {count} Zeichen',
|
||||
'section.basic_info': 'Grundinformationen',
|
||||
'section.no_data': 'Keine Daten',
|
||||
'monitor.section.request_headers': 'Anfrage-Header',
|
||||
'monitor.section.request_body': 'Anfrage-Body',
|
||||
'monitor.section.response_headers': 'Antwort-Header',
|
||||
'monitor.section.response_body': 'Antwort-Body',
|
||||
'monitor.section.no_response': 'Keine Antwort-Body-Daten',
|
||||
'monitor.section.response_failed': 'Antwort-Body-Verarbeitung fehlgeschlagen: ',
|
||||
'monitor.section.truncated': '[Inhalt gekürzt, exportieren für vollständigen Inhalt]',
|
||||
'monitor.section.large_data_warning': '⚠️ Große Datenmenge ({count} Zeichen), kann Leistung beeinträchtigen',
|
||||
'monitor.section.showing_chars': 'Zeige erste {count} Zeichen',
|
||||
'monitor.section.basic_info': 'Grundinformationen',
|
||||
'monitor.section.no_data': 'Keine Daten',
|
||||
|
||||
// ============ Ratenbegrenzung ============
|
||||
'status.rate_limited': 'Ratenbegrenzt',
|
||||
'monitor.status.rate_limited': 'Ratenbegrenzt',
|
||||
|
||||
// ============ Protokollstufen-Auswahl ============
|
||||
'log_level.all_with_debug': 'Alle Stufen (mit DEBUG)',
|
||||
'log_level.error': 'Fehlerprotokolle',
|
||||
'log_level.warning': 'Warnungsprotokolle',
|
||||
'log_level.info': 'Infoprotokolle',
|
||||
'log_level.debug': 'Debugprotokolle',
|
||||
'monitor.log_level.all_with_debug': 'Alle Stufen (mit DEBUG)',
|
||||
'monitor.log_level.error': 'Fehlerprotokolle',
|
||||
'monitor.log_level.warning': 'Warnungsprotokolle',
|
||||
'monitor.log_level.info': 'Infoprotokolle',
|
||||
'monitor.log_level.debug': 'Debugprotokolle',
|
||||
|
||||
// ============ DeadLetter ============
|
||||
'dl.reprocess': 'Neu verarbeiten',
|
||||
'dl.reprocess_success': 'DeadLetter erfolgreich neu verarbeitet',
|
||||
'dl.reprocess_failed': 'DeadLetter Neuverarbeitung fehlgeschlagen',
|
||||
'monitor.dl.reprocess': 'Neu verarbeiten',
|
||||
'monitor.dl.reprocess_success': 'DeadLetter erfolgreich neu verarbeitet',
|
||||
'monitor.dl.reprocess_failed': 'DeadLetter Neuverarbeitung fehlgeschlagen',
|
||||
|
||||
// ============ Backend-Warnmeldungen-Zuordnung ============
|
||||
'alert.scheduler_not_running': 'Planer läuft nicht',
|
||||
'alert.db_connection_failed': 'Datenbankverbindung fehlgeschlagen',
|
||||
'alert.redis_connection_failed': 'Redis-Verbindung fehlgeschlagen',
|
||||
'alert.event_listener_stopped': 'Ereignis-Listener gestoppt',
|
||||
'alert.binlog_listener_stopped': 'Binlog-Listener gestoppt',
|
||||
'alert.high_error_rate': 'Hohe Fehlerrate',
|
||||
'alert.memory_warning': 'Speichernutzung-Warnung',
|
||||
'alert.cpu_warning': 'CPU-Nutzung-Warnung',
|
||||
'monitor.alert.scheduler_not_running': 'Planer läuft nicht',
|
||||
'monitor.alert.db_connection_failed': 'Datenbankverbindung fehlgeschlagen',
|
||||
'monitor.alert.redis_connection_failed': 'Redis-Verbindung fehlgeschlagen',
|
||||
'monitor.alert.event_listener_stopped': 'Ereignis-Listener gestoppt',
|
||||
'monitor.alert.binlog_listener_stopped': 'Binlog-Listener gestoppt',
|
||||
'monitor.alert.high_error_rate': 'Hohe Fehlerrate',
|
||||
'monitor.alert.memory_warning': 'Speichernutzung-Warnung',
|
||||
'monitor.alert.cpu_warning': 'CPU-Nutzung-Warnung',
|
||||
|
||||
// ================================================================================
|
||||
// MDS-Modul (Daten-Bereitstellungssystem)
|
||||
@@ -659,5 +669,12 @@ window.__i18n_de_DE__ = {
|
||||
'mds.other.tip': 'Hinweis',
|
||||
'mds.other.warning': 'Warnung',
|
||||
'mds.other.error': 'Fehler',
|
||||
'mds.other.success': 'Erfolg'
|
||||
'mds.other.success': 'Erfolg',
|
||||
|
||||
// ============ 补充翻译键 ============
|
||||
'monitor.other.yes': 'Ja',
|
||||
'monitor.other.no': 'Nein',
|
||||
'monitor.other.data_points': 'Datenpunkte',
|
||||
'monitor.col.is_slow': 'Ist langsame Anfrage',
|
||||
'monitor.col.is_error': 'Ist Fehler'
|
||||
};
|
||||
|
||||
+431
-414
@@ -3,497 +3,507 @@
|
||||
*/
|
||||
window.__i18n_en_US__ = {
|
||||
// ============ Page Titles ============
|
||||
'page.title': 'MyAPI System Monitor',
|
||||
'page.live_logs': 'Live Logs - System Monitor',
|
||||
'page.history_logs': 'Log History Query - System Monitor',
|
||||
'monitor.page.title': 'MyAPI System Monitor',
|
||||
'monitor.page.live_logs': 'Live Logs - System Monitor',
|
||||
'monitor.page.history_logs': 'Log History Query - System Monitor',
|
||||
|
||||
// ============ Navigation ============
|
||||
'nav.overview': '📊 Overview',
|
||||
'nav.database': '🗃️ Database',
|
||||
'nav.events': '☎️ Events',
|
||||
'nav.scheduler': '⏰ Scheduler',
|
||||
'nav.http_requests': '📥 HTTP Requests',
|
||||
'nav.outbound_requests': '📤 Outbound',
|
||||
'nav.logs': '📋 Logs',
|
||||
'monitor.nav.overview': '📊 Overview',
|
||||
'monitor.nav.database': '🗃️ Database',
|
||||
'monitor.nav.events': '☎️ Events',
|
||||
'monitor.nav.scheduler': '⏰ Scheduler',
|
||||
'monitor.nav.http_requests': '📥 HTTP Requests',
|
||||
'monitor.nav.outbound_requests': '📤 Outbound',
|
||||
'monitor.nav.logs': '📋 Logs',
|
||||
|
||||
// ============ Tabs ============
|
||||
'tab.overview': 'Overview',
|
||||
'tab.database': 'Database',
|
||||
'tab.events': 'Events',
|
||||
'tab.scheduler': 'Scheduler',
|
||||
'tab.http': 'HTTP Requests',
|
||||
'tab.outbound': 'Outbound',
|
||||
'tab.logs': 'System Logs',
|
||||
'tab.timeline': 'Timeline',
|
||||
'tab.chart': 'Charts',
|
||||
'monitor.tab.overview': 'Overview',
|
||||
'monitor.tab.database': 'Database',
|
||||
'monitor.tab.events': 'Events',
|
||||
'monitor.tab.scheduler': 'Scheduler',
|
||||
'monitor.tab.http': 'HTTP Requests',
|
||||
'monitor.tab.outbound': 'Outbound',
|
||||
'monitor.tab.logs': 'System Logs',
|
||||
'monitor.tab.timeline': 'Timeline',
|
||||
'monitor.tab.chart': 'Charts',
|
||||
|
||||
// ============ Cards ============
|
||||
'card.resource': 'Resource Usage',
|
||||
'card.db_status': 'Database Status',
|
||||
'card.db_connections': 'Database Connections',
|
||||
'card.event_helpers': 'Event Helpers',
|
||||
'card.scheduler': 'Job Scheduler',
|
||||
'card.api_requests': 'HTTP Requests',
|
||||
'card.outbound_requests': 'Outbound Requests',
|
||||
'card.redis': 'Redis Status',
|
||||
'card.event_listener': 'Event Listener',
|
||||
'card.recent_alerts': 'Recent Alerts',
|
||||
'card.mysql': 'MySQL',
|
||||
'card.http_requests_log': 'HTTP Request Records',
|
||||
'card.scheduler_detail': 'Scheduler Details',
|
||||
'card.outbound_requests_log': 'Outbound Request Records',
|
||||
'card.callback_tracker': 'Callback Tracker',
|
||||
'card.event_deduplicator': 'Event Deduplicator',
|
||||
'monitor.card.resource': 'Resource Usage',
|
||||
'monitor.card.db_status': 'Database Status',
|
||||
'monitor.card.db_connections': 'Database Connections',
|
||||
'monitor.card.event_helpers': 'Event Helpers',
|
||||
'monitor.card.scheduler': 'Job Scheduler',
|
||||
'monitor.card.api_requests': 'HTTP Requests',
|
||||
'monitor.card.outbound_requests': 'Outbound Requests',
|
||||
'monitor.card.redis': 'Redis Status',
|
||||
'monitor.card.event_listener': 'Event Listener',
|
||||
'monitor.card.recent_alerts': 'Recent Alerts',
|
||||
'monitor.card.mysql': 'MySQL',
|
||||
'monitor.card.http_requests_log': 'HTTP Request Records',
|
||||
'monitor.card.scheduler_detail': 'Scheduler Details',
|
||||
'monitor.card.outbound_requests_log': 'Outbound Request Records',
|
||||
'monitor.card.callback_tracker': 'Callback Tracker',
|
||||
'monitor.card.event_deduplicator': 'Event Deduplicator',
|
||||
|
||||
// ============ Metrics ============
|
||||
'metric.cpu': 'CPU Usage',
|
||||
'metric.memory': 'Memory Usage',
|
||||
'metric.threads': 'Threads',
|
||||
'metric.uptime': 'Uptime',
|
||||
'metric.total_connections': 'Total Connections',
|
||||
'metric.healthy': 'Healthy',
|
||||
'metric.unhealthy': 'Unhealthy',
|
||||
'metric.degraded': 'Degraded',
|
||||
'metric.total': 'Total',
|
||||
'metric.success': 'Success',
|
||||
'metric.failed': 'Failed',
|
||||
'metric.pending': 'Pending',
|
||||
'metric.active': 'Active',
|
||||
'metric.idle': 'Idle',
|
||||
'metric.unknown': 'Unknown',
|
||||
'metric.warning': 'Warning',
|
||||
'metric.events_received': 'Events Received',
|
||||
'metric.events_processed': 'Events Processed',
|
||||
'metric.events_failed': 'Events Failed',
|
||||
'metric.jobs_running': 'Running Jobs',
|
||||
'metric.jobs_pending': 'Pending Jobs',
|
||||
'metric.requests_total': 'Total Requests',
|
||||
'metric.requests_slow': 'Slow Requests',
|
||||
'metric.requests_error': 'Error Requests',
|
||||
'metric.error_rate': 'Error Rate',
|
||||
'metric.avg_time': 'Avg Response',
|
||||
'metric.connection_status': 'Connection Status',
|
||||
'metric.host': 'Host',
|
||||
'metric.port': 'Port',
|
||||
'metric.database': 'Database',
|
||||
'metric.used_connections': 'Used Connections',
|
||||
'metric.max_connections': 'Max Connections',
|
||||
'metric.connection_usage': 'Connection Usage',
|
||||
'metric.buffer_size': 'Buffer Size',
|
||||
'metric.buffer_threshold': 'Buffer Threshold',
|
||||
'metric.buffer_usage': 'Buffer Usage',
|
||||
'metric.events_interrupted': 'Interrupted',
|
||||
'metric.overall_success_rate': 'Overall Success Rate',
|
||||
'metric.active_event_types': 'Active Event Types',
|
||||
'metric.backpressure_status': 'Backpressure Status',
|
||||
'metric.backpressure_pending': 'Pending Events',
|
||||
'metric.backpressure_usage': 'Backpressure Usage',
|
||||
'metric.event_loop_status': 'Event Loop Status',
|
||||
'metric.pending_callbacks': 'Pending Callbacks',
|
||||
'metric.max_retries': 'Max Retries',
|
||||
'metric.pending_retries': 'Pending Retries',
|
||||
'metric.total_entries': 'Total Entries',
|
||||
'metric.active_items': 'Active Items',
|
||||
'metric.ttl_seconds': 'TTL (seconds)',
|
||||
'metric.max_entries': 'Max Entries',
|
||||
'metric.dl_total': 'DL Total',
|
||||
'metric.recent_dl': 'Recent DL',
|
||||
'metric.process_success_rate': 'Process Success Rate',
|
||||
'metric.scheduler_status': 'Scheduler Status',
|
||||
'metric.job_count': 'Job Count',
|
||||
'metric.pending_events': 'Pending Events',
|
||||
'metric.total_events': 'Total Events',
|
||||
'metric.file_size': 'File Size',
|
||||
'metric.running_status': 'Running Status',
|
||||
'monitor.metric.cpu': 'CPU Usage',
|
||||
'monitor.metric.memory': 'Memory Usage',
|
||||
'monitor.metric.threads': 'Threads',
|
||||
'monitor.metric.uptime': 'Uptime',
|
||||
'monitor.metric.total_connections': 'Total Connections',
|
||||
'monitor.metric.healthy': 'Healthy',
|
||||
'monitor.metric.unhealthy': 'Unhealthy',
|
||||
'monitor.metric.degraded': 'Degraded',
|
||||
'monitor.metric.total': 'Total',
|
||||
'monitor.metric.success': 'Success',
|
||||
'monitor.metric.failed': 'Failed',
|
||||
'monitor.metric.pending': 'Pending',
|
||||
'monitor.metric.active': 'Active',
|
||||
'monitor.metric.idle': 'Idle',
|
||||
'monitor.metric.unknown': 'Unknown',
|
||||
'monitor.metric.warning': 'Warning',
|
||||
'monitor.metric.events_received': 'Events Received',
|
||||
'monitor.metric.events_processed': 'Events Processed',
|
||||
'monitor.metric.events_failed': 'Events Failed',
|
||||
'monitor.metric.jobs_running': 'Running Jobs',
|
||||
'monitor.metric.jobs_pending': 'Pending Jobs',
|
||||
'monitor.metric.requests_total': 'Total Requests',
|
||||
'monitor.metric.requests_slow': 'Slow Requests',
|
||||
'monitor.metric.requests_error': 'Error Requests',
|
||||
'monitor.metric.error_rate': 'Error Rate',
|
||||
'monitor.metric.avg_time': 'Avg Response',
|
||||
'monitor.metric.connection_status': 'Connection Status',
|
||||
'monitor.metric.host': 'Host',
|
||||
'monitor.metric.port': 'Port',
|
||||
'monitor.metric.database': 'Database',
|
||||
'monitor.metric.used_connections': 'Used Connections',
|
||||
'monitor.metric.max_connections': 'Max Connections',
|
||||
'monitor.metric.connection_usage': 'Connection Usage',
|
||||
'monitor.metric.buffer_size': 'Buffer Size',
|
||||
'monitor.metric.buffer_threshold': 'Buffer Threshold',
|
||||
'monitor.metric.buffer_usage': 'Buffer Usage',
|
||||
'monitor.metric.events_interrupted': 'Interrupted',
|
||||
'monitor.metric.overall_success_rate': 'Overall Success Rate',
|
||||
'monitor.metric.active_event_types': 'Active Event Types',
|
||||
'monitor.metric.backpressure_status': 'Backpressure Status',
|
||||
'monitor.metric.backpressure_pending': 'Pending Events',
|
||||
'monitor.metric.backpressure_usage': 'Backpressure Usage',
|
||||
'monitor.metric.event_loop_status': 'Event Loop Status',
|
||||
'monitor.metric.pending_callbacks': 'Pending Callbacks',
|
||||
'monitor.metric.max_retries': 'Max Retries',
|
||||
'monitor.metric.pending_retries': 'Pending Retries',
|
||||
'monitor.metric.total_entries': 'Total Entries',
|
||||
'monitor.metric.active_items': 'Active Items',
|
||||
'monitor.metric.ttl_seconds': 'TTL (seconds)',
|
||||
'monitor.metric.max_entries': 'Max Entries',
|
||||
'monitor.metric.dl_total': 'DL Total',
|
||||
'monitor.metric.recent_dl': 'Recent DL',
|
||||
'monitor.metric.process_success_rate': 'Process Success Rate',
|
||||
'monitor.metric.scheduler_status': 'Scheduler Status',
|
||||
'monitor.metric.job_count': 'Job Count',
|
||||
'monitor.metric.pending_events': 'Pending Events',
|
||||
'monitor.metric.total_events': 'Total Events',
|
||||
'monitor.metric.file_size': 'File Size',
|
||||
'monitor.metric.running_status': 'Running Status',
|
||||
|
||||
// ============ Status ============
|
||||
'status.healthy': '● System Healthy',
|
||||
'status.unhealthy': '● System Unhealthy',
|
||||
'status.degraded': '● System Degraded',
|
||||
'status.running': 'Running',
|
||||
'status.checking': 'Checking',
|
||||
'status.stopped': 'Stopped',
|
||||
'status.loading': 'Loading...',
|
||||
'status.querying': 'Querying...',
|
||||
'status.exporting': 'Exporting...',
|
||||
'status.no_data': 'No data',
|
||||
'status.connected': 'Connected',
|
||||
'status.connecting': 'Connecting...',
|
||||
'status.disconnected': 'Disconnected',
|
||||
'status.reconnecting': 'Reconnecting...',
|
||||
'status.paused': 'Paused',
|
||||
'status.enabled': 'Enabled',
|
||||
'status.disabled': 'Disabled',
|
||||
'status.no_db_connections': 'No database connections',
|
||||
'status.no_scheduler': 'No scheduled tasks',
|
||||
'status.no_http_requests': 'No HTTP requests',
|
||||
'status.no_alerts': 'No alerts',
|
||||
'status.no_logs': 'No logs',
|
||||
'status.no_events': 'No event statistics',
|
||||
'status.no_api_requests': 'No API request records',
|
||||
'status.no_outbound_requests': 'No outbound request records',
|
||||
'status.no_dead_letters': 'No DL',
|
||||
'status.partial_warnings': '● Partial Warnings',
|
||||
'status.monitoring': 'Monitoring',
|
||||
'monitor.status.healthy': '● System Healthy',
|
||||
'monitor.status.unhealthy': '● System Unhealthy',
|
||||
'monitor.status.degraded': '● System Degraded',
|
||||
'monitor.status.running': 'Running',
|
||||
'monitor.status.checking': 'Checking',
|
||||
'monitor.status.stopped': 'Stopped',
|
||||
'monitor.status.loading': 'Loading...',
|
||||
'monitor.status.querying': 'Querying...',
|
||||
'monitor.status.exporting': 'Exporting...',
|
||||
'monitor.status.no_data': 'No data',
|
||||
'monitor.status.connected': 'Connected',
|
||||
'monitor.status.connecting': 'Connecting...',
|
||||
'monitor.status.disconnected': 'Disconnected',
|
||||
'monitor.status.reconnecting': 'Reconnecting...',
|
||||
'monitor.status.paused': 'Paused',
|
||||
'monitor.status.enabled': 'Enabled',
|
||||
'monitor.status.disabled': 'Disabled',
|
||||
'monitor.status.no_db_connections': 'No database connections',
|
||||
'monitor.status.no_scheduler': 'No scheduled tasks',
|
||||
'monitor.status.no_http_requests': 'No HTTP requests',
|
||||
'monitor.status.no_alerts': 'No alerts',
|
||||
'monitor.status.no_logs': 'No logs',
|
||||
'monitor.status.no_events': 'No event statistics',
|
||||
'monitor.status.no_api_requests': 'No API request records',
|
||||
'monitor.status.no_outbound_requests': 'No outbound request records',
|
||||
'monitor.status.no_dead_letters': 'No DL',
|
||||
'monitor.status.partial_warnings': '● Partial Warnings',
|
||||
'monitor.status.monitoring': 'Monitoring',
|
||||
|
||||
// ============ Buttons ============
|
||||
'btn.query': 'Query',
|
||||
'btn.reset': 'Reset',
|
||||
'btn.refresh': 'Refresh',
|
||||
'btn.export': 'Export',
|
||||
'btn.export_csv': 'Export CSV',
|
||||
'btn.export_json': 'Export JSON',
|
||||
'btn.detail': 'Detail',
|
||||
'btn.pause': 'Pause',
|
||||
'btn.resume': 'Resume',
|
||||
'btn.clear': 'Clear',
|
||||
'btn.save': 'Save',
|
||||
'btn.delete': 'Delete',
|
||||
'btn.close': 'Close',
|
||||
'btn.confirm': 'Confirm',
|
||||
'btn.cancel': 'Cancel',
|
||||
'btn.test': 'Test',
|
||||
'btn.apply': 'Apply',
|
||||
'btn.filter': 'Filter',
|
||||
'btn.clear_all': 'Clear All',
|
||||
'btn.realtime_on': 'Realtime: ON',
|
||||
'btn.realtime_off': 'Realtime: OFF',
|
||||
'btn.precise_locate': '± 60s',
|
||||
'btn.precise_cancel': '± 60s - Click to cancel',
|
||||
'btn.reset_stats': 'Reset Stats',
|
||||
'btn.flush_all': 'Flush All',
|
||||
'btn.new_window': 'New Window',
|
||||
'btn.auto_scroll': 'Auto Scroll',
|
||||
'btn.live_logs': 'Live Logs',
|
||||
'btn.history_query': 'History Query',
|
||||
'btn.mark_all_read': 'Mark All Read',
|
||||
'btn.clear_read_status': 'Clear Read Status',
|
||||
'monitor.btn.query': 'Query',
|
||||
'monitor.btn.reset': 'Reset',
|
||||
'monitor.btn.refresh': 'Refresh',
|
||||
'monitor.btn.export': 'Export',
|
||||
'monitor.btn.export_csv': 'Export CSV',
|
||||
'monitor.btn.export_json': 'Export JSON',
|
||||
'monitor.btn.detail': 'Detail',
|
||||
'monitor.btn.pause': 'Pause',
|
||||
'monitor.btn.resume': 'Resume',
|
||||
'monitor.btn.clear': 'Clear',
|
||||
'monitor.btn.save': 'Save',
|
||||
'monitor.btn.delete': 'Delete',
|
||||
'monitor.btn.close': 'Close',
|
||||
'monitor.btn.confirm': 'Confirm',
|
||||
'monitor.btn.cancel': 'Cancel',
|
||||
'monitor.btn.test': 'Test',
|
||||
'monitor.btn.apply': 'Apply',
|
||||
'monitor.btn.filter': 'Filter',
|
||||
'monitor.btn.clear_all': 'Clear All',
|
||||
'monitor.btn.realtime_on': 'Realtime: ON',
|
||||
'monitor.btn.realtime_off': 'Realtime: OFF',
|
||||
'monitor.btn.precise_locate': '± 60s',
|
||||
'monitor.btn.precise_cancel': '± 60s - Click to cancel',
|
||||
'monitor.btn.reset_stats': 'Reset Stats',
|
||||
'monitor.btn.flush_all': 'Flush All',
|
||||
'monitor.btn.new_window': 'New Window',
|
||||
'monitor.btn.auto_scroll': 'Auto Scroll',
|
||||
'monitor.btn.live_logs': 'Live Logs',
|
||||
'monitor.btn.history_query': 'History Query',
|
||||
'monitor.btn.mark_all_read': 'Mark All Read',
|
||||
'monitor.btn.clear_read_status': 'Clear Read Status',
|
||||
|
||||
// ============ Table Columns ============
|
||||
'col.index': '#',
|
||||
'col.time': 'Time',
|
||||
'col.level': 'Level',
|
||||
'col.module': 'Module',
|
||||
'col.message': 'Message',
|
||||
'col.method': 'Method',
|
||||
'col.path': 'Path',
|
||||
'col.url': 'URL',
|
||||
'col.status': 'Status',
|
||||
'col.duration': 'Duration',
|
||||
'col.client_ip': 'Client IP',
|
||||
'col.source': 'Source',
|
||||
'col.function': 'Function',
|
||||
'col.line': 'Line',
|
||||
'col.operation': 'Action',
|
||||
'col.count': 'Count',
|
||||
'col.avg_time': 'Avg Time',
|
||||
'col.max_time': 'Max Time',
|
||||
'col.db_name': 'DB Name',
|
||||
'col.last_check': 'Last Check',
|
||||
'col.current_connections': 'Current',
|
||||
'col.max_connections': 'Max',
|
||||
'col.min_connections': 'Min',
|
||||
'col.idle_connections': 'Idle',
|
||||
'col.used_connections': 'Used',
|
||||
'col.usage': 'Usage',
|
||||
'col.processed_records': 'Processed',
|
||||
'col.timestamp': 'Timestamp',
|
||||
'col.query_params': 'Query Params',
|
||||
'col.error_message': 'Error Message',
|
||||
'col.url': 'URL',
|
||||
'col.is_read': 'Read',
|
||||
'col.description': 'Description',
|
||||
'col.total_received': 'Total Received',
|
||||
'col.pending': 'Pending',
|
||||
'col.processed': 'Processed',
|
||||
'col.interrupted': 'Interrupted',
|
||||
'col.completion_rate': 'Completion Rate',
|
||||
'col.avg_latency': 'Avg Latency',
|
||||
'col.last_action': 'Last Action',
|
||||
'col.id': 'ID',
|
||||
'col.event_type': 'Event Type',
|
||||
'col.table': 'Table',
|
||||
'monitor.col.index': '#',
|
||||
'monitor.col.time': 'Time',
|
||||
'monitor.col.level': 'Level',
|
||||
'monitor.col.module': 'Module',
|
||||
'monitor.col.message': 'Message',
|
||||
'monitor.col.method': 'Method',
|
||||
'monitor.col.path': 'Path',
|
||||
'monitor.col.url': 'URL',
|
||||
'monitor.col.status': 'Status',
|
||||
'monitor.col.duration': 'Duration',
|
||||
'monitor.col.client_ip': 'Client IP',
|
||||
'monitor.col.source': 'Source',
|
||||
'monitor.col.function': 'Function',
|
||||
'monitor.col.line': 'Line',
|
||||
'monitor.col.operation': 'Action',
|
||||
'monitor.col.count': 'Count',
|
||||
'monitor.col.avg_time': 'Avg Time',
|
||||
'monitor.col.max_time': 'Max Time',
|
||||
'monitor.col.db_name': 'DB Name',
|
||||
'monitor.col.last_check': 'Last Check',
|
||||
'monitor.col.current_connections': 'Current',
|
||||
'monitor.col.max_connections': 'Max',
|
||||
'monitor.col.min_connections': 'Min',
|
||||
'monitor.col.idle_connections': 'Idle',
|
||||
'monitor.col.used_connections': 'Used',
|
||||
'monitor.col.usage': 'Usage',
|
||||
'monitor.col.processed_records': 'Processed',
|
||||
'monitor.col.timestamp': 'Timestamp',
|
||||
'monitor.col.query_params': 'Query Params',
|
||||
'monitor.col.error_message': 'Error Message',
|
||||
'monitor.col.url': 'URL',
|
||||
'monitor.col.is_read': 'Read',
|
||||
'monitor.col.description': 'Description',
|
||||
'monitor.col.total_received': 'Total Received',
|
||||
'monitor.col.pending': 'Pending',
|
||||
'monitor.col.processed': 'Processed',
|
||||
'monitor.col.interrupted': 'Interrupted',
|
||||
'monitor.col.completion_rate': 'Completion Rate',
|
||||
'monitor.col.avg_latency': 'Avg Latency',
|
||||
'monitor.col.last_action': 'Last Action',
|
||||
'monitor.col.id': 'ID',
|
||||
'monitor.col.event_type': 'Event Type',
|
||||
'monitor.col.table': 'Table',
|
||||
|
||||
// ============ Quick Time ============
|
||||
'time.start_time': 'Start Time',
|
||||
'time.end_time': 'End Time',
|
||||
'time.last_10m': 'Last 10 min',
|
||||
'time.last_30m': 'Last 30 min',
|
||||
'time.last_1h': 'Last 1 hour',
|
||||
'time.last_6h': 'Last 6 hours',
|
||||
'time.last_24h': 'Last 24 hours',
|
||||
'time.range': 'Time Range',
|
||||
'monitor.time.start_time': 'Start Time',
|
||||
'monitor.time.end_time': 'End Time',
|
||||
'monitor.time.last_10m': 'Last 10 min',
|
||||
'monitor.time.last_30m': 'Last 30 min',
|
||||
'monitor.time.last_1h': 'Last 1 hour',
|
||||
'monitor.time.last_6h': 'Last 6 hours',
|
||||
'monitor.time.last_24h': 'Last 24 hours',
|
||||
'monitor.time.range': 'Time Range',
|
||||
|
||||
// ============ Filters ============
|
||||
'filter.level': 'All Levels',
|
||||
'filter.type': 'All Types',
|
||||
'filter.module': 'Module',
|
||||
'filter.keyword': 'Keyword',
|
||||
'filter.method': 'Method',
|
||||
'filter.client_ip': 'Client IP',
|
||||
'filter.status_range': 'Status Range',
|
||||
'filter.duration_range': 'Duration Range',
|
||||
'filter.advanced': 'Advanced Filters',
|
||||
'filter.collapse': 'Collapse',
|
||||
'filter.expand': 'Expand',
|
||||
'filter.clear': 'Clear',
|
||||
'filter.active': 'Active Filters',
|
||||
'filter.module_placeholder': 'Enter module name',
|
||||
'filter.keyword_placeholder': 'Enter keyword',
|
||||
'filter.ip_placeholder': 'Enter client IP',
|
||||
'filter.status_placeholder': 'e.g.: 400-499',
|
||||
'filter.duration_placeholder': 'e.g.: >1000',
|
||||
'filter.all_logs': 'All Logs',
|
||||
'monitor.filter.level': 'All Levels',
|
||||
'monitor.filter.type': 'All Types',
|
||||
'monitor.filter.module': 'Module',
|
||||
'monitor.filter.keyword': 'Keyword',
|
||||
'monitor.filter.method': 'Method',
|
||||
'monitor.filter.client_ip': 'Client IP',
|
||||
'monitor.filter.status_range': 'Status Range',
|
||||
'monitor.filter.duration_range': 'Duration Range',
|
||||
'monitor.filter.advanced': 'Advanced Filters',
|
||||
'monitor.filter.collapse': 'Collapse',
|
||||
'monitor.filter.expand': 'Expand',
|
||||
'monitor.filter.clear': 'Clear',
|
||||
'monitor.filter.active': 'Active Filters',
|
||||
'monitor.filter.module_placeholder': 'Enter module name',
|
||||
'monitor.filter.keyword_placeholder': 'Enter keyword',
|
||||
'monitor.filter.ip_placeholder': 'Enter client IP',
|
||||
'monitor.filter.status_placeholder': 'e.g.: 400-499',
|
||||
'monitor.filter.duration_placeholder': 'e.g.: >1000',
|
||||
'monitor.filter.all_logs': 'All Logs',
|
||||
|
||||
// ============ Charts ============
|
||||
'chart.request_trend': '📊 Request Trend',
|
||||
'chart.level_distribution': '📊 Log Level Distribution',
|
||||
'chart.status_distribution': '📈 Status Code Distribution',
|
||||
'chart.slow_requests': '⏱️ Slow Requests TOP10',
|
||||
'chart.total_requests': 'Total Requests',
|
||||
'chart.error_count': 'Errors',
|
||||
'chart.slow_count': 'Slow Requests',
|
||||
'chart.log_count': 'Total Logs',
|
||||
'chart.no_slow': '✅ No slow requests',
|
||||
'chart.query_required': 'Please execute query first',
|
||||
'chart.load_failed': '❌ Chart data load failed, please retry',
|
||||
'chart.redis_connections': 'Redis Connection Pool Usage',
|
||||
'chart.redis_buffer': 'Redis Buffer Size Changes',
|
||||
'chart.cpu': 'CPU',
|
||||
'chart.memory': 'Memory',
|
||||
'chart.upload': 'Upload',
|
||||
'chart.download': 'Download',
|
||||
'chart.cpu_memory_axis': 'CPU / Memory (%)',
|
||||
'chart.network_axis': 'Network Upload / Download (KB/s)',
|
||||
'chart.used_connections': 'Used Connections',
|
||||
'chart.buffer_size_mb': 'Buffer Size (MB)',
|
||||
'monitor.chart.request_trend': '📊 Request Trend',
|
||||
'monitor.chart.level_distribution': '📊 Log Level Distribution',
|
||||
'monitor.chart.status_distribution': '📈 Status Code Distribution',
|
||||
'monitor.chart.slow_requests': '⏱️ Slow Requests TOP10',
|
||||
'monitor.chart.total_requests': 'Total Requests',
|
||||
'monitor.chart.error_count': 'Errors',
|
||||
'monitor.chart.slow_count': 'Slow Requests',
|
||||
'monitor.chart.log_count': 'Total Logs',
|
||||
'monitor.chart.no_slow': '✅ No slow requests',
|
||||
'monitor.chart.query_required': 'Please execute query first',
|
||||
'monitor.chart.load_failed': '❌ Chart data load failed, please retry',
|
||||
'monitor.chart.no_data': 'No data',
|
||||
'monitor.chart.no_trend': 'No trend data',
|
||||
'monitor.chart.redis_connections': 'Redis Connection Pool Usage',
|
||||
'monitor.chart.redis_buffer': 'Redis Buffer Size Changes',
|
||||
'monitor.chart.cpu': 'CPU',
|
||||
'monitor.chart.memory': 'Memory',
|
||||
'monitor.chart.upload': 'Upload',
|
||||
'monitor.chart.download': 'Download',
|
||||
'monitor.chart.cpu_memory_axis': 'CPU / Memory (%)',
|
||||
'monitor.chart.network_axis': 'Network Upload / Download (KB/s)',
|
||||
'monitor.chart.used_connections': 'Used Connections',
|
||||
'monitor.chart.buffer_size_mb': 'Buffer Size (MB)',
|
||||
|
||||
// ============ Errors ============
|
||||
'error.time_range_invalid': 'Start time cannot be greater than end time',
|
||||
'error.time_range_required': 'Please select start time and end time',
|
||||
'error.query_failed': 'Query failed, please try again',
|
||||
'error.export_failed': 'Export failed, please retry',
|
||||
'error.connection_failed': 'Connection failed, please refresh page',
|
||||
'error.max_templates': 'Maximum 10 templates allowed, please delete some first',
|
||||
'error.auto_pause': 'Realtime tracking auto-paused (over 10 minutes)',
|
||||
'error.load_failed': 'Load failed, please retry',
|
||||
'error.invalid_params': 'Invalid parameters',
|
||||
'error.clear_dl_failed': 'Failed to clear DeadLetter queue',
|
||||
'monitor.error.time_range_invalid': 'Start time cannot be greater than end time',
|
||||
'monitor.error.time_range_required': 'Please select start time and end time',
|
||||
'monitor.error.query_failed': 'Query failed, please try again',
|
||||
'monitor.error.export_failed': 'Export failed, please retry',
|
||||
'monitor.error.connection_failed': 'Connection failed, please refresh page',
|
||||
'monitor.error.max_templates': 'Maximum 10 templates allowed, please delete some first',
|
||||
'monitor.error.auto_pause': 'Realtime tracking auto-paused (over 10 minutes)',
|
||||
'monitor.error.load_failed': 'Load failed, please retry',
|
||||
'monitor.error.invalid_params': 'Invalid parameters',
|
||||
'monitor.error.clear_dl_failed': 'Failed to clear DeadLetter queue',
|
||||
|
||||
// ============ Success ============
|
||||
'success.query_complete': 'Query Complete',
|
||||
'success.export_complete': 'Export Complete',
|
||||
'success.template_saved': 'Template "{name}" saved',
|
||||
'success.logs_cleared': 'Logs cleared',
|
||||
'success.operation_success': 'Operation successful',
|
||||
'success.dl_cleared': 'DeadLetter queue cleared',
|
||||
'monitor.success.query_complete': 'Query Complete',
|
||||
'monitor.success.export_complete': 'Export Complete',
|
||||
'monitor.success.template_saved': 'Template "{name}" saved',
|
||||
'monitor.success.logs_cleared': 'Logs cleared',
|
||||
'monitor.success.operation_success': 'Operation successful',
|
||||
'monitor.success.dl_cleared': 'DeadLetter queue cleared',
|
||||
|
||||
// ============ Timeline ============
|
||||
'timeline.title': 'Timeline',
|
||||
'timeline.no_data': 'No data, please execute query first',
|
||||
'timeline.anomaly_detected': '⚠️ {count} anomalies detected',
|
||||
'timeline.error_burst': '{count} consecutive ERROR logs',
|
||||
'timeline.slow_anomaly': 'Slow request anomaly ({duration}ms > avg {avg}ms×3)',
|
||||
'timeline.duplicate_error': 'Duplicate error "{msg}" appeared {count} times',
|
||||
'timeline.http_request': 'HTTP Request',
|
||||
'timeline.outbound_request': 'Outbound Request',
|
||||
'timeline.system_log': 'System Log',
|
||||
'monitor.timeline.title': 'Timeline',
|
||||
'monitor.timeline.no_data': 'No data, please execute query first',
|
||||
'monitor.timeline.anomaly_detected': '⚠️ {count} anomalies detected',
|
||||
'monitor.timeline.error_burst': '{count} consecutive ERROR logs',
|
||||
'monitor.timeline.slow_anomaly': 'Slow request anomaly ({duration}ms > avg {avg}ms×3)',
|
||||
'monitor.timeline.duplicate_error': 'Duplicate error "{msg}" appeared {count} times',
|
||||
'monitor.timeline.http_request': 'HTTP Request',
|
||||
'monitor.timeline.outbound_request': 'Outbound Request',
|
||||
'monitor.timeline.system_log': 'System Log',
|
||||
'monitor.timeline.summary_title': '📊 Timeline Statistics',
|
||||
'monitor.timeline.total_events': 'Total Events',
|
||||
'monitor.timeline.http_requests': 'HTTP Requests',
|
||||
'monitor.timeline.outbound_requests': 'Outbound Requests',
|
||||
'monitor.timeline.system_logs': 'System Logs',
|
||||
'monitor.timeline.errors': 'Errors',
|
||||
'monitor.timeline.warnings': 'Warnings',
|
||||
'monitor.timeline.slow_requests': 'Slow Requests',
|
||||
|
||||
// ============ Pagination ============
|
||||
'pagination.page': 'Page',
|
||||
'pagination.of': 'of',
|
||||
'pagination.items': 'items',
|
||||
'pagination.showing': 'Showing',
|
||||
'pagination.per_page': 'Per Page',
|
||||
'pagination.first': 'First',
|
||||
'pagination.last': 'Last',
|
||||
'pagination.prev': 'Previous',
|
||||
'pagination.next': 'Next',
|
||||
'pagination.go_to': 'Go to',
|
||||
'monitor.pagination.page': 'Page',
|
||||
'monitor.pagination.of': 'of',
|
||||
'monitor.pagination.items': 'items',
|
||||
'monitor.pagination.showing': 'Showing',
|
||||
'monitor.pagination.per_page': 'Per Page',
|
||||
'monitor.pagination.first': 'First',
|
||||
'monitor.pagination.last': 'Last',
|
||||
'monitor.pagination.prev': 'Previous',
|
||||
'monitor.pagination.next': 'Next',
|
||||
'monitor.pagination.go_to': 'Go to',
|
||||
|
||||
// ============ Export ============
|
||||
'export.current_page': 'Export Current Page',
|
||||
'export.all_data': 'Export All Data',
|
||||
'export.format_csv': 'CSV Format',
|
||||
'export.format_json': 'JSON Format',
|
||||
'export.select_format': 'Select Format',
|
||||
'monitor.export.current_page': 'Export Current Page',
|
||||
'monitor.export.all_data': 'Export All Data',
|
||||
'monitor.export.format_csv': 'CSV Format',
|
||||
'monitor.export.format_json': 'JSON Format',
|
||||
'monitor.export.select_format': 'Select Format',
|
||||
|
||||
// ============ Templates ============
|
||||
'template.saved_queries': 'Saved Queries...',
|
||||
'template.save': 'Save Query',
|
||||
'template.manage': 'Manage Templates',
|
||||
'template.name': 'Template Name',
|
||||
'template.description': 'Description',
|
||||
'template.delete_confirm': 'Delete this template?',
|
||||
'template.empty': 'No saved templates',
|
||||
'monitor.template.saved_queries': 'Saved Queries...',
|
||||
'monitor.template.save': 'Save Query',
|
||||
'monitor.template.manage': 'Manage Templates',
|
||||
'monitor.template.name': 'Template Name',
|
||||
'monitor.template.description': 'Description',
|
||||
'monitor.template.delete_confirm': 'Delete this template?',
|
||||
'monitor.template.empty': 'No saved templates',
|
||||
|
||||
// ============ Statistics ============
|
||||
'stats.time_range': 'Query Time Range',
|
||||
'stats.http_requests': 'HTTP Requests',
|
||||
'stats.outbound_requests': 'Outbound Requests',
|
||||
'stats.system_logs': 'System Logs',
|
||||
'stats.level_distribution': 'Level Distribution',
|
||||
'stats.all_time': 'All Time',
|
||||
'monitor.stats.time_range': 'Query Time Range',
|
||||
'monitor.stats.http_requests': 'HTTP Requests',
|
||||
'monitor.stats.outbound_requests': 'Outbound Requests',
|
||||
'monitor.stats.system_logs': 'System Logs',
|
||||
'monitor.stats.level_distribution': 'Level Distribution',
|
||||
'monitor.stats.all_time': 'All Time',
|
||||
|
||||
// ============ Others ============
|
||||
'other.last_update': 'Last Update',
|
||||
'other.auto_reconnect': 'reconnect in 5s',
|
||||
'other.waiting_logs': 'Waiting for log data...',
|
||||
'other.no_matching_logs': 'No matching logs',
|
||||
'other.precise_mode': 'Precise Mode',
|
||||
'other.saved_queries': 'Saved Queries...',
|
||||
'other.all_time': 'All Time',
|
||||
'other.linked_query': 'Linked Query',
|
||||
'other.seconds': 'seconds',
|
||||
'other.minutes': 'minutes',
|
||||
'other.hours': 'hours',
|
||||
'other.days': 'days',
|
||||
'other.ms': 'ms',
|
||||
'other.times': 'times',
|
||||
'other.view_detail': 'View Detail',
|
||||
'other.copy': 'Copy',
|
||||
'other.expand': 'Expand',
|
||||
'other.collapse': 'Collapse',
|
||||
'other.show_internal': 'Show Internal',
|
||||
'other.show_read': 'Show Read',
|
||||
'monitor.other.last_update': 'Last Update',
|
||||
'monitor.other.auto_reconnect': 'reconnect in 5s',
|
||||
'monitor.other.waiting_logs': 'Waiting for log data...',
|
||||
'monitor.other.no_matching_logs': 'No matching logs',
|
||||
'monitor.other.precise_mode': 'Precise Mode',
|
||||
'monitor.other.saved_queries': 'Saved Queries...',
|
||||
'monitor.other.all_time': 'All Time',
|
||||
'monitor.other.linked_query': 'Linked Query',
|
||||
'monitor.other.seconds': 'seconds',
|
||||
'monitor.other.minutes': 'minutes',
|
||||
'monitor.other.hours': 'hours',
|
||||
'monitor.other.days': 'days',
|
||||
'monitor.other.ms': 'ms',
|
||||
'monitor.other.times': 'times',
|
||||
'monitor.other.view_detail': 'View Detail',
|
||||
'monitor.other.copy': 'Copy',
|
||||
'monitor.other.expand': 'Expand',
|
||||
'monitor.other.collapse': 'Collapse',
|
||||
'monitor.other.show_internal': 'Show Internal',
|
||||
'monitor.other.show_read': 'Show Read',
|
||||
|
||||
// ============ Date ============
|
||||
'date.today': 'Today',
|
||||
'date.yesterday': 'Yesterday',
|
||||
'monitor.date.today': 'Today',
|
||||
'monitor.date.yesterday': 'Yesterday',
|
||||
|
||||
// ============ Language ============
|
||||
'lang.select': 'Select Language',
|
||||
'lang.zh': '中文',
|
||||
'lang.en': 'English',
|
||||
'lang.de': 'Deutsch',
|
||||
'monitor.lang.select': 'Select Language',
|
||||
'monitor.lang.zh': '中文',
|
||||
'monitor.lang.en': 'English',
|
||||
'monitor.lang.de': 'Deutsch',
|
||||
|
||||
// ============ HTTP Methods ============
|
||||
'method.get': 'GET',
|
||||
'method.post': 'POST',
|
||||
'method.put': 'PUT',
|
||||
'method.delete': 'DELETE',
|
||||
'method.patch': 'PATCH',
|
||||
'monitor.method.get': 'GET',
|
||||
'monitor.method.post': 'POST',
|
||||
'monitor.method.put': 'PUT',
|
||||
'monitor.method.delete': 'DELETE',
|
||||
'monitor.method.patch': 'PATCH',
|
||||
|
||||
// ============ Log Levels ============
|
||||
'level.debug': 'DEBUG',
|
||||
'level.info': 'INFO',
|
||||
'level.warning': 'WARNING',
|
||||
'level.error': 'ERROR',
|
||||
'level.critical': 'CRITICAL',
|
||||
'monitor.level.debug': 'DEBUG',
|
||||
'monitor.level.info': 'INFO',
|
||||
'monitor.level.warning': 'WARNING',
|
||||
'monitor.level.error': 'ERROR',
|
||||
'monitor.level.critical': 'CRITICAL',
|
||||
|
||||
// ============ Scheduler ============
|
||||
'scheduler.rule': 'Schedule Rule',
|
||||
'scheduler.last_run': 'Last Run',
|
||||
'scheduler.max_time': 'Max Time',
|
||||
'scheduler.never_run': 'Never Run',
|
||||
'scheduler.default': 'Default',
|
||||
'scheduler.running': 'Running',
|
||||
'scheduler.not_scheduled': 'Not Scheduled',
|
||||
'monitor.scheduler.rule': 'Schedule Rule',
|
||||
'monitor.scheduler.last_run': 'Last Run',
|
||||
'monitor.scheduler.max_time': 'Max Time',
|
||||
'monitor.scheduler.never_run': 'Never Run',
|
||||
'monitor.scheduler.default': 'Default',
|
||||
'monitor.scheduler.running': 'Running',
|
||||
'monitor.scheduler.not_scheduled': 'Not Scheduled',
|
||||
|
||||
// ============ Relative Time ============
|
||||
'time.just_now': 'Just now',
|
||||
'time.minutes_ago': '{n} min ago',
|
||||
'time.hours_ago': '{n} hours ago',
|
||||
'time.days_ago': '{n} days ago',
|
||||
'time.day_before_yesterday': 'Day before yesterday',
|
||||
'monitor.time.just_now': 'Just now',
|
||||
'monitor.time.minutes_ago': '{n} min ago',
|
||||
'monitor.time.hours_ago': '{n} hours ago',
|
||||
'monitor.time.days_ago': '{n} days ago',
|
||||
'monitor.time.day_before_yesterday': 'Day before yesterday',
|
||||
|
||||
// ============ Alert Types ============
|
||||
'alert.warning': 'Warning',
|
||||
'alert.error': 'Error',
|
||||
'alert.critical': 'Critical',
|
||||
'alert.normal': 'Normal',
|
||||
'monitor.alert.warning': 'Warning',
|
||||
'monitor.alert.error': 'Error',
|
||||
'monitor.alert.critical': 'Critical',
|
||||
'monitor.alert.normal': 'Normal',
|
||||
|
||||
// ============ Connection Status ============
|
||||
'connection.failed': 'Connection Failed',
|
||||
'connection.reconnecting': 'Reconnecting',
|
||||
'connection.connected': 'Connected',
|
||||
'connection.disconnected': 'Disconnected',
|
||||
'monitor.connection.failed': 'Connection Failed',
|
||||
'monitor.connection.reconnecting': 'Reconnecting',
|
||||
'monitor.connection.connected': 'Connected',
|
||||
'monitor.connection.disconnected': 'Disconnected',
|
||||
|
||||
// ============ Monitor Status ============
|
||||
'monitor.paused': '● Monitor paused (inactive)',
|
||||
'monitor.panel': 'Monitor Panel',
|
||||
'monitor.last_update': 'Last Update',
|
||||
'monitor.reset_stats_confirm': 'Reset all event statistics?',
|
||||
'monitor.monitor.paused': '● Monitor paused (inactive)',
|
||||
'monitor.monitor.panel': 'Monitor Panel',
|
||||
'monitor.monitor.last_update': 'Last Update',
|
||||
'monitor.monitor.reset_stats_confirm': 'Reset all event statistics?',
|
||||
|
||||
// ============ Highlight ============
|
||||
'highlight.on': 'Highlighted',
|
||||
'highlight.off': 'Highlight',
|
||||
'monitor.highlight.on': 'Highlighted',
|
||||
'monitor.highlight.off': 'Highlight',
|
||||
|
||||
// ============ Copy ============
|
||||
'copy.success': 'Copied',
|
||||
'copy.failed': 'Copy failed, please copy manually',
|
||||
'copy.error': 'Copy failed',
|
||||
'monitor.copy.success': 'Copied',
|
||||
'monitor.copy.failed': 'Copy failed, please copy manually',
|
||||
'monitor.copy.error': 'Copy failed',
|
||||
|
||||
// ============ Prompts ============
|
||||
'prompt.select_date': 'Please select a date',
|
||||
'prompt.fetch_failed': 'Failed to fetch request records, please try again',
|
||||
'prompt.fetch_outbound_failed': 'Failed to fetch outbound request records, please try again',
|
||||
'prompt.reset_failed': 'Reset failed, please try again',
|
||||
'monitor.prompt.select_date': 'Please select a date',
|
||||
'monitor.prompt.fetch_failed': 'Failed to fetch request records, please try again',
|
||||
'monitor.prompt.fetch_outbound_failed': 'Failed to fetch outbound request records, please try again',
|
||||
'monitor.prompt.reset_failed': 'Reset failed, please try again',
|
||||
|
||||
// ============ Page Titles ============
|
||||
'page.http_requests_log': 'HTTP Request Records',
|
||||
'page.outbound_requests_log': 'Outbound Request Records',
|
||||
'monitor.page.http_requests_log': 'HTTP Request Records',
|
||||
'monitor.page.outbound_requests_log': 'Outbound Request Records',
|
||||
|
||||
// ============ Time ============
|
||||
'time.tomorrow': 'Tomorrow',
|
||||
'time.day_after_tomorrow': 'Day after tomorrow',
|
||||
'time.over_24h': 'Over 24 hours',
|
||||
'time.expired': 'Expired',
|
||||
'time.days_hours_later': '{days}d {hours}h later',
|
||||
'time.unknown': 'Unknown',
|
||||
'time.month_day': '{month}/{day}',
|
||||
'monitor.time.tomorrow': 'Tomorrow',
|
||||
'monitor.time.day_after_tomorrow': 'Day after tomorrow',
|
||||
'monitor.time.over_24h': 'Over 24 hours',
|
||||
'monitor.time.expired': 'Expired',
|
||||
'monitor.time.days_hours_later': '{days}d {hours}h later',
|
||||
'monitor.time.unknown': 'Unknown',
|
||||
'monitor.time.month_day': '{month}/{day}',
|
||||
|
||||
// ============ Task Types ============
|
||||
'task.system': 'System',
|
||||
'task.project': 'Project',
|
||||
'task.avg_time': 'Avg Execution Time',
|
||||
'monitor.task.system': 'System',
|
||||
'monitor.task.project': 'Project',
|
||||
'monitor.task.avg_time': 'Avg Execution Time',
|
||||
|
||||
// ============ Detail Modal ============
|
||||
'modal.outbound_detail': 'Outbound Request Detail',
|
||||
'modal.timestamp': 'Timestamp:',
|
||||
'modal.method': 'Method:',
|
||||
'modal.status_code': 'Status Code:',
|
||||
'modal.response_time': 'Response Time:',
|
||||
'modal.module': 'Module:',
|
||||
'modal.error_msg': 'Error Message:',
|
||||
'monitor.modal.outbound_detail': 'Outbound Request Detail',
|
||||
'monitor.modal.timestamp': 'Timestamp:',
|
||||
'monitor.modal.method': 'Method:',
|
||||
'monitor.modal.status_code': 'Status Code:',
|
||||
'monitor.modal.response_time': 'Response Time:',
|
||||
'monitor.modal.module': 'Module:',
|
||||
'monitor.modal.error_msg': 'Error Message:',
|
||||
|
||||
// ============ Request/Response Sections ============
|
||||
'section.request_headers': 'Request Headers',
|
||||
'section.request_body': 'Request Body',
|
||||
'section.response_headers': 'Response Headers',
|
||||
'section.response_body': 'Response Body',
|
||||
'section.no_response': 'No response body data',
|
||||
'section.response_failed': 'Response body processing failed: ',
|
||||
'section.truncated': '[Content truncated, export to view full content]',
|
||||
'section.large_data_warning': '⚠️ Large data ({count} chars), may affect performance',
|
||||
'section.showing_chars': 'Showing first {count} chars',
|
||||
'section.basic_info': 'Basic Information',
|
||||
'section.no_data': 'No data',
|
||||
'monitor.section.request_headers': 'Request Headers',
|
||||
'monitor.section.request_body': 'Request Body',
|
||||
'monitor.section.response_headers': 'Response Headers',
|
||||
'monitor.section.response_body': 'Response Body',
|
||||
'monitor.section.no_response': 'No response body data',
|
||||
'monitor.section.response_failed': 'Response body processing failed: ',
|
||||
'monitor.section.truncated': '[Content truncated, export to view full content]',
|
||||
'monitor.section.large_data_warning': '⚠️ Large data ({count} chars), may affect performance',
|
||||
'monitor.section.showing_chars': 'Showing first {count} chars',
|
||||
'monitor.section.basic_info': 'Basic Information',
|
||||
'monitor.section.no_data': 'No data',
|
||||
|
||||
// ============ Rate Limiting ============
|
||||
'status.rate_limited': 'Rate Limited',
|
||||
'monitor.status.rate_limited': 'Rate Limited',
|
||||
|
||||
// ============ Log Level Selection ============
|
||||
'log_level.all_with_debug': 'All Levels (with DEBUG)',
|
||||
'log_level.error': 'Error Logs',
|
||||
'log_level.warning': 'Warning Logs',
|
||||
'log_level.info': 'Info Logs',
|
||||
'log_level.debug': 'Debug Logs',
|
||||
'monitor.log_level.all_with_debug': 'All Levels (with DEBUG)',
|
||||
'monitor.log_level.error': 'Error Logs',
|
||||
'monitor.log_level.warning': 'Warning Logs',
|
||||
'monitor.log_level.info': 'Info Logs',
|
||||
'monitor.log_level.debug': 'Debug Logs',
|
||||
|
||||
// ============ DeadLetter ============
|
||||
'dl.reprocess': 'Reprocess',
|
||||
'dl.reprocess_success': 'DeadLetter reprocessed successfully',
|
||||
'dl.reprocess_failed': 'DeadLetter reprocess failed',
|
||||
'monitor.dl.reprocess': 'Reprocess',
|
||||
'monitor.dl.reprocess_success': 'DeadLetter reprocessed successfully',
|
||||
'monitor.dl.reprocess_failed': 'DeadLetter reprocess failed',
|
||||
|
||||
// ============ Backend Alert Message Mapping ============
|
||||
'alert.scheduler_not_running': 'Scheduler not running',
|
||||
'alert.db_connection_failed': 'Database connection failed',
|
||||
'alert.redis_connection_failed': 'Redis connection failed',
|
||||
'alert.event_listener_stopped': 'Event listener stopped',
|
||||
'alert.binlog_listener_stopped': 'Binlog listener stopped',
|
||||
'alert.high_error_rate': 'High error rate',
|
||||
'alert.memory_warning': 'Memory usage warning',
|
||||
'alert.cpu_warning': 'CPU usage warning',
|
||||
'monitor.alert.scheduler_not_running': 'Scheduler not running',
|
||||
'monitor.alert.db_connection_failed': 'Database connection failed',
|
||||
'monitor.alert.redis_connection_failed': 'Redis connection failed',
|
||||
'monitor.alert.event_listener_stopped': 'Event listener stopped',
|
||||
'monitor.alert.binlog_listener_stopped': 'Binlog listener stopped',
|
||||
'monitor.alert.high_error_rate': 'High error rate',
|
||||
'monitor.alert.memory_warning': 'Memory usage warning',
|
||||
'monitor.alert.cpu_warning': 'CPU usage warning',
|
||||
|
||||
// ================================================================================
|
||||
// MDS Module (Data Staging System)
|
||||
@@ -658,5 +668,12 @@ window.__i18n_en_US__ = {
|
||||
'mds.other.tip': 'Tip',
|
||||
'mds.other.warning': 'Warning',
|
||||
'mds.other.error': 'Error',
|
||||
'mds.other.success': 'Success'
|
||||
'mds.other.success': 'Success',
|
||||
|
||||
// ============ 补充翻译键 ============
|
||||
'monitor.other.yes': 'Yes',
|
||||
'monitor.other.no': 'No',
|
||||
'monitor.other.data_points': 'data points',
|
||||
'monitor.col.is_slow': 'Is Slow Request',
|
||||
'monitor.col.is_error': 'Is Error'
|
||||
};
|
||||
|
||||
+431
-414
@@ -4,497 +4,507 @@
|
||||
*/
|
||||
window.__i18n_zh_CN__ = {
|
||||
// ============ 页面标题 ============
|
||||
'page.title': 'MyAPI 系统监控面板',
|
||||
'page.live_logs': '实时日志 - 系统监控',
|
||||
'page.history_logs': '日志历史查询 - 系统监控',
|
||||
'monitor.page.title': 'MyAPI 系统监控面板',
|
||||
'monitor.page.live_logs': '实时日志 - 系统监控',
|
||||
'monitor.page.history_logs': '日志历史查询 - 系统监控',
|
||||
|
||||
// ============ 导航菜单 ============
|
||||
'nav.overview': '📊 Overview',
|
||||
'nav.database': '🗃️ 数据库',
|
||||
'nav.events': '☎️ 事件处理',
|
||||
'nav.scheduler': '⏰ 定时任务',
|
||||
'nav.http_requests': '📥 接收请求',
|
||||
'nav.outbound_requests': '📤 发送请求',
|
||||
'nav.logs': '📋 日志',
|
||||
'monitor.nav.overview': '📊 Overview',
|
||||
'monitor.nav.database': '🗃️ 数据库',
|
||||
'monitor.nav.events': '☎️ 事件处理',
|
||||
'monitor.nav.scheduler': '⏰ 定时任务',
|
||||
'monitor.nav.http_requests': '📥 接收请求',
|
||||
'monitor.nav.outbound_requests': '📤 发送请求',
|
||||
'monitor.nav.logs': '📋 日志',
|
||||
|
||||
// ============ 标签页 ============
|
||||
'tab.overview': '概览',
|
||||
'tab.database': '数据库',
|
||||
'tab.events': '事件处理',
|
||||
'tab.scheduler': '定时任务',
|
||||
'tab.http': '接收请求',
|
||||
'tab.outbound': '发送请求',
|
||||
'tab.logs': '系统日志',
|
||||
'tab.timeline': '时间线',
|
||||
'tab.chart': '图表分析',
|
||||
'monitor.tab.overview': '概览',
|
||||
'monitor.tab.database': '数据库',
|
||||
'monitor.tab.events': '事件处理',
|
||||
'monitor.tab.scheduler': '定时任务',
|
||||
'monitor.tab.http': '接收请求',
|
||||
'monitor.tab.outbound': '发送请求',
|
||||
'monitor.tab.logs': '系统日志',
|
||||
'monitor.tab.timeline': '时间线',
|
||||
'monitor.tab.chart': '图表分析',
|
||||
|
||||
// ============ 卡片标题 ============
|
||||
'card.resource': '资源使用',
|
||||
'card.db_status': '账套状态',
|
||||
'card.db_connections': '数据库连接状态',
|
||||
'card.event_helpers': '事件辅助模块',
|
||||
'card.scheduler': '定时任务调度器',
|
||||
'card.api_requests': 'HTTP请求统计',
|
||||
'card.outbound_requests': '对外HTTP请求',
|
||||
'card.redis': 'Redis状态',
|
||||
'card.event_listener': '事件监听',
|
||||
'card.recent_alerts': '最近告警',
|
||||
'card.mysql': 'MySQL',
|
||||
'card.http_requests_log': '接收请求记录',
|
||||
'card.scheduler_detail': '定时任务详情',
|
||||
'card.outbound_requests_log': '发送请求记录',
|
||||
'card.callback_tracker': '回调跟踪器',
|
||||
'card.event_deduplicator': '事件去重器',
|
||||
'monitor.card.resource': '资源使用',
|
||||
'monitor.card.db_status': '账套状态',
|
||||
'monitor.card.db_connections': '数据库连接状态',
|
||||
'monitor.card.event_helpers': '事件辅助模块',
|
||||
'monitor.card.scheduler': '定时任务调度器',
|
||||
'monitor.card.api_requests': 'HTTP请求统计',
|
||||
'monitor.card.outbound_requests': '对外HTTP请求',
|
||||
'monitor.card.redis': 'Redis状态',
|
||||
'monitor.card.event_listener': '事件监听',
|
||||
'monitor.card.recent_alerts': '最近告警',
|
||||
'monitor.card.mysql': 'MySQL',
|
||||
'monitor.card.http_requests_log': '接收请求记录',
|
||||
'monitor.card.scheduler_detail': '定时任务详情',
|
||||
'monitor.card.outbound_requests_log': '发送请求记录',
|
||||
'monitor.card.callback_tracker': '回调跟踪器',
|
||||
'monitor.card.event_deduplicator': '事件去重器',
|
||||
|
||||
// ============ 指标标签 ============
|
||||
'metric.cpu': 'CPU 使用率',
|
||||
'metric.memory': '内存使用',
|
||||
'metric.threads': '线程数',
|
||||
'metric.uptime': '运行时间',
|
||||
'metric.total_connections': '总连接数',
|
||||
'metric.healthy': '健康',
|
||||
'metric.unhealthy': '异常',
|
||||
'metric.degraded': '降级',
|
||||
'metric.total': '总数',
|
||||
'metric.success': '成功',
|
||||
'metric.failed': '失败',
|
||||
'metric.pending': '待处理',
|
||||
'metric.active': '活跃',
|
||||
'metric.idle': '空闲',
|
||||
'metric.unknown': '未知',
|
||||
'metric.warning': '警告',
|
||||
'metric.events_received': '接收事件',
|
||||
'metric.events_processed': '处理事件',
|
||||
'metric.events_failed': '失败事件',
|
||||
'metric.jobs_running': '运行中任务',
|
||||
'metric.jobs_pending': '待执行任务',
|
||||
'metric.requests_total': '总请求数',
|
||||
'metric.requests_slow': '慢请求',
|
||||
'metric.requests_error': '错误请求',
|
||||
'metric.error_rate': '错误率',
|
||||
'metric.avg_time': '平均响应',
|
||||
'metric.connection_status': '连接状态',
|
||||
'metric.host': '主机',
|
||||
'metric.port': '端口',
|
||||
'metric.database': '数据库',
|
||||
'metric.used_connections': '使用连接数',
|
||||
'metric.max_connections': '最大连接数',
|
||||
'metric.connection_usage': '连接使用率',
|
||||
'metric.buffer_size': '缓冲大小',
|
||||
'metric.buffer_threshold': '缓冲阈值',
|
||||
'metric.buffer_usage': '缓冲使用率',
|
||||
'metric.events_interrupted': '中断处理',
|
||||
'metric.overall_success_rate': '整体成功率',
|
||||
'metric.active_event_types': '活跃事件类型',
|
||||
'metric.backpressure_status': '背压状态',
|
||||
'metric.backpressure_pending': '待处理事件',
|
||||
'metric.backpressure_usage': '背压使用率',
|
||||
'metric.event_loop_status': '事件循环状态',
|
||||
'metric.pending_callbacks': '待处理回调',
|
||||
'metric.max_retries': '最大重试次数',
|
||||
'metric.pending_retries': '待处理重试',
|
||||
'metric.total_entries': '总存储条目',
|
||||
'metric.active_items': '活跃项目',
|
||||
'metric.ttl_seconds': 'TTL (秒)',
|
||||
'metric.max_entries': '最大条目',
|
||||
'metric.dl_total': 'DL总数',
|
||||
'metric.recent_dl': '最近DL',
|
||||
'metric.process_success_rate': '处理成功率',
|
||||
'metric.scheduler_status': '调度器状态',
|
||||
'metric.job_count': '任务数量',
|
||||
'metric.pending_events': '待写入事件',
|
||||
'metric.total_events': '总事件数',
|
||||
'metric.file_size': '文件大小',
|
||||
'metric.running_status': '运行状态',
|
||||
'monitor.metric.cpu': 'CPU 使用率',
|
||||
'monitor.metric.memory': '内存使用',
|
||||
'monitor.metric.threads': '线程数',
|
||||
'monitor.metric.uptime': '运行时间',
|
||||
'monitor.metric.total_connections': '总连接数',
|
||||
'monitor.metric.healthy': '健康',
|
||||
'monitor.metric.unhealthy': '异常',
|
||||
'monitor.metric.degraded': '降级',
|
||||
'monitor.metric.total': '总数',
|
||||
'monitor.metric.success': '成功',
|
||||
'monitor.metric.failed': '失败',
|
||||
'monitor.metric.pending': '待处理',
|
||||
'monitor.metric.active': '活跃',
|
||||
'monitor.metric.idle': '空闲',
|
||||
'monitor.metric.unknown': '未知',
|
||||
'monitor.metric.warning': '警告',
|
||||
'monitor.metric.events_received': '接收事件',
|
||||
'monitor.metric.events_processed': '处理事件',
|
||||
'monitor.metric.events_failed': '失败事件',
|
||||
'monitor.metric.jobs_running': '运行中任务',
|
||||
'monitor.metric.jobs_pending': '待执行任务',
|
||||
'monitor.metric.requests_total': '总请求数',
|
||||
'monitor.metric.requests_slow': '慢请求',
|
||||
'monitor.metric.requests_error': '错误请求',
|
||||
'monitor.metric.error_rate': '错误率',
|
||||
'monitor.metric.avg_time': '平均响应',
|
||||
'monitor.metric.connection_status': '连接状态',
|
||||
'monitor.metric.host': '主机',
|
||||
'monitor.metric.port': '端口',
|
||||
'monitor.metric.database': '数据库',
|
||||
'monitor.metric.used_connections': '使用连接数',
|
||||
'monitor.metric.max_connections': '最大连接数',
|
||||
'monitor.metric.connection_usage': '连接使用率',
|
||||
'monitor.metric.buffer_size': '缓冲大小',
|
||||
'monitor.metric.buffer_threshold': '缓冲阈值',
|
||||
'monitor.metric.buffer_usage': '缓冲使用率',
|
||||
'monitor.metric.events_interrupted': '中断处理',
|
||||
'monitor.metric.overall_success_rate': '整体成功率',
|
||||
'monitor.metric.active_event_types': '活跃事件类型',
|
||||
'monitor.metric.backpressure_status': '背压状态',
|
||||
'monitor.metric.backpressure_pending': '待处理事件',
|
||||
'monitor.metric.backpressure_usage': '背压使用率',
|
||||
'monitor.metric.event_loop_status': '事件循环状态',
|
||||
'monitor.metric.pending_callbacks': '待处理回调',
|
||||
'monitor.metric.max_retries': '最大重试次数',
|
||||
'monitor.metric.pending_retries': '待处理重试',
|
||||
'monitor.metric.total_entries': '总存储条目',
|
||||
'monitor.metric.active_items': '活跃项目',
|
||||
'monitor.metric.ttl_seconds': 'TTL (秒)',
|
||||
'monitor.metric.max_entries': '最大条目',
|
||||
'monitor.metric.dl_total': 'DL总数',
|
||||
'monitor.metric.recent_dl': '最近DL',
|
||||
'monitor.metric.process_success_rate': '处理成功率',
|
||||
'monitor.metric.scheduler_status': '调度器状态',
|
||||
'monitor.metric.job_count': '任务数量',
|
||||
'monitor.metric.pending_events': '待写入事件',
|
||||
'monitor.metric.total_events': '总事件数',
|
||||
'monitor.metric.file_size': '文件大小',
|
||||
'monitor.metric.running_status': '运行状态',
|
||||
|
||||
// ============ 状态 ============
|
||||
'status.healthy': '● 系统正常',
|
||||
'status.unhealthy': '● 系统异常',
|
||||
'status.degraded': '● 系统降级',
|
||||
'status.running': '运行中',
|
||||
'status.checking': '检查中',
|
||||
'status.stopped': '已停止',
|
||||
'status.loading': '加载中...',
|
||||
'status.querying': '查询中...',
|
||||
'status.exporting': '导出中...',
|
||||
'status.no_data': '暂无数据',
|
||||
'status.connected': '已连接',
|
||||
'status.connecting': '连接中...',
|
||||
'status.disconnected': '已断开',
|
||||
'status.reconnecting': '重连中...',
|
||||
'status.paused': '已暂停',
|
||||
'status.enabled': '已启用',
|
||||
'status.disabled': '已禁用',
|
||||
'status.no_db_connections': '暂无数据库连接',
|
||||
'status.no_scheduler': '暂无定时任务',
|
||||
'status.no_http_requests': '暂无接收请求',
|
||||
'status.no_alerts': '暂无告警',
|
||||
'status.no_logs': '暂无日志',
|
||||
'status.no_events': '暂无事件统计',
|
||||
'status.no_api_requests': '暂无 API 请求记录',
|
||||
'status.no_outbound_requests': '暂无发送请求记录',
|
||||
'status.no_dead_letters': '暂无DL',
|
||||
'status.partial_warnings': '● 部分警告',
|
||||
'status.monitoring': '监控中',
|
||||
'monitor.status.healthy': '● 系统正常',
|
||||
'monitor.status.unhealthy': '● 系统异常',
|
||||
'monitor.status.degraded': '● 系统降级',
|
||||
'monitor.status.running': '运行中',
|
||||
'monitor.status.checking': '检查中',
|
||||
'monitor.status.stopped': '已停止',
|
||||
'monitor.status.loading': '加载中...',
|
||||
'monitor.status.querying': '查询中...',
|
||||
'monitor.status.exporting': '导出中...',
|
||||
'monitor.status.no_data': '暂无数据',
|
||||
'monitor.status.connected': '已连接',
|
||||
'monitor.status.connecting': '连接中...',
|
||||
'monitor.status.disconnected': '已断开',
|
||||
'monitor.status.reconnecting': '重连中...',
|
||||
'monitor.status.paused': '已暂停',
|
||||
'monitor.status.enabled': '已启用',
|
||||
'monitor.status.disabled': '已禁用',
|
||||
'monitor.status.no_db_connections': '暂无数据库连接',
|
||||
'monitor.status.no_scheduler': '暂无定时任务',
|
||||
'monitor.status.no_http_requests': '暂无接收请求',
|
||||
'monitor.status.no_alerts': '暂无告警',
|
||||
'monitor.status.no_logs': '暂无日志',
|
||||
'monitor.status.no_events': '暂无事件统计',
|
||||
'monitor.status.no_api_requests': '暂无 API 请求记录',
|
||||
'monitor.status.no_outbound_requests': '暂无发送请求记录',
|
||||
'monitor.status.no_dead_letters': '暂无DL',
|
||||
'monitor.status.partial_warnings': '● 部分警告',
|
||||
'monitor.status.monitoring': '监控中',
|
||||
|
||||
// ============ 按钮 ============
|
||||
'btn.query': '查询',
|
||||
'btn.reset': '重置',
|
||||
'btn.refresh': '刷新',
|
||||
'btn.export': '导出',
|
||||
'btn.export_csv': '导出 CSV',
|
||||
'btn.export_json': '导出 JSON',
|
||||
'btn.detail': '详情',
|
||||
'btn.pause': '暂停',
|
||||
'btn.resume': '继续',
|
||||
'btn.clear': '清空',
|
||||
'btn.save': '保存',
|
||||
'btn.delete': '删除',
|
||||
'btn.close': '关闭',
|
||||
'btn.confirm': '确认',
|
||||
'btn.cancel': '取消',
|
||||
'btn.test': '测试',
|
||||
'btn.apply': '应用',
|
||||
'btn.filter': '过滤',
|
||||
'btn.clear_all': '清空全部',
|
||||
'btn.realtime_on': '实时追踪: 开',
|
||||
'btn.realtime_off': '实时追踪: 关',
|
||||
'btn.precise_locate': '± 60s',
|
||||
'btn.precise_cancel': '± 60s - 点击取消',
|
||||
'btn.reset_stats': '重置统计',
|
||||
'btn.flush_all': '立即刷新所有',
|
||||
'btn.new_window': '新窗口',
|
||||
'btn.auto_scroll': '自动滚动',
|
||||
'btn.live_logs': '实时日志',
|
||||
'btn.history_query': '历史查询',
|
||||
'btn.mark_all_read': '标记全部已读',
|
||||
'btn.clear_read_status': '清空已读状态',
|
||||
'monitor.btn.query': '查询',
|
||||
'monitor.btn.reset': '重置',
|
||||
'monitor.btn.refresh': '刷新',
|
||||
'monitor.btn.export': '导出',
|
||||
'monitor.btn.export_csv': '导出 CSV',
|
||||
'monitor.btn.export_json': '导出 JSON',
|
||||
'monitor.btn.detail': '详情',
|
||||
'monitor.btn.pause': '暂停',
|
||||
'monitor.btn.resume': '继续',
|
||||
'monitor.btn.clear': '清空',
|
||||
'monitor.btn.save': '保存',
|
||||
'monitor.btn.delete': '删除',
|
||||
'monitor.btn.close': '关闭',
|
||||
'monitor.btn.confirm': '确认',
|
||||
'monitor.btn.cancel': '取消',
|
||||
'monitor.btn.test': '测试',
|
||||
'monitor.btn.apply': '应用',
|
||||
'monitor.btn.filter': '过滤',
|
||||
'monitor.btn.clear_all': '清空全部',
|
||||
'monitor.btn.realtime_on': '实时追踪: 开',
|
||||
'monitor.btn.realtime_off': '实时追踪: 关',
|
||||
'monitor.btn.precise_locate': '± 60s',
|
||||
'monitor.btn.precise_cancel': '± 60s - 点击取消',
|
||||
'monitor.btn.reset_stats': '重置统计',
|
||||
'monitor.btn.flush_all': '立即刷新所有',
|
||||
'monitor.btn.new_window': '新窗口',
|
||||
'monitor.btn.auto_scroll': '自动滚动',
|
||||
'monitor.btn.live_logs': '实时日志',
|
||||
'monitor.btn.history_query': '历史查询',
|
||||
'monitor.btn.mark_all_read': '标记全部已读',
|
||||
'monitor.btn.clear_read_status': '清空已读状态',
|
||||
|
||||
// ============ 表格列名 ============
|
||||
'col.index': '序号',
|
||||
'col.time': '时间',
|
||||
'col.level': '级别',
|
||||
'col.module': '模块',
|
||||
'col.message': '消息',
|
||||
'col.method': '方法',
|
||||
'col.path': '端点',
|
||||
'col.url': 'URL',
|
||||
'col.status': '状态码',
|
||||
'col.duration': '响应时间',
|
||||
'col.client_ip': '客户端IP',
|
||||
'col.source': '来源',
|
||||
'col.function': '函数',
|
||||
'col.line': '行号',
|
||||
'col.operation': '操作',
|
||||
'col.count': '数量',
|
||||
'col.avg_time': '平均时间',
|
||||
'col.max_time': '最大时间',
|
||||
'col.db_name': '账套名称',
|
||||
'col.last_check': '最后检查',
|
||||
'col.current_connections': '当前连接',
|
||||
'col.max_connections': '最大连接',
|
||||
'col.min_connections': '最小连接',
|
||||
'col.idle_connections': '空闲连接',
|
||||
'col.used_connections': '使用中连接',
|
||||
'col.usage': '使用率',
|
||||
'col.processed_records': '处理记录',
|
||||
'col.timestamp': '时间戳',
|
||||
'col.query_params': '查询参数',
|
||||
'col.error_message': '错误信息',
|
||||
'col.url': 'URL',
|
||||
'col.is_read': '已读',
|
||||
'col.description': '描述',
|
||||
'col.total_received': '总接收',
|
||||
'col.pending': '待处理',
|
||||
'col.processed': '已处理',
|
||||
'col.interrupted': '中断',
|
||||
'col.completion_rate': '完成率',
|
||||
'col.avg_latency': '平均延迟',
|
||||
'col.last_action': '最后动作',
|
||||
'col.id': 'ID',
|
||||
'col.event_type': '事件类型',
|
||||
'col.table': '表',
|
||||
'monitor.col.index': '序号',
|
||||
'monitor.col.time': '时间',
|
||||
'monitor.col.level': '级别',
|
||||
'monitor.col.module': '模块',
|
||||
'monitor.col.message': '消息',
|
||||
'monitor.col.method': '方法',
|
||||
'monitor.col.path': '端点',
|
||||
'monitor.col.url': 'URL',
|
||||
'monitor.col.status': '状态码',
|
||||
'monitor.col.duration': '响应时间',
|
||||
'monitor.col.client_ip': '客户端IP',
|
||||
'monitor.col.source': '来源',
|
||||
'monitor.col.function': '函数',
|
||||
'monitor.col.line': '行号',
|
||||
'monitor.col.operation': '操作',
|
||||
'monitor.col.count': '数量',
|
||||
'monitor.col.avg_time': '平均时间',
|
||||
'monitor.col.max_time': '最大时间',
|
||||
'monitor.col.db_name': '账套名称',
|
||||
'monitor.col.last_check': '最后检查',
|
||||
'monitor.col.current_connections': '当前连接',
|
||||
'monitor.col.max_connections': '最大连接',
|
||||
'monitor.col.min_connections': '最小连接',
|
||||
'monitor.col.idle_connections': '空闲连接',
|
||||
'monitor.col.used_connections': '使用中连接',
|
||||
'monitor.col.usage': '使用率',
|
||||
'monitor.col.processed_records': '处理记录',
|
||||
'monitor.col.timestamp': '时间戳',
|
||||
'monitor.col.query_params': '查询参数',
|
||||
'monitor.col.error_message': '错误信息',
|
||||
'monitor.col.url': 'URL',
|
||||
'monitor.col.is_read': '已读',
|
||||
'monitor.col.description': '描述',
|
||||
'monitor.col.total_received': '总接收',
|
||||
'monitor.col.pending': '待处理',
|
||||
'monitor.col.processed': '已处理',
|
||||
'monitor.col.interrupted': '中断',
|
||||
'monitor.col.completion_rate': '完成率',
|
||||
'monitor.col.avg_latency': '平均延迟',
|
||||
'monitor.col.last_action': '最后动作',
|
||||
'monitor.col.id': 'ID',
|
||||
'monitor.col.event_type': '事件类型',
|
||||
'monitor.col.table': '表',
|
||||
|
||||
// ============ 快捷时间 ============
|
||||
'time.start_time': '开始时间',
|
||||
'time.end_time': '结束时间',
|
||||
'time.last_10m': '最近10分钟',
|
||||
'time.last_30m': '最近30分钟',
|
||||
'time.last_1h': '最近1小时',
|
||||
'time.last_6h': '最近6小时',
|
||||
'time.last_24h': '最近24小时',
|
||||
'time.range': '时间范围',
|
||||
'monitor.time.start_time': '开始时间',
|
||||
'monitor.time.end_time': '结束时间',
|
||||
'monitor.time.last_10m': '最近10分钟',
|
||||
'monitor.time.last_30m': '最近30分钟',
|
||||
'monitor.time.last_1h': '最近1小时',
|
||||
'monitor.time.last_6h': '最近6小时',
|
||||
'monitor.time.last_24h': '最近24小时',
|
||||
'monitor.time.range': '时间范围',
|
||||
|
||||
// ============ 过滤条件 ============
|
||||
'filter.level': '全部级别',
|
||||
'filter.type': '全部数据',
|
||||
'filter.module': '模块',
|
||||
'filter.keyword': '关键词',
|
||||
'filter.method': '请求方法',
|
||||
'filter.client_ip': '客户端IP',
|
||||
'filter.status_range': '状态码范围',
|
||||
'filter.duration_range': '响应时间范围',
|
||||
'filter.advanced': '高级过滤',
|
||||
'filter.collapse': '收起',
|
||||
'filter.expand': '展开',
|
||||
'filter.clear': '清空',
|
||||
'filter.active': '已激活过滤条件',
|
||||
'filter.module_placeholder': '输入模块名',
|
||||
'filter.keyword_placeholder': '输入关键词搜索',
|
||||
'filter.ip_placeholder': '输入客户端IP',
|
||||
'filter.status_placeholder': '如: 400-499',
|
||||
'filter.duration_placeholder': '如: >1000',
|
||||
'filter.all_logs': '全部日志',
|
||||
'monitor.filter.level': '全部级别',
|
||||
'monitor.filter.type': '全部数据',
|
||||
'monitor.filter.module': '模块',
|
||||
'monitor.filter.keyword': '关键词',
|
||||
'monitor.filter.method': '请求方法',
|
||||
'monitor.filter.client_ip': '客户端IP',
|
||||
'monitor.filter.status_range': '状态码范围',
|
||||
'monitor.filter.duration_range': '响应时间范围',
|
||||
'monitor.filter.advanced': '高级过滤',
|
||||
'monitor.filter.collapse': '收起',
|
||||
'monitor.filter.expand': '展开',
|
||||
'monitor.filter.clear': '清空',
|
||||
'monitor.filter.active': '已激活过滤条件',
|
||||
'monitor.filter.module_placeholder': '输入模块名',
|
||||
'monitor.filter.keyword_placeholder': '输入关键词搜索',
|
||||
'monitor.filter.ip_placeholder': '输入客户端IP',
|
||||
'monitor.filter.status_placeholder': '如: 400-499',
|
||||
'monitor.filter.duration_placeholder': '如: >1000',
|
||||
'monitor.filter.all_logs': '全部日志',
|
||||
|
||||
// ============ 图表 ============
|
||||
'chart.request_trend': '📊 请求量趋势',
|
||||
'chart.level_distribution': '📊 日志级别分布',
|
||||
'chart.status_distribution': '📈 状态码分布',
|
||||
'chart.slow_requests': '⏱️ 慢请求TOP10',
|
||||
'chart.total_requests': '总请求',
|
||||
'chart.error_count': '错误',
|
||||
'chart.slow_count': '慢请求',
|
||||
'chart.log_count': '日志总数',
|
||||
'chart.no_slow': '✅ 无慢请求',
|
||||
'chart.query_required': '请先执行查询',
|
||||
'chart.load_failed': '❌ 图表数据加载失败,请重试',
|
||||
'chart.redis_connections': 'Redis 连接池使用情况',
|
||||
'chart.redis_buffer': 'Redis 缓冲大小变化',
|
||||
'chart.cpu': 'CPU',
|
||||
'chart.memory': '内存',
|
||||
'chart.upload': '上传',
|
||||
'chart.download': '下载',
|
||||
'chart.cpu_memory_axis': 'CPU / 内存 (%)',
|
||||
'chart.network_axis': '网络上传 / 下载 (KB/s)',
|
||||
'chart.used_connections': '使用连接数',
|
||||
'chart.buffer_size_mb': '缓冲大小 (MB)',
|
||||
'monitor.chart.request_trend': '📊 请求量趋势',
|
||||
'monitor.chart.level_distribution': '📊 日志级别分布',
|
||||
'monitor.chart.status_distribution': '📈 状态码分布',
|
||||
'monitor.chart.slow_requests': '⏱️ 慢请求TOP10',
|
||||
'monitor.chart.total_requests': '总请求',
|
||||
'monitor.chart.error_count': '错误',
|
||||
'monitor.chart.slow_count': '慢请求',
|
||||
'monitor.chart.log_count': '日志总数',
|
||||
'monitor.chart.no_slow': '✅ 无慢请求',
|
||||
'monitor.chart.query_required': '请先执行查询',
|
||||
'monitor.chart.load_failed': '❌ 图表数据加载失败,请重试',
|
||||
'monitor.chart.no_data': '无数据',
|
||||
'monitor.chart.no_trend': '无趋势数据',
|
||||
'monitor.chart.redis_connections': 'Redis 连接池使用情况',
|
||||
'monitor.chart.redis_buffer': 'Redis 缓冲大小变化',
|
||||
'monitor.chart.cpu': 'CPU',
|
||||
'monitor.chart.memory': '内存',
|
||||
'monitor.chart.upload': '上传',
|
||||
'monitor.chart.download': '下载',
|
||||
'monitor.chart.cpu_memory_axis': 'CPU / 内存 (%)',
|
||||
'monitor.chart.network_axis': '网络上传 / 下载 (KB/s)',
|
||||
'monitor.chart.used_connections': '使用连接数',
|
||||
'monitor.chart.buffer_size_mb': '缓冲大小 (MB)',
|
||||
|
||||
// ============ 错误提示 ============
|
||||
'error.time_range_invalid': '开始时间不能大于结束时间',
|
||||
'error.time_range_required': '请选择开始时间和结束时间',
|
||||
'error.query_failed': '查询失败,请稍后重试',
|
||||
'error.export_failed': '导出失败,请重试',
|
||||
'error.connection_failed': '连接失败,请刷新页面',
|
||||
'error.max_templates': '最多保存10个模板,请先删除部分模板',
|
||||
'error.auto_pause': '实时追踪已自动暂停(超过10分钟)',
|
||||
'error.load_failed': '加载失败,请重试',
|
||||
'error.invalid_params': '参数错误',
|
||||
'error.clear_dl_failed': '清空DeadLetter队列失败',
|
||||
'monitor.error.time_range_invalid': '开始时间不能大于结束时间',
|
||||
'monitor.error.time_range_required': '请选择开始时间和结束时间',
|
||||
'monitor.error.query_failed': '查询失败,请稍后重试',
|
||||
'monitor.error.export_failed': '导出失败,请重试',
|
||||
'monitor.error.connection_failed': '连接失败,请刷新页面',
|
||||
'monitor.error.max_templates': '最多保存10个模板,请先删除部分模板',
|
||||
'monitor.error.auto_pause': '实时追踪已自动暂停(超过10分钟)',
|
||||
'monitor.error.load_failed': '加载失败,请重试',
|
||||
'monitor.error.invalid_params': '参数错误',
|
||||
'monitor.error.clear_dl_failed': '清空DeadLetter队列失败',
|
||||
|
||||
// ============ 成功提示 ============
|
||||
'success.query_complete': '查询完成',
|
||||
'success.export_complete': '导出完成',
|
||||
'success.template_saved': '模板"{name}"已保存',
|
||||
'success.logs_cleared': '日志已清空',
|
||||
'success.operation_success': '操作成功',
|
||||
'success.dl_cleared': 'DeadLetter队列已清空',
|
||||
'monitor.success.query_complete': '查询完成',
|
||||
'monitor.success.export_complete': '导出完成',
|
||||
'monitor.success.template_saved': '模板"{name}"已保存',
|
||||
'monitor.success.logs_cleared': '日志已清空',
|
||||
'monitor.success.operation_success': '操作成功',
|
||||
'monitor.success.dl_cleared': 'DeadLetter队列已清空',
|
||||
|
||||
// ============ 时间线 ============
|
||||
'timeline.title': '时间线',
|
||||
'timeline.no_data': '暂无数据,请先执行查询',
|
||||
'timeline.anomaly_detected': '⚠️ 发现 {count} 处异常',
|
||||
'timeline.error_burst': '连续{count}条ERROR日志',
|
||||
'timeline.slow_anomaly': '异常慢请求({duration}ms > 平均{avg}ms×3)',
|
||||
'timeline.duplicate_error': '重复错误"{msg}"出现{count}次',
|
||||
'timeline.http_request': 'HTTP请求',
|
||||
'timeline.outbound_request': '发送请求',
|
||||
'timeline.system_log': '系统日志',
|
||||
'monitor.timeline.title': '时间线',
|
||||
'monitor.timeline.no_data': '暂无数据,请先执行查询',
|
||||
'monitor.timeline.anomaly_detected': '⚠️ 发现 {count} 处异常',
|
||||
'monitor.timeline.error_burst': '连续{count}条ERROR日志',
|
||||
'monitor.timeline.slow_anomaly': '异常慢请求({duration}ms > 平均{avg}ms×3)',
|
||||
'monitor.timeline.duplicate_error': '重复错误"{msg}"出现{count}次',
|
||||
'monitor.timeline.http_request': 'HTTP请求',
|
||||
'monitor.timeline.outbound_request': '发送请求',
|
||||
'monitor.timeline.system_log': '系统日志',
|
||||
'monitor.timeline.summary_title': '📊 时间线统计',
|
||||
'monitor.timeline.total_events': '总事件',
|
||||
'monitor.timeline.http_requests': 'HTTP请求',
|
||||
'monitor.timeline.outbound_requests': '发送请求',
|
||||
'monitor.timeline.system_logs': '系统日志',
|
||||
'monitor.timeline.errors': '错误',
|
||||
'monitor.timeline.warnings': '警告',
|
||||
'monitor.timeline.slow_requests': '慢请求',
|
||||
|
||||
// ============ 分页 ============
|
||||
'pagination.page': '页',
|
||||
'pagination.of': '共',
|
||||
'pagination.items': '条',
|
||||
'pagination.showing': '显示',
|
||||
'pagination.per_page': '每页',
|
||||
'pagination.first': '首页',
|
||||
'pagination.last': '末页',
|
||||
'pagination.prev': '上一页',
|
||||
'pagination.next': '下一页',
|
||||
'pagination.go_to': '跳转',
|
||||
'monitor.pagination.page': '页',
|
||||
'monitor.pagination.of': '共',
|
||||
'monitor.pagination.items': '条',
|
||||
'monitor.pagination.showing': '显示',
|
||||
'monitor.pagination.per_page': '每页',
|
||||
'monitor.pagination.first': '首页',
|
||||
'monitor.pagination.last': '末页',
|
||||
'monitor.pagination.prev': '上一页',
|
||||
'monitor.pagination.next': '下一页',
|
||||
'monitor.pagination.go_to': '跳转',
|
||||
|
||||
// ============ 导出 ============
|
||||
'export.current_page': '导出当前页',
|
||||
'export.all_data': '导出全部数据',
|
||||
'export.format_csv': 'CSV格式',
|
||||
'export.format_json': 'JSON格式',
|
||||
'export.select_format': '选择导出格式',
|
||||
'monitor.export.current_page': '导出当前页',
|
||||
'monitor.export.all_data': '导出全部数据',
|
||||
'monitor.export.format_csv': 'CSV格式',
|
||||
'monitor.export.format_json': 'JSON格式',
|
||||
'monitor.export.select_format': '选择导出格式',
|
||||
|
||||
// ============ 查询模板 ============
|
||||
'template.saved_queries': '已保存查询...',
|
||||
'template.save': '保存查询条件',
|
||||
'template.manage': '管理模板',
|
||||
'template.name': '模板名称',
|
||||
'template.description': '描述',
|
||||
'template.delete_confirm': '确定删除该模板?',
|
||||
'template.empty': '暂无保存的模板',
|
||||
'monitor.template.saved_queries': '已保存查询...',
|
||||
'monitor.template.save': '保存查询条件',
|
||||
'monitor.template.manage': '管理模板',
|
||||
'monitor.template.name': '模板名称',
|
||||
'monitor.template.description': '描述',
|
||||
'monitor.template.delete_confirm': '确定删除该模板?',
|
||||
'monitor.template.empty': '暂无保存的模板',
|
||||
|
||||
// ============ 统计信息 ============
|
||||
'stats.time_range': '查询时间范围',
|
||||
'stats.http_requests': '接收请求',
|
||||
'stats.outbound_requests': '发送请求',
|
||||
'stats.system_logs': '系统日志',
|
||||
'stats.level_distribution': '级别分布',
|
||||
'stats.all_time': '全部时间',
|
||||
'monitor.stats.time_range': '查询时间范围',
|
||||
'monitor.stats.http_requests': '接收请求',
|
||||
'monitor.stats.outbound_requests': '发送请求',
|
||||
'monitor.stats.system_logs': '系统日志',
|
||||
'monitor.stats.level_distribution': '级别分布',
|
||||
'monitor.stats.all_time': '全部时间',
|
||||
|
||||
// ============ 其他 ============
|
||||
'other.last_update': '最后更新',
|
||||
'other.auto_reconnect': '5秒后重连',
|
||||
'other.waiting_logs': '正在等待日志数据...',
|
||||
'other.no_matching_logs': '没有匹配的日志',
|
||||
'other.precise_mode': '精确定位',
|
||||
'other.saved_queries': '已保存查询...',
|
||||
'other.all_time': '全部时间',
|
||||
'other.linked_query': '联动查询',
|
||||
'other.seconds': '秒',
|
||||
'other.minutes': '分钟',
|
||||
'other.hours': '小时',
|
||||
'other.days': '天',
|
||||
'other.ms': '毫秒',
|
||||
'other.times': '次',
|
||||
'other.view_detail': '查看详情',
|
||||
'other.copy': '复制',
|
||||
'other.expand': '展开',
|
||||
'other.collapse': '收起',
|
||||
'other.show_internal': '显示内部请求',
|
||||
'other.show_read': '显示已读',
|
||||
'monitor.other.last_update': '最后更新',
|
||||
'monitor.other.auto_reconnect': '5秒后重连',
|
||||
'monitor.other.waiting_logs': '正在等待日志数据...',
|
||||
'monitor.other.no_matching_logs': '没有匹配的日志',
|
||||
'monitor.other.precise_mode': '精确定位',
|
||||
'monitor.other.saved_queries': '已保存查询...',
|
||||
'monitor.other.all_time': '全部时间',
|
||||
'monitor.other.linked_query': '联动查询',
|
||||
'monitor.other.seconds': '秒',
|
||||
'monitor.other.minutes': '分钟',
|
||||
'monitor.other.hours': '小时',
|
||||
'monitor.other.days': '天',
|
||||
'monitor.other.ms': '毫秒',
|
||||
'monitor.other.times': '次',
|
||||
'monitor.other.view_detail': '查看详情',
|
||||
'monitor.other.copy': '复制',
|
||||
'monitor.other.expand': '展开',
|
||||
'monitor.other.collapse': '收起',
|
||||
'monitor.other.show_internal': '显示内部请求',
|
||||
'monitor.other.show_read': '显示已读',
|
||||
|
||||
// ============ 日期 ============
|
||||
'date.today': '今天',
|
||||
'date.yesterday': '昨天',
|
||||
'monitor.date.today': '今天',
|
||||
'monitor.date.yesterday': '昨天',
|
||||
|
||||
// ============ 语言选择 ============
|
||||
'lang.select': '选择语言',
|
||||
'lang.zh': '中文',
|
||||
'lang.en': 'English',
|
||||
'lang.de': 'Deutsch',
|
||||
'monitor.lang.select': '选择语言',
|
||||
'monitor.lang.zh': '中文',
|
||||
'monitor.lang.en': 'English',
|
||||
'monitor.lang.de': 'Deutsch',
|
||||
|
||||
// ============ HTTP方法 ============
|
||||
'method.get': 'GET',
|
||||
'method.post': 'POST',
|
||||
'method.put': 'PUT',
|
||||
'method.delete': 'DELETE',
|
||||
'method.patch': 'PATCH',
|
||||
'monitor.method.get': 'GET',
|
||||
'monitor.method.post': 'POST',
|
||||
'monitor.method.put': 'PUT',
|
||||
'monitor.method.delete': 'DELETE',
|
||||
'monitor.method.patch': 'PATCH',
|
||||
|
||||
// ============ 日志级别 ============
|
||||
'level.debug': 'DEBUG',
|
||||
'level.info': 'INFO',
|
||||
'level.warning': 'WARNING',
|
||||
'level.error': 'ERROR',
|
||||
'level.critical': 'CRITICAL',
|
||||
'monitor.level.debug': 'DEBUG',
|
||||
'monitor.level.info': 'INFO',
|
||||
'monitor.level.warning': 'WARNING',
|
||||
'monitor.level.error': 'ERROR',
|
||||
'monitor.level.critical': 'CRITICAL',
|
||||
|
||||
// ============ 定时任务 ============
|
||||
'scheduler.rule': '定时规则',
|
||||
'scheduler.last_run': '最近执行',
|
||||
'scheduler.max_time': '最大执行时间',
|
||||
'scheduler.never_run': '从未执行',
|
||||
'scheduler.default': '默认',
|
||||
'scheduler.running': '执行中',
|
||||
'scheduler.not_scheduled': '未计划',
|
||||
'monitor.scheduler.rule': '定时规则',
|
||||
'monitor.scheduler.last_run': '最近执行',
|
||||
'monitor.scheduler.max_time': '最大执行时间',
|
||||
'monitor.scheduler.never_run': '从未执行',
|
||||
'monitor.scheduler.default': '默认',
|
||||
'monitor.scheduler.running': '执行中',
|
||||
'monitor.scheduler.not_scheduled': '未计划',
|
||||
|
||||
// ============ 相对时间 ============
|
||||
'time.just_now': '刚刚',
|
||||
'time.minutes_ago': '{n}分钟前',
|
||||
'time.hours_ago': '{n}小时前',
|
||||
'time.days_ago': '{n}天前',
|
||||
'time.day_before_yesterday': '前天',
|
||||
'monitor.time.just_now': '刚刚',
|
||||
'monitor.time.minutes_ago': '{n}分钟前',
|
||||
'monitor.time.hours_ago': '{n}小时前',
|
||||
'monitor.time.days_ago': '{n}天前',
|
||||
'monitor.time.day_before_yesterday': '前天',
|
||||
|
||||
// ============ 告警类型 ============
|
||||
'alert.warning': '警告',
|
||||
'alert.error': '错误',
|
||||
'alert.critical': '严重',
|
||||
'alert.normal': '正常',
|
||||
'monitor.alert.warning': '警告',
|
||||
'monitor.alert.error': '错误',
|
||||
'monitor.alert.critical': '严重',
|
||||
'monitor.alert.normal': '正常',
|
||||
|
||||
// ============ 连接状态 ============
|
||||
'connection.failed': '连接失败',
|
||||
'connection.reconnecting': '重新连接',
|
||||
'connection.connected': '已连接',
|
||||
'connection.disconnected': '断开',
|
||||
'monitor.connection.failed': '连接失败',
|
||||
'monitor.connection.reconnecting': '重新连接',
|
||||
'monitor.connection.connected': '已连接',
|
||||
'monitor.connection.disconnected': '断开',
|
||||
|
||||
// ============ 监控状态 ============
|
||||
'monitor.paused': '● 监控已暂停(长时间未活动)',
|
||||
'monitor.panel': '监控面板',
|
||||
'monitor.last_update': '最后更新',
|
||||
'monitor.reset_stats_confirm': '确定要重置所有事件统计吗?',
|
||||
'monitor.monitor.paused': '● 监控已暂停(长时间未活动)',
|
||||
'monitor.monitor.panel': '监控面板',
|
||||
'monitor.monitor.last_update': '最后更新',
|
||||
'monitor.monitor.reset_stats_confirm': '确定要重置所有事件统计吗?',
|
||||
|
||||
// ============ 高亮操作 ============
|
||||
'highlight.on': '已高亮',
|
||||
'highlight.off': '高亮',
|
||||
'monitor.highlight.on': '已高亮',
|
||||
'monitor.highlight.off': '高亮',
|
||||
|
||||
// ============ 复制操作 ============
|
||||
'copy.success': '已复制',
|
||||
'copy.failed': '复制失败,请手动复制',
|
||||
'copy.error': '复制失败',
|
||||
'monitor.copy.success': '已复制',
|
||||
'monitor.copy.failed': '复制失败,请手动复制',
|
||||
'monitor.copy.error': '复制失败',
|
||||
|
||||
// ============ 选择提示 ============
|
||||
'prompt.select_date': '请选择日期',
|
||||
'prompt.fetch_failed': '获取请求记录失败,请稍后重试',
|
||||
'prompt.fetch_outbound_failed': '获取对外请求记录失败,请稍后重试',
|
||||
'prompt.reset_failed': '重置失败,请重试',
|
||||
'monitor.prompt.select_date': '请选择日期',
|
||||
'monitor.prompt.fetch_failed': '获取请求记录失败,请稍后重试',
|
||||
'monitor.prompt.fetch_outbound_failed': '获取对外请求记录失败,请稍后重试',
|
||||
'monitor.prompt.reset_failed': '重置失败,请重试',
|
||||
|
||||
// ============ 页面标题 ============
|
||||
'page.http_requests_log': '接收请求记录',
|
||||
'page.outbound_requests_log': '发送请求记录',
|
||||
'monitor.page.http_requests_log': '接收请求记录',
|
||||
'monitor.page.outbound_requests_log': '发送请求记录',
|
||||
|
||||
// ============ 时间相关 ============
|
||||
'time.tomorrow': '明天',
|
||||
'time.day_after_tomorrow': '后天',
|
||||
'time.over_24h': '超过24小时',
|
||||
'time.expired': '已过期',
|
||||
'time.days_hours_later': '{days}天{hours}小时后',
|
||||
'time.unknown': '未知',
|
||||
'time.month_day': '{month}月{day}日',
|
||||
'monitor.time.tomorrow': '明天',
|
||||
'monitor.time.day_after_tomorrow': '后天',
|
||||
'monitor.time.over_24h': '超过24小时',
|
||||
'monitor.time.expired': '已过期',
|
||||
'monitor.time.days_hours_later': '{days}天{hours}小时后',
|
||||
'monitor.time.unknown': '未知',
|
||||
'monitor.time.month_day': '{month}月{day}日',
|
||||
|
||||
// ============ 任务类型 ============
|
||||
'task.system': '系统',
|
||||
'task.project': '项目',
|
||||
'task.avg_time': '平均执行时间',
|
||||
'monitor.task.system': '系统',
|
||||
'monitor.task.project': '项目',
|
||||
'monitor.task.avg_time': '平均执行时间',
|
||||
|
||||
// ============ 详情模态框 ============
|
||||
'modal.outbound_detail': '发送请求详情',
|
||||
'modal.timestamp': '时间戳:',
|
||||
'modal.method': '方法:',
|
||||
'modal.status_code': '状态码:',
|
||||
'modal.response_time': '响应时间:',
|
||||
'modal.module': '模块:',
|
||||
'modal.error_msg': '错误信息:',
|
||||
'monitor.modal.outbound_detail': '发送请求详情',
|
||||
'monitor.modal.timestamp': '时间戳:',
|
||||
'monitor.modal.method': '方法:',
|
||||
'monitor.modal.status_code': '状态码:',
|
||||
'monitor.modal.response_time': '响应时间:',
|
||||
'monitor.modal.module': '模块:',
|
||||
'monitor.modal.error_msg': '错误信息:',
|
||||
|
||||
// ============ 请求/响应部分 ============
|
||||
'section.request_headers': '请求头',
|
||||
'section.request_body': '请求体',
|
||||
'section.response_headers': '响应头',
|
||||
'section.response_body': '响应体',
|
||||
'section.no_response': '无响应体数据',
|
||||
'section.response_failed': '响应体处理失败: ',
|
||||
'section.truncated': '[内容已截断,完整内容请导出查看]',
|
||||
'section.large_data_warning': '⚠️ 数据量较大({count}字符),可能影响显示性能',
|
||||
'section.showing_chars': '仅显示前{count}字符',
|
||||
'section.basic_info': '基本信息',
|
||||
'section.no_data': '无数据',
|
||||
'monitor.section.request_headers': '请求头',
|
||||
'monitor.section.request_body': '请求体',
|
||||
'monitor.section.response_headers': '响应头',
|
||||
'monitor.section.response_body': '响应体',
|
||||
'monitor.section.no_response': '无响应体数据',
|
||||
'monitor.section.response_failed': '响应体处理失败: ',
|
||||
'monitor.section.truncated': '[内容已截断,完整内容请导出查看]',
|
||||
'monitor.section.large_data_warning': '⚠️ 数据量较大({count}字符),可能影响显示性能',
|
||||
'monitor.section.showing_chars': '仅显示前{count}字符',
|
||||
'monitor.section.basic_info': '基本信息',
|
||||
'monitor.section.no_data': '无数据',
|
||||
|
||||
// ============ 限流状态 ============
|
||||
'status.rate_limited': '限流',
|
||||
'monitor.status.rate_limited': '限流',
|
||||
|
||||
// ============ 日志级别选择 ============
|
||||
'log_level.all_with_debug': '全部级别 (含DEBUG)',
|
||||
'log_level.error': '错误日志',
|
||||
'log_level.warning': '警告日志',
|
||||
'log_level.info': '信息日志',
|
||||
'log_level.debug': '调试日志',
|
||||
'monitor.log_level.all_with_debug': '全部级别 (含DEBUG)',
|
||||
'monitor.log_level.error': '错误日志',
|
||||
'monitor.log_level.warning': '警告日志',
|
||||
'monitor.log_level.info': '信息日志',
|
||||
'monitor.log_level.debug': '调试日志',
|
||||
|
||||
// ============ DeadLetter ============
|
||||
'dl.reprocess': '重新处理',
|
||||
'dl.reprocess_success': 'DeadLetter重新处理成功',
|
||||
'dl.reprocess_failed': 'DeadLetter重新处理失败',
|
||||
'monitor.dl.reprocess': '重新处理',
|
||||
'monitor.dl.reprocess_success': 'DeadLetter重新处理成功',
|
||||
'monitor.dl.reprocess_failed': 'DeadLetter重新处理失败',
|
||||
|
||||
// ============ 后端告警消息映射 ============
|
||||
'alert.scheduler_not_running': '调度器未运行',
|
||||
'alert.db_connection_failed': '数据库连接失败',
|
||||
'alert.redis_connection_failed': 'Redis连接失败',
|
||||
'alert.event_listener_stopped': '事件监听器已停止',
|
||||
'alert.binlog_listener_stopped': 'Binlog监听器已停止',
|
||||
'alert.high_error_rate': '错误率过高',
|
||||
'alert.memory_warning': '内存使用警告',
|
||||
'alert.cpu_warning': 'CPU使用警告',
|
||||
'monitor.alert.scheduler_not_running': '调度器未运行',
|
||||
'monitor.alert.db_connection_failed': '数据库连接失败',
|
||||
'monitor.alert.redis_connection_failed': 'Redis连接失败',
|
||||
'monitor.alert.event_listener_stopped': '事件监听器已停止',
|
||||
'monitor.alert.binlog_listener_stopped': 'Binlog监听器已停止',
|
||||
'monitor.alert.high_error_rate': '错误率过高',
|
||||
'monitor.alert.memory_warning': '内存使用警告',
|
||||
'monitor.alert.cpu_warning': 'CPU使用警告',
|
||||
|
||||
// ================================================================================
|
||||
// MDS模块 (数据清洗管理系统)
|
||||
@@ -659,5 +669,12 @@ window.__i18n_zh_CN__ = {
|
||||
'mds.other.tip': '提示',
|
||||
'mds.other.warning': '警告',
|
||||
'mds.other.error': '错误',
|
||||
'mds.other.success': '成功'
|
||||
'mds.other.success': '成功',
|
||||
|
||||
// ============ 补充翻译键 ============
|
||||
'monitor.other.yes': '是',
|
||||
'monitor.other.no': '否',
|
||||
'monitor.other.data_points': '个时间点',
|
||||
'monitor.col.is_slow': '是否慢请求',
|
||||
'monitor.col.is_error': '是否错误'
|
||||
};
|
||||
|
||||
+344
-185
@@ -842,8 +842,8 @@
|
||||
<div class="history-logs-container">
|
||||
<div class="history-logs-header">
|
||||
<div class="history-logs-header-left">
|
||||
<h1 data-i18n="page.history_logs">📊 日志历史查询</h1>
|
||||
<span class="badge" id="history-query-badge" data-i18n="other.linked_query">联动查询</span>
|
||||
<h1 data-i18n="monitor.page.history_logs">📊 日志历史查询</h1>
|
||||
<span class="badge" id="history-query-badge" data-i18n="monitor.other.linked_query">联动查询</span>
|
||||
</div>
|
||||
<div class="history-logs-header-right">
|
||||
<select id="lang-selector" class="lang-selector" onchange="i18n.switchLanguage(this.value)">
|
||||
@@ -858,7 +858,7 @@
|
||||
</div>
|
||||
<div class="query-filters">
|
||||
<select id="history-log-level" class="filter-select">
|
||||
<option value="" data-i18n="filter.level">全部级别</option>
|
||||
<option value="" data-i18n="monitor.filter.level">全部级别</option>
|
||||
<option value="DEBUG">≥ DEBUG</option>
|
||||
<option value="INFO">≥ INFO</option>
|
||||
<option value="WARNING">≥ WARNING</option>
|
||||
@@ -866,19 +866,19 @@
|
||||
<option value="CRITICAL">≥ CRITICAL</option>
|
||||
</select>
|
||||
<select id="history-query-type" class="filter-select">
|
||||
<option value="all" data-i18n="filter.type">全部数据</option>
|
||||
<option value="http" data-i18n="tab.http">接收请求</option>
|
||||
<option value="outbound" data-i18n="tab.outbound">发送请求</option>
|
||||
<option value="logs" data-i18n="tab.logs">系统日志</option>
|
||||
<option value="all" data-i18n="monitor.filter.type">全部数据</option>
|
||||
<option value="http" data-i18n="monitor.tab.http">接收请求</option>
|
||||
<option value="outbound" data-i18n="monitor.tab.outbound">发送请求</option>
|
||||
<option value="logs" data-i18n="monitor.tab.logs">系统日志</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('10m')" data-i18n="time.last_10m">10分钟</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('30m')" data-i18n="time.last_30m">30分钟</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('1h')" data-i18n="time.last_1h">1小时</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('6h')" data-i18n="time.last_6h">6小时</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('24h')" data-i18n="time.last_24h">24小时</button>
|
||||
<button class="btn btn-secondary header-btn header-btn-reset" onclick="resetHistoryQuery()" data-i18n="btn.reset">重置</button>
|
||||
<button class="btn btn-primary header-btn" id="query-btn" onclick="executeHistoryQuery()" data-i18n="btn.query">查询</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('10m')" data-i18n="monitor.time.last_10m">10分钟</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('30m')" data-i18n="monitor.time.last_30m">30分钟</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('1h')" data-i18n="monitor.time.last_1h">1小时</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('6h')" data-i18n="monitor.time.last_6h">6小时</button>
|
||||
<button class="btn btn-secondary header-btn" onclick="quickTimeRange('24h')" data-i18n="monitor.time.last_24h">24小时</button>
|
||||
<button class="btn btn-secondary header-btn header-btn-reset" onclick="resetHistoryQuery()" data-i18n="monitor.btn.reset">重置</button>
|
||||
<button class="btn btn-primary header-btn" id="query-btn" onclick="executeHistoryQuery()" data-i18n="monitor.btn.query">查询</button>
|
||||
</div>
|
||||
<div id="precise-mode-container"></div>
|
||||
</div>
|
||||
@@ -887,36 +887,36 @@
|
||||
<div class="history-logs-body">
|
||||
<div class="result-tabs" id="result-tabs" style="display: none;">
|
||||
<div class="result-tabs-left">
|
||||
<button class="tab-btn active" data-tab="logs" onclick="switchResultTab('logs')"><i class="bi bi-journal-text"></i> <span data-i18n="tab.logs">系统日志</span></button>
|
||||
<button class="tab-btn" data-tab="http" onclick="switchResultTab('http')"><i class="bi bi-box-arrow-in-right"></i> <span data-i18n="tab.http">接收请求</span></button>
|
||||
<button class="tab-btn" data-tab="outbound" onclick="switchResultTab('outbound')"><i class="bi bi-box-arrow-right"></i> <span data-i18n="tab.outbound">发送请求</span></button>
|
||||
<button class="tab-btn" data-tab="timeline" onclick="switchResultTab('timeline')"><i class="bi bi-clock-history"></i> <span data-i18n="tab.timeline">时间线</span></button>
|
||||
<button class="tab-btn" data-tab="chart" onclick="switchResultTab('chart')"><i class="bi bi-bar-chart-line"></i> <span data-i18n="tab.chart">图表分析</span></button>
|
||||
<button class="tab-btn active" data-tab="logs" onclick="switchResultTab('logs')"><i class="bi bi-journal-text"></i> <span data-i18n="monitor.tab.logs">系统日志</span></button>
|
||||
<button class="tab-btn" data-tab="http" onclick="switchResultTab('http')"><i class="bi bi-box-arrow-in-right"></i> <span data-i18n="monitor.tab.http">接收请求</span></button>
|
||||
<button class="tab-btn" data-tab="outbound" onclick="switchResultTab('outbound')"><i class="bi bi-box-arrow-right"></i> <span data-i18n="monitor.tab.outbound">发送请求</span></button>
|
||||
<button class="tab-btn" data-tab="timeline" onclick="switchResultTab('timeline')"><i class="bi bi-clock-history"></i> <span data-i18n="monitor.tab.timeline">时间线</span></button>
|
||||
<button class="tab-btn" data-tab="chart" onclick="switchResultTab('chart')"><i class="bi bi-bar-chart-line"></i> <span data-i18n="monitor.tab.chart">图表分析</span></button>
|
||||
</div>
|
||||
<div class="result-tabs-right">
|
||||
<div class="result-summary-inline">
|
||||
<span class="summary-label">接收:</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.http_requests">接收:</span>
|
||||
<span class="badge badge-info" id="http-count">0</span>
|
||||
<span class="summary-label">发送:</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.outbound_requests">发送:</span>
|
||||
<span class="badge badge-info" id="outbound-count">0</span>
|
||||
<span class="summary-label">日志:</span>
|
||||
<span class="summary-label" data-i18n="monitor.tab.logs">日志:</span>
|
||||
<span class="badge badge-info" id="logs-count">0</span>
|
||||
<span class="summary-separator" id="logs-levels-separator" style="display:none;">|</span>
|
||||
<span class="summary-label" id="logs-levels-label" style="display:none;">级别:</span>
|
||||
<span class="summary-label debug" id="logs-debug-label" style="display:none;">DEBUG:</span>
|
||||
<span class="summary-label" id="logs-levels-label" style="display:none;" data-i18n="monitor.col.level">级别:</span>
|
||||
<span class="summary-label debug" id="logs-debug-label" style="display:none;" data-i18n="monitor.level.debug">DEBUG:</span>
|
||||
<span class="badge badge-debug" id="logs-debug-count" style="display:none;">0</span>
|
||||
<span class="summary-label info" id="logs-info-label" style="display:none;">INFO:</span>
|
||||
<span class="summary-label info" id="logs-info-label" style="display:none;" data-i18n="monitor.level.info">INFO:</span>
|
||||
<span class="badge badge-info" id="logs-info-count" style="display:none;">0</span>
|
||||
<span class="summary-label warning" id="logs-warning-label" style="display:none;">WARNING:</span>
|
||||
<span class="summary-label warning" id="logs-warning-label" style="display:none;" data-i18n="monitor.level.warning">WARNING:</span>
|
||||
<span class="badge badge-warning" id="logs-warning-count" style="display:none;">0</span>
|
||||
<span class="summary-label error" id="logs-error-label" style="display:none;">ERROR:</span>
|
||||
<span class="summary-label error" id="logs-error-label" style="display:none;" data-i18n="monitor.level.error">ERROR:</span>
|
||||
<span class="badge badge-error" id="logs-error-count" style="display:none;">0</span>
|
||||
<span class="summary-label critical" id="logs-critical-label" style="display:none;">CRITICAL:</span>
|
||||
<span class="summary-label critical" id="logs-critical-label" style="display:none;" data-i18n="monitor.level.critical">CRITICAL:</span>
|
||||
<span class="badge badge-critical" id="logs-critical-count" style="display:none;">0</span>
|
||||
</div>
|
||||
<div class="export-dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle" onclick="toggleExportMenu()">
|
||||
<i class="bi bi-download"></i> 导出
|
||||
<i class="bi bi-download"></i> <span data-i18n="monitor.btn.export">导出</span>
|
||||
</button>
|
||||
<div class="export-menu" id="export-menu" style="display:none;">
|
||||
<a href="javascript:void(0)" onclick="exportData('logs', 'csv')">导出系统日志 CSV</a>
|
||||
@@ -929,34 +929,34 @@
|
||||
</div>
|
||||
<div class="pagination-container-inline" id="http-pagination" style="display:none;">
|
||||
<select id="http-page-size" class="page-size-select-small" onchange="changePageSize('http')">
|
||||
<option value="50">50条/页</option>
|
||||
<option value="100">100条/页</option>
|
||||
<option value="200">200条/页</option>
|
||||
<option value="500">500条/页</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="200">200</option>
|
||||
<option value="500">500</option>
|
||||
</select>
|
||||
<span class="pagination-text">第 <input type="number" id="http-page-input" class="page-input-small" min="1" onchange="goToPage('http', this.value)"> / <span id="http-total-pages">1</span> 页</span>
|
||||
<span class="pagination-text"><span data-i18n="monitor.pagination.page">Page</span> <input type="number" id="http-page-input" class="page-input-small" min="1" onchange="goToPage('http', this.value)"> / <span id="http-total-pages">1</span></span>
|
||||
<button class="btn-page-small" onclick="goToPrevPage('http')" id="http-prev-btn">‹</button>
|
||||
<button class="btn-page-small" onclick="goToNextPage('http')" id="http-next-btn">›</button>
|
||||
</div>
|
||||
<div class="pagination-container-inline" id="outbound-pagination" style="display:none;">
|
||||
<select id="outbound-page-size" class="page-size-select-small" onchange="changePageSize('outbound')">
|
||||
<option value="50">50条/页</option>
|
||||
<option value="100">100条/页</option>
|
||||
<option value="200">200条/页</option>
|
||||
<option value="500">500条/页</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="200">200</option>
|
||||
<option value="500">500</option>
|
||||
</select>
|
||||
<span class="pagination-text">第 <input type="number" id="outbound-page-input" class="page-input-small" min="1" onchange="goToPage('outbound', this.value)"> / <span id="outbound-total-pages">1</span> 页</span>
|
||||
<span class="pagination-text"><span data-i18n="monitor.pagination.page">Page</span> <input type="number" id="outbound-page-input" class="page-input-small" min="1" onchange="goToPage('outbound', this.value)"> / <span id="outbound-total-pages">1</span></span>
|
||||
<button class="btn-page-small" onclick="goToPrevPage('outbound')" id="outbound-prev-btn">‹</button>
|
||||
<button class="btn-page-small" onclick="goToNextPage('outbound')" id="outbound-next-btn">›</button>
|
||||
</div>
|
||||
<div class="pagination-container-inline" id="logs-pagination" style="display:none;">
|
||||
<select id="logs-page-size" class="page-size-select-small" onchange="changePageSize('logs')">
|
||||
<option value="50">50条/页</option>
|
||||
<option value="100">100条/页</option>
|
||||
<option value="200">200条/页</option>
|
||||
<option value="500">500条/页</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="200">200</option>
|
||||
<option value="500">500</option>
|
||||
</select>
|
||||
<span class="pagination-text">第 <input type="number" id="logs-page-input" class="page-input-small" min="1" onchange="goToPage('logs', this.value)"> / <span id="logs-total-pages">1</span> 页</span>
|
||||
<span class="pagination-text"><span data-i18n="monitor.pagination.page">Page</span> <input type="number" id="logs-page-input" class="page-input-small" min="1" onchange="goToPage('logs', this.value)"> / <span id="logs-total-pages">1</span></span>
|
||||
<button class="btn-page-small" onclick="goToPrevPage('logs')" id="logs-prev-btn">‹</button>
|
||||
<button class="btn-page-small" onclick="goToNextPage('logs')" id="logs-next-btn">›</button>
|
||||
</div>
|
||||
@@ -966,11 +966,11 @@
|
||||
<div class="result-tab-content" id="tab-http">
|
||||
<div class="tab-filters">
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">关键词:</label>
|
||||
<label class="filter-label" data-i18n="monitor.filter.keyword">关键词:</label>
|
||||
<input type="text" id="filter-keyword-http" class="filter-input" placeholder="搜索路径/请求体/响应体" style="width:300px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">方法:</label>
|
||||
<label class="filter-label" data-i18n="monitor.filter.method">方法:</label>
|
||||
<select id="filter-method" class="filter-select" style="width:90px;">
|
||||
<option value="">全部</option>
|
||||
<option value="GET">GET</option>
|
||||
@@ -981,11 +981,11 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">IP:</label>
|
||||
<label class="filter-label" data-i18n="monitor.filter.client_ip">IP:</label>
|
||||
<input type="text" id="filter-client-ip" class="filter-input" placeholder="如:192.168.1.1" style="min-width:100px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">状态码:</label>
|
||||
<label class="filter-label" data-i18n="monitor.col.status_code">状态码:</label>
|
||||
<div class="range-input-group">
|
||||
<input type="number" id="filter-status-min" class="filter-input-small" placeholder="最小" min="100" max="999" style="width:90px;">
|
||||
<span class="range-separator">-</span>
|
||||
@@ -993,7 +993,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">耗时(ms):</label>
|
||||
<label class="filter-label" data-i18n="monitor.col.duration">耗时(ms):</label>
|
||||
<div class="range-input-group">
|
||||
<input type="number" id="filter-duration-min" class="filter-input-small" placeholder="最小" min="0" style="width:90px;">
|
||||
<span class="range-separator">-</span>
|
||||
@@ -1005,25 +1005,25 @@
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<select id="saved-templates" class="filter-select" onchange="loadQueryTemplate()" style="max-width:120px;">
|
||||
<option value="" data-i18n="template.saved_queries">已保存查询...</option>
|
||||
<option value="" data-i18n="monitor.template.saved_queries">已保存查询...</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<table class="history-table" id="http-results-table" data-result-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>时间</th>
|
||||
<th>方法</th>
|
||||
<th>端点</th>
|
||||
<th>状态码</th>
|
||||
<th>响应时间</th>
|
||||
<th>客户端IP</th>
|
||||
<th>操作</th>
|
||||
<th data-i18n="monitor.col.index">序号</th>
|
||||
<th data-i18n="monitor.col.time">时间</th>
|
||||
<th data-i18n="monitor.col.method">方法</th>
|
||||
<th data-i18n="monitor.col.path">端点</th>
|
||||
<th data-i18n="monitor.col.status_code">状态码</th>
|
||||
<th data-i18n="monitor.col.duration">响应时间</th>
|
||||
<th data-i18n="monitor.col.client_ip">客户端IP</th>
|
||||
<th data-i18n="monitor.col.operation">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="http-results-body">
|
||||
<tr><td colspan="8" class="no-data" data-i18n="status.no_data">暂无数据</td></tr>
|
||||
<tr><td colspan="8" class="no-data" data-i18n="monitor.status.no_data">暂无数据</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1031,11 +1031,11 @@
|
||||
<div class="result-tab-content" id="tab-outbound">
|
||||
<div class="tab-filters">
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">关键词:</label>
|
||||
<label class="filter-label" data-i18n="monitor.filter.keyword">关键词:</label>
|
||||
<input type="text" id="filter-keyword-outbound" class="filter-input" placeholder="搜索URL/请求体/响应体" style="width:300px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">方法:</label>
|
||||
<label class="filter-label" data-i18n="monitor.filter.method">方法:</label>
|
||||
<select id="filter-method-outbound" class="filter-select" style="width:90px;">
|
||||
<option value="">全部</option>
|
||||
<option value="GET">GET</option>
|
||||
@@ -1046,7 +1046,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">状态码:</label>
|
||||
<label class="filter-label" data-i18n="monitor.col.status_code">状态码:</label>
|
||||
<div class="range-input-group">
|
||||
<input type="number" id="filter-status-min-outbound" class="filter-input-small" placeholder="最小" min="100" max="999" style="width:90px;">
|
||||
<span class="range-separator">-</span>
|
||||
@@ -1054,7 +1054,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">耗时(ms):</label>
|
||||
<label class="filter-label" data-i18n="monitor.col.duration">耗时(ms):</label>
|
||||
<div class="range-input-group">
|
||||
<input type="number" id="filter-duration-min-outbound" class="filter-input-small" placeholder="最小" min="0" style="width:90px;">
|
||||
<span class="range-separator">-</span>
|
||||
@@ -1065,18 +1065,18 @@
|
||||
<table class="history-table" id="outbound-results-table" data-result-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>时间</th>
|
||||
<th>方法</th>
|
||||
<th>URL</th>
|
||||
<th>状态码</th>
|
||||
<th>响应时间</th>
|
||||
<th>模块</th>
|
||||
<th>操作</th>
|
||||
<th data-i18n="monitor.col.index">序号</th>
|
||||
<th data-i18n="monitor.col.time">时间</th>
|
||||
<th data-i18n="monitor.col.method">方法</th>
|
||||
<th data-i18n="monitor.col.URL">URL</th>
|
||||
<th data-i18n="monitor.col.status_code">状态码</th>
|
||||
<th data-i18n="monitor.col.duration">响应时间</th>
|
||||
<th data-i18n="monitor.col.模块">模块</th>
|
||||
<th data-i18n="monitor.col.operation">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="outbound-results-body">
|
||||
<tr><td colspan="8" class="no-data" data-i18n="status.no_data">暂无数据</td></tr>
|
||||
<tr><td colspan="8" class="no-data" data-i18n="monitor.status.no_data">暂无数据</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1084,27 +1084,27 @@
|
||||
<div class="result-tab-content active" id="tab-logs">
|
||||
<div class="tab-filters">
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">关键词:</label>
|
||||
<input type="text" id="filter-keyword" class="filter-input" placeholder="搜索消息内容" style="width:300px;">
|
||||
<label class="filter-label" data-i18n="monitor.filter.keyword">关键词:</label>
|
||||
<input type="text" id="filter-keyword" class="filter-input" data-i18n-placeholder="monitor.filter.keyword_placeholder" placeholder="搜索消息内容" style="width:300px;">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label class="filter-label">模块:</label>
|
||||
<input type="text" id="filter-module" class="filter-input" placeholder="多个用逗号分隔" style="min-width:300px;">
|
||||
<label class="filter-label" data-i18n="monitor.filter.module">模块:</label>
|
||||
<input type="text" id="filter-module" class="filter-input" data-i18n-placeholder="monitor.filter.module_placeholder" placeholder="多个用逗号分隔" style="min-width:300px;">
|
||||
</div>
|
||||
</div>
|
||||
<table class="history-table" id="logs-results-table" data-result-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>时间</th>
|
||||
<th>级别</th>
|
||||
<th>模块</th>
|
||||
<th>消息</th>
|
||||
<th>操作</th>
|
||||
<th data-i18n="monitor.col.index">序号</th>
|
||||
<th data-i18n="monitor.col.time">时间</th>
|
||||
<th data-i18n="monitor.col.level">级别</th>
|
||||
<th data-i18n="monitor.col.module">模块</th>
|
||||
<th data-i18n="monitor.col.message">消息</th>
|
||||
<th data-i18n="monitor.col.operation">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="logs-results-body">
|
||||
<tr><td colspan="6" class="no-data" data-i18n="status.no_data">暂无数据</td></tr>
|
||||
<tr><td colspan="6" class="no-data" data-i18n="monitor.status.no_data">暂无数据</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1112,7 +1112,7 @@
|
||||
<!-- 时间线标签页 -->
|
||||
<div class="result-tab-content" id="tab-timeline">
|
||||
<div class="timeline-container" id="timeline-container">
|
||||
<div class="timeline-empty" data-i18n="timeline.no_data">暂无数据,请先执行查询</div>
|
||||
<div class="timeline-empty" data-i18n="monitor.timeline.no_data">暂无数据,请先执行查询</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1121,21 +1121,21 @@
|
||||
<div class="chart-container">
|
||||
<div class="chart-row">
|
||||
<div class="chart-card">
|
||||
<h4>请求量趋势</h4>
|
||||
<h4 data-i18n="monitor.chart.request_trend">📊 请求量趋势</h4>
|
||||
<canvas id="chart-trend"></canvas>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h4>日志级别分布</h4>
|
||||
<h4 data-i18n="monitor.chart.level_distribution">📊 日志级别分布</h4>
|
||||
<canvas id="chart-levels"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-row">
|
||||
<div class="chart-card">
|
||||
<h4>状态码分布</h4>
|
||||
<h4 data-i18n="monitor.chart.status_distribution">📈 状态码分布</h4>
|
||||
<canvas id="chart-status"></canvas>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h4>慢请求TOP10</h4>
|
||||
<h4 data-i18n="monitor.chart.slow_requests">⏱️ 慢请求TOP10</h4>
|
||||
<canvas id="chart-slow"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1181,7 +1181,7 @@
|
||||
const endDate = new Date(endTime);
|
||||
|
||||
if (startDate >= endDate) {
|
||||
alert(i18n.t('error.time_range_invalid'));
|
||||
alert(i18n.t('monitor.error.time_range_invalid'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1194,14 +1194,14 @@
|
||||
try {
|
||||
const badge = document.getElementById('history-query-badge');
|
||||
if (badge) {
|
||||
badge.textContent = i18n.t('status.querying');
|
||||
badge.textContent = i18n.t('monitor.status.querying');
|
||||
badge.className = 'badge warning';
|
||||
}
|
||||
|
||||
const queryBtn = document.getElementById('query-btn');
|
||||
if (queryBtn) {
|
||||
queryBtn.disabled = true;
|
||||
queryBtn.textContent = i18n.t('status.querying');
|
||||
queryBtn.textContent = i18n.t('monitor.status.querying');
|
||||
}
|
||||
|
||||
let url = `${API_BASE}/history/query?timezone_offset=${timezoneOffset}`;
|
||||
@@ -1306,29 +1306,29 @@
|
||||
switchResultTab(currentTab);
|
||||
|
||||
if (badge) {
|
||||
badge.textContent = i18n.t('success.query_complete');
|
||||
badge.textContent = i18n.t('monitor.success.query_complete');
|
||||
badge.className = 'badge healthy';
|
||||
}
|
||||
|
||||
if (queryBtn) {
|
||||
queryBtn.disabled = false;
|
||||
queryBtn.textContent = i18n.t('btn.query');
|
||||
queryBtn.textContent = i18n.t('monitor.btn.query');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('执行历史查询失败:', error);
|
||||
alert(i18n.t('error.query_failed'));
|
||||
alert(i18n.t('monitor.error.query_failed'));
|
||||
|
||||
const badge = document.getElementById('history-query-badge');
|
||||
if (badge) {
|
||||
badge.textContent = i18n.t('error.query_failed');
|
||||
badge.textContent = i18n.t('monitor.error.query_failed');
|
||||
badge.className = 'badge error';
|
||||
}
|
||||
|
||||
const queryBtn = document.getElementById('query-btn');
|
||||
if (queryBtn) {
|
||||
queryBtn.disabled = false;
|
||||
queryBtn.textContent = i18n.t('btn.query');
|
||||
queryBtn.textContent = i18n.t('monitor.btn.query');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1353,9 +1353,9 @@
|
||||
|
||||
document.getElementById('result-tabs').style.display = 'none';
|
||||
|
||||
document.getElementById('http-results-body').innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('status.no_data') + '</td></tr>';
|
||||
document.getElementById('outbound-results-body').innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('status.no_data') + '</td></tr>';
|
||||
document.getElementById('logs-results-body').innerHTML = '<tr><td colspan="6" class="no-data">' + i18n.t('status.no_data') + '</td></tr>';
|
||||
document.getElementById('http-results-body').innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('monitor.status.no_data') + '</td></tr>';
|
||||
document.getElementById('outbound-results-body').innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('monitor.status.no_data') + '</td></tr>';
|
||||
document.getElementById('logs-results-body').innerHTML = '<tr><td colspan="6" class="no-data">' + i18n.t('monitor.status.no_data') + '</td></tr>';
|
||||
|
||||
historyQueryData = { http: [], outbound: [], logs: [] };
|
||||
// 清理缓存的排序数据
|
||||
@@ -1365,7 +1365,7 @@
|
||||
|
||||
const badge = document.getElementById('history-query-badge');
|
||||
if (badge) {
|
||||
badge.textContent = i18n.t('other.linked_query');
|
||||
badge.textContent = i18n.t('monitor.other.linked_query');
|
||||
badge.className = '';
|
||||
}
|
||||
}
|
||||
@@ -1553,7 +1553,7 @@
|
||||
const endTime = document.getElementById('history-end-time').value;
|
||||
|
||||
if (!startTime || !endTime) {
|
||||
alert(i18n.t('error.time_range_required'));
|
||||
alert(i18n.t('monitor.error.time_range_required'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1630,25 +1630,93 @@
|
||||
// 时间线渲染
|
||||
let timelineData = [];
|
||||
|
||||
async function loadTimeline() {
|
||||
const startTime = document.getElementById('history-start-time').value;
|
||||
const endTime = document.getElementById('history-end-time').value;
|
||||
|
||||
if (!startTime || !endTime) return;
|
||||
|
||||
let url = `${API_BASE}/history/timeline?start_time=${encodeURIComponent(startTime)}&end_time=${encodeURIComponent(endTime)}&limit=200`;
|
||||
|
||||
const logLevel = document.getElementById('history-log-level').value;
|
||||
if (logLevel) url += `&level=${logLevel}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
timelineData = data.events || [];
|
||||
function loadTimeline() {
|
||||
// 复用已查询的数据,避免重复请求
|
||||
if (!historyQueryData || (!historyQueryData.http?.length && !historyQueryData.outbound?.length && !historyQueryData.logs?.length)) {
|
||||
timelineData = [];
|
||||
renderTimeline();
|
||||
} catch (error) {
|
||||
console.error('加载时间线失败:', error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 转换为统一事件格式(与后端逻辑一致)
|
||||
const events = [];
|
||||
|
||||
// HTTP请求事件
|
||||
for (const req of historyQueryData.http || []) {
|
||||
events.push({
|
||||
id: `http_${req.id}`,
|
||||
timestamp: req.timestamp,
|
||||
type: 'http',
|
||||
icon: '📥',
|
||||
level: req.status_code < 400 ? 'INFO' : 'ERROR',
|
||||
summary: `${req.method} ${req.path}`,
|
||||
detail: {
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
status_code: req.status_code,
|
||||
duration: req.response_time,
|
||||
client_ip: req.client_ip,
|
||||
is_error: req.is_error,
|
||||
is_slow: req.is_slow
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 发送请求事件
|
||||
for (const req of historyQueryData.outbound || []) {
|
||||
events.push({
|
||||
id: `outbound_${req.id}`,
|
||||
timestamp: req.timestamp,
|
||||
type: 'outbound',
|
||||
icon: '📤',
|
||||
level: req.status_code < 400 ? 'INFO' : 'ERROR',
|
||||
summary: `${req.method} ${req.url?.substring(0, 80) || ''}`,
|
||||
detail: {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
status_code: req.status_code,
|
||||
duration: req.duration * 1000,
|
||||
module: req.module,
|
||||
is_error: req.is_error,
|
||||
is_slow: req.is_slow
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 系统日志事件
|
||||
const iconMap = {
|
||||
'DEBUG': '🔍',
|
||||
'INFO': '📝',
|
||||
'WARNING': '⚠️',
|
||||
'ERROR': '❌',
|
||||
'CRITICAL': '🔥'
|
||||
};
|
||||
for (const log of historyQueryData.logs || []) {
|
||||
events.push({
|
||||
id: `log_${log.id}`,
|
||||
timestamp: log.timestamp,
|
||||
type: 'log',
|
||||
icon: iconMap[log.level] || '📝',
|
||||
level: log.level,
|
||||
summary: log.message?.substring(0, 100) || '',
|
||||
detail: {
|
||||
level: log.level,
|
||||
module: log.module,
|
||||
function: log.function,
|
||||
line_number: log.line_number,
|
||||
message: log.message,
|
||||
stack_trace: log.stack_trace
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 按时间戳排序(降序)
|
||||
events.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
|
||||
|
||||
// 应用限制(最多200条)
|
||||
timelineData = events.slice(0, 200);
|
||||
|
||||
renderTimeline();
|
||||
}
|
||||
|
||||
function renderTimeline() {
|
||||
@@ -1656,25 +1724,63 @@
|
||||
if (!container) return;
|
||||
|
||||
if (timelineData.length === 0) {
|
||||
container.innerHTML = '<div class="timeline-empty">' + i18n.t('status.no_data') + '</div>';
|
||||
container.innerHTML = '<div class="timeline-empty">' + i18n.t('monitor.status.no_data') + '</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// 异常检测
|
||||
const anomalies = detectAnomalies(timelineData);
|
||||
|
||||
// 异常摘要
|
||||
let summaryHtml = '';
|
||||
// 统计摘要(一次遍历完成所有统计)
|
||||
const stats = { total: timelineData.length, http: 0, outbound: 0, log: 0, errors: 0, warnings: 0, slow: 0 };
|
||||
for (const e of timelineData) {
|
||||
if (e.type === 'http') stats.http++;
|
||||
else if (e.type === 'outbound') stats.outbound++;
|
||||
else if (e.type === 'log') stats.log++;
|
||||
|
||||
if (e.level === 'ERROR' || e.level === 'CRITICAL') stats.errors++;
|
||||
else if (e.level === 'WARNING') stats.warnings++;
|
||||
|
||||
if (e.detail?.is_slow) stats.slow++;
|
||||
}
|
||||
|
||||
// 统计摘要HTML
|
||||
const summaryTitle = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.summary_title') : '📊 时间线统计';
|
||||
const totalLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.total_events') : '总事件';
|
||||
const httpLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.http_requests') : 'HTTP请求';
|
||||
const outboundLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.outbound_requests') : '发送请求';
|
||||
const logLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.system_logs') : '系统日志';
|
||||
const errorLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.errors') : '错误';
|
||||
const warningLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.warnings') : '警告';
|
||||
const slowLabel = typeof i18n !== 'undefined' ? i18n.t('monitor.timeline.slow_requests') : '慢请求';
|
||||
|
||||
let summaryHtml = `<div style="background:#f0f9ff;border:1px solid #bae6fd;padding:12px;margin-bottom:16px;border-radius:6px;">
|
||||
<strong style="color:#0369a1;">${summaryTitle}</strong>
|
||||
<div style="display:flex;gap:16px;margin-top:8px;font-size:12px;color:#0c4a6e;flex-wrap:wrap;">
|
||||
<span><strong>${stats.total}</strong> ${totalLabel}</span>
|
||||
<span>📥 <strong>${stats.http}</strong> ${httpLabel}</span>
|
||||
<span>📤 <strong>${stats.outbound}</strong> ${outboundLabel}</span>
|
||||
<span>📝 <strong>${stats.log}</strong> ${logLabel}</span>
|
||||
${stats.errors > 0 ? `<span style="color:#dc2626;">❌ <strong>${stats.errors}</strong> ${errorLabel}</span>` : ''}
|
||||
${stats.warnings > 0 ? `<span style="color:#f59e0b;">⚠️ <strong>${stats.warnings}</strong> ${warningLabel}</span>` : ''}
|
||||
${stats.slow > 0 ? `<span style="color:#ef4444;">⏱️ <strong>${stats.slow}</strong> ${slowLabel}</span>` : ''}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
// 异常告警HTML(如果有异常)
|
||||
if (anomalies.length > 0) {
|
||||
summaryHtml = `<div style="background:#fef2f2;border:1px solid #fecaca;padding:12px;margin-bottom:16px;border-radius:6px;">
|
||||
<strong style="color:#dc2626;">⚠️ 发现 ${anomalies.length} 处异常</strong>
|
||||
const anomalyText = typeof i18n !== 'undefined' ?
|
||||
i18n.t('monitor.timeline.anomaly_detected', {count: anomalies.length}) :
|
||||
`发现 ${anomalies.length} 处异常`;
|
||||
summaryHtml += `<div style="background:#fef2f2;border:1px solid #fecaca;padding:12px;margin-bottom:16px;border-radius:6px;">
|
||||
<strong style="color:#dc2626;">⚠️ ${anomalyText}</strong>
|
||||
<div style="font-size:12px;color:#991b1b;margin-top:4px;">
|
||||
${anomalies.map(a => a.description).join('、')}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
container.innerHTML = summaryHtml + timelineData.map(event => {
|
||||
const renderedHtml = timelineData.map(event => {
|
||||
const isError = event.level === 'ERROR' || event.level === 'CRITICAL';
|
||||
const isWarning = event.level === 'WARNING';
|
||||
const isAnomaly = anomalies.some(a => a.eventId === event.id);
|
||||
@@ -1692,6 +1798,8 @@
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
container.innerHTML = summaryHtml + renderedHtml;
|
||||
}
|
||||
|
||||
// 异常检测算法
|
||||
@@ -1726,10 +1834,13 @@
|
||||
const threshold = avg * 3;
|
||||
events.forEach(e => {
|
||||
if (e.type === 'http' && e.detail?.duration > threshold) {
|
||||
const slowReqText = typeof i18n !== 'undefined' ?
|
||||
i18n.t('monitor.timeline.slow_anomaly', {duration: e.detail.duration.toFixed(0), avg: avg.toFixed(0)}) :
|
||||
`异常慢请求(${e.detail.duration.toFixed(0)}ms > 平均${avg.toFixed(0)}ms×3)`;
|
||||
anomalies.push({
|
||||
eventId: e.id,
|
||||
type: 'slow_anomaly',
|
||||
description: `异常慢请求(${e.detail.duration.toFixed(0)}ms > 平均${avg.toFixed(0)}ms×3)`
|
||||
description: slowReqText
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1746,10 +1857,13 @@
|
||||
});
|
||||
Object.entries(errorMessages).forEach(([msg, ids]) => {
|
||||
if (ids.length >= 3) {
|
||||
const dupErrorText = typeof i18n !== 'undefined' ?
|
||||
i18n.t('monitor.timeline.duplicate_error', {msg: msg.substring(0, 20), count: ids.length}) :
|
||||
`重复错误"${msg.substring(0, 20)}..."出现${ids.length}次`;
|
||||
anomalies.push({
|
||||
eventId: ids[ids.length - 1],
|
||||
type: 'duplicate_error',
|
||||
description: `重复错误"${msg.substring(0, 20)}..."出现${ids.length}次`
|
||||
description: dupErrorText
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1769,7 +1883,7 @@
|
||||
const endTime = document.getElementById('history-end-time').value;
|
||||
|
||||
if (!startTime || !endTime) {
|
||||
document.getElementById('tab-chart').innerHTML = '<div style="padding:40px;text-align:center;color:#999;">' + i18n.t('chart.query_required') + '</div>';
|
||||
document.getElementById('tab-chart').innerHTML = '<div style="padding:40px;text-align:center;color:#999;">' + i18n.t('monitor.chart.query_required') + '</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1797,8 +1911,9 @@
|
||||
<div style="background:${color};width:${pct}%;height:100%;transition:width 0.3s;"></div>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join('') || '<div style="color:#999;text-align:center;">无数据</div>';
|
||||
levelCanvas.parentElement.innerHTML = '<h4>📊 日志级别分布</h4><div style="padding:8px 0;">' + levelHtml + '</div>';
|
||||
}).join('') || `<div style="color:#999;text-align:center;">${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.no_data') : '无数据'}</div>`;
|
||||
const levelTitle = typeof i18n !== 'undefined' ? i18n.t('monitor.chart.level_distribution') : '📊 日志级别分布';
|
||||
levelCanvas.parentElement.innerHTML = `<h4>${levelTitle}</h4><div style="padding:8px 0;">` + levelHtml + '</div>';
|
||||
}
|
||||
|
||||
// 渲染状态码分布(饼图样式)
|
||||
@@ -1815,8 +1930,9 @@
|
||||
<div style="width:60px;height:60px;border-radius:50%;background:${color};display:flex;align-items:center;justify-content:center;color:white;font-weight:bold;font-size:14px;">${pct}%</div>
|
||||
<div style="margin-top:4px;font-size:12px;">${k} (${v})</div>
|
||||
</div>`;
|
||||
}).join('') || '<div style="color:#999;text-align:center;">无数据</div>';
|
||||
statusCanvas.parentElement.innerHTML = '<h4>📈 状态码分布</h4><div style="text-align:center;padding:8px 0;">' + statusHtml + '</div>';
|
||||
}).join('') || `<div style="color:#999;text-align:center;">${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.no_data') : '无数据'}</div>`;
|
||||
const statusTitle = typeof i18n !== 'undefined' ? i18n.t('monitor.chart.status_distribution') : '📈 状态码分布';
|
||||
statusCanvas.parentElement.innerHTML = `<h4>${statusTitle}</h4><div style="text-align:center;padding:8px 0;">` + statusHtml + '</div>';
|
||||
}
|
||||
|
||||
// 渲染慢请求TOP10(表格)
|
||||
@@ -1838,8 +1954,9 @@
|
||||
</tr>`).join('')}
|
||||
</tbody>
|
||||
</table>`
|
||||
: '<div style="color:#22c55e;text-align:center;padding:20px;">✅ 无慢请求</div>';
|
||||
slowCanvas.parentElement.innerHTML = '<h4>⏱️ 慢请求TOP10</h4>' + slowHtml;
|
||||
: `<div style="color:#22c55e;text-align:center;padding:20px;">✅ ${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.no_slow') : '无慢请求'}</div>`;
|
||||
const slowTitle = typeof i18n !== 'undefined' ? i18n.t('monitor.chart.slow_requests') : '⏱️ 慢请求TOP10';
|
||||
slowCanvas.parentElement.innerHTML = `<h4>${slowTitle}</h4>` + slowHtml;
|
||||
}
|
||||
|
||||
// 渲染趋势摘要
|
||||
@@ -1850,23 +1967,24 @@
|
||||
const trendHtml = trend.length > 0
|
||||
? `<div style="padding:12px;">
|
||||
<div style="display:flex;justify-content:space-around;text-align:center;">
|
||||
<div><div style="font-size:28px;font-weight:bold;color:#3b82f6;">${summary.total_requests || 0}</div><div style="font-size:12px;color:#6b7280;">总请求</div></div>
|
||||
<div><div style="font-size:28px;font-weight:bold;color:#ef4444;">${summary.error_count || 0}</div><div style="font-size:12px;color:#6b7280;">错误</div></div>
|
||||
<div><div style="font-size:28px;font-weight:bold;color:#f59e0b;">${summary.slow_count || 0}</div><div style="font-size:12px;color:#6b7280;">慢请求</div></div>
|
||||
<div><div style="font-size:28px;font-weight:bold;color:#3b82f6;">${summary.total_requests || 0}</div><div style="font-size:12px;color:#6b7280;">${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.total_requests') : '总请求'}</div></div>
|
||||
<div><div style="font-size:28px;font-weight:bold;color:#ef4444;">${summary.error_count || 0}</div><div style="font-size:12px;color:#6b7280;">${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.error_count') : '错误'}</div></div>
|
||||
<div><div style="font-size:28px;font-weight:bold;color:#f59e0b;">${summary.slow_count || 0}</div><div style="font-size:12px;color:#6b7280;">${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.slow_count') : '慢请求'}</div></div>
|
||||
</div>
|
||||
<div style="margin-top:12px;padding-top:12px;border-top:1px solid #e5e7eb;font-size:12px;color:#6b7280;">
|
||||
时间范围: ${trend.length}个时间点 | 日志总数: ${summary.total_logs || 0}条
|
||||
${typeof i18n !== 'undefined' ? i18n.t('monitor.stats.time_range') : '时间范围'}: ${trend.length}${typeof i18n !== 'undefined' ? i18n.t('monitor.other.data_points') : '个时间点'} | ${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.log_count') : '日志总数'}: ${summary.total_logs || 0}${typeof i18n !== 'undefined' ? i18n.t('monitor.pagination.items') : '条'}
|
||||
</div>
|
||||
</div>`
|
||||
: '<div style="color:#999;text-align:center;padding:20px;">无趋势数据</div>';
|
||||
trendCanvas.parentElement.innerHTML = '<h4>📊 请求量趋势</h4>' + trendHtml;
|
||||
: `<div style="color:#999;text-align:center;padding:20px;">${typeof i18n !== 'undefined' ? i18n.t('monitor.chart.no_trend') : '无趋势数据'}</div>`;
|
||||
const trendTitle = typeof i18n !== 'undefined' ? i18n.t('monitor.chart.request_trend') : '📊 请求量趋势';
|
||||
trendCanvas.parentElement.innerHTML = `<h4>${trendTitle}</h4>` + trendHtml;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('渲染图表失败:', error);
|
||||
const chartContainer = document.querySelector('.chart-container');
|
||||
if (chartContainer) {
|
||||
chartContainer.innerHTML = '<div style="padding:40px;text-align:center;color:#ef4444;">' + i18n.t('chart.load_failed') + '</div>';
|
||||
chartContainer.innerHTML = '<div style="padding:40px;text-align:center;color:#ef4444;">' + i18n.t('monitor.chart.load_failed') + '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1882,11 +2000,11 @@
|
||||
const btn = document.getElementById('realtime-btn');
|
||||
|
||||
if (realtimeTracking) {
|
||||
btn.textContent = i18n.t('btn.realtime_on');
|
||||
btn.textContent = i18n.t('monitor.btn.realtime_on');
|
||||
btn.className = 'btn btn-primary';
|
||||
startRealtimeTracking();
|
||||
} else {
|
||||
btn.textContent = i18n.t('btn.realtime_off');
|
||||
btn.textContent = i18n.t('monitor.btn.realtime_off');
|
||||
btn.className = 'btn btn-secondary';
|
||||
stopRealtimeTracking();
|
||||
}
|
||||
@@ -1902,7 +2020,7 @@
|
||||
// 10分钟自动暂停
|
||||
if (trackingDuration >= 600) {
|
||||
stopRealtimeTracking();
|
||||
alert(i18n.t('error.auto_pause'));
|
||||
alert(i18n.t('monitor.error.auto_pause'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1938,7 +2056,7 @@
|
||||
}
|
||||
realtimeTracking = false;
|
||||
const btn = document.getElementById('realtime-btn');
|
||||
btn.textContent = i18n.t('btn.realtime_off');
|
||||
btn.textContent = i18n.t('monitor.btn.realtime_off');
|
||||
btn.className = 'btn btn-secondary';
|
||||
}
|
||||
|
||||
@@ -1964,14 +2082,14 @@
|
||||
if (!select) return;
|
||||
|
||||
const templates = getTemplates();
|
||||
select.innerHTML = '<option value="">' + i18n.t('template.saved_queries') + '</option>' +
|
||||
select.innerHTML = '<option value="">' + i18n.t('monitor.template.saved_queries') + '</option>' +
|
||||
templates.map((t, i) => `<option value="${i}">${t.name}</option>`).join('');
|
||||
}
|
||||
|
||||
function saveQueryTemplate() {
|
||||
const templates = getTemplates();
|
||||
if (templates.length >= 10) {
|
||||
alert(i18n.t('error.max_templates'));
|
||||
alert(i18n.t('monitor.error.max_templates'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1997,7 +2115,7 @@
|
||||
|
||||
templates.push(template);
|
||||
saveTemplates(templates);
|
||||
alert(i18n.t('success.template_saved', {name: name}));
|
||||
alert(i18n.t('monitor.success.template_saved', {name: name}));
|
||||
}
|
||||
|
||||
function loadQueryTemplate() {
|
||||
@@ -2133,7 +2251,7 @@
|
||||
if (!tbody) return;
|
||||
|
||||
if (historyQueryData.http.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('status.no_data') + '</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('monitor.status.no_data') + '</td></tr>';
|
||||
sortedHttpData = [];
|
||||
return;
|
||||
}
|
||||
@@ -2170,7 +2288,7 @@
|
||||
if (!tbody) return;
|
||||
|
||||
if (historyQueryData.outbound.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('status.no_data') + '</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="no-data">' + i18n.t('monitor.status.no_data') + '</td></tr>';
|
||||
sortedOutboundData = [];
|
||||
return;
|
||||
}
|
||||
@@ -2207,7 +2325,7 @@
|
||||
if (!tbody) return;
|
||||
|
||||
if (historyQueryData.logs.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="no-data">' + i18n.t('status.no_data') + '</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="no-data">' + i18n.t('monitor.status.no_data') + '</td></tr>';
|
||||
sortedLogsData = [];
|
||||
return;
|
||||
}
|
||||
@@ -2255,26 +2373,40 @@
|
||||
return pairs.length > 0 ? '?' + pairs.join('&') : '-';
|
||||
}
|
||||
|
||||
function showHistoryHttpDetail(index) {
|
||||
async function showHistoryHttpDetail(index) {
|
||||
const req = sortedHttpData[index];
|
||||
if (!req) return;
|
||||
|
||||
// 懒加载:如果数据不包含request_body,则从API加载完整数据
|
||||
let detailData = req;
|
||||
if (!req.hasOwnProperty('request_body')) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/history/http/${req.id}`);
|
||||
detailData = await response.json();
|
||||
} catch (error) {
|
||||
console.error('加载详情失败:', error);
|
||||
alert(i18n.t('monitor.error.detail_load_failed') || '加载详情失败');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const detail = `
|
||||
<div style="max-height: 60vh; overflow-y: auto;">
|
||||
<table style="width: 100%; border-collapse: collapse; font-size: 13px;">
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; width: 120px; color: #8c8c8c;">请求ID</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.id || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">时间戳</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.timestamp || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求方法</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;"><span class="api-method ${(req.method || '').toLowerCase()}">${req.method || '-'}</span></td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求路径</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.path || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">查询参数</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${formatQueryParams(req.query_params)}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">状态码</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono api-status ${(req.status_code || 0) >= 400 ? 'error' : 'success'}">${req.status_code || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">响应时间</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.duration ? req.duration.toFixed(2) + 'ms' : '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">客户端IP</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.client_ip || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">User Agent</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.user_agent || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">是否慢请求</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${req.is_slow ? '是' : '否'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">是否错误</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${req.is_error ? '是' : '否'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">错误信息</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #f5222d;" class="font-mono">${req.error_message || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; color: #8c8c8c;">请求体</td><td style="padding: 8px;" class="font-mono">${req.request_body || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; width: 120px; color: #8c8c8c;">请求ID</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.id || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">时间戳</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.timestamp || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求方法</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;"><span class="api-method ${(detailData.method || '').toLowerCase()}">${detailData.method || '-'}</span></td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求路径</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.path || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">查询参数</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${formatQueryParams(detailData.query_params)}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">状态码</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono api-status ${(detailData.status_code || 0) >= 400 ? 'error' : 'success'}">${detailData.status_code || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">响应时间</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.duration ? detailData.duration.toFixed(2) + 'ms' : '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">客户端IP</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.client_ip || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">User Agent</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.user_agent || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">${typeof i18n !== 'undefined' ? i18n.t('monitor.col.is_slow') : '是否慢请求'}</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${detailData.is_slow ? (typeof i18n !== 'undefined' ? i18n.t('monitor.other.yes') : '是') : (typeof i18n !== 'undefined' ? i18n.t('monitor.other.no') : '否')}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">${typeof i18n !== 'undefined' ? i18n.t('monitor.col.is_error') : '是否错误'}</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${detailData.is_error ? (typeof i18n !== 'undefined' ? i18n.t('monitor.other.yes') : '是') : (typeof i18n !== 'undefined' ? i18n.t('monitor.other.no') : '否')}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">${typeof i18n !== 'undefined' ? i18n.t('monitor.col.error_message') : '错误信息'}</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #f5222d;" class="font-mono">${detailData.error_message || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求体</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono"><pre style="margin:0;white-space:pre-wrap;word-break:break-all;">${detailData.request_body || '-'}</pre></td></tr>
|
||||
<tr><td style="padding: 8px; color: #8c8c8c;">响应体</td><td style="padding: 8px;" class="font-mono"><pre style="margin:0;white-space:pre-wrap;word-break:break-all;">${detailData.response_body || '-'}</pre></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
@@ -2282,25 +2414,38 @@
|
||||
showDetailModal('接收请求详情', detail);
|
||||
}
|
||||
|
||||
function showHistoryOutboundDetail(index) {
|
||||
async function showHistoryOutboundDetail(index) {
|
||||
const req = sortedOutboundData[index];
|
||||
if (!req) return;
|
||||
|
||||
// 懒加载:如果数据不包含request_body,则从API加载完整数据
|
||||
let detailData = req;
|
||||
if (!req.hasOwnProperty('request_body')) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/history/outbound/${req.id}`);
|
||||
detailData = await response.json();
|
||||
} catch (error) {
|
||||
console.error('加载详情失败:', error);
|
||||
alert(i18n.t('monitor.error.detail_load_failed') || '加载详情失败');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const detail = `
|
||||
<div style="max-height: 60vh; overflow-y: auto;">
|
||||
<table style="width: 100%; border-collapse: collapse; font-size: 13px;">
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; width: 120px; color: #8c8c8c;">请求ID</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.id || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">时间戳</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.timestamp || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求方法</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;"><span class="api-method ${(req.method || '').toLowerCase()}">${req.method || '-'}</span></td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求URL</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.url || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">状态码</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono api-status ${(req.status_code || 0) >= 400 ? 'error' : 'success'}">${req.status_code || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">响应时间</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.duration ? req.duration.toFixed(2) + 'ms' : '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">模块</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.module || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">是否慢请求</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${req.is_slow ? '是' : '否'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">是否错误</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${req.is_error ? '是' : '否'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">错误信息</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #f5222d;" class="font-mono">${req.error_message || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求体</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${req.request_body || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; color: #8c8c8c;">响应体</td><td style="padding: 8px;" class="font-mono">${req.response_body || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; width: 120px; color: #8c8c8c;">请求ID</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.id || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">时间戳</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.timestamp || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求方法</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;"><span class="api-method ${(detailData.method || '').toLowerCase()}">${detailData.method || '-'}</span></td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求URL</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.url || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">状态码</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono api-status ${(detailData.status_code || 0) >= 400 ? 'error' : 'success'}">${detailData.status_code || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">响应时间</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.duration ? detailData.duration.toFixed(2) + 'ms' : '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">模块</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.module || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">${typeof i18n !== 'undefined' ? i18n.t('monitor.col.is_slow') : '是否慢请求'}</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${detailData.is_slow ? (typeof i18n !== 'undefined' ? i18n.t('monitor.other.yes') : '是') : (typeof i18n !== 'undefined' ? i18n.t('monitor.other.no') : '否')}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">${typeof i18n !== 'undefined' ? i18n.t('monitor.col.is_error') : '是否错误'}</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;">${detailData.is_error ? (typeof i18n !== 'undefined' ? i18n.t('monitor.other.yes') : '是') : (typeof i18n !== 'undefined' ? i18n.t('monitor.other.no') : '否')}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">${typeof i18n !== 'undefined' ? i18n.t('monitor.col.error_message') : '错误信息'}</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #f5222d;" class="font-mono">${detailData.error_message || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">请求体</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono"><pre style="margin:0;white-space:pre-wrap;word-break:break-all;">${detailData.request_body || '-'}</pre></td></tr>
|
||||
<tr><td style="padding: 8px; color: #8c8c8c;">响应体</td><td style="padding: 8px;" class="font-mono"><pre style="margin:0;white-space:pre-wrap;word-break:break-all;">${detailData.response_body || '-'}</pre></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
@@ -2308,20 +2453,34 @@
|
||||
showDetailModal('发送请求详情', detail);
|
||||
}
|
||||
|
||||
function showHistoryLogDetail(index) {
|
||||
async function showHistoryLogDetail(index) {
|
||||
const log = sortedLogsData[index];
|
||||
if (!log) return;
|
||||
|
||||
// 懒加载:如果数据不包含stack_trace,则从API加载完整数据
|
||||
let detailData = log;
|
||||
if (!log.hasOwnProperty('stack_trace')) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/history/log/${log.id}`);
|
||||
detailData = await response.json();
|
||||
} catch (error) {
|
||||
console.error('加载详情失败:', error);
|
||||
alert(i18n.t('monitor.error.detail_load_failed') || '加载详情失败');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const detail = `
|
||||
<div style="max-height: 60vh; overflow-y: auto;">
|
||||
<table style="width: 100%; border-collapse: collapse; font-size: 13px;">
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; width: 120px; color: #8c8c8c;">日志ID</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${log.id || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">时间戳</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${log.timestamp || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">日志级别</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono"><span class="log-level-badge ${(log.level || '').toLowerCase()}">${log.level || '-'}</span></td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">模块</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${log.module || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">函数</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${log.function || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">行号</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${log.line_number || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; color: #8c8c8c;">消息</td><td style="padding: 8px;" class="font-mono">${log.message || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; width: 120px; color: #8c8c8c;">日志ID</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.id || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">时间戳</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.timestamp || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">日志级别</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono"><span class="log-level-badge ${(detailData.level || '').toLowerCase()}">${detailData.level || '-'}</span></td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">模块</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.module || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">函数</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.function || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">行号</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono">${detailData.line_number || '-'}</td></tr>
|
||||
<tr><td style="padding: 8px; border-bottom: 1px solid #e8e8e8; color: #8c8c8c;">消息</td><td style="padding: 8px; border-bottom: 1px solid #e8e8e8;" class="font-mono"><pre style="margin:0;white-space:pre-wrap;word-break:break-all;">${detailData.message || '-'}</pre></td></tr>
|
||||
${detailData.stack_trace ? `<tr><td style="padding: 8px; color: #8c8c8c;">堆栈</td><td style="padding: 8px;" class="font-mono"><pre style="margin:0;white-space:pre-wrap;word-break:break-all;color:#f5222d;">${detailData.stack_trace}</pre></td></tr>` : ''}
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
|
||||
+157
-157
@@ -16,13 +16,13 @@
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<nav class="nav-menu">
|
||||
<a href="#" class="nav-item active" data-page="overview" data-i18n="nav.overview">📊 Overview</a>
|
||||
<a href="#" class="nav-item" data-page="database" data-i18n="nav.database">🗃️ 数据库<span id="database-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item" data-page="event-helpers" data-i18n="nav.events">☎️ 事件处理</a>
|
||||
<a href="#" class="nav-item" data-page="scheduler" data-i18n="nav.scheduler">⏰ 定时任务</a>
|
||||
<a href="#" class="nav-item" data-page="api-requests" data-i18n="nav.http_requests">📥 接收请求<span id="api-requests-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item" data-page="outbound-requests" data-i18n="nav.outbound_requests">📤 发送请求<span id="outbound-requests-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item" data-page="logs" data-i18n="nav.logs">📋 日志<span id="logs-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item active" data-page="overview" data-i18n="monitor.nav.overview">📊 Overview</a>
|
||||
<a href="#" class="nav-item" data-page="database" data-i18n="monitor.nav.database">🗃️ 数据库<span id="database-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item" data-page="event-helpers" data-i18n="monitor.nav.events">☎️ 事件处理</a>
|
||||
<a href="#" class="nav-item" data-page="scheduler" data-i18n="monitor.nav.scheduler">⏰ 定时任务</a>
|
||||
<a href="#" class="nav-item" data-page="api-requests" data-i18n="monitor.nav.http_requests">📥 接收请求<span id="api-requests-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item" data-page="outbound-requests" data-i18n="monitor.nav.outbound_requests">📤 发送请求<span id="outbound-requests-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
<a href="#" class="nav-item" data-page="logs" data-i18n="monitor.nav.logs">📋 日志<span id="logs-badge" class="nav-badge" style="display: none;"></span></a>
|
||||
</nav>
|
||||
<div class="header-info">
|
||||
<select id="lang-selector" class="lang-selector" onchange="i18n.switchLanguage(this.value)">
|
||||
@@ -30,9 +30,9 @@
|
||||
<option value="en-US">🇺🇸 English</option>
|
||||
<option value="de-DE">🇩🇪 Deutsch</option>
|
||||
</select>
|
||||
<span id="status-indicator" class="status healthy" data-i18n="status.healthy">● 系统正常</span>
|
||||
<span id="last-update"><span data-i18n="other.last_update">最后更新</span> --</span>
|
||||
<button id="refresh-btn" class="btn btn-primary" onclick="refreshAll()" data-i18n="btn.refresh">刷新</button>
|
||||
<span id="status-indicator" class="status healthy" data-i18n="monitor.status.healthy">● 系统正常</span>
|
||||
<span id="last-update"><span data-i18n="monitor.other.last_update">最后更新</span> --</span>
|
||||
<button id="refresh-btn" class="btn btn-primary" onclick="refreshAll()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -41,20 +41,20 @@
|
||||
<!-- 资源监控卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.resource">资源使用</h2>
|
||||
<span class="badge" id="resource-badge" data-i18n="status.running">运行中</span>
|
||||
<h2 data-i18n="monitor.card.resource">资源使用</h2>
|
||||
<span class="badge" id="resource-badge" data-i18n="monitor.status.running">运行中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.cpu">CPU 使用率</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.cpu">CPU 使用率</div>
|
||||
<div class="metric-value" id="cpu-value">--%</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" id="cpu-bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.memory">内存使用</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.memory">内存使用</div>
|
||||
<div class="metric-value" id="memory-value">
|
||||
<span id="memory-usage">-- MB</span>
|
||||
<span id="memory-percent" class="memory-percent">--%</span>
|
||||
@@ -64,11 +64,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.threads">线程数</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.threads">线程数</div>
|
||||
<div class="metric-value" id="threads-value">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.uptime">运行时间</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.uptime">运行时间</div>
|
||||
<div class="metric-value" id="uptime-value">--</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,21 +81,21 @@
|
||||
<!-- 数据库状态卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.db_status">账套状态</h2>
|
||||
<span class="badge" id="db-badge" data-i18n="status.checking">检查中</span>
|
||||
<h2 data-i18n="monitor.card.db_status">账套状态</h2>
|
||||
<span class="badge" id="db-badge" data-i18n="monitor.status.checking">检查中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="db-summary" id="db-summary">
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.total_connections">总连接数</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.total_connections">总连接数</span>
|
||||
<span class="summary-value" id="db-total">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.healthy">健康</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.healthy">健康</span>
|
||||
<span class="summary-value healthy" id="db-healthy">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.unhealthy">异常</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.unhealthy">异常</span>
|
||||
<span class="summary-value error" id="db-unhealthy">--</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,8 +108,8 @@
|
||||
<!-- 提醒信息卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.recent_alerts">最近告警</h2>
|
||||
<button class="btn btn-small" onclick="clearAlerts()" data-i18n="btn.clear">清空</button>
|
||||
<h2 data-i18n="monitor.card.recent_alerts">最近告警</h2>
|
||||
<button class="btn btn-small" onclick="clearAlerts()" data-i18n="monitor.btn.clear">清空</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="alert-list" id="alert-list">
|
||||
@@ -121,21 +121,21 @@
|
||||
<!-- 接收请求卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.api_requests">接收请求</h2>
|
||||
<span class="badge" id="http-badge" data-i18n="status.running">监控中</span>
|
||||
<h2 data-i18n="monitor.card.api_requests">接收请求</h2>
|
||||
<span class="badge" id="http-badge" data-i18n="monitor.status.running">监控中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="http-summary" id="http-summary">
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.requests_total">总请求数</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.requests_total">总请求数</span>
|
||||
<span class="summary-value" id="http-total">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.error_rate">错误率</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.error_rate">错误率</span>
|
||||
<span class="summary-value" id="http-error-rate">--%</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.avg_time">平均响应</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.avg_time">平均响应</span>
|
||||
<span class="summary-value" id="http-avg-time">--ms</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
@@ -149,21 +149,21 @@
|
||||
<!-- 发送请求卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.outbound_requests">发送请求</h2>
|
||||
<span class="badge" id="outbound-badge" data-i18n="status.running">监控中</span>
|
||||
<h2 data-i18n="monitor.card.outbound_requests">发送请求</h2>
|
||||
<span class="badge" id="outbound-badge" data-i18n="monitor.status.running">监控中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="outbound-summary" id="outbound-summary">
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.requests_total">总请求数</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.requests_total">总请求数</span>
|
||||
<span class="summary-value" id="outbound-total">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.error_rate">错误率</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.error_rate">错误率</span>
|
||||
<span class="summary-value" id="outbound-error-rate">--%</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.avg_time">平均响应</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.avg_time">平均响应</span>
|
||||
<span class="summary-value" id="outbound-avg">--ms</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -173,17 +173,17 @@
|
||||
<!-- 定时任务监控卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.scheduler">定时任务</h2>
|
||||
<span class="badge" id="scheduler-badge" data-i18n="status.checking">检查中</span>
|
||||
<h2 data-i18n="monitor.card.scheduler">定时任务</h2>
|
||||
<span class="badge" id="scheduler-badge" data-i18n="monitor.status.checking">检查中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="scheduler-info" id="scheduler-info">
|
||||
<div class="info-item">
|
||||
<span class="info-label" data-i18n="metric.scheduler_status">调度器状态</span>
|
||||
<span class="info-label" data-i18n="monitor.metric.scheduler_status">调度器状态</span>
|
||||
<span class="info-value" id="scheduler-status">--</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label" data-i18n="metric.job_count">任务数量</span>
|
||||
<span class="info-label" data-i18n="monitor.metric.job_count">任务数量</span>
|
||||
<span class="info-value" id="job-count">--</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -196,8 +196,8 @@
|
||||
<!-- 数据库详细信息卡片 -->
|
||||
<section class="card full-width">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.mysql">MySQL</h2>
|
||||
<span class="badge" id="db-detail-badge" data-i18n="status.checking">检查中</span>
|
||||
<h2 data-i18n="monitor.card.mysql">MySQL</h2>
|
||||
<span class="badge" id="db-detail-badge" data-i18n="monitor.status.checking">检查中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- 数据库详细信息 -->
|
||||
@@ -205,17 +205,17 @@
|
||||
<table class="db-detail-table" id="db-detail-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="col.db_name">账套名称</th>
|
||||
<th data-i18n="metric.connection_status">连接状态</th>
|
||||
<th data-i18n="col.last_check">最后检查</th>
|
||||
<th data-i18n="col.current_connections">当前连接</th>
|
||||
<th data-i18n="col.max_connections">最大连接</th>
|
||||
<th data-i18n="col.min_connections">最小连接</th>
|
||||
<th data-i18n="col.idle_connections">空闲连接</th>
|
||||
<th data-i18n="col.used_connections">使用中连接</th>
|
||||
<th data-i18n="col.usage">使用率</th>
|
||||
<th data-i18n="col.processed_records">处理记录</th>
|
||||
<th data-i18n="col.count">次数</th>
|
||||
<th data-i18n="monitor.col.db_name">账套名称</th>
|
||||
<th data-i18n="monitor.metric.connection_status">连接状态</th>
|
||||
<th data-i18n="monitor.col.last_check">最后检查</th>
|
||||
<th data-i18n="monitor.col.current_connections">当前连接</th>
|
||||
<th data-i18n="monitor.col.max_connections">最大连接</th>
|
||||
<th data-i18n="monitor.col.min_connections">最小连接</th>
|
||||
<th data-i18n="monitor.col.idle_connections">空闲连接</th>
|
||||
<th data-i18n="monitor.col.used_connections">使用中连接</th>
|
||||
<th data-i18n="monitor.col.usage">使用率</th>
|
||||
<th data-i18n="monitor.col.processed_records">处理记录</th>
|
||||
<th data-i18n="monitor.col.count">次数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="db-detail-tbody">
|
||||
@@ -229,62 +229,62 @@
|
||||
<!-- Redis 监控卡片 -->
|
||||
<section class="card full-width">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.redis">Redis</h2>
|
||||
<span class="badge" id="redis-badge" data-i18n="status.checking">检查中</span>
|
||||
<h2 data-i18n="monitor.card.redis">Redis</h2>
|
||||
<span class="badge" id="redis-badge" data-i18n="monitor.status.checking">检查中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="redis-metrics-grid">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.connection_status">连接状态</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.connection_status">连接状态</div>
|
||||
<div class="metric-value" id="redis-status">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.host">主机</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.host">主机</div>
|
||||
<div class="metric-value" id="redis-host">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.port">端口</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.port">端口</div>
|
||||
<div class="metric-value" id="redis-port">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.database">数据库</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.database">数据库</div>
|
||||
<div class="metric-value" id="redis-db">--</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="redis-pool-metrics">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.used_connections">使用连接数</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.used_connections">使用连接数</div>
|
||||
<div class="metric-value" id="redis-connections-used">0</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.max_connections">最大连接数</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.max_connections">最大连接数</div>
|
||||
<div class="metric-value" id="redis-connections-max">0</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.connection_usage">连接使用率</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.connection_usage">连接使用率</div>
|
||||
<div class="metric-value" id="redis-connection-usage">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="redis-buffer-metrics">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.buffer_size">缓冲大小</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.buffer_size">缓冲大小</div>
|
||||
<div class="metric-value" id="redis-buffer-size">0</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.buffer_threshold">缓冲阈值</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.buffer_threshold">缓冲阈值</div>
|
||||
<div class="metric-value" id="redis-buffer-threshold">0</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.buffer_usage">缓冲使用率</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.buffer_usage">缓冲使用率</div>
|
||||
<div class="metric-value" id="redis-buffer-usage">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<h3 data-i18n="chart.redis_connections">Redis 连接池使用情况</h3>
|
||||
<h3 data-i18n="monitor.chart.redis_connections">Redis 连接池使用情况</h3>
|
||||
<canvas id="redis-connections-chart"></canvas>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<h3 data-i18n="chart.redis_buffer">Redis 缓冲大小变化</h3>
|
||||
<h3 data-i18n="monitor.chart.redis_buffer">Redis 缓冲大小变化</h3>
|
||||
<canvas id="redis-buffer-chart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
@@ -295,7 +295,7 @@
|
||||
<main class="main-content page-content" id="page-api-requests">
|
||||
<section class="card full-width">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.http_requests_log">接收请求记录</h2>
|
||||
<h2 data-i18n="monitor.card.http_requests_log">接收请求记录</h2>
|
||||
<div class="card-actions">
|
||||
<div class="date-selector" style="display: none;">
|
||||
<label for="api-date-picker">选择日期:</label>
|
||||
@@ -306,11 +306,11 @@
|
||||
<label>
|
||||
<input type="checkbox" id="show-api-internal-requests" onchange="toggleAPIIntternalRequests()">
|
||||
<span class="toggle-slider"></span>
|
||||
<span data-i18n="other.show_internal">显示内部请求</span>
|
||||
<span data-i18n="monitor.other.show_internal">显示内部请求</span>
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-sm" onclick="refreshAPIRequests()" data-i18n="btn.refresh">刷新</button>
|
||||
<button class="btn btn-sm btn-secondary" onclick="resetAPIStats()" data-i18n="btn.reset_stats">重置统计</button>
|
||||
<button class="btn btn-sm" onclick="refreshAPIRequests()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
<button class="btn btn-sm btn-secondary" onclick="resetAPIStats()" data-i18n="monitor.btn.reset_stats">重置统计</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -318,15 +318,15 @@
|
||||
<table class="api-requests-table" id="api-requests-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="col.index">序号</th>
|
||||
<th data-i18n="col.timestamp">时间戳</th>
|
||||
<th data-i18n="col.method">方法</th>
|
||||
<th data-i18n="col.path">端点</th>
|
||||
<th data-i18n="col.query_params">查询参数</th>
|
||||
<th data-i18n="col.status">状态码</th>
|
||||
<th data-i18n="col.duration">响应时间</th>
|
||||
<th data-i18n="col.client_ip">客户端IP</th>
|
||||
<th data-i18n="col.error_message">错误信息</th>
|
||||
<th data-i18n="monitor.col.index">序号</th>
|
||||
<th data-i18n="monitor.col.timestamp">时间戳</th>
|
||||
<th data-i18n="monitor.col.method">方法</th>
|
||||
<th data-i18n="monitor.col.path">端点</th>
|
||||
<th data-i18n="monitor.col.query_params">查询参数</th>
|
||||
<th data-i18n="monitor.col.status">状态码</th>
|
||||
<th data-i18n="monitor.col.duration">响应时间</th>
|
||||
<th data-i18n="monitor.col.client_ip">客户端IP</th>
|
||||
<th data-i18n="monitor.col.error_message">错误信息</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="api-requests-tbody">
|
||||
@@ -381,9 +381,9 @@
|
||||
<main class="main-content page-content" id="page-scheduler">
|
||||
<section class="card full-width">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.scheduler_detail">定时任务详情</h2>
|
||||
<span class="badge" id="scheduler-detail-badge" data-i18n="status.checking">检查中</span>
|
||||
<button class="btn btn-small" onclick="refreshSchedulerPage()" data-i18n="btn.refresh">刷新</button>
|
||||
<h2 data-i18n="monitor.card.scheduler_detail">定时任务详情</h2>
|
||||
<span class="badge" id="scheduler-detail-badge" data-i18n="monitor.status.checking">检查中</span>
|
||||
<button class="btn btn-small" onclick="refreshSchedulerPage()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="scheduler-detail-grid" id="scheduler-detail-grid">
|
||||
@@ -397,7 +397,7 @@
|
||||
<main class="main-content page-content" id="page-outbound-requests">
|
||||
<section class="card full-width">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.outbound_requests_log">发送请求记录</h2>
|
||||
<h2 data-i18n="monitor.card.outbound_requests_log">发送请求记录</h2>
|
||||
<div class="card-actions">
|
||||
<div class="date-selector" style="display: none;">
|
||||
<label for="outbound-date-picker">选择日期:</label>
|
||||
@@ -408,11 +408,11 @@
|
||||
<label>
|
||||
<input type="checkbox" id="show-internal-requests" onchange="toggleInternalRequests()">
|
||||
<span class="toggle-slider"></span>
|
||||
<span data-i18n="other.show_internal">显示内部请求</span>
|
||||
<span data-i18n="monitor.other.show_internal">显示内部请求</span>
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-sm" onclick="refreshOutboundRequests()" data-i18n="btn.refresh">刷新</button>
|
||||
<button class="btn btn-sm btn-secondary" onclick="resetOutboundStats()" data-i18n="btn.reset_stats">重置统计</button>
|
||||
<button class="btn btn-sm" onclick="refreshOutboundRequests()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
<button class="btn btn-sm btn-secondary" onclick="resetOutboundStats()" data-i18n="monitor.btn.reset_stats">重置统计</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -421,14 +421,14 @@
|
||||
<table class="outbound-requests-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="col.index">序号</th>
|
||||
<th data-i18n="col.timestamp">时间戳</th>
|
||||
<th data-i18n="col.method">方法</th>
|
||||
<th data-i18n="col.url">URL</th>
|
||||
<th data-i18n="col.status">状态码</th>
|
||||
<th data-i18n="col.duration">响应时间</th>
|
||||
<th data-i18n="col.module">模块</th>
|
||||
<th data-i18n="col.error_message">错误信息</th>
|
||||
<th data-i18n="monitor.col.index">序号</th>
|
||||
<th data-i18n="monitor.col.timestamp">时间戳</th>
|
||||
<th data-i18n="monitor.col.method">方法</th>
|
||||
<th data-i18n="monitor.col.url">URL</th>
|
||||
<th data-i18n="monitor.col.status">状态码</th>
|
||||
<th data-i18n="monitor.col.duration">响应时间</th>
|
||||
<th data-i18n="monitor.col.module">模块</th>
|
||||
<th data-i18n="monitor.col.error_message">错误信息</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="outbound-requests-table">
|
||||
@@ -447,23 +447,23 @@
|
||||
<div class="card-header">
|
||||
<h2>Warning & Error</h2>
|
||||
<div class="log-page-controls">
|
||||
<button class="btn btn-primary" onclick="window.open('/monitor/live-logs', '_blank')" data-i18n="btn.live_logs">实时日志</button>
|
||||
<button class="btn btn-primary" onclick="window.open('/monitor/history-logs', '_blank')" data-i18n="btn.history_query">历史查询</button>
|
||||
<button class="btn btn-primary" onclick="window.open('/monitor/live-logs', '_blank')" data-i18n="monitor.btn.live_logs">实时日志</button>
|
||||
<button class="btn btn-primary" onclick="window.open('/monitor/history-logs', '_blank')" data-i18n="monitor.btn.history_query">历史查询</button>
|
||||
<div class="toggle-switch">
|
||||
<label>
|
||||
<input type="checkbox" id="show-read-logs" onchange="toggleReadLogs()">
|
||||
<span class="toggle-slider"></span>
|
||||
<span data-i18n="other.show_read">显示已读</span>
|
||||
<span data-i18n="monitor.other.show_read">显示已读</span>
|
||||
</label>
|
||||
</div>
|
||||
<select id="log-page-level" onchange="fetchLogsPage()">
|
||||
<option value="" data-i18n="filter.all_logs">全部日志</option>
|
||||
<option value="" data-i18n="monitor.filter.all_logs">全部日志</option>
|
||||
<option value="error">错误日志</option>
|
||||
<option value="warning">警告日志</option>
|
||||
</select>
|
||||
<button class="btn btn-small" onclick="markAllLogsAsRead()" data-i18n="btn.mark_all_read">标记全部已读</button>
|
||||
<button class="btn btn-small" onclick="clearReadStatus()" data-i18n="btn.clear_read_status">清空已读状态</button>
|
||||
<button class="btn btn-small" onclick="refreshLogsPage()" data-i18n="btn.refresh">刷新</button>
|
||||
<button class="btn btn-small" onclick="markAllLogsAsRead()" data-i18n="monitor.btn.mark_all_read">标记全部已读</button>
|
||||
<button class="btn btn-small" onclick="clearReadStatus()" data-i18n="monitor.btn.clear_read_status">清空已读状态</button>
|
||||
<button class="btn btn-small" onclick="refreshLogsPage()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -471,12 +471,12 @@
|
||||
<table class="logs-table" id="logs-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="col.index">序号</th>
|
||||
<th data-i18n="col.time">时间</th>
|
||||
<th data-i18n="col.level">级别</th>
|
||||
<th data-i18n="col.module">模块</th>
|
||||
<th data-i18n="col.message">消息</th>
|
||||
<th data-i18n="col.is_read">已读</th>
|
||||
<th data-i18n="monitor.col.index">序号</th>
|
||||
<th data-i18n="monitor.col.time">时间</th>
|
||||
<th data-i18n="monitor.col.level">级别</th>
|
||||
<th data-i18n="monitor.col.module">模块</th>
|
||||
<th data-i18n="monitor.col.message">消息</th>
|
||||
<th data-i18n="monitor.col.is_read">已读</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="logs-tbody">
|
||||
@@ -493,55 +493,55 @@
|
||||
<!-- 事件监听卡片 -->
|
||||
<section class="card full-width">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.event_listener">事件监听</h2>
|
||||
<h2 data-i18n="monitor.card.event_listener">事件监听</h2>
|
||||
<div class="events-actions">
|
||||
<button class="btn btn-small" onclick="refreshEventStats()" data-i18n="btn.refresh">刷新</button>
|
||||
<button class="btn btn-small" onclick="flushAllEvents()" data-i18n="btn.flush_all">立即刷新所有</button>
|
||||
<button class="btn btn-small btn-secondary" onclick="resetEventStats()" data-i18n="btn.reset_stats">重置统计</button>
|
||||
<button class="btn btn-small" onclick="refreshEventStats()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
<button class="btn btn-small" onclick="flushAllEvents()" data-i18n="monitor.btn.flush_all">立即刷新所有</button>
|
||||
<button class="btn btn-small btn-secondary" onclick="resetEventStats()" data-i18n="monitor.btn.reset_stats">重置统计</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="events-summary" id="events-summary">
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.events_received">总接收事件</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.events_received">总接收事件</span>
|
||||
<span class="summary-value" id="events-total-received">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.events_processed">已处理事件</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.events_processed">已处理事件</span>
|
||||
<span class="summary-value healthy" id="events-total-processed">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.events_interrupted">中断处理</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.events_interrupted">中断处理</span>
|
||||
<span class="summary-value error" id="events-total-failed">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.pending">待处理</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.pending">待处理</span>
|
||||
<span class="summary-value" id="events-total-pending">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.overall_success_rate">整体成功率</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.overall_success_rate">整体成功率</span>
|
||||
<span class="summary-value" id="events-success-rate">--%</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.active_event_types">活跃事件类型</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.active_event_types">活跃事件类型</span>
|
||||
<span class="summary-value" id="events-active-types">--</span>
|
||||
</div>
|
||||
<!-- 背压监控 -->
|
||||
<div class="summary-item" id="backpressure-summary" style="display: none;">
|
||||
<span class="summary-label" data-i18n="metric.backpressure_status">背压状态</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.backpressure_status">背压状态</span>
|
||||
<span class="summary-value" id="backpressure-status">正常</span>
|
||||
</div>
|
||||
<div class="summary-item" id="backpressure-pending" style="display: none;">
|
||||
<span class="summary-label" data-i18n="metric.backpressure_pending">待处理事件</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.backpressure_pending">待处理事件</span>
|
||||
<span class="summary-value" id="backpressure-pending-count">--</span>
|
||||
</div>
|
||||
<div class="summary-item" id="backpressure-percent" style="display: none;">
|
||||
<span class="summary-label" data-i18n="metric.backpressure_usage">背压使用率</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.backpressure_usage">背压使用率</span>
|
||||
<span class="summary-value" id="backpressure-usage">--%</span>
|
||||
</div>
|
||||
<!-- 事件循环健康状态 -->
|
||||
<div class="summary-item" id="event-loop-status" style="display: none;">
|
||||
<span class="summary-label" data-i18n="metric.event_loop_status">事件循环状态</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.event_loop_status">事件循环状态</span>
|
||||
<span class="summary-value" id="event-loop-health">正常</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -549,17 +549,17 @@
|
||||
<table class="events-table" id="events-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="col.description">描述</th>
|
||||
<th data-i18n="col.total_received">总接收</th>
|
||||
<th data-i18n="col.pending">待处理</th>
|
||||
<th data-i18n="col.processed">已处理</th>
|
||||
<th data-i18n="col.interrupted">中断</th>
|
||||
<th data-i18n="col.completion_rate">完成率</th>
|
||||
<th data-i18n="col.avg_latency">平均延迟</th>
|
||||
<th data-i18n="col.operation">操作</th>
|
||||
<th data-i18n="col.last_action">最后动作</th>
|
||||
<th data-i18n="col.status">状态</th>
|
||||
<th data-i18n="col.operation">操作</th>
|
||||
<th data-i18n="monitor.col.description">描述</th>
|
||||
<th data-i18n="monitor.col.total_received">总接收</th>
|
||||
<th data-i18n="monitor.col.pending">待处理</th>
|
||||
<th data-i18n="monitor.col.processed">已处理</th>
|
||||
<th data-i18n="monitor.col.interrupted">中断</th>
|
||||
<th data-i18n="monitor.col.completion_rate">完成率</th>
|
||||
<th data-i18n="monitor.col.avg_latency">平均延迟</th>
|
||||
<th data-i18n="monitor.col.operation">操作</th>
|
||||
<th data-i18n="monitor.col.last_action">最后动作</th>
|
||||
<th data-i18n="monitor.col.status">状态</th>
|
||||
<th data-i18n="monitor.col.operation">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="events-tbody">
|
||||
@@ -577,21 +577,21 @@
|
||||
<!-- 回调跟踪器卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.callback_tracker">回调跟踪器</h2>
|
||||
<span class="badge" id="callback-badge" data-i18n="status.monitoring">监控中</span>
|
||||
<h2 data-i18n="monitor.card.callback_tracker">回调跟踪器</h2>
|
||||
<span class="badge" id="callback-badge" data-i18n="monitor.status.monitoring">监控中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.pending_callbacks">待处理回调</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.pending_callbacks">待处理回调</div>
|
||||
<div class="metric-value" id="callback-pending">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.max_retries">最大重试次数</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.max_retries">最大重试次数</div>
|
||||
<div class="metric-value" id="callback-max-retries">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.pending_retries">待处理重试</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.pending_retries">待处理重试</div>
|
||||
<div class="metric-value" id="callback-pending-retries">--</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -601,25 +601,25 @@
|
||||
<!-- 事件去重器卡片 -->
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h2 data-i18n="card.event_deduplicator">事件去重器</h2>
|
||||
<span class="badge" id="deduplicator-badge" data-i18n="status.monitoring">监控中</span>
|
||||
<h2 data-i18n="monitor.card.event_deduplicator">事件去重器</h2>
|
||||
<span class="badge" id="deduplicator-badge" data-i18n="monitor.status.monitoring">监控中</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.total_entries">总存储条目</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.total_entries">总存储条目</div>
|
||||
<div class="metric-value" id="deduplicator-total">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.active_items">活跃项目</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.active_items">活跃项目</div>
|
||||
<div class="metric-value" id="deduplicator-active">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.ttl_seconds">TTL (秒)</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.ttl_seconds">TTL (秒)</div>
|
||||
<div class="metric-value" id="deduplicator-ttl">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.max_entries">最大条目</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.max_entries">最大条目</div>
|
||||
<div class="metric-value" id="deduplicator-max">--</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -633,40 +633,40 @@
|
||||
<div class="card-header">
|
||||
<h2>Dead Letter Queue</h2>
|
||||
<div class="dead-letter-actions">
|
||||
<button class="btn btn-small" onclick="refreshDeadLetterStats()" data-i18n="btn.refresh">刷新</button>
|
||||
<button class="btn btn-small btn-secondary" onclick="clearDeadLetters()" data-i18n="btn.clear">清空</button>
|
||||
<button class="btn btn-small" onclick="refreshDeadLetterStats()" data-i18n="monitor.btn.refresh">刷新</button>
|
||||
<button class="btn btn-small btn-secondary" onclick="clearDeadLetters()" data-i18n="monitor.btn.clear">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.pending_events">待写入事件</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.pending_events">待写入事件</div>
|
||||
<div class="metric-value" id="dlq-pending">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.total_events">总事件数</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.total_events">总事件数</div>
|
||||
<div class="metric-value" id="dlq-total">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.file_size">文件大小</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.file_size">文件大小</div>
|
||||
<div class="metric-value" id="dlq-file-size">--</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-label" data-i18n="metric.running_status">运行状态</div>
|
||||
<div class="metric-label" data-i18n="monitor.metric.running_status">运行状态</div>
|
||||
<div class="metric-value" id="dlq-running">--</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dead-letter-summary" id="dead-letter-summary" style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #e2e8f0;">
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.dl_total">DL总数</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.dl_total">DL总数</span>
|
||||
<span class="summary-value" id="dead-letter-total">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.recent_dl">最近DL</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.recent_dl">最近DL</span>
|
||||
<span class="summary-value" id="dead-letter-recent">--</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label" data-i18n="metric.process_success_rate">处理成功率</span>
|
||||
<span class="summary-label" data-i18n="monitor.metric.process_success_rate">处理成功率</span>
|
||||
<span class="summary-value" id="dead-letter-success-rate">--%</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -674,13 +674,13 @@
|
||||
<table class="dead-letter-table" id="dead-letter-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="col.id">ID</th>
|
||||
<th data-i18n="col.event_type">事件类型</th>
|
||||
<th data-i18n="col.time">时间</th>
|
||||
<th data-i18n="col.database">数据库</th>
|
||||
<th data-i18n="col.table">表</th>
|
||||
<th data-i18n="col.error_message">错误信息</th>
|
||||
<th data-i18n="col.operation">操作</th>
|
||||
<th data-i18n="monitor.col.id">ID</th>
|
||||
<th data-i18n="monitor.col.event_type">事件类型</th>
|
||||
<th data-i18n="monitor.col.time">时间</th>
|
||||
<th data-i18n="monitor.col.database">数据库</th>
|
||||
<th data-i18n="monitor.col.table">表</th>
|
||||
<th data-i18n="monitor.col.error_message">错误信息</th>
|
||||
<th data-i18n="monitor.col.operation">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dead-letter-tbody">
|
||||
|
||||
+179
-179
File diff suppressed because it is too large
Load Diff
@@ -331,10 +331,10 @@
|
||||
<div class="live-logs-container">
|
||||
<div class="live-logs-header">
|
||||
<div class="live-logs-header-left">
|
||||
<h3 data-i18n="page.live_logs">实时日志流</h3>
|
||||
<h3 data-i18n="monitor.page.live_logs">实时日志流</h3>
|
||||
<div class="connection-status">
|
||||
<div class="status-dot connecting" id="statusDot"></div>
|
||||
<span id="statusText" data-i18n="status.connecting">连接中...</span>
|
||||
<span id="statusText" data-i18n="monitor.status.connecting">连接中...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -345,9 +345,9 @@
|
||||
<option value="de-DE">🇩🇪 Deutsch</option>
|
||||
</select>
|
||||
<div class="header-control-group">
|
||||
<label data-i18n="filter.level">级别:</label>
|
||||
<label data-i18n="monitor.filter.level">级别:</label>
|
||||
<select id="levelFilter" onchange="applyFilters()">
|
||||
<option value="" data-i18n="filter.level">全部</option>
|
||||
<option value="" data-i18n="monitor.filter.level">全部</option>
|
||||
<option value="INFO" selected>INFO</option>
|
||||
<option value="WARNING">WARNING</option>
|
||||
<option value="ERROR">ERROR</option>
|
||||
@@ -360,7 +360,7 @@
|
||||
</div>
|
||||
|
||||
<div class="header-control-group">
|
||||
<label data-i18n="other.auto_scroll">自动滚动</label>
|
||||
<label data-i18n="monitor.other.auto_scroll">自动滚动</label>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="autoScroll" checked onchange="toggleAutoScroll()">
|
||||
<span class="toggle-slider"></span>
|
||||
@@ -368,17 +368,17 @@
|
||||
</div>
|
||||
|
||||
<button class="btn btn-secondary" onclick="togglePause()">
|
||||
<span id="pauseBtnText" data-i18n="btn.pause">暂停</span>
|
||||
<span id="pauseBtnText" data-i18n="monitor.btn.pause">暂停</span>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-danger" onclick="clearLogs()" data-i18n="btn.clear">清空</button>
|
||||
<button class="btn btn-danger" onclick="clearLogs()" data-i18n="monitor.btn.clear">清空</button>
|
||||
|
||||
<button class="btn btn-primary" onclick="openInNewWindow()" data-i18n="btn.new_window">新窗口</button>
|
||||
<button class="btn btn-primary" onclick="openInNewWindow()" data-i18n="monitor.btn.new_window">新窗口</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="log-stats">
|
||||
<span data-i18n="metric.total">总日志: <strong id="totalCount">0</strong></span>
|
||||
<span data-i18n="monitor.metric.total">总日志: <strong id="totalCount">0</strong></span>
|
||||
<span>DEBUG: <span class="level-count DEBUG" id="debugCount">0</span></span>
|
||||
<span>INFO: <span class="level-count INFO" id="infoCount">0</span></span>
|
||||
<span>WARNING: <span class="level-count WARNING" id="warningCount">0</span></span>
|
||||
@@ -387,7 +387,7 @@
|
||||
</div>
|
||||
|
||||
<div class="logs-container" id="logsContainer">
|
||||
<div class="no-logs" id="noLogs" data-i18n="other.waiting_logs">
|
||||
<div class="no-logs" id="noLogs" data-i18n="monitor.other.waiting_logs">
|
||||
正在等待日志数据...
|
||||
</div>
|
||||
</div>
|
||||
@@ -549,7 +549,7 @@
|
||||
if (isDomReady) {
|
||||
const statusText = document.getElementById('statusText');
|
||||
if (statusText) {
|
||||
statusText.textContent = i18n.t('error.connection_failed');
|
||||
statusText.textContent = i18n.t('monitor.error.connection_failed');
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -605,14 +605,14 @@
|
||||
switch (status) {
|
||||
case 'connected':
|
||||
dot.classList.add('connected');
|
||||
text.textContent = i18n.t('status.connected');
|
||||
text.textContent = i18n.t('monitor.status.connected');
|
||||
break;
|
||||
case 'connecting':
|
||||
dot.classList.add('connecting');
|
||||
text.textContent = i18n.t('status.connecting');
|
||||
text.textContent = i18n.t('monitor.status.connecting');
|
||||
break;
|
||||
case 'disconnected':
|
||||
text.textContent = i18n.t('status.disconnected') + ' (' + i18n.t('other.auto_reconnect') + ')';
|
||||
text.textContent = i18n.t('monitor.status.disconnected') + ' (' + i18n.t('monitor.other.auto_reconnect') + ')';
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -727,7 +727,7 @@
|
||||
}
|
||||
|
||||
if (logs.length === 0) {
|
||||
container.innerHTML = '<div class="no-logs" id="noLogs">' + i18n.t('other.waiting_logs') + '</div>';
|
||||
container.innerHTML = '<div class="no-logs" id="noLogs">' + i18n.t('monitor.other.waiting_logs') + '</div>';
|
||||
lastRenderIndex = 0;
|
||||
return;
|
||||
}
|
||||
@@ -743,7 +743,7 @@
|
||||
});
|
||||
|
||||
if (filteredLogs.length === 0) {
|
||||
container.innerHTML = '<div class="no-logs" id="noLogs">' + i18n.t('other.no_matching_logs') + '</div>';
|
||||
container.innerHTML = '<div class="no-logs" id="noLogs">' + i18n.t('monitor.other.no_matching_logs') + '</div>';
|
||||
lastRenderIndex = 0;
|
||||
return;
|
||||
}
|
||||
@@ -816,7 +816,7 @@
|
||||
const autoScrollIndicator = document.getElementById('autoScrollIndicator');
|
||||
|
||||
if (pauseBtnText) {
|
||||
pauseBtnText.textContent = isPaused ? i18n.t('btn.resume') : i18n.t('btn.pause');
|
||||
pauseBtnText.textContent = isPaused ? i18n.t('monitor.btn.resume') : i18n.t('monitor.btn.pause');
|
||||
}
|
||||
if (autoScrollIndicator) {
|
||||
autoScrollIndicator.classList.toggle('show', isPaused);
|
||||
@@ -861,7 +861,7 @@
|
||||
updateStats();
|
||||
const logsContainer = document.getElementById('logsContainer');
|
||||
if (logsContainer) {
|
||||
logsContainer.innerHTML = '<div class="no-logs">' + i18n.t('success.logs_cleared') + '</div>';
|
||||
logsContainer.innerHTML = '<div class="no-logs">' + i18n.t('monitor.success.logs_cleared') + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user