github.com/galamsiva2020/kubernetes-heapster-monitoring@v0.0.0-20210823134957-3c1baa7c1e70/common/riemann/riemann.go (about) 1 // Copyright 2017 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package riemann 16 17 import ( 18 "net/url" 19 "runtime" 20 "strconv" 21 "sync" 22 "time" 23 24 "github.com/golang/glog" 25 "github.com/riemann/riemann-go-client" 26 ) 27 28 // Used to store the Riemann configuration specified in the Heapster cli 29 type RiemannConfig struct { 30 Host string 31 Ttl float32 32 State string 33 Tags []string 34 BatchSize int 35 } 36 37 // contains the riemann client, the riemann configuration, and a RWMutex 38 type RiemannSink struct { 39 Client riemanngo.Client 40 Config RiemannConfig 41 sync.RWMutex 42 } 43 44 // creates a Riemann sink. Returns a riemannSink 45 func CreateRiemannSink(uri *url.URL) (*RiemannSink, error) { 46 // Default configuration 47 c := RiemannConfig{ 48 Host: "riemann-heapster:5555", 49 Ttl: 60.0, 50 State: "", 51 Tags: make([]string, 0), 52 BatchSize: 1000, 53 } 54 // check host 55 if len(uri.Host) > 0 { 56 c.Host = uri.Host 57 } 58 options := uri.Query() 59 // check ttl 60 if len(options["ttl"]) > 0 { 61 var ttl, err = strconv.ParseFloat(options["ttl"][0], 32) 62 if err != nil { 63 return nil, err 64 } 65 c.Ttl = float32(ttl) 66 } 67 // check batch size 68 if len(options["batchsize"]) > 0 { 69 var batchSize, err = strconv.Atoi(options["batchsize"][0]) 70 if err != nil { 71 return nil, err 72 } 73 c.BatchSize = batchSize 74 } 75 // check state 76 if len(options["state"]) > 0 { 77 c.State = options["state"][0] 78 } 79 // check tags 80 if len(options["tags"]) > 0 { 81 c.Tags = options["tags"] 82 } else { 83 c.Tags = []string{"heapster"} 84 } 85 86 glog.Infof("Riemann sink URI: '%+v', host: '%+v', options: '%+v', ", uri, c.Host, options) 87 rs := &RiemannSink{ 88 Client: nil, 89 Config: c, 90 } 91 client, err := GetRiemannClient(rs.Config) 92 if err != nil { 93 glog.Warningf("Riemann sink not connected: %v", err) 94 // Warn but return the sink => the client in the sink can be nil 95 } 96 rs.Client = client 97 98 return rs, nil 99 } 100 101 // Receives a sink, connect the riemann client. 102 func GetRiemannClient(config RiemannConfig) (riemanngo.Client, error) { 103 glog.Infof("Connect Riemann client...") 104 client := riemanngo.NewTcpClient(config.Host) 105 runtime.SetFinalizer(client, func(c riemanngo.Client) { c.Close() }) 106 // 5 seconds timeout 107 err := client.Connect(5) 108 if err != nil { 109 return nil, err 110 } 111 return client, nil 112 } 113 114 // Send Events to Riemann using the client from the sink. 115 func SendData(client riemanngo.Client, events []riemanngo.Event) error { 116 // do nothing if we are not connected 117 if client == nil { 118 glog.Warningf("Riemann sink not connected") 119 return nil 120 } 121 start := time.Now() 122 _, err := riemanngo.SendEvents(client, &events) 123 end := time.Now() 124 if err == nil { 125 glog.V(4).Infof("Exported %d events to riemann in %s", len(events), end.Sub(start)) 126 return nil 127 } else { 128 glog.Warningf("There were errors sending events to Riemman, forcing reconnection. Error : %+v", err) 129 return err 130 } 131 }