mlisting

Mailing list service

git clone git://git.lin.moe/go/mlisting.git

  1package service
  2
  3import (
  4	"context"
  5	"net/http"
  6
  7	"git.lin.moe/go/mlisting/config"
  8	"git.lin.moe/go/mlisting/storage"
  9	"github.com/prometheus/client_golang/prometheus"
 10	"github.com/prometheus/client_golang/prometheus/promhttp"
 11)
 12
 13var lmtpMetrics *struct {
 14	msgReceived  *prometheus.CounterVec
 15	msgForwarded *prometheus.CounterVec
 16	msgSent      *prometheus.CounterVec
 17
 18	listMemberNum *prometheus.GaugeVec
 19}
 20
 21func init() {
 22	lmtpMetrics = &struct {
 23		msgReceived   *prometheus.CounterVec
 24		msgForwarded  *prometheus.CounterVec
 25		msgSent       *prometheus.CounterVec
 26		listMemberNum *prometheus.GaugeVec
 27	}{
 28		prometheus.NewCounterVec(
 29			prometheus.CounterOpts{
 30				Name: "mlisting_lmtp_message_received",
 31				Help: "messages count received from the lmtp listen port",
 32			},
 33			[]string{"list"},
 34		),
 35		prometheus.NewCounterVec(
 36			prometheus.CounterOpts{
 37				Name: "mlisting_lmtp_message_forwarded",
 38				Help: "messages count should be forwarded",
 39			},
 40			[]string{"list"},
 41		),
 42
 43		prometheus.NewCounterVec(
 44			prometheus.CounterOpts{
 45				Name: "mlisting_lmtp_message_sent",
 46				Help: "messages count total sent to smtp server",
 47			},
 48			[]string{"list"},
 49		),
 50		prometheus.NewGaugeVec(
 51			prometheus.GaugeOpts{
 52				Name: "mlisting_list_member_number",
 53				Help: "member number of list",
 54			},
 55			[]string{"list"},
 56		),
 57	}
 58}
 59
 60func NewMetricMux(cfg *config.Config, st storage.Storage, l config.Logger) http.Handler {
 61	mux := http.NewServeMux()
 62	reg := prometheus.NewRegistry()
 63
 64	registMetrics(reg)
 65
 66	ctx := context.TODO()
 67	ctx = config.Context(ctx, cfg)
 68	ctx = storage.Context(ctx, st)
 69
 70	mux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {
 71		st, ok := storage.FromContext(ctx)
 72		if !ok {
 73			promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}).ServeHTTP(w, r)
 74			return
 75		}
 76
 77		lists, err := st.Lists(ctx)
 78		if err != nil {
 79			l.Error("load lists", "err", err)
 80			promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}).ServeHTTP(w, r)
 81			return
 82		}
 83		for _, list := range lists {
 84			addrs, err := list.Members(ctx)
 85			if err != nil {
 86				l.Error("load members of list", "err", err, "list", list.Address())
 87				continue
 88			}
 89			lmtpMetrics.listMemberNum.With(prometheus.Labels{"list": list.Address()}).Set(float64(len(addrs)))
 90		}
 91
 92		promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}).ServeHTTP(w, r)
 93	})
 94
 95	lists, err := st.Lists(ctx)
 96	if err != nil {
 97		panic(err)
 98	}
 99
100	for _, l := range lists {
101		lmtpMetrics.msgReceived.With(prometheus.Labels{"list": l.Address()}).Add(0)
102		lmtpMetrics.msgForwarded.With(prometheus.Labels{"list": l.Address()}).Add(0)
103		lmtpMetrics.msgSent.With(prometheus.Labels{"list": l.Address()}).Add(0)
104	}
105
106	return mux
107
108}
109
110func registMetrics(reg prometheus.Registerer) {
111	reg.MustRegister(lmtpMetrics.msgReceived)
112	reg.MustRegister(lmtpMetrics.msgForwarded)
113	reg.MustRegister(lmtpMetrics.msgSent)
114	reg.MustRegister(lmtpMetrics.listMemberNum)
115}