introduce metric naming test (#3789)
* introduce metric naming test Signed-off-by: zounengren <zounengren@cmss.chinamobile.com> * Update metrics.go Signed-off-by: zounengren <zounengren@cmss.chinamobile.com>
This commit is contained in:
parent
10d176b811
commit
87214a4c5c
18 changed files with 297 additions and 97 deletions
1
go.mod
1
go.mod
|
@ -30,6 +30,7 @@ require (
|
||||||
github.com/prometheus/client_golang v1.5.1
|
github.com/prometheus/client_golang v1.5.1
|
||||||
github.com/prometheus/client_model v0.2.0
|
github.com/prometheus/client_model v0.2.0
|
||||||
github.com/prometheus/common v0.9.1
|
github.com/prometheus/common v0.9.1
|
||||||
|
github.com/prometheus/prometheus v2.5.0+incompatible
|
||||||
github.com/tinylib/msgp v1.1.0 // indirect
|
github.com/tinylib/msgp v1.1.0 // indirect
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -367,6 +367,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
||||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
|
github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=
|
||||||
|
github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
|
github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
|
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
|
||||||
.TH "COREDNS-DNSSEC" 7 "January 2020" "CoreDNS" "CoreDNS Plugins"
|
.TH "COREDNS-DNSSEC" 7 "March 2020" "CoreDNS" "CoreDNS Plugins"
|
||||||
|
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
.PP
|
.PP
|
||||||
|
@ -72,7 +72,7 @@ RRSIGs. The default for \fBCAPACITY\fP is 10000.
|
||||||
If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported:
|
If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported:
|
||||||
|
|
||||||
.IP \(bu 4
|
.IP \(bu 4
|
||||||
\fB\fCcoredns_dnssec_cache_size{server, type}\fR - total elements in the cache, type is "signature".
|
\fB\fCcoredns_dnssec_cache_entries{server, type}\fR - total elements in the cache, type is "signature".
|
||||||
.IP \(bu 4
|
.IP \(bu 4
|
||||||
\fB\fCcoredns_dnssec_cache_hits_total{server}\fR - Counter of cache hits.
|
\fB\fCcoredns_dnssec_cache_hits_total{server}\fR - Counter of cache hits.
|
||||||
.IP \(bu 4
|
.IP \(bu 4
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
|
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
|
||||||
.TH "COREDNS-HOSTS" 7 "January 2020" "CoreDNS" "CoreDNS Plugins"
|
.TH "COREDNS-HOSTS" 7 "March 2020" "CoreDNS" "CoreDNS Plugins"
|
||||||
|
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
.PP
|
.PP
|
||||||
|
@ -98,7 +98,7 @@ queries for those zones will be subject to fallthrough.
|
||||||
If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported:
|
If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported:
|
||||||
|
|
||||||
.IP \(bu 4
|
.IP \(bu 4
|
||||||
\fB\fCcoredns_hosts_entries_count{}\fR - The combined number of entries in hosts and Corefile.
|
\fB\fCcoredns_hosts_entries{}\fR - The combined number of entries in hosts and Corefile.
|
||||||
.IP \(bu 4
|
.IP \(bu 4
|
||||||
\fB\fCcoredns_hosts_reload_timestamp_seconds{}\fR - The timestamp of the last reload of hosts file.
|
\fB\fCcoredns_hosts_reload_timestamp_seconds{}\fR - The timestamp of the last reload of hosts file.
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// autoPathCount is counter of successfully autopath-ed queries.
|
||||||
autoPathCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
autoPathCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: plugin.Namespace,
|
Namespace: plugin.Namespace,
|
||||||
Subsystem: "autopath",
|
Subsystem: "autopath",
|
||||||
|
|
45
plugin/cache/handler.go
vendored
45
plugin/cache/handler.go
vendored
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServeDNS implements the plugin.Handler interface.
|
// ServeDNS implements the plugin.Handler interface.
|
||||||
|
@ -128,47 +127,3 @@ func (c *Cache) exists(state request.Request) *item {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
cacheSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "cache",
|
|
||||||
Name: "size",
|
|
||||||
Help: "The number of elements in the cache.",
|
|
||||||
}, []string{"server", "type"})
|
|
||||||
|
|
||||||
cacheHits = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "cache",
|
|
||||||
Name: "hits_total",
|
|
||||||
Help: "The count of cache hits.",
|
|
||||||
}, []string{"server", "type"})
|
|
||||||
|
|
||||||
cacheMisses = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "cache",
|
|
||||||
Name: "misses_total",
|
|
||||||
Help: "The count of cache misses.",
|
|
||||||
}, []string{"server"})
|
|
||||||
|
|
||||||
cachePrefetches = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "cache",
|
|
||||||
Name: "prefetch_total",
|
|
||||||
Help: "The number of time the cache has prefetched a cached item.",
|
|
||||||
}, []string{"server"})
|
|
||||||
|
|
||||||
cacheDrops = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "cache",
|
|
||||||
Name: "drops_total",
|
|
||||||
Help: "The number responses that are not cached, because the reply is malformed.",
|
|
||||||
}, []string{"server"})
|
|
||||||
|
|
||||||
servedStale = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "cache",
|
|
||||||
Name: "served_stale_total",
|
|
||||||
Help: "The number of requests served from stale cache entries.",
|
|
||||||
}, []string{"server"})
|
|
||||||
)
|
|
||||||
|
|
52
plugin/cache/metrics.go
vendored
Normal file
52
plugin/cache/metrics.go
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/coredns/coredns/plugin"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// cacheSize is total elements in the cache by cache type.
|
||||||
|
cacheSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "cache",
|
||||||
|
Name: "size",
|
||||||
|
Help: "The number of elements in the cache.",
|
||||||
|
}, []string{"server", "type"})
|
||||||
|
// cacheHits is counter of cache hits by cache type.
|
||||||
|
cacheHits = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "cache",
|
||||||
|
Name: "hits_total",
|
||||||
|
Help: "The count of cache hits.",
|
||||||
|
}, []string{"server", "type"})
|
||||||
|
// cacheMisses is the counter of cache misses.
|
||||||
|
cacheMisses = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "cache",
|
||||||
|
Name: "misses_total",
|
||||||
|
Help: "The count of cache misses.",
|
||||||
|
}, []string{"server"})
|
||||||
|
// cachePrefetches is the number of time the cache has prefetched a cached item.
|
||||||
|
cachePrefetches = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "cache",
|
||||||
|
Name: "prefetch_total",
|
||||||
|
Help: "The number of time the cache has prefetched a cached item.",
|
||||||
|
}, []string{"server"})
|
||||||
|
// cacheDrops is the number responses that are not cached, because the reply is malformed.
|
||||||
|
cacheDrops = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "cache",
|
||||||
|
Name: "drops_total",
|
||||||
|
Help: "The number responses that are not cached, because the reply is malformed.",
|
||||||
|
}, []string{"server"})
|
||||||
|
// servedStale is the number of requests served from stale cache entries.
|
||||||
|
servedStale = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "cache",
|
||||||
|
Name: "served_stale_total",
|
||||||
|
Help: "The number of requests served from stale cache entries.",
|
||||||
|
}, []string{"server"})
|
||||||
|
)
|
|
@ -53,7 +53,7 @@ used (See [bugs](#bugs)).
|
||||||
|
|
||||||
If monitoring is enabled (via the *prometheus* plugin) then the following metrics are exported:
|
If monitoring is enabled (via the *prometheus* plugin) then the following metrics are exported:
|
||||||
|
|
||||||
* `coredns_dnssec_cache_size{server, type}` - total elements in the cache, type is "signature".
|
* `coredns_dnssec_cache_entries{server, type}` - total elements in the cache, type is "signature".
|
||||||
* `coredns_dnssec_cache_hits_total{server}` - Counter of cache hits.
|
* `coredns_dnssec_cache_hits_total{server}` - Counter of cache hits.
|
||||||
* `coredns_dnssec_cache_misses_total{server}` - Counter of cache misses.
|
* `coredns_dnssec_cache_misses_total{server}` - Counter of cache misses.
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServeDNS implements the plugin.Handler interface.
|
// ServeDNS implements the plugin.Handler interface.
|
||||||
|
@ -47,28 +46,5 @@ func (d Dnssec) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
|
||||||
return plugin.NextOrFailure(d.Name(), d.Next, ctx, w, r)
|
return plugin.NextOrFailure(d.Name(), d.Next, ctx, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
cacheSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "dnssec",
|
|
||||||
Name: "cache_size",
|
|
||||||
Help: "The number of elements in the dnssec cache.",
|
|
||||||
}, []string{"server", "type"})
|
|
||||||
|
|
||||||
cacheHits = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "dnssec",
|
|
||||||
Name: "cache_hits_total",
|
|
||||||
Help: "The count of cache hits.",
|
|
||||||
}, []string{"server"})
|
|
||||||
|
|
||||||
cacheMisses = prometheus.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "dnssec",
|
|
||||||
Name: "cache_misses_total",
|
|
||||||
Help: "The count of cache misses.",
|
|
||||||
}, []string{"server"})
|
|
||||||
)
|
|
||||||
|
|
||||||
// Name implements the Handler interface.
|
// Name implements the Handler interface.
|
||||||
func (d Dnssec) Name() string { return "dnssec" }
|
func (d Dnssec) Name() string { return "dnssec" }
|
||||||
|
|
31
plugin/dnssec/metrics.go
Normal file
31
plugin/dnssec/metrics.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package dnssec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/coredns/coredns/plugin"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// cacheSize is the number of elements in the dnssec cache.
|
||||||
|
cacheSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "dnssec",
|
||||||
|
Name: "cache_entries",
|
||||||
|
Help: "The number of elements in the dnssec cache.",
|
||||||
|
}, []string{"server", "type"})
|
||||||
|
// cacheHits is the count of cache hits.
|
||||||
|
cacheHits = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "dnssec",
|
||||||
|
Name: "cache_hits_total",
|
||||||
|
Help: "The count of cache hits.",
|
||||||
|
}, []string{"server"})
|
||||||
|
// cacheMisses is the count of cache misses.
|
||||||
|
cacheMisses = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "dnssec",
|
||||||
|
Name: "cache_misses_total",
|
||||||
|
Help: "The count of cache misses.",
|
||||||
|
}, []string{"server"})
|
||||||
|
)
|
|
@ -76,7 +76,7 @@ hosts [FILE [ZONES...]] {
|
||||||
|
|
||||||
If monitoring is enabled (via the *prometheus* plugin) then the following metrics are exported:
|
If monitoring is enabled (via the *prometheus* plugin) then the following metrics are exported:
|
||||||
|
|
||||||
- `coredns_hosts_entries_count{}` - The combined number of entries in hosts and Corefile.
|
- `coredns_hosts_entries{}` - The combined number of entries in hosts and Corefile.
|
||||||
- `coredns_hosts_reload_timestamp_seconds{}` - The timestamp of the last reload of hosts file.
|
- `coredns_hosts_reload_timestamp_seconds{}` - The timestamp of the last reload of hosts file.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
|
@ -17,8 +17,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// parseIP calls discards any v6 zone info, before calling net.ParseIP.
|
// parseIP calls discards any v6 zone info, before calling net.ParseIP.
|
||||||
|
@ -256,19 +254,3 @@ func (h *Hostsfile) LookupStaticAddr(addr string) []string {
|
||||||
copy(hostsCp[len(hosts1):], hosts2)
|
copy(hostsCp[len(hosts1):], hosts2)
|
||||||
return hostsCp
|
return hostsCp
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
hostsEntries = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "hosts",
|
|
||||||
Name: "entries_count",
|
|
||||||
Help: "The combined number of entries in hosts and Corefile.",
|
|
||||||
}, []string{})
|
|
||||||
|
|
||||||
hostsReloadTime = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Namespace: plugin.Namespace,
|
|
||||||
Subsystem: "hosts",
|
|
||||||
Name: "reload_timestamp_seconds",
|
|
||||||
Help: "The timestamp of the last reload of hosts file.",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
24
plugin/hosts/metrics.go
Normal file
24
plugin/hosts/metrics.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package hosts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/coredns/coredns/plugin"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// hostsEntries is the combined number of entries in hosts and Corefile.
|
||||||
|
hostsEntries = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "hosts",
|
||||||
|
Name: "entries",
|
||||||
|
Help: "The combined number of entries in hosts and Corefile.",
|
||||||
|
}, []string{})
|
||||||
|
// hostsReloadTime is the timestamp of the last reload of hosts file.
|
||||||
|
hostsReloadTime = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Namespace: plugin.Namespace,
|
||||||
|
Subsystem: "hosts",
|
||||||
|
Name: "reload_timestamp_seconds",
|
||||||
|
Help: "The timestamp of the last reload of hosts file.",
|
||||||
|
})
|
||||||
|
)
|
|
@ -8,13 +8,14 @@ import (
|
||||||
|
|
||||||
// Metrics for the reload plugin
|
// Metrics for the reload plugin
|
||||||
var (
|
var (
|
||||||
FailedCount = prometheus.NewCounter(prometheus.CounterOpts{
|
// failedCount is the counter of the number of failed reload attempts.
|
||||||
|
failedCount = prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
Namespace: plugin.Namespace,
|
Namespace: plugin.Namespace,
|
||||||
Subsystem: "reload",
|
Subsystem: "reload",
|
||||||
Name: "failed_total",
|
Name: "failed_total",
|
||||||
Help: "Counter of the number of failed reload attempts.",
|
Help: "Counter of the number of failed reload attempts.",
|
||||||
})
|
})
|
||||||
|
// reloadInfo is record the hash value during reload.
|
||||||
reloadInfo = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
reloadInfo = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
Namespace: plugin.Namespace,
|
Namespace: plugin.Namespace,
|
||||||
Subsystem: "reload",
|
Subsystem: "reload",
|
||||||
|
|
|
@ -107,7 +107,7 @@ func hook(event caddy.EventName, info interface{}) error {
|
||||||
reloadInfo.WithLabelValues("md5", hex.EncodeToString(md5sum[:])).Set(1)
|
reloadInfo.WithLabelValues("md5", hex.EncodeToString(md5sum[:])).Set(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Corefile changed but reload failed: %s", err)
|
log.Errorf("Corefile changed but reload failed: %s", err)
|
||||||
FailedCount.Add(1)
|
failedCount.Add(1)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// we are done, if the plugin was not set used, then it is not.
|
// we are done, if the plugin was not set used, then it is not.
|
||||||
|
|
|
@ -71,7 +71,7 @@ func setup(c *caddy.Controller) error {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
caddy.RegisterEventHook("reload", hook)
|
caddy.RegisterEventHook("reload", hook)
|
||||||
c.OnRestart(func() error {
|
c.OnRestart(func() error {
|
||||||
metrics.MustRegister(c, reloadInfo, FailedCount)
|
metrics.MustRegister(c, reloadInfo, failedCount)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,18 +9,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// templateMatchesCount is the counter of template regex matches.
|
||||||
templateMatchesCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
templateMatchesCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: plugin.Namespace,
|
Namespace: plugin.Namespace,
|
||||||
Subsystem: "template",
|
Subsystem: "template",
|
||||||
Name: "matches_total",
|
Name: "matches_total",
|
||||||
Help: "Counter of template regex matches.",
|
Help: "Counter of template regex matches.",
|
||||||
}, []string{"server", "zone", "class", "type"})
|
}, []string{"server", "zone", "class", "type"})
|
||||||
|
// templateFailureCount is the counter of go template failures.
|
||||||
templateFailureCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
templateFailureCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: plugin.Namespace,
|
Namespace: plugin.Namespace,
|
||||||
Subsystem: "template",
|
Subsystem: "template",
|
||||||
Name: "template_failures_total",
|
Name: "template_failures_total",
|
||||||
Help: "Counter of go template failures.",
|
Help: "Counter of go template failures.",
|
||||||
}, []string{"server", "zone", "class", "type", "section", "template"})
|
}, []string{"server", "zone", "class", "type", "section", "template"})
|
||||||
|
// templateRRFailureCount is the counter of mis-templated RRs.
|
||||||
templateRRFailureCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
templateRRFailureCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: plugin.Namespace,
|
Namespace: plugin.Namespace,
|
||||||
Subsystem: "template",
|
Subsystem: "template",
|
||||||
|
|
172
test/metric_naming_test.go
Normal file
172
test/metric_naming_test.go
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"go/ast"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coredns/coredns/plugin"
|
||||||
|
|
||||||
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
"github.com/prometheus/common/expfmt"
|
||||||
|
"github.com/prometheus/prometheus/util/promlint"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMetricNaming(t *testing.T) {
|
||||||
|
|
||||||
|
walker := validMetricWalker{}
|
||||||
|
err := filepath.Walk("..", walker.walk)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(walker.Metrics) > 0 {
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
encoder := expfmt.NewEncoder(buf, expfmt.FmtText)
|
||||||
|
for _, mf := range walker.Metrics {
|
||||||
|
if err := encoder.Encode(mf); err != nil {
|
||||||
|
t.Fatalf("Encoding and sending metric family: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l := promlint.New(buf)
|
||||||
|
problems, err := l.Lint()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Link found error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(problems) > 0 {
|
||||||
|
t.Fatalf("A slice of Problems indicating any issues found in the metrics stream: %s", problems)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type validMetricWalker struct {
|
||||||
|
Metrics []*dto.MetricFamily
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *validMetricWalker) walk(path string, info os.FileInfo, _ error) error {
|
||||||
|
// only for regular files, not starting with a . and those that are go files.
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Is it appropriate to compare the file name equals metrics.go directly?
|
||||||
|
if strings.HasPrefix(path, "../.") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(path, "_test.go") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(path, ".go") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fs := token.NewFileSet()
|
||||||
|
f, err := parser.ParseFile(fs, path, nil, parser.AllErrors)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
l := &metric{}
|
||||||
|
ast.Walk(l, f)
|
||||||
|
if l.Metric != nil {
|
||||||
|
w.Metrics = append(w.Metrics, l.Metric)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type metric struct {
|
||||||
|
Metric *dto.MetricFamily
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l metric) Visit(n ast.Node) ast.Visitor {
|
||||||
|
if n == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ce, ok := n.(*ast.CallExpr)
|
||||||
|
if !ok {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
se, ok := ce.Fun.(*ast.SelectorExpr)
|
||||||
|
if !ok {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
id, ok := se.X.(*ast.Ident)
|
||||||
|
if !ok {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
if id.Name != "prometheus" { //prometheus
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
var metricsType dto.MetricType
|
||||||
|
switch se.Sel.Name {
|
||||||
|
case "NewCounterVec", "NewCounter":
|
||||||
|
metricsType = dto.MetricType_COUNTER
|
||||||
|
case "NewGaugeVec", "NewGauge":
|
||||||
|
metricsType = dto.MetricType_GAUGE
|
||||||
|
case "NewHistogramVec", "NewHistogram":
|
||||||
|
metricsType = dto.MetricType_HISTOGRAM
|
||||||
|
case "NewSummaryVec", "NewSummary":
|
||||||
|
metricsType = dto.MetricType_SUMMARY
|
||||||
|
default:
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
// Check first arg, that should have basic lit with capital
|
||||||
|
if len(ce.Args) < 1 {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
bl, ok := ce.Args[0].(*ast.CompositeLit)
|
||||||
|
if !ok {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse Namespace Subsystem Name Help
|
||||||
|
var subsystem, name, help string
|
||||||
|
for _, elt := range bl.Elts {
|
||||||
|
expr, ok := elt.(*ast.KeyValueExpr)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
object, ok := expr.Key.(*ast.Ident)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
value, ok := expr.Value.(*ast.BasicLit)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch object.Name {
|
||||||
|
case "Subsystem":
|
||||||
|
subsystem = value.Value
|
||||||
|
case "Name":
|
||||||
|
name = value.Value
|
||||||
|
case "Help":
|
||||||
|
help = value.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate metrics field
|
||||||
|
if len(name) == 0 || len(help) == 0 {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
var metricName string
|
||||||
|
if len(subsystem) > 0 {
|
||||||
|
metricName = strings.Join([]string{plugin.Namespace, subsystem, name}, "_")
|
||||||
|
} else {
|
||||||
|
metricName = strings.Join([]string{plugin.Namespace, name}, "_")
|
||||||
|
}
|
||||||
|
l.Metric = &dto.MetricFamily{
|
||||||
|
Name: &metricName,
|
||||||
|
Help: &help,
|
||||||
|
Type: &metricsType,
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue