Files
logs/internal/config/config.go
2026-09-09 16:45:01 +08:00

133 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"fmt"
"net"
"net/url"
"strconv"
"strings"
"git.apinb.com/bsm-sdk/core/conf"
)
var Spec SrvConfig
type AlertForwardConf struct {
BaseURL string `yaml:"base_url"`
InternalKey string `yaml:"internal_key"`
Enabled bool `yaml:"enabled"`
DefaultPolicyID uint `yaml:"default_policy_id"`
}
type IngestConf struct {
SyslogListenAddr string `yaml:"syslog_listen_addr"`
TrapListenAddr string `yaml:"trap_listen_addr"`
RuleRefreshSecs int `yaml:"rule_refresh_secs"`
}
type ResourceEventConf struct {
// HMACSecret 用于校验 dc-control 推送签名(X-Event-Signature)。
HMACSecret string `yaml:"hmac_secret"`
// MaxSkewSecs 允许事件时间与服务端时间的最大偏差(秒)。
MaxSkewSecs int `yaml:"max_skew_secs"`
}
type OTLPConf struct {
InternalKey string `yaml:"internal_key"`
}
type SystemSettingsConf struct {
BaseURL string `yaml:"base_url"`
RefreshSeconds int `yaml:"refresh_seconds"`
TimeoutSeconds int `yaml:"timeout_seconds"`
}
type SrvConfig struct {
conf.Base `yaml:",inline"`
Databases *conf.DBConf `yaml:"Databases"`
MicroService *conf.MicroServiceConf `yaml:"MicroService"`
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
Gateway *conf.GatewayConf `yaml:"Gateway"`
Apm *conf.ApmConf `yaml:"APM"`
AlertForward *AlertForwardConf `yaml:"AlertForward"`
Ingest IngestConf `yaml:"Ingest"`
ResourceEvent ResourceEventConf `yaml:"ResourceEvent"`
OTLP OTLPConf `yaml:"OTLP"`
SystemSettings SystemSettingsConf `yaml:"SystemSettings"`
}
func New(srvKey string) {
conf.New(srvKey, &Spec)
if err := Validate(); err != nil {
panic(fmt.Errorf("logs 配置校验失败: %w", err))
}
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
conf.PrintInfo(Spec.Addr)
}
// Validate 校验日志服务配置,不生成随机端口、监听地址或刷新间隔。
func Validate() error {
Spec.Service = strings.TrimSpace(Spec.Service)
Spec.Port = strings.TrimSpace(Spec.Port)
Spec.BindIP = strings.TrimSpace(Spec.BindIP)
Spec.ResourceEvent.HMACSecret = strings.TrimSpace(Spec.ResourceEvent.HMACSecret)
Spec.OTLP.InternalKey = strings.TrimSpace(Spec.OTLP.InternalKey)
Spec.SystemSettings.BaseURL = strings.TrimRight(strings.TrimSpace(Spec.SystemSettings.BaseURL), "/")
if Spec.Service == "" {
return fmt.Errorf("Service 不能为空")
}
port, err := strconv.Atoi(Spec.Port)
if err != nil || port < 1 || port > 65535 {
return fmt.Errorf("Port 必须是 1 到 65535 的整数")
}
if net.ParseIP(Spec.BindIP) == nil {
return fmt.Errorf("BindIP 必须是明确的 IPv4 或 IPv6 地址")
}
if Spec.Databases == nil || strings.TrimSpace(Spec.Databases.Driver) == "" || len(Spec.Databases.Source) == 0 {
return fmt.Errorf("Databases.Driver 和 Databases.Source 不能为空")
}
if strings.TrimSpace(Spec.Cache) == "" {
return fmt.Errorf("Cache 不能为空")
}
if Spec.ResourceEvent.HMACSecret == "" || Spec.ResourceEvent.MaxSkewSecs <= 0 {
return fmt.Errorf("ResourceEvent.hmac_secret 和 max_skew_secs 必须有效")
}
if Spec.OTLP.InternalKey == "" {
return fmt.Errorf("OTLP.internal_key 不能为空")
}
parsedSystemSettingsURL, err := url.Parse(Spec.SystemSettings.BaseURL)
if err != nil || parsedSystemSettingsURL.Host == "" || (parsedSystemSettingsURL.Scheme != "http" && parsedSystemSettingsURL.Scheme != "https") {
return fmt.Errorf("SystemSettings.base_url 必须是完整的 HTTP 或 HTTPS 地址")
}
if Spec.SystemSettings.RefreshSeconds <= 0 || Spec.SystemSettings.TimeoutSeconds <= 0 {
return fmt.Errorf("SystemSettings.refresh_seconds 和 timeout_seconds 必须大于 0")
}
if Spec.Ingest.RuleRefreshSecs <= 0 {
return fmt.Errorf("Ingest.rule_refresh_secs 必须大于 0")
}
for name, addr := range map[string]string{
"syslog_listen_addr": Spec.Ingest.SyslogListenAddr,
"trap_listen_addr": Spec.Ingest.TrapListenAddr,
} {
addr = strings.TrimSpace(addr)
if addr == "" {
continue
}
if _, err := net.ResolveUDPAddr("udp", addr); err != nil {
return fmt.Errorf("Ingest.%s 无效: %w", name, err)
}
}
if Spec.AlertForward != nil && Spec.AlertForward.Enabled {
Spec.AlertForward.BaseURL = strings.TrimSpace(Spec.AlertForward.BaseURL)
Spec.AlertForward.InternalKey = strings.TrimSpace(Spec.AlertForward.InternalKey)
parsed, err := url.Parse(Spec.AlertForward.BaseURL)
if err != nil || parsed.Host == "" || (parsed.Scheme != "http" && parsed.Scheme != "https") {
return fmt.Errorf("AlertForward.base_url 必须是完整的 HTTP 或 HTTPS 地址")
}
if Spec.AlertForward.InternalKey == "" {
return fmt.Errorf("AlertForward.internal_key 不能为空")
}
}
return nil
}