From 02923f4547a1ebfaa3e260f03e0608de69bf1662 Mon Sep 17 00:00:00 2001 From: Guillaume Quintard Date: Wed, 5 Jun 2019 19:00:47 -0400 Subject: [PATCH] Normalize counter names New varnish versions allows vmods to create custom counters and it's mandatory to normalize their names to avoid scaring the scraper. This commit doesn't prevent collisions but there's only so much we can do. --- test/scrape/6.0.0.json | 15 +++++++++++++++ varnish.go | 12 +++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/test/scrape/6.0.0.json b/test/scrape/6.0.0.json index 285dd27..7e7163f 100644 --- a/test/scrape/6.0.0.json +++ b/test/scrape/6.0.0.json @@ -1514,5 +1514,20 @@ "description": "Backend requests sent", "flag": "c", "format": "i", "value": 0 + }, + "TEST.#_character": { + "description": "Try to trip the parser", + "flag": "c", "format": "i", + "value": 0 + }, + "__TEST.double_underscores": { + "description": "Try to trip the parser", + "flag": "c", "format": "i", + "value": 0 + }, + "0TEST.number": { + "description": "Try to trip the parser", + "flag": "c", "format": "i", + "value": 0 } } diff --git a/varnish.go b/varnish.go index 0698db8..e36d009 100644 --- a/varnish.go +++ b/varnish.go @@ -61,12 +61,22 @@ func ScrapeVarnish(ch chan<- prometheus.Metric) ([]byte, error) { func ScrapeVarnishFrom(buf []byte, ch chan<- prometheus.Metric) ([]byte, error) { // The output JSON annoyingly is not structured so that we could make a nice map[string]struct for it. metricsJSON := make(map[string]interface{}) + metricsJSON_raw := make(map[string]interface{}) + + reFancyChar := regexp.MustCompile("[^a-zA-Z_]") + reUnderscore := regexp.MustCompile("^(__|[0-9])") dec := json.NewDecoder(bytes.NewBuffer(buf)) dec.UseNumber() - if err := dec.Decode(&metricsJSON); err != nil { + if err := dec.Decode(&metricsJSON_raw); err != nil { return buf, err } + for vName, raw := range metricsJSON_raw { + newName := reFancyChar.ReplaceAllString(vName, "_") + newName = reUnderscore.ReplaceAllString(newName, "a$1") + metricsJSON[newName] = raw + } + for vName, raw := range metricsJSON { if vName == "timestamp" { continue