// NewCollector returns a prometheus.Collector for a given stats var. // It supports all stats var types except String, StringFunc and Rates. // The returned collector still needs to be registered with prometheus registry. func NewCollector(opts prometheus.Opts, v expvar.Var) prometheus.Collector { switch st := v.(type) { case *stats.Int: return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 { return float64(st.Get()) }) case stats.IntFunc: return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 { return float64(st()) }) case *stats.Duration: return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 { return st.Get().Seconds() }) case stats.DurationFunc: return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 { return st().Seconds() }) case *stats.Float: return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), st.Get) case stats.FloatFunc: return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), st) case *stats.Counters: return newCountersCollector(opts, st, "tag") case stats.CountersFunc: return newCountersCollector(opts, st, "tag") case *stats.MultiCounters: return newCountersCollector(opts, st, st.Labels()...) case *stats.MultiCountersFunc: return newCountersCollector(opts, st, st.Labels()...) case *stats.Histogram: return newHistogramCollector(opts, st) case *stats.Timings: return newTimingsCollector(opts, st, "category") case *stats.MultiTimings: return newTimingsCollector(opts, &st.Timings, st.Labels()...) case *stats.String: // prometheus can't collect string values return nil case stats.StringFunc: // prometheus can't collect string values return nil case *stats.Rates: // Ignore these, because monitoring tools will calculate // rates for us. return nil default: log.Warningf("Unsupported type for %s: %T", opts.Name, v) return nil } }
func (m *metric) init() error { name := m.Measurable.MsName() mangledName := mangleName(name) opts := prometheus.Opts{ Name: mangledName, Help: name, } switch m.Measurable.MsType() { case measurable.CounterType: mi, ok := m.Measurable.(interface { MsInt64() int64 }) if !ok { return errNotSupported } m.Metric = prometheus.NewCounterFunc(prometheus.CounterOpts(opts), func() float64 { return float64(mi.MsInt64()) }) case measurable.GaugeType: mi, ok := m.Measurable.(interface { MsInt64() int64 }) if !ok { return errNotSupported } m.Metric = prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 { return float64(mi.MsInt64()) }) default: return errNotSupported } return nil }