github.com/greenboxal/deis@v1.12.1/logger/configurer/configurer.go (about) 1 package configurer 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/coreos/go-etcd/etcd" 9 "github.com/deis/deis/logger/drain" 10 "github.com/deis/deis/logger/storage" 11 "github.com/deis/deis/logger/syslogish" 12 ) 13 14 // Exported so it can be set by an external agent-- namely main.go, which does some flag parsing. 15 var DefaultDrainURI string 16 17 // Configurer takes responsibility for dynamically reconfiguring a syslogish.Server based on 18 // changes in etcd. 19 type Configurer struct { 20 etcdClient *etcd.Client 21 etcdPath string 22 ticker *time.Ticker 23 syslogishServer *syslogish.Server 24 running bool 25 currentStorageAdapterType string 26 currentDrainURL string 27 } 28 29 // NewConfigurer returns a pointer to a new Configurer instance. 30 func NewConfigurer(etcdHost string, etcdPort int, etcdPath string, configInterval int, 31 syslogishServer *syslogish.Server) (*Configurer, error) { 32 etcdClient := etcd.NewClient([]string{fmt.Sprintf("http://%s:%d", etcdHost, etcdPort)}) 33 ticker := time.NewTicker(time.Duration(configInterval) * time.Second) 34 configurer := &Configurer{ 35 etcdClient: etcdClient, 36 etcdPath: etcdPath, 37 syslogishServer: syslogishServer, 38 ticker: ticker, 39 } 40 41 // Support legacy behavior that allows default drain uri to be specified using a drain-uri flag 42 if _, err := etcdClient.Get(etcdPath+"/drain", false, false); err != nil { 43 etcdErr, ok := err.(*etcd.EtcdError) 44 // Error code 100 is key not found 45 if ok && etcdErr.ErrorCode == 100 { 46 configurer.setEtcd("/drain", DefaultDrainURI) 47 } else { 48 log.Println(err) 49 } 50 } 51 52 return configurer, nil 53 } 54 55 // Start begins the configurer's main loop. 56 func (c *Configurer) Start() { 57 // Should only ever be called once 58 if !c.running { 59 c.running = true 60 go c.configure() 61 log.Println("configurer running") 62 } 63 } 64 65 func (c *Configurer) configure() { 66 for { 67 <-c.ticker.C 68 c.manageStorageAdapter() 69 c.manageDrain() 70 } 71 } 72 73 func (c *Configurer) manageStorageAdapter() { 74 newStorageAdapterType, err := c.getEtcd("/storageAdapterType", "file") 75 if err != nil { 76 log.Println("configurer: Error retrieving storage adapter type from etcd. Skipping.", err) 77 return 78 } 79 if newStorageAdapterType == c.currentStorageAdapterType { 80 return 81 } 82 newStorageAdapter, err := storage.NewAdapter(newStorageAdapterType) 83 if err != nil { 84 log.Println("configurer: Error creating new storage adapter. Skipping.", err) 85 return 86 } 87 c.syslogishServer.SetStorageAdapter(newStorageAdapter) 88 c.currentStorageAdapterType = newStorageAdapterType 89 log.Printf("configurer: Activated new storage adapter: %s", newStorageAdapterType) 90 } 91 92 func (c *Configurer) manageDrain() { 93 newDrainURL, err := c.getEtcd("/drain", "") 94 if err != nil { 95 log.Println("configurer: Error retrieving drain URL from etcd. Skipping.", err) 96 return 97 } 98 if newDrainURL == c.currentDrainURL { 99 return 100 } 101 newDrain, err := drain.NewDrain(newDrainURL) 102 if err != nil { 103 log.Println("configurer: Error creating new drain. Skipping.", err) 104 return 105 } 106 c.syslogishServer.SetDrain(newDrain) 107 c.currentDrainURL = newDrainURL 108 if newDrainURL == "" { 109 log.Println("configurer: Deactivated drain") 110 } else { 111 log.Printf("configurer: Activated new drain: %s", newDrainURL) 112 } 113 } 114 115 func (c *Configurer) getEtcd(key string, defaultValue string) (string, error) { 116 resp, err := c.etcdClient.Get(fmt.Sprintf("%s%s", c.etcdPath, key), false, false) 117 if err != nil { 118 etcdErr, ok := err.(*etcd.EtcdError) 119 // Error code 100 is key not found 120 if ok && etcdErr.ErrorCode == 100 { 121 return defaultValue, nil 122 } 123 return "", err 124 } 125 return resp.Node.Value, nil 126 } 127 128 func (c *Configurer) setEtcd(key string, value string) { 129 _, err := c.etcdClient.Set(fmt.Sprintf("%s%s", c.etcdPath, key), value, 0) 130 if err != nil { 131 etcdErr, ok := err.(*etcd.EtcdError) 132 // Error code 105 is key already exists 133 if !ok || etcdErr.ErrorCode != 105 { 134 log.Println(err) 135 } 136 } 137 }