euspaceCfg.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package config
  2. import (
  3. "fmt"
  4. "github.com/coroot/coroot-node-agent/flags"
  5. "github.com/coroot/coroot-node-agent/utils"
  6. "github.com/coroot/coroot-node-agent/utils/enums"
  7. "github.com/fsnotify/fsnotify"
  8. log "github.com/sirupsen/logrus"
  9. "github.com/spf13/viper"
  10. "reflect"
  11. )
  12. type euspaceCfgRecord struct {
  13. LogLevel string `mapstructure:"logLevel"`
  14. NetDataInterval int `mapstructure:"netDataInterval"`
  15. ConfigServer string `mapstructure:"configServer"`
  16. DataServer string `mapstructure:"dataServer"`
  17. }
  18. type euspaceCfg struct {
  19. runtimeV *viper.Viper
  20. watchedV *viper.Viper
  21. cfgRecordLast *euspaceCfgRecord
  22. }
  23. func initEuspaceCfg() (*euspaceCfg, error) {
  24. v := viper.New()
  25. v.SetConfigName("config")
  26. v.SetConfigType("yaml")
  27. v.AddConfigPath(utils.GetDefaultConfPath())
  28. if err := v.ReadInConfig(); err != nil {
  29. /*if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
  30. return nil, err
  31. }*/
  32. return nil, err
  33. }
  34. sv := viper.New()
  35. sv.SetConfigFile(v.ConfigFileUsed())
  36. ec := &euspaceCfg{
  37. runtimeV: v,
  38. watchedV: sv,
  39. cfgRecordLast: new(euspaceCfgRecord),
  40. }
  41. ec.setDefault()
  42. return ec, nil
  43. }
  44. func (ec *euspaceCfg) setDefault() {
  45. ec.runtimeV.SetDefault("logLevel", enums.DefaultLogLevel)
  46. ec.runtimeV.SetDefault("netDataInterval", enums.DefaultNetDataInterval1Min)
  47. ec.runtimeV.SetDefault("configServer", "")
  48. ec.runtimeV.SetDefault("dataServer", "")
  49. }
  50. func (ec *euspaceCfg) syncConfToFile(ecr *euspaceCfgRecord) error {
  51. if ecr != nil {
  52. syncV := viper.New()
  53. syncV.SetConfigFile(ec.watchedV.ConfigFileUsed())
  54. syncV.Set("logLevel", ecr.LogLevel)
  55. syncV.Set("netDataInterval", ecr.NetDataInterval)
  56. syncV.Set("configServer", ecr.ConfigServer)
  57. syncV.Set("dataServer", ecr.DataServer)
  58. err := syncV.WriteConfig()
  59. if err != nil {
  60. return fmt.Errorf("sync config to [%s] failed : %s", ec.watchedV.ConfigFileUsed(), err.Error())
  61. }
  62. return nil
  63. }
  64. return fmt.Errorf("sync config to [%s] euspaceCfgRecord is nil", ec.watchedV.ConfigFileUsed())
  65. }
  66. func (ec *euspaceCfg) watchConfig(c *Config) {
  67. ec.watchedV.OnConfigChange(func(e fsnotify.Event) {
  68. //fmt.Printf("euspaceCfg Config file changed [%s],Op:%d ,AllKeys:%#v======> \n", e.Name, e.Op, ec.watchedV.AllSettings())
  69. if !e.Op.Has(fsnotify.Create) && !e.Op.Has(fsnotify.Write) {
  70. return
  71. }
  72. //viper的特殊情况:ec.watchedV.AllKeys()返回为空切片
  73. if len(ec.watchedV.AllKeys()) == 0 {
  74. return
  75. }
  76. c.m.Lock()
  77. //defer c.m.Unlock()
  78. cr := new(euspaceCfgRecord)
  79. if err := ec.watchedV.Unmarshal(cr); err != nil {
  80. log.Warningf("on-config-change, `watchedV` unmarshal `euspaceCfgRecord` failed : %s", err.Error())
  81. c.m.Unlock()
  82. return
  83. }
  84. //ConfigServer 和 DataServer 不允许为空
  85. if cr.ConfigServer == "" || cr.DataServer == "" {
  86. c.m.Unlock()
  87. return
  88. }
  89. if cr.LogLevel == "" {
  90. cr.LogLevel = enums.DefaultLogLevel
  91. }
  92. if cr.NetDataInterval <= 0 {
  93. cr.NetDataInterval = enums.DefaultNetDataInterval1Min
  94. }
  95. if reflect.DeepEqual(ec.cfgRecordLast, cr) {
  96. c.m.Unlock()
  97. return
  98. }
  99. //拷贝ec.cfgRecordLast 到临时变量,目的是及时释放锁
  100. crLast := ec.cfgRecordLast
  101. //update cfgRecordLast
  102. ec.cfgRecordLast = cr
  103. c.m.Unlock()
  104. if *flags.ConfigServer == "" {
  105. if crLast.ConfigServer != cr.ConfigServer {
  106. c.m.Lock()
  107. ec.runtimeV.Set("configServer", cr.ConfigServer)
  108. c.m.Unlock()
  109. c.noticeSubscribers(ScbTypeConfigServerChg)
  110. }
  111. }
  112. if *flags.DataServer == "" {
  113. if crLast.DataServer != cr.DataServer {
  114. c.m.Lock()
  115. ec.runtimeV.Set("dataServer", cr.DataServer)
  116. c.m.Unlock()
  117. c.noticeSubscribers(ScbTypeDataServerChg)
  118. c.noticeSubscribers(ScbTypeTracesEndpointChg)
  119. }
  120. }
  121. if *flags.LogLevel == "" {
  122. if crLast.LogLevel != cr.LogLevel {
  123. c.m.Lock()
  124. ec.runtimeV.Set("logLevel", cr.LogLevel)
  125. c.m.Unlock()
  126. c.noticeSubscribers(ScbTypeLogLevelChg)
  127. }
  128. }
  129. if crLast.NetDataInterval != cr.NetDataInterval {
  130. c.m.Lock()
  131. ec.runtimeV.Set("netDataInterval", cr.NetDataInterval)
  132. c.m.Unlock()
  133. c.noticeSubscribers(ScbTypeNetDataIntervalChg)
  134. }
  135. })
  136. ec.watchedV.WatchConfig()
  137. }