|
|
@@ -0,0 +1,664 @@
|
|
|
+package config
|
|
|
+
|
|
|
+import (
|
|
|
+ "net/url"
|
|
|
+ "os"
|
|
|
+ "strings"
|
|
|
+ "sync"
|
|
|
+
|
|
|
+ "github.com/coroot/coroot-node-agent/flags"
|
|
|
+ "github.com/spf13/viper"
|
|
|
+)
|
|
|
+
|
|
|
+// Config 统一的配置结构体
|
|
|
+// 所有配置项都通过这个结构体访问,内部自动判断优先级
|
|
|
+type Config struct {
|
|
|
+ mu sync.RWMutex
|
|
|
+
|
|
|
+ // Viper 实例(用于读取配置文件)
|
|
|
+ viper *viper.Viper
|
|
|
+
|
|
|
+ // 命令行参数值(最高优先级)
|
|
|
+ cmdLineValues map[string]interface{}
|
|
|
+
|
|
|
+ // 环境变量值(第二优先级)
|
|
|
+ envValues map[string]interface{}
|
|
|
+
|
|
|
+ // 配置文件值(第三优先级)
|
|
|
+ configFileValues map[string]interface{}
|
|
|
+
|
|
|
+ // 默认值(最低优先级)
|
|
|
+ defaultValues map[string]interface{}
|
|
|
+
|
|
|
+ // 特殊配置:common.ini 中的值(最高优先级,仅用于 ConfigServer 和 DataServer)
|
|
|
+ commonIniValues map[string]string
|
|
|
+}
|
|
|
+
|
|
|
+var (
|
|
|
+ globalConfig *Config
|
|
|
+ globalConfigOnce sync.Once
|
|
|
+)
|
|
|
+
|
|
|
+// Get 获取全局配置实例
|
|
|
+func Get() *Config {
|
|
|
+ globalConfigOnce.Do(func() {
|
|
|
+ globalConfig = &Config{
|
|
|
+ cmdLineValues: make(map[string]interface{}),
|
|
|
+ envValues: make(map[string]interface{}),
|
|
|
+ configFileValues: make(map[string]interface{}),
|
|
|
+ defaultValues: make(map[string]interface{}),
|
|
|
+ commonIniValues: make(map[string]string),
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return globalConfig
|
|
|
+}
|
|
|
+
|
|
|
+// Init 初始化配置管理器
|
|
|
+// 必须在 flags.Parse() 之后调用
|
|
|
+func (c *Config) Init(viperInstance *viper.Viper) {
|
|
|
+ c.mu.Lock()
|
|
|
+ defer c.mu.Unlock()
|
|
|
+
|
|
|
+ c.viper = viperInstance
|
|
|
+
|
|
|
+ // 1. 收集命令行参数值(最高优先级)
|
|
|
+ c.collectCmdLineValues()
|
|
|
+
|
|
|
+ // 2. 收集环境变量值(第二优先级)
|
|
|
+ c.collectEnvValues()
|
|
|
+
|
|
|
+ // 3. 收集配置文件值(第三优先级)
|
|
|
+ c.collectConfigFileValues()
|
|
|
+
|
|
|
+ // 4. 收集默认值(最低优先级)
|
|
|
+ c.collectDefaultValues()
|
|
|
+
|
|
|
+ // 5. 收集 common.ini 中的值(特殊处理)
|
|
|
+ c.collectCommonIniValues()
|
|
|
+}
|
|
|
+
|
|
|
+// collectCmdLineValues 收集命令行参数值
|
|
|
+func (c *Config) collectCmdLineValues() {
|
|
|
+ // 从 flags 包中读取命令行参数值
|
|
|
+ c.cmdLineValues["server.config_server"] = *flags.ConfigServer
|
|
|
+ c.cmdLineValues["server.data_server"] = *flags.DataServer
|
|
|
+ c.cmdLineValues["server.server_prefix"] = *flags.ServerPrefix
|
|
|
+ c.cmdLineValues["server.license_key"] = *flags.LicenseKey
|
|
|
+ c.cmdLineValues["server.register_app_to_doop"] = *flags.RegisterAppToDoop
|
|
|
+
|
|
|
+ c.cmdLineValues["agent.disable_e2e_tracing"] = *flags.DisableE2ETracing
|
|
|
+ c.cmdLineValues["agent.disable_stack_tracing"] = *flags.DisableStackTracing
|
|
|
+ c.cmdLineValues["agent.disable_l7_tracing"] = *flags.DisableL7Tracing
|
|
|
+ c.cmdLineValues["agent.enable_elasticsearch_detection"] = *flags.EnableElasticsearchDetection
|
|
|
+ c.cmdLineValues["agent.run_in_container"] = *flags.RunInContainer
|
|
|
+ c.cmdLineValues["agent.run_in_omniagent"] = *flags.RunInOmniagent
|
|
|
+ c.cmdLineValues["agent.disable_register_host"] = *flags.DisableRegisterHost
|
|
|
+ c.cmdLineValues["agent.enable_license_check"] = *flags.EnableLicenseCheck
|
|
|
+ c.cmdLineValues["agent.send_net_data"] = *flags.SendNetData
|
|
|
+
|
|
|
+ c.cmdLineValues["network.listen_address"] = *flags.ListenAddress
|
|
|
+ c.cmdLineValues["network.track_public_network"] = *flags.ExternalNetworksWhitelist
|
|
|
+ c.cmdLineValues["network.ephemeral_port_range"] = *flags.EphemeralPortRange
|
|
|
+
|
|
|
+ c.cmdLineValues["container.cgroupfs_root"] = *flags.CgroupRoot
|
|
|
+ c.cmdLineValues["container.host_dir_path_prefix"] = *flags.HostDirPathPrefix
|
|
|
+ c.cmdLineValues["container.disable_log_parsing"] = *flags.DisableLogParsing
|
|
|
+ c.cmdLineValues["container.disable_pinger"] = *flags.DisablePinger
|
|
|
+
|
|
|
+ c.cmdLineValues["logging.log_level"] = *flags.LogLevel
|
|
|
+ c.cmdLineValues["logging.console_log"] = *flags.ConsoleLog
|
|
|
+ c.cmdLineValues["logging.log_per_second"] = *flags.LogPerSecond
|
|
|
+ c.cmdLineValues["logging.log_burst"] = *flags.LogBurst
|
|
|
+
|
|
|
+ c.cmdLineValues["ebpf.ebpf_file_path"] = *flags.EbpfFilePath
|
|
|
+}
|
|
|
+
|
|
|
+// collectEnvValues 收集环境变量值
|
|
|
+func (c *Config) collectEnvValues() {
|
|
|
+ // 环境变量映射表:环境变量名 -> 配置键
|
|
|
+ envMap := map[string]string{
|
|
|
+ // Server 配置
|
|
|
+ "CONFIG_SERVER": "server.config_server",
|
|
|
+ "EUSPACE_SERVER_CONFIG_SERVER": "server.config_server",
|
|
|
+ "DATA_SERVER": "server.data_server",
|
|
|
+ "EUSPACE_SERVER_DATA_SERVER": "server.data_server",
|
|
|
+ "SERVER_PREFIX": "server.server_prefix",
|
|
|
+ "EUSPACE_SERVER_SERVER_PREFIX": "server.server_prefix",
|
|
|
+ "LICENSE_KEY": "server.license_key",
|
|
|
+ "EUSPACE_SERVER_LICENSE_KEY": "server.license_key",
|
|
|
+ "REGISTER_APP_TO_DOOP": "server.register_app_to_doop",
|
|
|
+ "EUSPACE_SERVER_REGISTER_APP_TO_DOOP": "server.register_app_to_doop",
|
|
|
+ // Agent 配置
|
|
|
+ "DISABLE_E2E_TRACING": "agent.disable_e2e_tracing",
|
|
|
+ "EUSPACE_AGENT_DISABLE_E2E_TRACING": "agent.disable_e2e_tracing",
|
|
|
+ "DISABLE_STACK_TRACING": "agent.disable_stack_tracing",
|
|
|
+ "EUSPACE_AGENT_DISABLE_STACK_TRACING": "agent.disable_stack_tracing",
|
|
|
+ "DISABLE_L7_TRACING": "agent.disable_l7_tracing",
|
|
|
+ "EUSPACE_AGENT_DISABLE_L7_TRACING": "agent.disable_l7_tracing",
|
|
|
+ "ENABLE_ES": "agent.enable_elasticsearch_detection",
|
|
|
+ "EUSPACE_AGENT_ENABLE_ELASTICSEARCH_DETECTION": "agent.enable_elasticsearch_detection",
|
|
|
+ "RUN_IN_CONTAINER": "agent.run_in_container",
|
|
|
+ "EUSPACE_AGENT_RUN_IN_CONTAINER": "agent.run_in_container",
|
|
|
+ "RUN_IN_OMNIAGENT": "agent.run_in_omniagent",
|
|
|
+ "EUSPACE_AGENT_RUN_IN_OMNIAGENT": "agent.run_in_omniagent",
|
|
|
+ "DISABLE_REG_HOST": "agent.disable_register_host",
|
|
|
+ "EUSPACE_AGENT_DISABLE_REGISTER_HOST": "agent.disable_register_host",
|
|
|
+ "ENABLE_LICENSE_CHECK": "agent.enable_license_check",
|
|
|
+ "EUSPACE_AGENT_ENABLE_LICENSE_CHECK": "agent.enable_license_check",
|
|
|
+ "SEND_NET_DATA": "agent.send_net_data",
|
|
|
+ "EUSPACE_AGENT_SEND_NET_DATA": "agent.send_net_data",
|
|
|
+ // Network 配置
|
|
|
+ "LISTEN": "network.listen_address",
|
|
|
+ "EUSPACE_NETWORK_LISTEN_ADDRESS": "network.listen_address",
|
|
|
+ "TRACK_PUBLIC_NETWORK": "network.track_public_network",
|
|
|
+ "EUSPACE_NETWORK_TRACK_PUBLIC_NETWORK": "network.track_public_network",
|
|
|
+ "EPHEMERAL_PORT_RANGE": "network.ephemeral_port_range",
|
|
|
+ "EUSPACE_NETWORK_EPHEMERAL_PORT_RANGE": "network.ephemeral_port_range",
|
|
|
+ // Container 配置
|
|
|
+ "CGROUPFS_ROOT": "container.cgroupfs_root",
|
|
|
+ "EUSPACE_CONTAINER_CGROUPFS_ROOT": "container.cgroupfs_root",
|
|
|
+ "HOST_DIR_PATH_PREFIX": "container.host_dir_path_prefix",
|
|
|
+ "EUSPACE_CONTAINER_HOST_DIR_PATH_PREFIX": "container.host_dir_path_prefix",
|
|
|
+ "DISABLE_LOG_PARSING": "container.disable_log_parsing",
|
|
|
+ "EUSPACE_CONTAINER_DISABLE_LOG_PARSING": "container.disable_log_parsing",
|
|
|
+ "DISABLE_PINGER": "container.disable_pinger",
|
|
|
+ "EUSPACE_CONTAINER_DISABLE_PINGER": "container.disable_pinger",
|
|
|
+ // Logging 配置
|
|
|
+ "LOG_LEVEL": "logging.log_level",
|
|
|
+ "EUSPACE_LOGGING_LOG_LEVEL": "logging.log_level",
|
|
|
+ "CONSOLE_LOG": "logging.console_log",
|
|
|
+ "EUSPACE_LOGGING_CONSOLE_LOG": "logging.console_log",
|
|
|
+ "LOG_PER_SECOND": "logging.log_per_second",
|
|
|
+ "EUSPACE_LOGGING_LOG_PER_SECOND": "logging.log_per_second",
|
|
|
+ "LOG_BURST": "logging.log_burst",
|
|
|
+ "EUSPACE_LOGGING_LOG_BURST": "logging.log_burst",
|
|
|
+ // eBPF 配置
|
|
|
+ "EBPF_FILE": "ebpf.ebpf_file_path",
|
|
|
+ "EUSPACE_EBPF_EBPF_FILE_PATH": "ebpf.ebpf_file_path",
|
|
|
+ // Cloud 配置
|
|
|
+ "PROVIDER": "cloud.provider",
|
|
|
+ "EUSPACE_CLOUD_PROVIDER": "cloud.provider",
|
|
|
+ "REGION": "cloud.region",
|
|
|
+ "EUSPACE_CLOUD_REGION": "cloud.region",
|
|
|
+ "AVAILABILITY_ZONE": "cloud.availability_zone",
|
|
|
+ "EUSPACE_CLOUD_AVAILABILITY_ZONE": "cloud.availability_zone",
|
|
|
+ "INSTANCE_TYPE": "cloud.instance_type",
|
|
|
+ "EUSPACE_CLOUD_INSTANCE_TYPE": "cloud.instance_type",
|
|
|
+ "INSTANCE_LIFE_CYCLE": "cloud.instance_life_cycle",
|
|
|
+ "EUSPACE_CLOUD_INSTANCE_LIFE_CYCLE": "cloud.instance_life_cycle",
|
|
|
+ }
|
|
|
+
|
|
|
+ for envKey, configKey := range envMap {
|
|
|
+ if val := os.Getenv(envKey); val != "" {
|
|
|
+ c.envValues[configKey] = val
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// collectConfigFileValues 收集配置文件值
|
|
|
+func (c *Config) collectConfigFileValues() {
|
|
|
+ if c.viper == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从 Viper 中读取所有配置项
|
|
|
+ allKeys := c.viper.AllKeys()
|
|
|
+ for _, key := range allKeys {
|
|
|
+ if c.viper.IsSet(key) {
|
|
|
+ c.configFileValues[key] = c.viper.Get(key)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// collectDefaultValues 收集默认值
|
|
|
+func (c *Config) collectDefaultValues() {
|
|
|
+ // 默认值定义
|
|
|
+ c.defaultValues["server.config_server"] = ""
|
|
|
+ c.defaultValues["server.data_server"] = ""
|
|
|
+ c.defaultValues["server.server_prefix"] = ""
|
|
|
+ c.defaultValues["server.license_key"] = "J45Engw88NeHUZ4Q7qNsK8L47FTH**QvgW113IEnsNaBNMR5zZ**oj/g!!!!"
|
|
|
+ c.defaultValues["server.register_app_to_doop"] = false
|
|
|
+
|
|
|
+ c.defaultValues["agent.disable_e2e_tracing"] = true
|
|
|
+ c.defaultValues["agent.disable_stack_tracing"] = true
|
|
|
+ c.defaultValues["agent.disable_l7_tracing"] = false
|
|
|
+ c.defaultValues["agent.enable_elasticsearch_detection"] = false
|
|
|
+ c.defaultValues["agent.run_in_container"] = false
|
|
|
+ c.defaultValues["agent.run_in_omniagent"] = false
|
|
|
+ c.defaultValues["agent.disable_register_host"] = false
|
|
|
+ c.defaultValues["agent.enable_license_check"] = true
|
|
|
+ c.defaultValues["agent.send_net_data"] = false
|
|
|
+
|
|
|
+ c.defaultValues["network.listen_address"] = "0.0.0.0:8123"
|
|
|
+ c.defaultValues["network.track_public_network"] = []string{"0.0.0.0/0"}
|
|
|
+ c.defaultValues["network.ephemeral_port_range"] = ""
|
|
|
+
|
|
|
+ c.defaultValues["container.cgroupfs_root"] = "/sys/fs/cgroup"
|
|
|
+ c.defaultValues["container.host_dir_path_prefix"] = ""
|
|
|
+ c.defaultValues["container.disable_log_parsing"] = true
|
|
|
+ c.defaultValues["container.disable_pinger"] = false
|
|
|
+
|
|
|
+ c.defaultValues["logging.log_level"] = "info"
|
|
|
+ c.defaultValues["logging.console_log"] = false
|
|
|
+ c.defaultValues["logging.log_per_second"] = 10.0
|
|
|
+ c.defaultValues["logging.log_burst"] = 100
|
|
|
+
|
|
|
+ c.defaultValues["ebpf.ebpf_file_path"] = ""
|
|
|
+}
|
|
|
+
|
|
|
+// collectCommonIniValues 收集 common.ini 中的值
|
|
|
+func (c *Config) collectCommonIniValues() {
|
|
|
+ if !*flags.RunInOmniagent || *flags.CommonIni == "" {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从 common.ini 加载 ConfigServer 和 DataServer
|
|
|
+ // 这个逻辑已经在 flags.go 的 init() 中执行了
|
|
|
+ // 这里我们只是记录一下
|
|
|
+ if *flags.ConfigServer != "" {
|
|
|
+ c.commonIniValues["server.config_server"] = *flags.ConfigServer
|
|
|
+ }
|
|
|
+ if *flags.DataServer != "" {
|
|
|
+ c.commonIniValues["server.data_server"] = *flags.DataServer
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// getValue 获取配置值(自动判断优先级)
|
|
|
+// 优先级:common.ini > 环境变量(非空)> 配置文件(非空)> 默认值
|
|
|
+func (c *Config) getValue(key string) interface{} {
|
|
|
+ c.mu.RLock()
|
|
|
+ defer c.mu.RUnlock()
|
|
|
+ // 1. 最高优先级:common.ini 中的值(仅用于 ConfigServer 和 DataServer)
|
|
|
+ if val, ok := c.commonIniValues[key]; ok {
|
|
|
+ if val != "" {
|
|
|
+ return val
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 环境变量(如果值不为空)
|
|
|
+ if envVal, ok := c.envValues[key]; ok {
|
|
|
+ // 检查环境变量值是否为空
|
|
|
+ if strVal, ok := envVal.(string); ok {
|
|
|
+ if strVal != "" {
|
|
|
+ if strVal == "true" {
|
|
|
+ return true
|
|
|
+ } else if strVal == "false" {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return envVal
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 非字符串类型,直接返回
|
|
|
+ return envVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 配置文件(如果值不为空)
|
|
|
+ if configVal, ok := c.configFileValues[key]; ok {
|
|
|
+ // 检查配置文件值是否为空
|
|
|
+ if strVal, ok := configVal.(string); ok {
|
|
|
+ if strVal != "" {
|
|
|
+ return configVal
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 非字符串类型,直接返回
|
|
|
+ return configVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // flags 中的值
|
|
|
+ if cmdVal, ok := c.cmdLineValues[key]; ok {
|
|
|
+ return cmdVal
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认值
|
|
|
+ if defaultVal, ok := c.defaultValues[key]; ok {
|
|
|
+ return defaultVal
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// Reload 重新加载配置(用于热更新)
|
|
|
+func (c *Config) Reload() {
|
|
|
+ c.mu.Lock()
|
|
|
+ defer c.mu.Unlock()
|
|
|
+
|
|
|
+ // 重新收集配置文件值
|
|
|
+ c.collectConfigFileValues()
|
|
|
+
|
|
|
+ // 重新收集 common.ini 值
|
|
|
+ c.collectCommonIniValues()
|
|
|
+
|
|
|
+ // 同步更新 flags 中的值,确保使用 *flags.XXX 的地方也能获取到最新值
|
|
|
+ c.syncFlagsValues()
|
|
|
+}
|
|
|
+
|
|
|
+// syncFlagsValues 同步更新 flags 中的值
|
|
|
+// 这样即使代码使用 *flags.XXX,也能在热更新后获取到新值
|
|
|
+// 注意:调用此方法时,必须已经持有 c.mu 写锁
|
|
|
+func (c *Config) syncFlagsValues() {
|
|
|
+ if c.viper == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新所有可以通过配置文件设置的 flags 值
|
|
|
+ // 注意:只更新那些没有被命令行参数或环境变量设置的配置项
|
|
|
+ // 注意:这里直接访问内部字段,不调用 getValue(),避免死锁(因为调用者已经持有写锁)
|
|
|
+
|
|
|
+ // Server 配置
|
|
|
+ if c.viper.IsSet("server.config_server") {
|
|
|
+ // 直接访问内部字段,按优先级顺序检查
|
|
|
+ if val, ok := c.commonIniValues["server.config_server"]; ok && val != "" {
|
|
|
+ *flags.ConfigServer = val
|
|
|
+ } else if envVal, ok := c.envValues["server.config_server"]; ok {
|
|
|
+ if s, ok := envVal.(string); ok && s != "" {
|
|
|
+ *flags.ConfigServer = s
|
|
|
+ }
|
|
|
+ } else if configVal, ok := c.configFileValues["server.config_server"]; ok {
|
|
|
+ if s, ok := configVal.(string); ok && s != "" {
|
|
|
+ *flags.ConfigServer = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("server.data_server") {
|
|
|
+ if val, ok := c.commonIniValues["server.data_server"]; ok && val != "" {
|
|
|
+ *flags.DataServer = val
|
|
|
+ } else if envVal, ok := c.envValues["server.data_server"]; ok {
|
|
|
+ if s, ok := envVal.(string); ok && s != "" {
|
|
|
+ *flags.DataServer = s
|
|
|
+ }
|
|
|
+ } else if configVal, ok := c.configFileValues["server.data_server"]; ok {
|
|
|
+ if s, ok := configVal.(string); ok && s != "" {
|
|
|
+ *flags.DataServer = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 辅助函数:按优先级获取值(不获取锁,因为调用者已持有写锁)
|
|
|
+ getValueUnsafe := func(key string) interface{} {
|
|
|
+ // 1. common.ini(最高优先级)
|
|
|
+ if val, ok := c.commonIniValues[key]; ok && val != "" {
|
|
|
+ return val
|
|
|
+ }
|
|
|
+ // 2. 环境变量
|
|
|
+ if envVal, ok := c.envValues[key]; ok {
|
|
|
+ if strVal, ok := envVal.(string); ok {
|
|
|
+ if strVal != "" {
|
|
|
+ return envVal
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return envVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 3. 配置文件
|
|
|
+ if configVal, ok := c.configFileValues[key]; ok {
|
|
|
+ if strVal, ok := configVal.(string); ok {
|
|
|
+ if strVal != "" {
|
|
|
+ return configVal
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return configVal
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 4. 默认值
|
|
|
+ if defaultVal, ok := c.defaultValues[key]; ok {
|
|
|
+ return defaultVal
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if c.viper.IsSet("server.server_prefix") {
|
|
|
+ if val := getValueUnsafe("server.server_prefix"); val != nil {
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ *flags.ServerPrefix = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("server.license_key") {
|
|
|
+ if val := getValueUnsafe("server.license_key"); val != nil {
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ *flags.LicenseKey = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Logging 配置
|
|
|
+ if c.viper.IsSet("logging.log_level") {
|
|
|
+ if val := getValueUnsafe("logging.log_level"); val != nil {
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ *flags.LogLevel = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("logging.console_log") {
|
|
|
+ if val := getValueUnsafe("logging.console_log"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.ConsoleLog = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Agent 配置
|
|
|
+ if c.viper.IsSet("agent.disable_e2e_tracing") {
|
|
|
+ if val := getValueUnsafe("agent.disable_e2e_tracing"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.DisableE2ETracing = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("agent.disable_stack_tracing") {
|
|
|
+ if val := getValueUnsafe("agent.disable_stack_tracing"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.DisableStackTracing = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("agent.disable_l7_tracing") {
|
|
|
+ if val := getValueUnsafe("agent.disable_l7_tracing"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.DisableL7Tracing = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("agent.disable_register_host") {
|
|
|
+ if val := getValueUnsafe("agent.disable_register_host"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.DisableRegisterHost = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("agent.enable_license_check") {
|
|
|
+ if val := getValueUnsafe("agent.enable_license_check"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.EnableLicenseCheck = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if c.viper.IsSet("agent.send_net_data") {
|
|
|
+ if val := getValueUnsafe("agent.send_net_data"); val != nil {
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ *flags.SendNetData = b
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Network 配置
|
|
|
+ if c.viper.IsSet("network.listen_address") {
|
|
|
+ if val := getValueUnsafe("network.listen_address"); val != nil {
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ *flags.ListenAddress = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Container 配置
|
|
|
+ if c.viper.IsSet("container.cgroupfs_root") {
|
|
|
+ if val := getValueUnsafe("container.cgroupfs_root"); val != nil {
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ *flags.CgroupRoot = s
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 注意:这里只更新了部分常用的配置项
|
|
|
+ // 如果需要更新其他配置项,可以继续添加
|
|
|
+}
|
|
|
+
|
|
|
+// 便捷方法:获取各种类型的配置值
|
|
|
+
|
|
|
+func (c *Config) LogLevel() string {
|
|
|
+ val := c.getValue("logging.log_level")
|
|
|
+ if s, ok := val.(string); ok && s != "" {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return "info"
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) ConsoleLog() bool {
|
|
|
+ val := c.getValue("logging.console_log")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) ConfigServer() string {
|
|
|
+ val := c.getValue("server.config_server")
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) DataServer() string {
|
|
|
+ val := c.getValue("server.data_server")
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) ServerPrefix() string {
|
|
|
+ val := c.getValue("server.server_prefix")
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) LicenseKey() string {
|
|
|
+ val := c.getValue("server.license_key")
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return "J45Engw88NeHUZ4Q7qNsK8L47FTH**QvgW113IEnsNaBNMR5zZ**oj/g!!!!"
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) DisableRegisterHost() bool {
|
|
|
+ val := c.getValue("agent.disable_register_host")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) EnableLicenseCheck() bool {
|
|
|
+ val := c.getValue("agent.enable_license_check")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) SendNetData() bool {
|
|
|
+ val := c.getValue("agent.send_net_data")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) DisableE2ETracing() bool {
|
|
|
+ val := c.getValue("agent.disable_e2e_tracing")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) DisableStackTracing() bool {
|
|
|
+ val := c.getValue("agent.disable_stack_tracing")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) DisableL7Tracing() bool {
|
|
|
+ val := c.getValue("agent.disable_l7_tracing")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) RunInContainer() bool {
|
|
|
+ val := c.getValue("agent.run_in_container")
|
|
|
+ if b, ok := val.(bool); ok {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) RunInOmniagent() bool {
|
|
|
+ // RunInOmniagent 不支持热更新,直接从 flags 获取
|
|
|
+ return *flags.RunInOmniagent
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) ListenAddress() string {
|
|
|
+ val := c.getValue("network.listen_address")
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return "0.0.0.0:8123"
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Config) CgroupRoot() string {
|
|
|
+ val := c.getValue("container.cgroupfs_root")
|
|
|
+ if s, ok := val.(string); ok {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ return "/sys/fs/cgroup"
|
|
|
+}
|
|
|
+
|
|
|
+// TracesEndpoint 获取 TracesEndpoint
|
|
|
+// 优先级:命令行参数/环境变量 > 根据 DataServer 和 ServerPrefix 计算
|
|
|
+// 如果都为空,返回 nil
|
|
|
+func (c *Config) TracesEndpoint() *url.URL {
|
|
|
+ // 1. 优先使用命令行参数或环境变量设置的 TracesEndpoint
|
|
|
+ if *flags.TracesEndpoint != nil {
|
|
|
+ return *flags.TracesEndpoint
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 如果 TracesEndpoint 未设置,根据 DataServer 和 ServerPrefix 计算
|
|
|
+ dataServer := c.DataServer()
|
|
|
+ if dataServer == "" {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果 DataServer 没有 http/https 前缀,添加 http://
|
|
|
+ dataServerStr := dataServer
|
|
|
+ if !strings.HasPrefix(dataServerStr, "http://") && !strings.HasPrefix(dataServerStr, "https://") {
|
|
|
+ dataServerStr = "http://" + dataServerStr
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 DataServer URL
|
|
|
+ dataServerURL, err := url.Parse(dataServerStr)
|
|
|
+ if err != nil || dataServerURL == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建 TracesEndpoint:DataServer + ServerPrefix + "/api/v2/data/receive"
|
|
|
+ serverPrefix := c.ServerPrefix()
|
|
|
+ path := serverPrefix + "/api/v2/data/receive"
|
|
|
+ return dataServerURL.JoinPath(path)
|
|
|
+}
|