예제 #1
0
// for debugging, show goroutine trace on receipt of USR1. uninstall by calling
// Stop on the returned object
func InstallStackTracer() stopper.Stopper {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, traceSignal)
	stopper := stopper.NewChanStopper()
	go func() {
		defer func() {
			signal.Stop(signals)
			close(signals)
		}()
		for {
			select {
			case <-signals:
				log.Print(instrumentation.GetStackTrace(true))
			case <-stopper.Chan:
				return
			}
		}
	}()
	return stopper
}
예제 #2
0
// NewGangliaReporterWithOptions is NewGangliaReporter with the groupName.
func NewGangliaReporterWithOptions(interval time.Duration, groupName string) *Reporter {
	gm, err := NewGmetric()
	if err != nil {
		vlog.VLogfQuiet("ganglia", "Couldn't start Ganglia reporter: %s", err)
		return nil
	} else if gm == nil {
		return nil
	}
	stopper := stopper.NewChanStopper()
	gr := &Reporter{
		ChanStopper: stopper,
		prefix:      "",
		callbacks:   []ReporterCallback{},
		previous:    make(map[string]gmetricSample),
		groupName:   groupName,
		dmax:        0,
	}
	go func() {
		defer stopper.Done()
		for {
			select {
			case <-stopper.Chan:
				return
			case <-time.After(interval):
				go func() {
					// SendMetric "opens" and "closes" UDP connections each
					// time, but since we expect the callback to send several
					// metrics at once, avoid that here.
					conns := gm.OpenConnections()
					n := 0
					sender := func(name string, value string, metricType uint32, units string, rate bool) {
						v := value
						if rate {
							prev, exists := gr.previous[name]
							units += "/sec"

							now := time.Now()

							switch metricType {
							case Ushort, Short, Uint, Int:
								i, err := strconv.Atoi(value)
								if err != nil {
									vlog.VLogfQuiet(name, "Value %q doesn't look like an int: %s", value, err)
									return
								}
								gr.previous[name] = gmetricSample{i, now}
								if !exists {
									return
								}
								delta := i - prev.value.(int)
								elapsed := time.Now().Sub(prev.when).Seconds()
								v = fmt.Sprint(float64(delta) / elapsed)
								// upgrade to a float to avoid loss of precision
								metricType = Float

							case Float, Double:
								f, err := strconv.ParseFloat(value, 64)
								if err != nil {
									vlog.VLogfQuiet(name, "Value %q doesn't look like a float: %s", value, err)
									return
								}
								gr.previous[name] = gmetricSample{f, now}
								if !exists {
									return
								}
								delta := f - prev.value.(float64)
								elapsed := time.Now().Sub(prev.when).Seconds()
								v = fmt.Sprint(delta / elapsed)

							case String:
								vlog.VLogfQuiet(name, "Can't compute deltas for string metric %q", value)
								return
							}
						}

						// gmetad fails to escape quotes, eventually generating
						// invalid xml. do it here as a workaround.
						v = html.EscapeString(v)
						name = html.EscapeString(name)
						units = html.EscapeString(units)

						n++
						gm.SendMetricPackets(
							gr.prefix+name, v, metricType, units,
							gmetric.SLOPE_BOTH,
							uint32(interval.Seconds()), // tmax is the expected reporting interval
							gr.dmax,
							gr.groupName,
							gmetric.PACKET_BOTH, conns,
						)
						if debug.On() {
							if rate {
								log.Printf("gmetric: name=%q, rate=%q, value=%q, type=%d, units=%q, slope=%d, tmax=%d, dmax=%v, group=%q, packet=%d",
									gr.prefix+name, v, value, metricType, units, gmetric.SLOPE_BOTH,
									uint32(interval.Seconds()), gr.dmax, gr.groupName, gmetric.PACKET_BOTH,
								)
							} else {
								log.Printf("gmetric: name=%q, value=%q, type=%d, units=%q, slope=%d, tmax=%d, dmax=%v, group=%q, packet=%d",
									gr.prefix+name, v, metricType, units, gmetric.SLOPE_BOTH,
									uint32(interval.Seconds()), gr.dmax, gr.groupName, gmetric.PACKET_BOTH,
								)
							}
						}
					}
					defer gm.CloseConnections(conns)
					for _, callback := range gr.callbacks {
						callback(sender)
					}
					if debug.On() {
						log.Printf("Published %d metrics to Ganglia", n)
					}
				}()
			}
		}
	}()
	return gr
}