package etcd import ( "context" "encoding/json" "fmt" clientv3 "go.etcd.io/etcd/client/v3" "time" ) var ( cli *clientv3.Client ) //需要手机的日志的配置信息 type LogEntry struct { Path string `json:"path"` //日志存放的路径 Topic string `json:"topic"` //日志要发往kafka中的哪个Topic } //初始化etcd func Init(addr string, timeout time.Duration) (err error) { cli, err = clientv3.New(clientv3.Config{ Endpoints: []string{addr}, DialTimeout: timeout, }) if err != nil { //handle error! fmt.Println("connect etcd server failed,error:", err) return } fmt.Println("connect etcd server success") return } // 从etcd中根据key获取配置项 func GetConf(key string) (logEntryConf []*LogEntry, err error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second) resp, err := cli.Get(ctx, key) cancel() if err != nil { fmt.Println("get etcd config failed,error:", err) } for _, ev := range resp.Kvs { err = json.Unmarshal(ev.Value, &logEntryConf) if err != nil { fmt.Println("parse etcd config failed,error:", err) return } } return } //etcd的哨兵 func Watcher(key string, newConfCh chan<- []*LogEntry) { ch := cli.Watch(context.Background(), key) for w := range ch { for _, evt := range w.Events { fmt.Printf("index:%v value:%v\n", evt.Type, string(evt.Kv.Value)) //通知taillog.tailTskMgr //1.先判断操作的类型 var newConf []*LogEntry if evt.Type != clientv3.EventTypeDelete { err := json.Unmarshal(evt.Kv.Value, &newConf) if err != nil { fmt.Println("parse etcd config failed,error:", err) continue } } fmt.Println("get etcd new config success", newConf) newConfCh <- newConf } } }