From 121831b44c16d799c355b48cb20c55ab406304dd Mon Sep 17 00:00:00 2001 From: Mariusz Olejnik Date: Fri, 10 Feb 2023 15:22:23 +0100 Subject: [PATCH] zone port in metrics --- metrics.go | 24 ++++++++++++------------ recursor.go | 34 +++++++++++++++++----------------- recursor_test.go | 4 ++-- setup.go | 12 ++++++------ 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/metrics.go b/metrics.go index d404d9f..81d2b85 100644 --- a/metrics.go +++ b/metrics.go @@ -1,12 +1,10 @@ package recursor import ( - "sync" - "github.com/coredns/coredns/plugin" - "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "sync" ) var promBuildInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{ @@ -20,57 +18,59 @@ var promResolvesInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{ Subsystem: pluginName, Name: "resolvers_info", Help: "Resolves info", -}, []string{"zone", "resolver", "urls"}) +}, []string{"port", "zone", "resolver", "urls"}) var promAliasesInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "aliases_info", Help: "Aliases info", -}, []string{"zone", "alias", "resolver", "ttl"}) +}, []string{"port", "zone", "alias", "resolver", "ttl"}) var promAliasesEntriesInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "aliases_entries_info", Help: "Aliases entries info", -}, []string{"zone", "alias", "resolver", "type", "entry"}) +}, []string{"port", "zone", "alias", "resolver", "type", "entry"}) var promQueryServedCountTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "query_served_count_total", Help: "Total count of served queries", -}, []string{"zone", "alias", "resolver", "client_ip"}) +}, []string{"port", "zone", "alias", "resolver", "client_ip"}) var promQueryOmittedCountTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "query_omitted_count_total", Help: "Total count of omitted queries", -}, []string{"zone", "alias", "reason", "client_ip"}) +}, []string{"port", "zone", "alias", "reason", "client_ip"}) + +var commonLabels = []string{"port", "zone", "alias", "resolver", "host", "result"} var promResolveCountTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "resolve_count_total", Help: "Total count of resolve operations", -}, []string{"zone", "alias", "resolver", "host", "result"}) +}, commonLabels) var promResolveDurationMs = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "resolve_duration_ms", Help: "Duration of resolve operation in milliseconds", -}, []string{"zone", "alias", "resolver", "host", "result"}) +}, commonLabels) var promResolveDurationMsTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "resolve_duration_ms_total", Help: "Total duration of resolve operations in milliseconds", -}, []string{"zone", "alias", "resolver", "host", "result"}) +}, commonLabels) var promResolveIpCountTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, Subsystem: pluginName, Name: "resolve_ip_count_total", Help: "Total count of answers", -}, []string{"zone", "alias", "resolver", "ip"}) +}, []string{"port", "zone", "alias", "resolver", "ip"}) var _ sync.Once diff --git a/recursor.go b/recursor.go index 66b716f..12f6d3d 100644 --- a/recursor.go +++ b/recursor.go @@ -14,7 +14,7 @@ import ( ) const pluginName = "recursor" -const pluginVersion = "1.1.0" +const pluginVersion = "1.1.2" const defaultResolverName = "default" // Name implements the Handler interface. @@ -77,7 +77,7 @@ func (r recursor) ServeDNS(ctx context.Context, out dns.ResponseWriter, query *d alias := strings.TrimSuffix(domain, zoneSuffix) port := state.LocalPort() if r.verbose > 0 { - log.Infof("Recursor query domain '%s', alias '%s', zone '%s', port '%s', client_ip '%s'", domain, alias, r.zone, port, clientIp) + log.Infof("Recursor query domain '%s', alias '%s', port '%s', zone '%s', client_ip '%s'", domain, alias, port, r.zone, clientIp) } qA, qAAAA := extractQuestions(query.Question) @@ -85,20 +85,20 @@ func (r recursor) ServeDNS(ctx context.Context, out dns.ResponseWriter, query *d log.Infof("Recursor query: A=%t, AAAA=%t, client_ip=%s\n```\n%s```", qA, qAAAA, clientIp, query.String()) } if !qA && !qAAAA { - promQueryOmittedCountTotal.With(prometheus.Labels{"zone": r.zone, "alias": alias, "reason": "not-supported-query-code", "client_ip": clientIp}).Inc() - log.Errorf("Query code not supported: zone '%s', domain '%s', alias '%s'", r.zone, domain, alias) + promQueryOmittedCountTotal.With(prometheus.Labels{"port": port, "zone": r.zone, "alias": alias, "reason": "not-supported-query-code", "client_ip": clientIp}).Inc() + log.Errorf("Query code not supported: port '%s', zone '%s', domain '%s', alias '%s'", port, r.zone, domain, alias) return plugin.NextOrFailure(r.Name(), r.Next, ctx, out, query) } aDef, aFound, aWildcard := r.findAlias(alias) if !aFound { - promQueryOmittedCountTotal.With(prometheus.Labels{"zone": r.zone, "alias": alias, "reason": "alias-not-found", "client_ip": clientIp}).Inc() - log.Errorf("Alias not found: zone '%s', domain '%s', alias '%s'", r.zone, domain, alias) + promQueryOmittedCountTotal.With(prometheus.Labels{"port": port, "zone": r.zone, "alias": alias, "reason": "alias-not-found", "client_ip": clientIp}).Inc() + log.Errorf("Alias not found: port '%s', zone '%s', domain '%s', alias '%s'", port, r.zone, domain, alias) return plugin.NextOrFailure(r.Name(), r.Next, ctx, out, query) } if !aWildcard && len(aDef.hosts) < 1 && len(aDef.ips) < 1 { - promQueryOmittedCountTotal.With(prometheus.Labels{"zone": r.zone, "alias": alias, "reason": "alias-empty-def", "client_ip": clientIp}).Inc() - log.Errorf("Empty alias definition: zone '%s', domain '%s', alias '%s'", r.zone, domain, alias) + promQueryOmittedCountTotal.With(prometheus.Labels{"port": port, "zone": r.zone, "alias": alias, "reason": "alias-empty-def", "client_ip": clientIp}).Inc() + log.Errorf("Empty alias definition: port '%s', zone '%s', domain '%s', alias '%s'", port, r.zone, domain, alias) return plugin.NextOrFailure(r.Name(), r.Next, ctx, out, query) } @@ -109,16 +109,16 @@ func (r recursor) ServeDNS(ctx context.Context, out dns.ResponseWriter, query *d hosts = append(hosts, strings.TrimSuffix(domain, ".")) } for _, host := range hosts { - dynIps, err := multiResolve(ctx, aDef.resolverDefRef, r.zone, alias, host) + dynIps, err := multiResolve(ctx, aDef.resolverDefRef, port, r.zone, alias, host) if err != nil { - promQueryOmittedCountTotal.With(prometheus.Labels{"zone": r.zone, "alias": alias, "reason": "resolving-error", "client_ip": clientIp}).Inc() - log.Errorf("Could not resolve host '%s': zone '%s', domain '%s', alias '%s'", host, r.zone, domain, alias) + promQueryOmittedCountTotal.With(prometheus.Labels{"port": port, "zone": r.zone, "alias": alias, "reason": "resolving-error", "client_ip": clientIp}).Inc() + log.Errorf("Could not resolve host '%s': port '%s', zone '%s', domain '%s', alias '%s'", host, port, r.zone, domain, alias) return plugin.NextOrFailure(r.Name(), r.Next, ctx, out, query) } ips = ipsAppendUnique(ips, dynIps) } - aMsg := createDnsAnswer(query, r.zone, domain, alias, aDef.resolverDefRef.name, ips, qA, qAAAA, aDef.ttl) + aMsg := createDnsAnswer(query, port, r.zone, domain, alias, aDef.resolverDefRef.name, ips, qA, qAAAA, aDef.ttl) if r.verbose > 1 { log.Infof("Recursor answer:\n```\n%s```", aMsg.String()) } @@ -127,7 +127,7 @@ func (r recursor) ServeDNS(ctx context.Context, out dns.ResponseWriter, query *d log.Errorf("Could not write message: %v", err) return dns.RcodeServerFailure, err } - promQueryServedCountTotal.With(prometheus.Labels{"zone": r.zone, "alias": alias, "resolver": aDef.resolverDefRef.name, "client_ip": clientIp}).Inc() + promQueryServedCountTotal.With(prometheus.Labels{"port": port, "zone": r.zone, "alias": alias, "resolver": aDef.resolverDefRef.name, "client_ip": clientIp}).Inc() return dns.RcodeSuccess, nil } @@ -143,7 +143,7 @@ func (r recursor) findAlias(alias string) (aliasDef, bool, bool) { return aDef, aFound, aWildcard } -func multiResolve(ctx context.Context, resolverDefRef *resolverDef, zone string, alias string, host string) ([]net.IP, error) { +func multiResolve(ctx context.Context, resolverDefRef *resolverDef, port string, zone string, alias string, host string) ([]net.IP, error) { var lastErr error for ri, rslRef := range resolverDefRef.resolverRefs { rslUrl := resolverDefRef.urls[ri] @@ -154,7 +154,7 @@ func multiResolve(ctx context.Context, resolverDefRef *resolverDef, zone string, if err != nil { result = "error" } - labels := prometheus.Labels{"zone": zone, "alias": alias, "resolver": resolverDefRef.name, "host": host, "result": result} + labels := prometheus.Labels{"port": port, "zone": zone, "alias": alias, "resolver": resolverDefRef.name, "host": host, "result": result} promResolveDurationMs.With(labels).Set(float64(elapsed.Milliseconds())) promResolveCountTotal.With(labels).Inc() promResolveDurationMsTotal.With(labels).Add(float64(elapsed.Milliseconds())) @@ -203,7 +203,7 @@ func ipsExists(arr []net.IP, ipaToFind net.IP) bool { return false } -func createDnsAnswer(qMsg *dns.Msg, zone string, domain string, alias string, resolver string, ips []net.IP, qA bool, qAAAA bool, ttl uint32) *dns.Msg { +func createDnsAnswer(qMsg *dns.Msg, port string, zone string, domain string, alias string, resolver string, ips []net.IP, qA bool, qAAAA bool, ttl uint32) *dns.Msg { aMsg := new(dns.Msg) aMsg.SetReply(qMsg) aMsg.Answer = []dns.RR{} @@ -236,7 +236,7 @@ func createDnsAnswer(qMsg *dns.Msg, zone string, domain string, alias string, re } if resRec != nil { - promResolveIpCountTotal.With(prometheus.Labels{"zone": zone, "alias": alias, "resolver": resolver, "ip": ip.String()}).Inc() + promResolveIpCountTotal.With(prometheus.Labels{"port": port, "zone": zone, "alias": alias, "resolver": resolver, "ip": ip.String()}).Inc() aMsg.Answer = append(aMsg.Answer, resRec) } } diff --git a/recursor_test.go b/recursor_test.go index bfc51da..605d3ac 100644 --- a/recursor_test.go +++ b/recursor_test.go @@ -95,8 +95,8 @@ func TestRecursor_should_work_as_repeater(t *testing.T) { }, }) - testQuestion(t, rcu, []uint16{dns.TypeA}, "www.wikipedia.org", []string{"185.15.58.224"}, 10, false) - testQuestion(t, rcu, []uint16{dns.TypeA}, "pl.wikipedia.org", []string{"185.15.58.224"}, 20, false) + testQuestion(t, rcu, []uint16{dns.TypeA}, "www.wikipedia.org", []string{"91.198.174.192"}, 10, false) + testQuestion(t, rcu, []uint16{dns.TypeA}, "pl.wikipedia.org", []string{"91.198.174.192"}, 20, false) testQuestion(t, rcu, []uint16{dns.TypeA}, "domain-that-doesnt-exist.wikipedia.org", []string{}, 0, true) testQuestion(t, rcu, []uint16{dns.TypeA}, "domain.that.doesnt.exist.wikipedia.org", []string{}, 0, true) } diff --git a/setup.go b/setup.go index 358ec7b..995f7e1 100644 --- a/setup.go +++ b/setup.go @@ -28,7 +28,7 @@ func setup(c *caddy.Controller) error { if err != nil { return plugin.Error(pluginName, fmt.Errorf("%s/%s create recursor error: %w", pluginName, pluginVersion, err)) } - updateInfoMetrics(rcu) + updateInfoMetrics(cfg.Port, rcu) if rcu.verbose > 1 { log.Infof("Plugin %s/%s created (zone '%s'): %s", pluginName, pluginVersion, rcu.zone, rcu.String()) } @@ -42,18 +42,18 @@ func setup(c *caddy.Controller) error { return nil } -func updateInfoMetrics(rcu recursor) { +func updateInfoMetrics(port string, rcu recursor) { promBuildInfo.With(prometheus.Labels{"version": pluginVersion}).Set(0) for name, def := range rcu.resolvers { - promResolvesInfo.With(prometheus.Labels{"zone": rcu.zone, "resolver": name, "urls": strings.Join(def.urls, ",")}).Set(1) + promResolvesInfo.With(prometheus.Labels{"port": port, "zone": rcu.zone, "resolver": name, "urls": strings.Join(def.urls, ",")}).Set(1) } for name, def := range rcu.aliases { - promAliasesInfo.With(prometheus.Labels{"zone": rcu.zone, "alias": name, "resolver": def.resolverDefRef.name, "ttl": strconv.Itoa(int(def.ttl))}).Set(1) + promAliasesInfo.With(prometheus.Labels{"port": port, "zone": rcu.zone, "alias": name, "resolver": def.resolverDefRef.name, "ttl": strconv.Itoa(int(def.ttl))}).Set(1) for _, host := range def.hosts { - promAliasesEntriesInfo.With(prometheus.Labels{"zone": rcu.zone, "alias": name, "resolver": def.resolverDefRef.name, "type": "host", "entry": host}).Set(1) + promAliasesEntriesInfo.With(prometheus.Labels{"port": port, "zone": rcu.zone, "alias": name, "resolver": def.resolverDefRef.name, "type": "host", "entry": host}).Set(1) } for _, ip := range def.ips { - promAliasesEntriesInfo.With(prometheus.Labels{"zone": rcu.zone, "alias": name, "resolver": def.resolverDefRef.name, "type": "ip", "entry": ip.String()}).Set(1) + promAliasesEntriesInfo.With(prometheus.Labels{"port": port, "zone": rcu.zone, "alias": name, "resolver": def.resolverDefRef.name, "type": "ip", "entry": ip.String()}).Set(1) } } }