chore: 初始提交 Fonu 1.0.2
- 公网反代:Nginx 状态卡片(版本 / 运行状态 / 配置校验 / 端口监听) - 部署设置第一、二梯队(HTTPS 开关、安全头、限流、连接数、仅中国大陆 IP) - 隧道检测兼容 frps v0.68 / v0.71(V2 与旧版端点) - 恢复被清空的 internal/frp/store.go、internal/api/ddns_handler.go、web/src/views/DdnsView.vue
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
package logstore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func localizeSystemEntry(entry SystemEntry, raw map[string]any) SystemEntry {
|
||||
msg := strings.TrimSpace(entry.Message)
|
||||
if msg == "" {
|
||||
return entry
|
||||
}
|
||||
entry.Module = localizeSystemModule(entry.Module)
|
||||
entry.Message = localizeSystemMessage(msg, raw)
|
||||
return entry
|
||||
}
|
||||
|
||||
func localizeSystemModule(module string) string {
|
||||
switch strings.ToUpper(strings.TrimSpace(module)) {
|
||||
case "SYSTEM":
|
||||
return "系统"
|
||||
case "NGINX":
|
||||
return "Nginx"
|
||||
case "DDNS":
|
||||
return "域名解析"
|
||||
case "ACME", "CERT":
|
||||
return "证书"
|
||||
case "CHINA_CIDR":
|
||||
return "中国 IP 段"
|
||||
case "API":
|
||||
return "API"
|
||||
case "HTTP":
|
||||
return "HTTP"
|
||||
case "FRP":
|
||||
return "内网穿透"
|
||||
default:
|
||||
if module == "" {
|
||||
return "系统"
|
||||
}
|
||||
return module
|
||||
}
|
||||
}
|
||||
|
||||
func localizeSystemMessage(msg string, raw map[string]any) string {
|
||||
if looksChinese(msg) {
|
||||
return appendSystemAttrs(msg, raw)
|
||||
}
|
||||
|
||||
switch msg {
|
||||
case "application started":
|
||||
if listen := rawString(raw, "listen"); listen != "" {
|
||||
return fmt.Sprintf("应用已启动,监听 %s", listen)
|
||||
}
|
||||
return "应用已启动"
|
||||
case "application shutting down":
|
||||
return "应用正在关闭"
|
||||
case "nginx started":
|
||||
return "Nginx 已启动"
|
||||
case "nginx stopped":
|
||||
return "Nginx 已停止"
|
||||
case "nginx reloaded":
|
||||
return "Nginx 已重载"
|
||||
case "nginx reloaded existing master":
|
||||
return "Nginx 已重载(使用现有主进程)"
|
||||
case "nginx start skipped duplicate master, reloaded instead":
|
||||
return "检测到重复 Nginx 主进程,已改为重载"
|
||||
case "nginx reload failed, trying restart":
|
||||
return fmt.Sprintf("Nginx 重载失败,正在尝试重启:%s", rawString(raw, "error"))
|
||||
case "nginx signal reload failed, falling back to cli":
|
||||
return fmt.Sprintf("Nginx 信号重载失败,回退到命令行重载(PID %s):%s", rawString(raw, "pid"), rawString(raw, "error"))
|
||||
case "nginx command failed":
|
||||
return fmt.Sprintf("Nginx 命令执行失败(%s):%s", rawString(raw, "args"), rawString(raw, "error"))
|
||||
case "nginx start failed":
|
||||
return fmt.Sprintf("Nginx 启动失败(%s):%s", rawString(raw, "args"), rawString(raw, "error"))
|
||||
case "nginx binary not found, applied syntax-only validation":
|
||||
return fmt.Sprintf("未找到 Nginx 可执行文件,仅进行配置语法校验(%s)", rawString(raw, "bin"))
|
||||
case "nginx binary not found, syntax-only validation":
|
||||
return fmt.Sprintf("未找到 Nginx 可执行文件,仅进行语法校验(%s)", rawString(raw, "bin"))
|
||||
case "initial nginx apply skipped":
|
||||
return fmt.Sprintf("初始 Nginx 配置应用已跳过:%s", rawString(raw, "error"))
|
||||
case "initial frpc bootstrap skipped":
|
||||
return fmt.Sprintf("初始 frpc 引导已跳过:%s", rawString(raw, "error"))
|
||||
case "nginx stop failed":
|
||||
return fmt.Sprintf("Nginx 停止失败:%s", rawString(raw, "error"))
|
||||
case "frpc stop failed":
|
||||
return fmt.Sprintf("frpc 停止失败:%s", rawString(raw, "error"))
|
||||
case "frpc started":
|
||||
return "frpc 已启动"
|
||||
case "frpc stopped":
|
||||
return "frpc 已停止"
|
||||
case "frpc reloaded":
|
||||
return "frpc 已重载"
|
||||
case "frpc reload failed, trying restart":
|
||||
return fmt.Sprintf("frpc 重载失败,正在尝试重启:%s", rawString(raw, "error"))
|
||||
case "frpc binary not found, skipping bootstrap":
|
||||
return fmt.Sprintf("未找到 frpc 可执行文件,已跳过引导(%s)", rawString(raw, "bin"))
|
||||
case "initial frpc apply skipped":
|
||||
return fmt.Sprintf("初始 frpc 配置应用已跳过:%s", rawString(raw, "error"))
|
||||
case "frpc exited during start":
|
||||
return fmt.Sprintf("frpc 启动过程中退出:%s", rawString(raw, "error"))
|
||||
case "china cidr update failed":
|
||||
return fmt.Sprintf("中国 IP 段更新失败:%s", rawString(raw, "error"))
|
||||
case "china cidr updated":
|
||||
return fmt.Sprintf("中国 IP 段已更新(IPv4 %s 条,IPv6 %s 条)", rawString(raw, "v4"), rawString(raw, "v6"))
|
||||
case "ddns update failed":
|
||||
return fmt.Sprintf("DDNS 更新失败(%s):%s", rawString(raw, "domain"), rawString(raw, "error"))
|
||||
case "ddns ipv4 updated":
|
||||
return fmt.Sprintf("DDNS IPv4 已更新:%s → %s", rawString(raw, "domain"), rawString(raw, "ip"))
|
||||
case "ddns ipv6 updated":
|
||||
return fmt.Sprintf("DDNS IPv6 已更新:%s → %s", rawString(raw, "domain"), rawString(raw, "ip"))
|
||||
case "ddns records updated":
|
||||
return fmt.Sprintf("DDNS 记录已更新(服务商:%s)", rawString(raw, "provider"))
|
||||
case "notify load config failed":
|
||||
return fmt.Sprintf("通知配置加载失败:%s", rawString(raw, "error"))
|
||||
case "notify send failed":
|
||||
return fmt.Sprintf("通知发送失败(%s):%s", rawString(raw, "event"), rawString(raw, "error"))
|
||||
case "notify test send failed":
|
||||
return fmt.Sprintf("通知测试发送失败:%s", rawString(raw, "error"))
|
||||
case "request failed":
|
||||
return fmt.Sprintf("API 请求失败(%s %s,状态 %s):%s",
|
||||
rawString(raw, "method"), rawString(raw, "path"), rawString(raw, "status"), rawString(raw, "message"))
|
||||
case "request rejected":
|
||||
return fmt.Sprintf("API 请求被拒绝(%s %s,状态 %s):%s",
|
||||
rawString(raw, "method"), rawString(raw, "path"), rawString(raw, "status"), rawString(raw, "message"))
|
||||
case "api request completed with client error":
|
||||
return fmt.Sprintf("API 请求返回客户端错误(%s %s,状态 %s,耗时 %sms)",
|
||||
rawString(raw, "method"), rawString(raw, "path"), rawString(raw, "status"), rawString(raw, "duration_ms"))
|
||||
case "api request failed":
|
||||
return fmt.Sprintf("API 请求返回服务端错误(%s %s,状态 %s,耗时 %sms)",
|
||||
rawString(raw, "method"), rawString(raw, "path"), rawString(raw, "status"), rawString(raw, "duration_ms"))
|
||||
case "certificate operation failed":
|
||||
return fmt.Sprintf("证书操作失败(%s):%s", rawString(raw, "domain"), rawString(raw, "error"))
|
||||
case "certificate obtained":
|
||||
return fmt.Sprintf("证书已获取:%s(CA %s,到期 %s)",
|
||||
rawString(raw, "domain"), rawString(raw, "ca"), rawString(raw, "expires_at"))
|
||||
case "certificate imported":
|
||||
return fmt.Sprintf("证书已导入:%s(到期 %s)", rawString(raw, "domain"), rawString(raw, "expires_at"))
|
||||
case "certificate deleted":
|
||||
return fmt.Sprintf("证书已删除:%s", rawString(raw, "domain"))
|
||||
case "certificate renew failed":
|
||||
return fmt.Sprintf("证书续签失败(%s):%s", rawString(raw, "domain"), rawString(raw, "error"))
|
||||
case "save cert error status failed":
|
||||
return fmt.Sprintf("保存证书错误状态失败(%s):%s", rawString(raw, "domain"), rawString(raw, "error"))
|
||||
case "nginx reload after cert apply failed":
|
||||
return fmt.Sprintf("证书申请后 Nginx 重载失败:%s", rawString(raw, "error"))
|
||||
case "nginx reload after cert import failed":
|
||||
return fmt.Sprintf("证书导入后 Nginx 重载失败:%s", rawString(raw, "error"))
|
||||
case "nginx reload after cert delete failed":
|
||||
return fmt.Sprintf("证书删除后 Nginx 重载失败:%s", rawString(raw, "error"))
|
||||
case "nginx reload after cert renew failed":
|
||||
return fmt.Sprintf("证书续签后 Nginx 重载失败:%s", rawString(raw, "error"))
|
||||
case "save acme ca setting failed":
|
||||
return fmt.Sprintf("保存 ACME 颁发机构设置失败:%s", rawString(raw, "error"))
|
||||
case "save acme email failed":
|
||||
return fmt.Sprintf("保存 ACME 邮箱失败:%s", rawString(raw, "error"))
|
||||
case "remove cert files failed":
|
||||
return fmt.Sprintf("删除证书文件失败(%s):%s", rawString(raw, "domain"), rawString(raw, "error"))
|
||||
default:
|
||||
return appendSystemAttrs(msg, raw)
|
||||
}
|
||||
}
|
||||
|
||||
func appendSystemAttrs(msg string, raw map[string]any) string {
|
||||
if strings.Contains(msg, "首次启动已创建管理员账户") {
|
||||
username := rawString(raw, "username")
|
||||
password := rawString(raw, "password")
|
||||
if username != "" && password != "" {
|
||||
return fmt.Sprintf("%s(用户名:%s,密码:%s)", msg, username, password)
|
||||
}
|
||||
}
|
||||
if err := rawString(raw, "error"); err != "" && !strings.Contains(msg, err) {
|
||||
return fmt.Sprintf("%s:%s", msg, err)
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func looksChinese(msg string) bool {
|
||||
for _, r := range msg {
|
||||
if r >= 0x4e00 && r <= 0x9fff {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func rawString(raw map[string]any, key string) string {
|
||||
v, ok := raw[key]
|
||||
if !ok || v == nil {
|
||||
return ""
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return t
|
||||
case float64:
|
||||
if t == float64(int64(t)) {
|
||||
return fmt.Sprintf("%d", int64(t))
|
||||
}
|
||||
return fmt.Sprintf("%v", t)
|
||||
case int:
|
||||
return fmt.Sprintf("%d", t)
|
||||
case int64:
|
||||
return fmt.Sprintf("%d", t)
|
||||
case bool:
|
||||
if t {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
default:
|
||||
return fmt.Sprintf("%v", t)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user