diff --git a/doc/dashboards.md b/doc/dashboards.md index feb7a626..cbe712ad 100644 --- a/doc/dashboards.md +++ b/doc/dashboards.md @@ -6,9 +6,7 @@ Build-in dashboard are available with multiple data source - [Prometheus - Advanced](https://grafana.com/grafana/dashboards/15416) - [Loki](https://grafana.com/grafana/dashboards/15415) -## Metrics - -### Basic +## Prometheus - Basic dashboard Activate the **[Prometheus](https://github.com/dmachard/go-dns-collector/blob/main/doc/configuration.md#Prometheus)** logger to use this dashboard @@ -16,7 +14,7 @@ Activate the **[Prometheus](https://github.com/dmachard/go-dns-collector/blob/ma
-### Advanced +## Prometheus - Advanced dashboard@@ -26,7 +24,7 @@ Activate the **[Prometheus](https://github.com/dmachard/go-dns-collector/blob/ma
-## Logs +## Loki Dashboarddiff --git a/loggers/prometheus.go b/loggers/prometheus.go index 5f74f1fe..33151654 100644 --- a/loggers/prometheus.go +++ b/loggers/prometheus.go @@ -39,7 +39,8 @@ type EpsCounters struct { type Prometheus struct { done chan bool done_api chan bool - httpserver net.Listener + httpServer *http.Server + netListener net.Listener channel chan dnsutils.DnsMessage config *dnsutils.Config logger *logger.Logger @@ -115,11 +116,17 @@ func NewPrometheus(config *dnsutils.Config, logger *logger.Logger, version strin name: name, } + + // init prometheus o.InitProm() // add build version in metrics o.gaugeBuildInfo.WithLabelValues(o.version).Set(1) + mux := http.NewServeMux() + mux.Handle("/metrics", promhttp.HandlerFor(o.promRegistry, promhttp.HandlerOpts{})) + o.httpServer = &http.Server{Handler: mux, ErrorLog: o.logger.ErrorLogger()} + return o } @@ -339,7 +346,7 @@ func (o *Prometheus) Stop() { o.LogInfo("stopping...") // stopping http server - o.httpserver.Close() + o.netListener.Close() // close output channel o.LogInfo("closing channel") @@ -356,15 +363,6 @@ func (o *Prometheus) Stop() { o.LogInfo(" stopped") } -/*func (o *Prometheus) BasicAuth(w http.ResponseWriter, r *http.Request) bool { - login, password, authOK := r.BasicAuth() - if !authOK { - return false - } - - return (login == o.config.Loggers.Prometheus.BasicAuthLogin) && (password == o.config.Loggers.Prometheus.BasicAuthPwd) -}*/ - func (o *Prometheus) Record(dm dnsutils.DnsMessage) { // record stream identity if _, exists := o.streamsMap[dm.DnsTap.Identity]; !exists { @@ -528,10 +526,6 @@ func (o *Prometheus) ComputeEps() { func (s *Prometheus) ListenAndServe() { s.LogInfo("starting prometheus metrics...") - mux := http.NewServeMux() - - mux.Handle("/metrics", promhttp.HandlerFor(s.promRegistry, promhttp.HandlerOpts{})) - var err error var listener net.Listener addrlisten := s.config.Loggers.Prometheus.ListenIP + ":" + strconv.Itoa(s.config.Loggers.Prometheus.ListenPort) @@ -575,11 +569,10 @@ func (s *Prometheus) ListenAndServe() { s.logger.Fatal("listening failed:", err) } - s.httpserver = listener + s.netListener = listener s.LogInfo("is listening on %s", listener.Addr()) - srv := &http.Server{Handler: mux, ErrorLog: s.logger.ErrorLogger()} - srv.Serve(s.httpserver) + s.httpServer.Serve(s.netListener) s.LogInfo("terminated") s.done_api <- true diff --git a/loggers/prometheus_test.go b/loggers/prometheus_test.go new file mode 100644 index 00000000..706ac5dd --- /dev/null +++ b/loggers/prometheus_test.go @@ -0,0 +1,59 @@ +package loggers + +import ( + "net/http" + "net/http/httptest" + "regexp" + "strings" + "testing" + + "github.com/dmachard/go-dnscollector/dnsutils" + "github.com/dmachard/go-logger" +) + +func TestPrometheusGetMetrics(t *testing.T) { + // init the logger + config := dnsutils.GetFakeConfig() + g := NewPrometheus(config, logger.New(false), "dev", "test") + + // record one dns message to simulate some incoming data + g.Record(dnsutils.GetFakeDnsMessage()) + + tt := []struct { + name string + method string + handler func(w http.ResponseWriter, r *http.Request) + want string + statusCode int + }{ + { + name: "total domains", + method: http.MethodGet, + handler: g.httpServer.Handler.ServeHTTP, + want: config.Loggers.Prometheus.PromPrefix + `_domains_count{stream_id="collector"} 1`, + statusCode: http.StatusOK, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + // init httptest + request := httptest.NewRequest(tc.method, "/metrics", strings.NewReader("")) + responseRecorder := httptest.NewRecorder() + + // call handler + tc.handler(responseRecorder, request) + + // checking status code + if responseRecorder.Code != tc.statusCode { + t.Errorf("Want status '%d', got '%d'", tc.statusCode, responseRecorder.Code) + } + + // checking content + metrics := strings.TrimSpace(responseRecorder.Body.String()) + if regexp.MustCompile(tc.want).MatchString(string(metrics)) != true { + t.Errorf("Want '%s', got '%s'", tc.want, responseRecorder.Body) + } + }) + } +}