waf: CLI 标准化(--log-level/--instance + config.yaml 字段全 CLI 覆盖)
- 新增 --listen/--host (覆盖 listen)、--upstream、--tls-cert、--tls-key、--rules-dir - 新增 --log-level debug|info|warn|error(logclient 加级别过滤) - 新增 --instance 实例名(注册中心用) - 自定义 --help 用法文本 - logclient: 新增 SetLevel() + Debug() + ENV LOG_LEVEL 支持 - services.yaml: waf 声明 --instance 和 --log-level
This commit is contained in:
1 parent
01e67648e0
commit
01c6d0cb1f
3 files changed
+102
-7
No files matched your search
+1
-1
@@ -71,7 +71,7 @@ services:
|
|||||||
# --- 安全链路 ---
|
# --- 安全链路 ---
|
||||||
- name: waf
|
- name: waf
|
||||||
cmd: bash /opt/micro_servers/waf/_run.sh
|
cmd: bash /opt/micro_servers/waf/_run.sh
|
||||||
args: [] # -c config.yaml 保留在 _run.sh 作为默认值
|
args: ["--instance", "waf", "--log-level", "info"]
|
||||||
depends_on: [ca, gateway]
|
depends_on: [ca, gateway]
|
||||||
sleep_before: 0
|
sleep_before: 0
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,47 @@ const (
|
|||||||
maxMsgSize = 64 * 1024 * 1024
|
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),支持非标准部署场景。
|
// dbAddr 通过环境变量 LOG_DB_ADDR 配置(默认 127.0.0.1:8005),支持非标准部署场景。
|
||||||
var dbAddr = defaultDBAddr
|
var dbAddr = defaultDBAddr
|
||||||
|
|
||||||
|
// minLevel 控制最低输出级别,默认 info(debug 被过滤)。
|
||||||
|
var minLevel = levelInfo
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if v := os.Getenv("LOG_DB_ADDR"); v != "" {
|
if v := os.Getenv("LOG_DB_ADDR"); v != "" {
|
||||||
dbAddr = 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 单条日志。
|
// Entry 单条日志。
|
||||||
@@ -93,10 +127,15 @@ func New() *Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push 推送一条日志(非阻塞,队列满时丢弃)。
|
// Push 推送一条日志(非阻塞,队列满时丢弃)。
|
||||||
|
// 低于 SetLevel 设定的最低级别的日志将被静默丢弃。
|
||||||
func Push(service, level, message string, extra map[string]any) {
|
func Push(service, level, message string, extra map[string]any) {
|
||||||
if global == nil {
|
if global == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
n, ok := levelMap[level]
|
||||||
|
if !ok || n < minLevel {
|
||||||
|
return
|
||||||
|
}
|
||||||
global.push(Entry{
|
global.push(Entry{
|
||||||
Service: service,
|
Service: service,
|
||||||
Level: level,
|
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 级别日志。
|
// Info 推送 INFO 级别日志。
|
||||||
func Info(service, message string, extra map[string]any) {
|
func Info(service, message string, extra map[string]any) {
|
||||||
Push(service, "INFO", message, extra)
|
Push(service, "INFO", message, extra)
|
||||||
|
|||||||
+57
-6
@@ -42,15 +42,66 @@ type Config struct {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var (
|
var (
|
||||||
configFile = flag.String("c", "config.yaml", "配置文件路径")
|
configFile = flag.String("c", "config.yaml", "配置文件路径")
|
||||||
doList = flag.Bool("list", false, "列出所有规则后退出")
|
doList = flag.Bool("list", false, "列出所有规则后退出")
|
||||||
doTest = flag.String("test", "", "校验单个规则文件语法后退出")
|
doTest = flag.String("test", "", "校验单个规则文件语法后退出")
|
||||||
doCheck = flag.String("check", "", "用当前规则测试输入字符串(URI/path)后退出")
|
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 <file> 配置文件路径,默认 config.yaml\n"+
|
||||||
|
" --listen <addr> 监听地址(别名: --host),覆盖 config.yaml\n"+
|
||||||
|
" --upstream <url> gateway 地址,覆盖 config.yaml\n"+
|
||||||
|
" --tls-cert <file> TLS 证书文件,覆盖 config.yaml\n"+
|
||||||
|
" --tls-key <file> TLS 私钥文件,覆盖 config.yaml\n"+
|
||||||
|
" --rules-dir <dir> 规则根目录,覆盖 config.yaml\n"+
|
||||||
|
" --log-level <lv> debug|info|warn|error,默认 info\n"+
|
||||||
|
" --instance <name> 实例名,默认 waf\n"+
|
||||||
|
" -list 列出所有规则后退出\n"+
|
||||||
|
" -test <file> 校验单个规则文件语法后退出\n"+
|
||||||
|
" -check <input> 用当前规则测试输入字符串后退出\n"+
|
||||||
|
" -h, --help 显示此帮助并退出\n\n"+
|
||||||
|
"配置优先级: CLI > config.yaml\n")
|
||||||
|
}
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
// 日志级别
|
||||||
|
logclient.SetLevel(*logLevel)
|
||||||
|
|
||||||
cfg := loadConfig(*configFile)
|
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 工具
|
// 子命令:极客 CLI 工具
|
||||||
if *doTest != "" {
|
if *doTest != "" {
|
||||||
if err := engine.TestFile(*doTest); err != nil {
|
if err := engine.TestFile(*doTest); err != nil {
|
||||||
@@ -146,8 +197,8 @@ func main() {
|
|||||||
termCh := make(chan os.Signal, 1)
|
termCh := make(chan os.Signal, 1)
|
||||||
signal.Notify(termCh, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(termCh, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
logclient.Info("waf", fmt.Sprintf("服务启动 listen=%s upstream=%s rules=%s pid=%d",
|
logclient.Info("waf", fmt.Sprintf("服务启动 instance=%s listen=%s upstream=%s rules=%s pid=%d",
|
||||||
cfg.Listen, cfg.Upstream, cfg.RulesDir, os.Getpid()), nil)
|
*instance, cfg.Listen, cfg.Upstream, cfg.RulesDir, os.Getpid()), nil)
|
||||||
|
|
||||||
errCh := make(chan error, 1)
|
errCh := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
Reference in new issue
Block a user