예제 #1
0
func init() {
	// NOTE(stevvooe): Setup registry metrics structure to report to expvar.
	// Ideally, we do more metrics through logging but we need some nice
	// realtime metrics for queue state for now.

	registry := expvar.Get("registry")

	if registry == nil {
		registry = expvar.NewMap("registry")
	}

	var notifications expvar.Map
	notifications.Init()
	notifications.Set("endpoints", expvar.Func(func() interface{} {
		endpoints.mu.Lock()
		defer endpoints.mu.Unlock()

		var names []interface{}
		for _, v := range endpoints.registered {
			var epjson struct {
				Name string `json:"name"`
				URL  string `json:"url"`
				EndpointConfig

				Metrics EndpointMetrics
			}

			epjson.Name = v.Name()
			epjson.URL = v.URL()
			epjson.EndpointConfig = v.EndpointConfig

			v.ReadMetrics(&epjson.Metrics)

			names = append(names, epjson)
		}

		return names
	}))

	registry.(*expvar.Map).Set("notifications", &notifications)
}
예제 #2
0
// TODO: maybe we should use Func() and just keep a stats structure.
// But that would require locking and nngh nngh.
func setupExpvars() {
	var m expvar.Map
	m.Init()
	m.Set("notls", expvar.Func(notls.Stats))
	m.Set("yakkers", expvar.Func(yakkers.Stats))
	stats.Set("sizes", &m)
	stats.Set("dnsbl_hits", expvar.Func(dblcounts.Stats))
	stats.Set("sbl_hits", expvar.Func(sblcounts.Stats))

	// BUG: must remember to do this for all counters so they have
	// an initial value.
	var evts expvar.Map
	evts.Init()
	evts.Set("connections", &events.connections)
	evts.Set("tls_errors", &events.tlserrs)
	evts.Set("yakkers", &events.yakkers)
	evts.Set("notls_conns", &events.notlscnt)
	evts.Set("rules_errors", &events.ruleserr)
	evts.Set("yakker_adds", &events.yakads)
	evts.Set("rsetdrops", &events.rsetdrops)
	evts.Set("abandons", &events.abandons)
	evts.Set("refuseds", &events.refuseds)
	stats.Set("events", &evts)
	var mailevts expvar.Map
	var goodevts expvar.Map
	var cmds expvar.Map
	mailevts.Init()
	goodevts.Init()
	cmds.Init()
	// Maybe these should track refused commands? Not sure.
	cmds.Set("ehlo", &events.ehlo)
	cmds.Set("mailfrom", &events.mailfrom)
	cmds.Set("rcptto", &events.rcptto)
	cmds.Set("data", &events.data)
	mailevts.Set("commands", &cmds)

	// These are counts of *accepted* commands.
	// TODO: maybe revise how things are counted? Dunno.
	goodevts.Set("ehlo", &events.ehloAccept)
	goodevts.Set("mailfrom", &events.mailfromAccept)
	goodevts.Set("rcptto", &events.rcpttoAccept)
	goodevts.Set("data", &events.dataAccept)
	goodevts.Set("messages", &events.messages)
	mailevts.Set("accepted", &goodevts)

	mailevts.Set("ehlo_tlson", &events.tlson)
	mailevts.Set("quits", &events.quits)
	mailevts.Set("aborts", &events.aborts)
	mailevts.Set("rsets", &events.rsets)
	stats.Set("smtpcounts", &mailevts)

	// constants
	stats.Add("pid", int64(os.Getpid()))
	var stime expvar.String
	stime.Set(time.Now().String())
	stats.Set("startTime", &stime)

	var conntime expvar.String
	times.Init()
	// We're going to have connections, so we set this now.
	times.Set("connection", &conntime)
	stats.Set("last", &times)
}
예제 #3
0
func ExampleExpvarCollector() {
	expvarCollector := prometheus.NewExpvarCollector(map[string]*prometheus.Desc{
		"memstats": prometheus.NewDesc(
			"expvar_memstats",
			"All numeric memstats as one metric family. Not a good role-model, actually... ;-)",
			[]string{"type"}, nil,
		),
		"lone-int": prometheus.NewDesc(
			"expvar_lone_int",
			"Just an expvar int as an example.",
			nil, nil,
		),
		"http-request-map": prometheus.NewDesc(
			"expvar_http_request_total",
			"How many http requests processed, partitioned by status code and http method.",
			[]string{"code", "method"}, nil,
		),
	})
	prometheus.MustRegister(expvarCollector)

	// The Prometheus part is done here. But to show that this example is
	// doing anything, we have to manually export something via expvar.  In
	// real-life use-cases, some library would already have exported via
	// expvar what we want to re-export as Prometheus metrics.
	expvar.NewInt("lone-int").Set(42)
	expvarMap := expvar.NewMap("http-request-map")
	var (
		expvarMap1, expvarMap2                             expvar.Map
		expvarInt11, expvarInt12, expvarInt21, expvarInt22 expvar.Int
	)
	expvarMap1.Init()
	expvarMap2.Init()
	expvarInt11.Set(3)
	expvarInt12.Set(13)
	expvarInt21.Set(11)
	expvarInt22.Set(212)
	expvarMap1.Set("POST", &expvarInt11)
	expvarMap1.Set("GET", &expvarInt12)
	expvarMap2.Set("POST", &expvarInt21)
	expvarMap2.Set("GET", &expvarInt22)
	expvarMap.Set("404", &expvarMap1)
	expvarMap.Set("200", &expvarMap2)
	// Results in the following expvar map:
	// "http-request-count": {"200": {"POST": 11, "GET": 212}, "404": {"POST": 3, "GET": 13}}

	// Let's see what the scrape would yield, but exclude the memstats metrics.
	metricStrings := []string{}
	metric := dto.Metric{}
	metricChan := make(chan prometheus.Metric)
	go func() {
		expvarCollector.Collect(metricChan)
		close(metricChan)
	}()
	for m := range metricChan {
		if strings.Index(m.Desc().String(), "expvar_memstats") == -1 {
			metric.Reset()
			m.Write(&metric)
			metricStrings = append(metricStrings, metric.String())
		}
	}
	sort.Strings(metricStrings)
	for _, s := range metricStrings {
		fmt.Println(strings.TrimRight(s, " "))
	}
	// Output:
	// label:<name:"code" value:"200" > label:<name:"method" value:"GET" > untyped:<value:212 >
	// label:<name:"code" value:"200" > label:<name:"method" value:"POST" > untyped:<value:11 >
	// label:<name:"code" value:"404" > label:<name:"method" value:"GET" > untyped:<value:13 >
	// label:<name:"code" value:"404" > label:<name:"method" value:"POST" > untyped:<value:3 >
	// untyped:<value:42 >
}