diff --git a/core/services.yaml b/core/services.yaml index 2dedd24..3177a6a 100644 --- a/core/services.yaml +++ b/core/services.yaml @@ -71,7 +71,7 @@ services: # --- 安全链路 --- - name: waf cmd: bash /opt/micro_servers/waf/_run.sh - args: [] # -c config.yaml 保留在 _run.sh 作为默认值 + args: ["--instance", "waf", "--log-level", "info"] depends_on: [ca, gateway] sleep_before: 0 diff --git a/waf/internal/logclient/logclient.go b/waf/internal/logclient/logclient.go index 8523b60..554bb46 100644 --- a/waf/internal/logclient/logclient.go +++ b/waf/internal/logclient/logclient.go @@ -30,13 +30,47 @@ const ( maxMsgSize = 64 * 1024 * 1024 ) +// 日志级别数值(越小越详细)。 +const ( + levelDebug = 0 + levelInfo = 1 + levelWarn = 2 + levelError = 3 +) + +var levelMap = map[string]int{ + "debug": levelDebug, + "info": levelInfo, + "warn": levelWarn, + "warning": levelWarn, + "error": levelError, + "DEBUG": levelDebug, + "INFO": levelInfo, + "WARN": levelWarn, + "WARNING": levelWarn, + "ERROR": levelError, +} + // dbAddr 通过环境变量 LOG_DB_ADDR 配置(默认 127.0.0.1:8005),支持非标准部署场景。 var dbAddr = defaultDBAddr +// minLevel 控制最低输出级别,默认 info(debug 被过滤)。 +var minLevel = levelInfo + func init() { if v := os.Getenv("LOG_DB_ADDR"); v != "" { dbAddr = v } + if v := os.Getenv("LOG_LEVEL"); v != "" { + SetLevel(v) + } +} + +// SetLevel 设置最低日志级别(debug|info|warn|error,大小写不敏感)。 +func SetLevel(level string) { + if n, ok := levelMap[level]; ok { + minLevel = n + } } // Entry 单条日志。 @@ -93,10 +127,15 @@ func New() *Client { } // Push 推送一条日志(非阻塞,队列满时丢弃)。 +// 低于 SetLevel 设定的最低级别的日志将被静默丢弃。 func Push(service, level, message string, extra map[string]any) { if global == nil { return } + n, ok := levelMap[level] + if !ok || n < minLevel { + return + } global.push(Entry{ Service: service, Level: level, @@ -105,6 +144,11 @@ func Push(service, level, message string, extra map[string]any) { }) } +// Debug 推送 DEBUG 级别日志。 +func Debug(service, message string, extra map[string]any) { + Push(service, "DEBUG", message, extra) +} + // Info 推送 INFO 级别日志。 func Info(service, message string, extra map[string]any) { Push(service, "INFO", message, extra) diff --git a/waf/main.go b/waf/main.go index d5f95c9..a72cf16 100644 --- a/waf/main.go +++ b/waf/main.go @@ -42,15 +42,66 @@ type Config struct { func main() { var ( - configFile = flag.String("c", "config.yaml", "配置文件路径") - doList = flag.Bool("list", false, "列出所有规则后退出") - doTest = flag.String("test", "", "校验单个规则文件语法后退出") - doCheck = flag.String("check", "", "用当前规则测试输入字符串(URI/path)后退出") + configFile = flag.String("c", "config.yaml", "配置文件路径") + doList = flag.Bool("list", false, "列出所有规则后退出") + doTest = flag.String("test", "", "校验单个规则文件语法后退出") + doCheck = flag.String("check", "", "用当前规则测试输入字符串(URI/path)后退出") + // CLI 标准化参数(覆盖 config.yaml) + cliListen = flag.String("listen", "", "监听地址(别名: --host),覆盖 config.yaml") + cliHost = flag.String("host", "", "监听地址(--listen 别名)") + cliUpstream = flag.String("upstream", "", "gateway 地址,覆盖 config.yaml") + cliTLSCert = flag.String("tls-cert", "", "TLS 证书文件,覆盖 config.yaml") + cliTLSKey = flag.String("tls-key", "", "TLS 私钥文件,覆盖 config.yaml") + cliRulesDir = flag.String("rules-dir", "", "规则根目录,覆盖 config.yaml") + logLevel = flag.String("log-level", "info", "日志级别: debug|info|warn|error") + instance = flag.String("instance", "waf", "实例名(注册中心用)") ) + flag.Usage = func() { + fmt.Fprintf(os.Stderr, + "waf — WAF 入口网关\n\n"+ + "用法: waf [选项]\n\n"+ + "选项:\n"+ + " -c 配置文件路径,默认 config.yaml\n"+ + " --listen 监听地址(别名: --host),覆盖 config.yaml\n"+ + " --upstream gateway 地址,覆盖 config.yaml\n"+ + " --tls-cert TLS 证书文件,覆盖 config.yaml\n"+ + " --tls-key TLS 私钥文件,覆盖 config.yaml\n"+ + " --rules-dir 规则根目录,覆盖 config.yaml\n"+ + " --log-level debug|info|warn|error,默认 info\n"+ + " --instance 实例名,默认 waf\n"+ + " -list 列出所有规则后退出\n"+ + " -test 校验单个规则文件语法后退出\n"+ + " -check 用当前规则测试输入字符串后退出\n"+ + " -h, --help 显示此帮助并退出\n\n"+ + "配置优先级: CLI > config.yaml\n") + } flag.Parse() + // 日志级别 + logclient.SetLevel(*logLevel) + cfg := loadConfig(*configFile) + // CLI 覆盖 config.yaml + if *cliListen != "" { + cfg.Listen = *cliListen + } + if *cliHost != "" { + cfg.Listen = *cliHost + } + if *cliUpstream != "" { + cfg.Upstream = *cliUpstream + } + if *cliTLSCert != "" { + cfg.TLSCert = *cliTLSCert + } + if *cliTLSKey != "" { + cfg.TLSKey = *cliTLSKey + } + if *cliRulesDir != "" { + cfg.RulesDir = *cliRulesDir + } + // 子命令:极客 CLI 工具 if *doTest != "" { if err := engine.TestFile(*doTest); err != nil { @@ -146,8 +197,8 @@ func main() { termCh := make(chan os.Signal, 1) signal.Notify(termCh, syscall.SIGINT, syscall.SIGTERM) - logclient.Info("waf", fmt.Sprintf("服务启动 listen=%s upstream=%s rules=%s pid=%d", - cfg.Listen, cfg.Upstream, cfg.RulesDir, os.Getpid()), nil) + logclient.Info("waf", fmt.Sprintf("服务启动 instance=%s listen=%s upstream=%s rules=%s pid=%d", + *instance, cfg.Listen, cfg.Upstream, cfg.RulesDir, os.Getpid()), nil) errCh := make(chan error, 1) go func() {