From 7e597c91430bde68d64fc0771abf63157b101ae1 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 4 Sep 2017 16:23:49 +0100 Subject: [PATCH] Add debug url parameter to return debug logs. --- README.md | 4 +++- main.go | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc6065c..35159e6 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ HTTP, HTTPS, DNS, TCP and ICMP. ./blackbox_exporter Visiting [http://localhost:9115/probe?target=google.com&module=http_2xx](http://localhost:9115/probe?target=google.com&module=http_2xx) -will return metrics for a HTTP probe against google.com. The `probe_success` metric indicates if the probe succeeded. +will return metrics for a HTTP probe against google.com. The `probe_success` +metric indicates if the probe succeeded. Adding a `debug=true` parameter +will return debug information for that probe. ### Building with Docker diff --git a/main.go b/main.go index 044d976..2495d98 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ package main import ( + "bytes" "context" "fmt" "net/http" @@ -30,6 +31,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/prometheus/common/expfmt" "github.com/prometheus/common/promlog" "github.com/prometheus/common/promlog/flag" "github.com/prometheus/common/version" @@ -108,19 +110,79 @@ func probeHandler(w http.ResponseWriter, r *http.Request, c *config.Config, logg return } + sl := newScrapeLogger(logger, moduleName, target) + level.Info(sl).Log("msg", "Beginning probe", "probe", module.Prober) + start := time.Now() registry := prometheus.NewRegistry() registry.MustRegister(probeSuccessGauge) registry.MustRegister(probeDurationGauge) - success := prober(ctx, target, module, registry, logger) + success := prober(ctx, target, module, registry, sl) probeDurationGauge.Set(time.Since(start).Seconds()) if success { probeSuccessGauge.Set(1) + level.Info(sl).Log("msg", "Probe succeeded") + } else { + level.Error(sl).Log("msg", "Probe failed") + } + + debug := false + if r.URL.Query().Get("debug") == "true" { + debug = true + } + + if debug { + w.Header().Set("Content-Type", "text/plain") + fmt.Fprintf(w, "Logs for the probe:\n") + sl.buffer.WriteTo(w) + fmt.Fprintf(w, "\n\n\nMetrics that would have been returned:\n") + mfs, err := registry.Gather() + if err != nil { + fmt.Fprintf(w, "Error gathering metrics: %s\n", err) + return + } + for _, mf := range mfs { + expfmt.MetricFamilyToText(w, mf) + } + return } + h := promhttp.HandlerFor(registry, promhttp.HandlerOpts{}) h.ServeHTTP(w, r) } +type scrapeLogger struct { + next log.Logger + module string + target string + buffer bytes.Buffer + bufferLogger log.Logger +} + +func newScrapeLogger(logger log.Logger, module string, target string) *scrapeLogger { + logger = log.With(logger, "module", module, "target", target) + sl := &scrapeLogger{ + next: logger, + buffer: bytes.Buffer{}, + } + bl := log.NewLogfmtLogger(&sl.buffer) + sl.bufferLogger = log.With(bl, "ts", log.DefaultTimestampUTC, "caller", log.Caller(6), "module", module, "target", target) + return sl +} + +func (sl scrapeLogger) Log(keyvals ...interface{}) error { + sl.bufferLogger.Log(keyvals...) + kvs := make([]interface{}, len(keyvals)) + copy(kvs, keyvals) + // Switch level to debug for application output. + for i := 0; i < len(kvs); i += 2 { + if kvs[i] == level.Key() { + kvs[i+1] = level.DebugValue() + } + } + return sl.next.Log(kvs...) +} + func init() { prometheus.MustRegister(version.NewCollector("blackbox_exporter")) } @@ -193,6 +255,7 @@ func main() {

Blackbox Exporter

Probe prometheus.io for http_2xx

+

Debug probe prometheus.io for http_2xx

Metrics

Configuration

-- 2.25.1