13 // InmemSignal is used to listen for a given signal, and when received,
14 // to dump the current metrics from the InmemSink to an io.Writer
15 type InmemSignal struct {
26 // NewInmemSignal creates a new InmemSignal which listens for a given signal,
27 // and dumps the current metrics out to a writer
28 func NewInmemSignal(inmem *InmemSink, sig syscall.Signal, w io.Writer) *InmemSignal {
33 sigCh: make(chan os.Signal, 1),
34 stopCh: make(chan struct{}),
36 signal.Notify(i.sigCh, sig)
41 // DefaultInmemSignal returns a new InmemSignal that responds to SIGUSR1
42 // and writes output to stderr. Windows uses SIGBREAK
43 func DefaultInmemSignal(inmem *InmemSink) *InmemSignal {
44 return NewInmemSignal(inmem, DefaultSignal, os.Stderr)
47 // Stop is used to stop the InmemSignal from listening
48 func (i *InmemSignal) Stop() {
50 defer i.stopLock.Unlock()
60 // run is a long running routine that handles signals
61 func (i *InmemSignal) run() {
72 // dumpStats is used to dump the data to output writer
73 func (i *InmemSignal) dumpStats() {
74 buf := bytes.NewBuffer(nil)
77 // Skip the last period which is still being aggregated
78 for i := 0; i < len(data)-1; i++ {
81 for name, val := range intv.Gauges {
82 fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val)
84 for name, vals := range intv.Points {
85 for _, val := range vals {
86 fmt.Fprintf(buf, "[%v][P] '%s': %0.3f\n", intv.Interval, name, val)
89 for name, agg := range intv.Counters {
90 fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg)
92 for name, agg := range intv.Samples {
93 fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg)
98 // Write out the bytes
99 i.w.Write(buf.Bytes())