go/telemetry/telemetry.go (80 lines of code) (raw):

package telemetry import ( "bytes" "fmt" "io" "os" "strings" "time" "github.com/golang/glog" "github.com/hashicorp/go-metrics" ) // InmemSignal is used to listen for a given signal, and when received, // to dump the current metrics from the InmemSink to an io.Writer type MetricsDumper struct { inm *metrics.InmemSink w io.Writer stopCh chan struct{} ticker *time.Ticker } func NewMetricsDumper(sink *metrics.InmemSink, period time.Duration) *MetricsDumper { obj := &MetricsDumper{ inm: sink, w: os.Stderr, stopCh: make(chan struct{}), ticker: time.NewTicker(period), } go obj.run() return obj } func (i *MetricsDumper) run() { for { select { case <-i.ticker.C: i.dumpStats() case <-i.stopCh: return } } } func (i *MetricsDumper) Stop() { close(i.stopCh) i.ticker.Stop() } // dumpStats is used to dump the data to output writer func (i *MetricsDumper) dumpStats() { buf := bytes.NewBuffer(nil) data := i.inm.Data() // Skip the last period which is still being aggregated for j := 0; j < len(data)-1; j++ { intv := data[j] intv.RLock() for _, val := range intv.Gauges { name := i.flattenLabels(val.Name, val.Labels) fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val.Value) } for name, vals := range intv.Points { for _, val := range vals { fmt.Fprintf(buf, "[%v][P] '%s': %0.3f\n", intv.Interval, name, val) } } for _, agg := range intv.Counters { name := i.flattenLabels(agg.Name, agg.Labels) fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg.AggregateSample) } for _, agg := range intv.Samples { name := i.flattenLabels(agg.Name, agg.Labels) fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg.AggregateSample) } intv.RUnlock() } // Write out the bytes _, err := i.w.Write(buf.Bytes()) if err != nil { glog.Warningf("Could not emit stats: %v", err) } } // Flattens the key for formatting along with its labels, removes spaces func (i *MetricsDumper) flattenLabels(name string, labels []metrics.Label) string { buf := bytes.NewBufferString(name) replacer := strings.NewReplacer(" ", "_", ":", "_") for _, label := range labels { _, _ = replacer.WriteString(buf, ".") _, _ = replacer.WriteString(buf, label.Value) } return buf.String() }