Andrey Meshkov da0cb6fd0e Sync v2.9.0
2024-10-14 17:44:24 +03:00

142 lines
3.8 KiB
Go

// Package metrics contains definitions of most of the prometheus metrics that
// we use in AdGuard DNS.
//
// NOTE: Prefer to not import any packages from the current module here,
// because a lot of packages import metrics, and so import cycles may happen.
//
// TODO(a.garipov): Do not use promauto.
package metrics
import (
"cmp"
"os"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
// namespace is the configurable namespace that we use in our prometheus
// metrics.
//
// TODO(a.garipov): Refactor to not require any global state.
var namespace = cmp.Or(os.Getenv("METRICS_NAMESPACE"), "dns")
// Constants with the subsystem names that we use in our prometheus metrics.
const (
subsystemAccess = "access"
subsystemApplication = "app"
subsystemBackend = "backend"
subsystemBillStat = "billstat"
subsystemBindToDevice = "bindtodevice"
subsystemConnLimiter = "connlimiter"
subsystemConsul = "consul"
subsystemDNSCheck = "dnscheck"
subsystemDNSDB = "dnsdb"
subsystemDNSMsg = "dnsmsg"
subsystemDNSSvc = "dnssvc"
subsystemECSCache = "ecscache"
subsystemFilter = "filter"
subsystemGeoIP = "geoip"
subsystemQueryLog = "querylog"
subsystemResearch = "research"
subsystemRuleStat = "rulestat"
subsystemTLS = "tls"
subsystemWebSvc = "websvc"
)
// Constants that should be kept in sync with ones in package prometheus in
// module dnsserver.
const (
subsystemRateLimit = "ratelimit"
)
const (
// dontStoreLabel is a label that signals that the metric should not be
// stored in the long-term storage.
dontStoreLabel = "do_not_store_metric"
// dontStoreLabelValue is a positive value of the [dontStoreLabel] label to
// avoid calling [BoolString] every time.
dontStoreLabelValue = "1"
)
// SetUpGauge signals that the server has been started. Use a function here to
// avoid circular dependencies.
func SetUpGauge(version, commitTime, branch, revision, goversion string) {
upGauge := promauto.NewGauge(
prometheus.GaugeOpts{
Name: "up",
Namespace: namespace,
Subsystem: subsystemApplication,
Help: `A metric with a constant '1' value labeled by ` +
`version and goversion from which the program was built. ` +
`NOTE: buildtime is actually the time of the commit.`,
ConstLabels: prometheus.Labels{
"version": version,
// TODO(a.garipov): Consider renaming the metric.
"buildtime": commitTime,
"branch": branch,
"revision": revision,
"goversion": goversion,
},
},
)
upGauge.Set(1)
}
// SetStatusGauge is a helper function that automatically checks if there's an
// error and sets the gauge to either 1 (success) or 0 (error).
func SetStatusGauge(gauge prometheus.Gauge, err error) {
if err == nil {
gauge.Set(1)
} else {
gauge.Set(0)
}
}
// BoolString returns "1" if cond is true and "0" otherwise.
func BoolString(cond bool) (s string) {
if cond {
return "1"
}
return "0"
}
// IncrementCond increments trueCounter if cond is true and falseCounter
// otherwise.
func IncrementCond(cond bool, trueCounter, falseCounter prometheus.Counter) {
if cond {
trueCounter.Inc()
} else {
falseCounter.Inc()
}
}
// SetAdditionalInfo adds a gauge with extra info labels. If info is nil,
// SetAdditionalInfo does nothing.
func SetAdditionalInfo(info map[string]string) {
if info == nil {
return
}
gauge := promauto.NewGauge(
prometheus.GaugeOpts{
Name: "additional_info",
Namespace: namespace,
Subsystem: subsystemApplication,
Help: `A metric with a constant '1' value labeled by additional ` +
`info provided in configuration`,
ConstLabels: info,
},
)
gauge.Set(1)
}
// Namespace returns the namespace that we use in our prometheus metrics.
func Namespace() (ns string) {
return namespace
}