Merge branch 'master' into feat/pg_stat_user_indexes

This commit is contained in:
Michael Todorovic 2024-11-18 10:50:42 +01:00
commit f2fe2d176b
No known key found for this signature in database
GPG Key ID: 639C573EC58E6099
38 changed files with 326 additions and 252 deletions

View File

@ -8,7 +8,7 @@ executors:
# This must match .promu.yml. # This must match .promu.yml.
golang: golang:
docker: docker:
- image: cimg/go:1.21 - image: cimg/go:1.23
jobs: jobs:
test: test:
@ -23,7 +23,7 @@ jobs:
integration: integration:
docker: docker:
- image: cimg/go:1.20 - image: cimg/go:1.23
- image: << parameters.postgres_image >> - image: << parameters.postgres_image >>
environment: environment:
POSTGRES_DB: circle_test POSTGRES_DB: circle_test

View File

@ -0,0 +1,57 @@
---
name: Push README to Docker Hub
on:
push:
paths:
- "README.md"
- "README-containers.md"
- ".github/workflows/container_description.yml"
branches: [ main, master ]
permissions:
contents: read
jobs:
PushDockerHubReadme:
runs-on: ubuntu-latest
name: Push README to Docker Hub
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
steps:
- name: git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set docker hub repo name
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
- name: Push README to Dockerhub
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
env:
DOCKER_USER: ${{ secrets.DOCKER_HUB_LOGIN }}
DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }}
with:
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
provider: dockerhub
short_description: ${{ env.DOCKER_REPO_NAME }}
# Empty string results in README-containers.md being pushed if it
# exists. Otherwise, README.md is pushed.
readme_file: ''
PushQuayIoReadme:
runs-on: ubuntu-latest
name: Push README to quay.io
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
steps:
- name: git checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set quay.io org name
run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV
- name: Set quay.io repo name
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
- name: Push README to quay.io
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
env:
DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }}
with:
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
provider: quay
# Empty string results in README-containers.md being pushed if it
# exists. Otherwise, README.md is pushed.
readme_file: ''

View File

@ -12,21 +12,28 @@ on:
- ".golangci.yml" - ".golangci.yml"
pull_request: pull_request:
permissions: # added using https://github.com/step-security/secure-repo
contents: read
jobs: jobs:
golangci: golangci:
permissions:
contents: read # for actions/checkout to fetch code
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
name: lint name: lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: install Go - name: Install Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
with: with:
go-version: 1.21.x go-version: 1.23.x
- name: Install snmp_exporter/generator dependencies - name: Install snmp_exporter/generator dependencies
run: sudo apt-get update && sudo apt-get -y install libsnmp-dev run: sudo apt-get update && sudo apt-get -y install libsnmp-dev
if: github.repository == 'prometheus/snmp_exporter' if: github.repository == 'prometheus/snmp_exporter'
- name: Lint - name: Lint
uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0 uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
with: with:
version: v1.54.2 args: --verbose
version: v1.61.0

View File

@ -1,6 +1,6 @@
go: go:
# This must match .circle/config.yml. # This must match .circle/config.yml.
version: 1.21 version: 1.23
repository: repository:
path: github.com/prometheus-community/postgres_exporter path: github.com/prometheus-community/postgres_exporter
build: build:

View File

@ -1,5 +1,7 @@
--- ---
extends: default extends: default
ignore: |
ui/react-app/node_modules
rules: rules:
braces: braces:

View File

@ -1,3 +1,19 @@
## 0.16.0 / 2024-11-10
BREAKING CHANGES:
The logging system has been replaced with log/slog from the stdlib. This change is being made across the prometheus ecosystem. The logging output has changed, but the messages and levels remain the same. The `ts` label for the timestamp has bewen replaced with `time`, the accuracy is less, and the timezone is not forced to UTC. The `caller` field has been replaced by the `source` field, which now includes the full path to the source file. The `level` field now exposes the log level in capital letters.
* [CHANGE] Replace logging system #1073
* [ENHANCEMENT] Add save_wal_size and wal_status to replication_slot collector #1027
* [ENHANCEMENT] Add roles collector and connection limit metrics to database collector #997
* [ENHANCEMENT] Excluded databases log messgae is now info level #1003
* [ENHANCEMENT] Add active_time to stat_database collector #961
* [ENHANCEMENT] Add slot_type label to replication_slot collector #960
* [BUGFIX] Fix walreceiver collectore when no repmgr #1086
* [BUGFIX] Remove logging errors on replicas #1048
* [BUGFIX] Fix active_time query on postgres>=14 #1045
## 0.15.0 / 2023-10-27 ## 0.15.0 / 2023-10-27
* [ENHANCEMENT] Add 1kB and 2kB units #915 * [ENHANCEMENT] Add 1kB and 2kB units #915

View File

@ -49,23 +49,23 @@ endif
GOTEST := $(GO) test GOTEST := $(GO) test
GOTEST_DIR := GOTEST_DIR :=
ifneq ($(CIRCLE_JOB),) ifneq ($(CIRCLE_JOB),)
ifneq ($(shell command -v gotestsum > /dev/null),) ifneq ($(shell command -v gotestsum 2> /dev/null),)
GOTEST_DIR := test-results GOTEST_DIR := test-results
GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml -- GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --
endif endif
endif endif
PROMU_VERSION ?= 0.15.0 PROMU_VERSION ?= 0.17.0
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
SKIP_GOLANGCI_LINT := SKIP_GOLANGCI_LINT :=
GOLANGCI_LINT := GOLANGCI_LINT :=
GOLANGCI_LINT_OPTS ?= GOLANGCI_LINT_OPTS ?=
GOLANGCI_LINT_VERSION ?= v1.54.2 GOLANGCI_LINT_VERSION ?= v1.60.2
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
# windows isn't included here because of the path separator being different. # windows isn't included here because of the path separator being different.
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64))
# If we're in CI and there is an Actions file, that means the linter # If we're in CI and there is an Actions file, that means the linter
# is being run in Actions, so we don't need to run it here. # is being run in Actions, so we don't need to run it here.
ifneq (,$(SKIP_GOLANGCI_LINT)) ifneq (,$(SKIP_GOLANGCI_LINT))
@ -169,16 +169,20 @@ common-vet:
common-lint: $(GOLANGCI_LINT) common-lint: $(GOLANGCI_LINT)
ifdef GOLANGCI_LINT ifdef GOLANGCI_LINT
@echo ">> running golangci-lint" @echo ">> running golangci-lint"
# 'go list' needs to be executed before staticcheck to prepopulate the modules cache.
# Otherwise staticcheck might fail randomly for some reason not yet explained.
$(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null
$(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
endif endif
.PHONY: common-lint-fix
common-lint-fix: $(GOLANGCI_LINT)
ifdef GOLANGCI_LINT
@echo ">> running golangci-lint fix"
$(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs)
endif
.PHONY: common-yamllint .PHONY: common-yamllint
common-yamllint: common-yamllint:
@echo ">> running yamllint on all YAML files in the repository" @echo ">> running yamllint on all YAML files in the repository"
ifeq (, $(shell command -v yamllint > /dev/null)) ifeq (, $(shell command -v yamllint 2> /dev/null))
@echo "yamllint not installed so skipping" @echo "yamllint not installed so skipping"
else else
yamllint . yamllint .
@ -204,6 +208,10 @@ common-tarball: promu
@echo ">> building release tarball" @echo ">> building release tarball"
$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
.PHONY: common-docker-repo-name
common-docker-repo-name:
@echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)"
.PHONY: common-docker $(BUILD_DOCKER_ARCHS) .PHONY: common-docker $(BUILD_DOCKER_ARCHS)
common-docker: $(BUILD_DOCKER_ARCHS) common-docker: $(BUILD_DOCKER_ARCHS)
$(BUILD_DOCKER_ARCHS): common-docker-%: $(BUILD_DOCKER_ARCHS): common-docker-%:
@ -267,3 +275,9 @@ $(1)_precheck:
exit 1; \ exit 1; \
fi fi
endef endef
govulncheck: install-govulncheck
govulncheck ./...
install-govulncheck:
command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest

View File

@ -1 +1 @@
0.15.0 0.16.0

View File

@ -20,7 +20,6 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -39,19 +38,19 @@ func (e *Exporter) discoverDatabaseDSNs() []string {
var err error var err error
dsnURI, err = url.Parse(dsn) dsnURI, err = url.Parse(dsn)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Unable to parse DSN as URI", "dsn", loggableDSN(dsn), "err", err) logger.Error("Unable to parse DSN as URI", "dsn", loggableDSN(dsn), "err", err)
continue continue
} }
} else if connstringRe.MatchString(dsn) { } else if connstringRe.MatchString(dsn) {
dsnConnstring = dsn dsnConnstring = dsn
} else { } else {
level.Error(logger).Log("msg", "Unable to parse DSN as either URI or connstring", "dsn", loggableDSN(dsn)) logger.Error("Unable to parse DSN as either URI or connstring", "dsn", loggableDSN(dsn))
continue continue
} }
server, err := e.servers.GetServer(dsn) server, err := e.servers.GetServer(dsn)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Error opening connection to database", "dsn", loggableDSN(dsn), "err", err) logger.Error("Error opening connection to database", "dsn", loggableDSN(dsn), "err", err)
continue continue
} }
dsns[dsn] = struct{}{} dsns[dsn] = struct{}{}
@ -61,7 +60,7 @@ func (e *Exporter) discoverDatabaseDSNs() []string {
databaseNames, err := queryDatabases(server) databaseNames, err := queryDatabases(server)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Error querying databases", "dsn", loggableDSN(dsn), "err", err) logger.Error("Error querying databases", "dsn", loggableDSN(dsn), "err", err)
continue continue
} }
for _, databaseName := range databaseNames { for _, databaseName := range databaseNames {
@ -109,7 +108,7 @@ func (e *Exporter) scrapeDSN(ch chan<- prometheus.Metric, dsn string) error {
// Check if map versions need to be updated // Check if map versions need to be updated
if err := e.checkMapVersions(ch, server); err != nil { if err := e.checkMapVersions(ch, server); err != nil {
level.Warn(logger).Log("msg", "Proceeding with outdated query maps, as the Postgres version could not be determined", "err", err) logger.Warn("Proceeding with outdated query maps, as the Postgres version could not be determined", "err", err)
} }
return server.Scrape(ch, e.disableSettingsMetrics) return server.Scrape(ch, e.disableSettingsMetrics)

View File

@ -20,14 +20,13 @@ import (
"strings" "strings"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus-community/postgres_exporter/collector" "github.com/prometheus-community/postgres_exporter/collector"
"github.com/prometheus-community/postgres_exporter/config" "github.com/prometheus-community/postgres_exporter/config"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/promlog" "github.com/prometheus/common/promslog"
"github.com/prometheus/common/promlog/flag" "github.com/prometheus/common/promslog/flag"
"github.com/prometheus/common/version" "github.com/prometheus/common/version"
"github.com/prometheus/exporter-toolkit/web" "github.com/prometheus/exporter-toolkit/web"
"github.com/prometheus/exporter-toolkit/web/kingpinflag" "github.com/prometheus/exporter-toolkit/web/kingpinflag"
@ -50,7 +49,7 @@ var (
excludeDatabases = kingpin.Flag("exclude-databases", "A list of databases to remove when autoDiscoverDatabases is enabled (DEPRECATED)").Default("").Envar("PG_EXPORTER_EXCLUDE_DATABASES").String() excludeDatabases = kingpin.Flag("exclude-databases", "A list of databases to remove when autoDiscoverDatabases is enabled (DEPRECATED)").Default("").Envar("PG_EXPORTER_EXCLUDE_DATABASES").String()
includeDatabases = kingpin.Flag("include-databases", "A list of databases to include when autoDiscoverDatabases is enabled (DEPRECATED)").Default("").Envar("PG_EXPORTER_INCLUDE_DATABASES").String() includeDatabases = kingpin.Flag("include-databases", "A list of databases to include when autoDiscoverDatabases is enabled (DEPRECATED)").Default("").Envar("PG_EXPORTER_INCLUDE_DATABASES").String()
metricPrefix = kingpin.Flag("metric-prefix", "A metric prefix can be used to have non-default (not \"pg\") prefixes for each of the metrics").Default("pg").Envar("PG_EXPORTER_METRIC_PREFIX").String() metricPrefix = kingpin.Flag("metric-prefix", "A metric prefix can be used to have non-default (not \"pg\") prefixes for each of the metrics").Default("pg").Envar("PG_EXPORTER_METRIC_PREFIX").String()
logger = log.NewNopLogger() logger = promslog.NewNopLogger()
) )
// Metric name parts. // Metric name parts.
@ -70,11 +69,11 @@ const (
func main() { func main() {
kingpin.Version(version.Print(exporterName)) kingpin.Version(version.Print(exporterName))
promlogConfig := &promlog.Config{} promslogConfig := &promslog.Config{}
flag.AddFlags(kingpin.CommandLine, promlogConfig) flag.AddFlags(kingpin.CommandLine, promslogConfig)
kingpin.HelpFlag.Short('h') kingpin.HelpFlag.Short('h')
kingpin.Parse() kingpin.Parse()
logger = promlog.New(promlogConfig) logger = promslog.New(promslogConfig)
if *onlyDumpMaps { if *onlyDumpMaps {
dumpMaps() dumpMaps()
@ -83,28 +82,28 @@ func main() {
if err := c.ReloadConfig(*configFile, logger); err != nil { if err := c.ReloadConfig(*configFile, logger); err != nil {
// This is not fatal, but it means that auth must be provided for every dsn. // This is not fatal, but it means that auth must be provided for every dsn.
level.Warn(logger).Log("msg", "Error loading config", "err", err) logger.Warn("Error loading config", "err", err)
} }
dsns, err := getDataSources() dsns, err := getDataSources()
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Failed reading data sources", "err", err.Error()) logger.Error("Failed reading data sources", "err", err.Error())
os.Exit(1) os.Exit(1)
} }
excludedDatabases := strings.Split(*excludeDatabases, ",") excludedDatabases := strings.Split(*excludeDatabases, ",")
level.Info(logger).Log("msg", "Excluded databases", "databases", fmt.Sprintf("%v", excludedDatabases)) logger.Info("Excluded databases", "databases", fmt.Sprintf("%v", excludedDatabases))
if *queriesPath != "" { if *queriesPath != "" {
level.Warn(logger).Log("msg", "The extended queries.yaml config is DEPRECATED", "file", *queriesPath) logger.Warn("The extended queries.yaml config is DEPRECATED", "file", *queriesPath)
} }
if *autoDiscoverDatabases || *excludeDatabases != "" || *includeDatabases != "" { if *autoDiscoverDatabases || *excludeDatabases != "" || *includeDatabases != "" {
level.Warn(logger).Log("msg", "Scraping additional databases via auto discovery is DEPRECATED") logger.Warn("Scraping additional databases via auto discovery is DEPRECATED")
} }
if *constantLabelsList != "" { if *constantLabelsList != "" {
level.Warn(logger).Log("msg", "Constant labels on all metrics is DEPRECATED") logger.Warn("Constant labels on all metrics is DEPRECATED")
} }
opts := []ExporterOpt{ opts := []ExporterOpt{
@ -122,7 +121,7 @@ func main() {
exporter.servers.Close() exporter.servers.Close()
}() }()
prometheus.MustRegister(version.NewCollector(exporterName)) prometheus.MustRegister(versioncollector.NewCollector(exporterName))
prometheus.MustRegister(exporter) prometheus.MustRegister(exporter)
@ -139,7 +138,7 @@ func main() {
[]string{}, []string{},
) )
if err != nil { if err != nil {
level.Warn(logger).Log("msg", "Failed to create PostgresCollector", "err", err.Error()) logger.Warn("Failed to create PostgresCollector", "err", err.Error())
} else { } else {
prometheus.MustRegister(pe) prometheus.MustRegister(pe)
} }
@ -160,7 +159,7 @@ func main() {
} }
landingPage, err := web.NewLandingPage(landingConfig) landingPage, err := web.NewLandingPage(landingConfig)
if err != nil { if err != nil {
level.Error(logger).Log("err", err) logger.Error("error creating landing page", "err", err)
os.Exit(1) os.Exit(1)
} }
http.Handle("/", landingPage) http.Handle("/", landingPage)
@ -170,7 +169,7 @@ func main() {
srv := &http.Server{} srv := &http.Server{}
if err := web.ListenAndServe(srv, webConfig, logger); err != nil { if err := web.ListenAndServe(srv, webConfig, logger); err != nil {
level.Error(logger).Log("msg", "Error running HTTP server", "err", err) logger.Error("Error running HTTP server", "err", err)
os.Exit(1) os.Exit(1)
} }
} }

View File

@ -20,7 +20,6 @@ import (
"time" "time"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log/level"
"github.com/lib/pq" "github.com/lib/pq"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -190,10 +189,10 @@ func queryNamespaceMappings(ch chan<- prometheus.Metric, server *Server) map[str
scrapeStart := time.Now() scrapeStart := time.Now()
for namespace, mapping := range server.metricMap { for namespace, mapping := range server.metricMap {
level.Debug(logger).Log("msg", "Querying namespace", "namespace", namespace) logger.Debug("Querying namespace", "namespace", namespace)
if mapping.master && !server.master { if mapping.master && !server.master {
level.Debug(logger).Log("msg", "Query skipped...") logger.Debug("Query skipped...")
continue continue
} }
@ -202,7 +201,7 @@ func queryNamespaceMappings(ch chan<- prometheus.Metric, server *Server) map[str
serVersion, _ := semver.Parse(server.lastMapVersion.String()) serVersion, _ := semver.Parse(server.lastMapVersion.String())
runServerRange, _ := semver.ParseRange(server.runonserver) runServerRange, _ := semver.ParseRange(server.runonserver)
if !runServerRange(serVersion) { if !runServerRange(serVersion) {
level.Debug(logger).Log("msg", "Query skipped for this database version", "version", server.lastMapVersion.String(), "target_version", server.runonserver) logger.Debug("Query skipped for this database version", "version", server.lastMapVersion.String(), "target_version", server.runonserver)
continue continue
} }
} }
@ -233,12 +232,12 @@ func queryNamespaceMappings(ch chan<- prometheus.Metric, server *Server) map[str
// Serious error - a namespace disappeared // Serious error - a namespace disappeared
if err != nil { if err != nil {
namespaceErrors[namespace] = err namespaceErrors[namespace] = err
level.Info(logger).Log("err", err) logger.Info("error finding namespace", "err", err)
} }
// Non-serious errors - likely version or parsing problems. // Non-serious errors - likely version or parsing problems.
if len(nonFatalErrors) > 0 { if len(nonFatalErrors) > 0 {
for _, err := range nonFatalErrors { for _, err := range nonFatalErrors {
level.Info(logger).Log("err", err) logger.Info("error querying namespace", "err", err)
} }
} }

View File

@ -19,7 +19,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -32,7 +31,7 @@ var (
// Query the pg_settings view containing runtime variables // Query the pg_settings view containing runtime variables
func querySettings(ch chan<- prometheus.Metric, server *Server) error { func querySettings(ch chan<- prometheus.Metric, server *Server) error {
level.Debug(logger).Log("msg", "Querying pg_setting view", "server", server) logger.Debug("Querying pg_setting view", "server", server)
// pg_settings docs: https://www.postgresql.org/docs/current/static/view-pg-settings.html // pg_settings docs: https://www.postgresql.org/docs/current/static/view-pg-settings.html
// //

View File

@ -25,7 +25,6 @@ import (
"time" "time"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -284,7 +283,7 @@ func makeDescMap(pgVersion semver.Version, serverLabels prometheus.Labels, metri
if !columnMapping.supportedVersions(pgVersion) { if !columnMapping.supportedVersions(pgVersion) {
// It's very useful to be able to see what columns are being // It's very useful to be able to see what columns are being
// rejected. // rejected.
level.Debug(logger).Log("msg", "Column is being forced to discard due to version incompatibility", "column", columnName) logger.Debug("Column is being forced to discard due to version incompatibility", "column", columnName)
thisMap[columnName] = MetricMap{ thisMap[columnName] = MetricMap{
discard: true, discard: true,
conversion: func(_ interface{}) (float64, bool) { conversion: func(_ interface{}) (float64, bool) {
@ -371,7 +370,7 @@ func makeDescMap(pgVersion semver.Version, serverLabels prometheus.Labels, metri
case string: case string:
durationString = t durationString = t
default: default:
level.Error(logger).Log("msg", "Duration conversion metric was not a string") logger.Error("Duration conversion metric was not a string")
return math.NaN(), false return math.NaN(), false
} }
@ -381,7 +380,7 @@ func makeDescMap(pgVersion semver.Version, serverLabels prometheus.Labels, metri
d, err := time.ParseDuration(durationString) d, err := time.ParseDuration(durationString)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Failed converting result to metric", "column", columnName, "in", in, "err", err) logger.Error("Failed converting result to metric", "column", columnName, "in", in, "err", err)
return math.NaN(), false return math.NaN(), false
} }
return float64(d / time.Millisecond), true return float64(d / time.Millisecond), true
@ -491,7 +490,7 @@ func parseConstLabels(s string) prometheus.Labels {
for _, p := range parts { for _, p := range parts {
keyValue := strings.Split(strings.TrimSpace(p), "=") keyValue := strings.Split(strings.TrimSpace(p), "=")
if len(keyValue) != 2 { if len(keyValue) != 2 {
level.Error(logger).Log(`Wrong constant labels format, should be "key=value"`, "input", p) logger.Error(`Wrong constant labels format, should be "key=value"`, "input", p)
continue continue
} }
key := strings.TrimSpace(keyValue[0]) key := strings.TrimSpace(keyValue[0])
@ -582,7 +581,7 @@ func newDesc(subsystem, name, help string, labels prometheus.Labels) *prometheus
} }
func checkPostgresVersion(db *sql.DB, server string) (semver.Version, string, error) { func checkPostgresVersion(db *sql.DB, server string) (semver.Version, string, error) {
level.Debug(logger).Log("msg", "Querying PostgreSQL version", "server", server) logger.Debug("Querying PostgreSQL version", "server", server)
versionRow := db.QueryRow("SELECT version();") versionRow := db.QueryRow("SELECT version();")
var versionString string var versionString string
err := versionRow.Scan(&versionString) err := versionRow.Scan(&versionString)
@ -605,12 +604,12 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, server *Server)
} }
if !e.disableDefaultMetrics && semanticVersion.LT(lowestSupportedVersion) { if !e.disableDefaultMetrics && semanticVersion.LT(lowestSupportedVersion) {
level.Warn(logger).Log("msg", "PostgreSQL version is lower than our lowest supported version", "server", server, "version", semanticVersion, "lowest_supported_version", lowestSupportedVersion) logger.Warn("PostgreSQL version is lower than our lowest supported version", "server", server, "version", semanticVersion, "lowest_supported_version", lowestSupportedVersion)
} }
// Check if semantic version changed and recalculate maps if needed. // Check if semantic version changed and recalculate maps if needed.
if semanticVersion.NE(server.lastMapVersion) || server.metricMap == nil { if semanticVersion.NE(server.lastMapVersion) || server.metricMap == nil {
level.Info(logger).Log("msg", "Semantic version changed", "server", server, "from", server.lastMapVersion, "to", semanticVersion) logger.Info("Semantic version changed", "server", server, "from", server.lastMapVersion, "to", semanticVersion)
server.mappingMtx.Lock() server.mappingMtx.Lock()
// Get Default Metrics only for master database // Get Default Metrics only for master database
@ -631,13 +630,13 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, server *Server)
// Calculate the hashsum of the useQueries // Calculate the hashsum of the useQueries
userQueriesData, err := os.ReadFile(e.userQueriesPath) userQueriesData, err := os.ReadFile(e.userQueriesPath)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Failed to reload user queries", "path", e.userQueriesPath, "err", err) logger.Error("Failed to reload user queries", "path", e.userQueriesPath, "err", err)
e.userQueriesError.WithLabelValues(e.userQueriesPath, "").Set(1) e.userQueriesError.WithLabelValues(e.userQueriesPath, "").Set(1)
} else { } else {
hashsumStr := fmt.Sprintf("%x", sha256.Sum256(userQueriesData)) hashsumStr := fmt.Sprintf("%x", sha256.Sum256(userQueriesData))
if err := addQueries(userQueriesData, semanticVersion, server); err != nil { if err := addQueries(userQueriesData, semanticVersion, server); err != nil {
level.Error(logger).Log("msg", "Failed to reload user queries", "path", e.userQueriesPath, "err", err) logger.Error("Failed to reload user queries", "path", e.userQueriesPath, "err", err)
e.userQueriesError.WithLabelValues(e.userQueriesPath, hashsumStr).Set(1) e.userQueriesError.WithLabelValues(e.userQueriesPath, hashsumStr).Set(1)
} else { } else {
// Mark user queries as successfully loaded // Mark user queries as successfully loaded
@ -679,7 +678,7 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
if err := e.scrapeDSN(ch, dsn); err != nil { if err := e.scrapeDSN(ch, dsn); err != nil {
errorsCount++ errorsCount++
level.Error(logger).Log("err", err) logger.Error("error scraping dsn", "err", err, "dsn", dsn)
if _, ok := err.(*ErrorConnectToServer); ok { if _, ok := err.(*ErrorConnectToServer); ok {
connectionErrorsCount++ connectionErrorsCount++

View File

@ -15,17 +15,16 @@ package main
import ( import (
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus-community/postgres_exporter/collector" "github.com/prometheus-community/postgres_exporter/collector"
"github.com/prometheus-community/postgres_exporter/config" "github.com/prometheus-community/postgres_exporter/config"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
) )
func handleProbe(logger log.Logger, excludeDatabases []string) http.HandlerFunc { func handleProbe(logger *slog.Logger, excludeDatabases []string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
conf := c.GetConfig() conf := c.GetConfig()
@ -38,7 +37,7 @@ func handleProbe(logger log.Logger, excludeDatabases []string) http.HandlerFunc
var authModule config.AuthModule var authModule config.AuthModule
authModuleName := params.Get("auth_module") authModuleName := params.Get("auth_module")
if authModuleName == "" { if authModuleName == "" {
level.Info(logger).Log("msg", "no auth_module specified, using default") logger.Info("no auth_module specified, using default")
} else { } else {
var ok bool var ok bool
authModule, ok = conf.AuthModules[authModuleName] authModule, ok = conf.AuthModules[authModuleName]
@ -54,14 +53,14 @@ func handleProbe(logger log.Logger, excludeDatabases []string) http.HandlerFunc
dsn, err := authModule.ConfigureTarget(target) dsn, err := authModule.ConfigureTarget(target)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "failed to configure target", "err", err) logger.Error("failed to configure target", "err", err)
http.Error(w, fmt.Sprintf("could not configure dsn for target: %v", err), http.StatusBadRequest) http.Error(w, fmt.Sprintf("could not configure dsn for target: %v", err), http.StatusBadRequest)
return return
} }
// TODO(@sysadmind): Timeout // TODO(@sysadmind): Timeout
tl := log.With(logger, "target", target) tl := logger.With("target", target)
registry := prometheus.NewRegistry() registry := prometheus.NewRegistry()
@ -85,7 +84,7 @@ func handleProbe(logger log.Logger, excludeDatabases []string) http.HandlerFunc
// Run the probe // Run the probe
pc, err := collector.NewProbeCollector(tl, excludeDatabases, registry, dsn) pc, err := collector.NewProbeCollector(tl, excludeDatabases, registry, dsn)
if err != nil { if err != nil {
level.Error(logger).Log("msg", "Error creating probe collector", "err", err) logger.Error("Error creating probe collector", "err", err)
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }

View File

@ -18,7 +18,6 @@ import (
"fmt" "fmt"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log/level"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
@ -172,7 +171,7 @@ func makeQueryOverrideMap(pgVersion semver.Version, queryOverrides map[string][]
} }
} }
if !matched { if !matched {
level.Warn(logger).Log("msg", "No query matched override, disabling metric space", "name", name) logger.Warn("No query matched override, disabling metric space", "name", name)
resultMap[name] = "" resultMap[name] = ""
} }
} }
@ -193,7 +192,7 @@ func parseUserQueries(content []byte) (map[string]intermediateMetricMap, map[str
newQueryOverrides := make(map[string]string) newQueryOverrides := make(map[string]string)
for metric, specs := range userQueries { for metric, specs := range userQueries {
level.Debug(logger).Log("msg", "New user metric namespace from YAML metric", "metric", metric, "cache_seconds", specs.CacheSeconds) logger.Debug("New user metric namespace from YAML metric", "metric", metric, "cache_seconds", specs.CacheSeconds)
newQueryOverrides[metric] = specs.Query newQueryOverrides[metric] = specs.Query
metricMap, ok := metricMaps[metric] metricMap, ok := metricMaps[metric]
if !ok { if !ok {
@ -245,9 +244,9 @@ func addQueries(content []byte, pgVersion semver.Version, server *Server) error
for k, v := range partialExporterMap { for k, v := range partialExporterMap {
_, found := server.metricMap[k] _, found := server.metricMap[k]
if found { if found {
level.Debug(logger).Log("msg", "Overriding metric from user YAML file", "metric", k) logger.Debug("Overriding metric from user YAML file", "metric", k)
} else { } else {
level.Debug(logger).Log("msg", "Adding new metric from user YAML file", "metric", k) logger.Debug("Adding new metric from user YAML file", "metric", k)
} }
server.metricMap[k] = v server.metricMap[k] = v
} }
@ -256,9 +255,9 @@ func addQueries(content []byte, pgVersion semver.Version, server *Server) error
for k, v := range newQueryOverrides { for k, v := range newQueryOverrides {
_, found := server.queryOverrides[k] _, found := server.queryOverrides[k]
if found { if found {
level.Debug(logger).Log("msg", "Overriding query override from user YAML file", "query_override", k) logger.Debug("Overriding query override from user YAML file", "query_override", k)
} else { } else {
level.Debug(logger).Log("msg", "Adding new query override from user YAML file", "query_override", k) logger.Debug("Adding new query override from user YAML file", "query_override", k)
} }
server.queryOverrides[k] = v server.queryOverrides[k] = v
} }

View File

@ -20,7 +20,6 @@ import (
"time" "time"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -71,7 +70,7 @@ func NewServer(dsn string, opts ...ServerOpt) (*Server, error) {
db.SetMaxOpenConns(1) db.SetMaxOpenConns(1)
db.SetMaxIdleConns(1) db.SetMaxIdleConns(1)
level.Info(logger).Log("msg", "Established new database connection", "fingerprint", fingerprint) logger.Info("Established new database connection", "fingerprint", fingerprint)
s := &Server{ s := &Server{
db: db, db: db,
@ -98,7 +97,7 @@ func (s *Server) Close() error {
func (s *Server) Ping() error { func (s *Server) Ping() error {
if err := s.db.Ping(); err != nil { if err := s.db.Ping(); err != nil {
if cerr := s.Close(); cerr != nil { if cerr := s.Close(); cerr != nil {
level.Error(logger).Log("msg", "Error while closing non-pinging DB connection", "server", s, "err", cerr) logger.Error("Error while closing non-pinging DB connection", "server", s, "err", cerr)
} }
return err return err
} }
@ -184,7 +183,7 @@ func (s *Servers) Close() {
defer s.m.Unlock() defer s.m.Unlock()
for _, server := range s.servers { for _, server := range s.servers {
if err := server.Close(); err != nil { if err := server.Close(); err != nil {
level.Error(logger).Log("msg", "Failed to close connection", "server", server, "err", err) logger.Error("Failed to close connection", "server", server, "err", err)
} }
} }
} }

View File

@ -21,7 +21,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/go-kit/log/level"
"github.com/lib/pq" "github.com/lib/pq"
) )
@ -82,14 +81,14 @@ func dbToFloat64(t interface{}) (float64, bool) {
strV := string(v) strV := string(v)
result, err := strconv.ParseFloat(strV, 64) result, err := strconv.ParseFloat(strV, 64)
if err != nil { if err != nil {
level.Info(logger).Log("msg", "Could not parse []byte", "err", err) logger.Info("Could not parse []byte", "err", err)
return math.NaN(), false return math.NaN(), false
} }
return result, true return result, true
case string: case string:
result, err := strconv.ParseFloat(v, 64) result, err := strconv.ParseFloat(v, 64)
if err != nil { if err != nil {
level.Info(logger).Log("msg", "Could not parse string", "err", err) logger.Info("Could not parse string", "err", err)
return math.NaN(), false return math.NaN(), false
} }
return result, true return result, true
@ -122,14 +121,14 @@ func dbToUint64(t interface{}) (uint64, bool) {
strV := string(v) strV := string(v)
result, err := strconv.ParseUint(strV, 10, 64) result, err := strconv.ParseUint(strV, 10, 64)
if err != nil { if err != nil {
level.Info(logger).Log("msg", "Could not parse []byte", "err", err) logger.Info("Could not parse []byte", "err", err)
return 0, false return 0, false
} }
return result, true return result, true
case string: case string:
result, err := strconv.ParseUint(v, 10, 64) result, err := strconv.ParseUint(v, 10, 64)
if err != nil { if err != nil {
level.Info(logger).Log("msg", "Could not parse string", "err", err) logger.Info("Could not parse string", "err", err)
return 0, false return 0, false
} }
return result, true return result, true

View File

@ -17,12 +17,11 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"log/slog"
"sync" "sync"
"time" "time"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -62,7 +61,7 @@ type Collector interface {
} }
type collectorConfig struct { type collectorConfig struct {
logger log.Logger logger *slog.Logger
excludeDatabases []string excludeDatabases []string
} }
@ -89,7 +88,7 @@ func registerCollector(name string, isDefaultEnabled bool, createFunc func(colle
// PostgresCollector implements the prometheus.Collector interface. // PostgresCollector implements the prometheus.Collector interface.
type PostgresCollector struct { type PostgresCollector struct {
Collectors map[string]Collector Collectors map[string]Collector
logger log.Logger logger *slog.Logger
instance *instance instance *instance
} }
@ -97,7 +96,7 @@ type PostgresCollector struct {
type Option func(*PostgresCollector) error type Option func(*PostgresCollector) error
// NewPostgresCollector creates a new PostgresCollector. // NewPostgresCollector creates a new PostgresCollector.
func NewPostgresCollector(logger log.Logger, excludeDatabases []string, dsn string, filters []string, options ...Option) (*PostgresCollector, error) { func NewPostgresCollector(logger *slog.Logger, excludeDatabases []string, dsn string, filters []string, options ...Option) (*PostgresCollector, error) {
p := &PostgresCollector{ p := &PostgresCollector{
logger: logger, logger: logger,
} }
@ -131,7 +130,7 @@ func NewPostgresCollector(logger log.Logger, excludeDatabases []string, dsn stri
collectors[key] = collector collectors[key] = collector
} else { } else {
collector, err := factories[key](collectorConfig{ collector, err := factories[key](collectorConfig{
logger: log.With(logger, "collector", key), logger: logger.With("collector", key),
excludeDatabases: excludeDatabases, excludeDatabases: excludeDatabases,
}) })
if err != nil { if err != nil {
@ -173,7 +172,7 @@ func (p PostgresCollector) Collect(ch chan<- prometheus.Metric) {
// Set up the database connection for the collector. // Set up the database connection for the collector.
err := inst.setup() err := inst.setup()
if err != nil { if err != nil {
level.Error(p.logger).Log("msg", "Error opening connection to database", "err", err) p.logger.Error("Error opening connection to database", "err", err)
return return
} }
defer inst.Close() defer inst.Close()
@ -189,7 +188,7 @@ func (p PostgresCollector) Collect(ch chan<- prometheus.Metric) {
wg.Wait() wg.Wait()
} }
func execute(ctx context.Context, name string, c Collector, instance *instance, ch chan<- prometheus.Metric, logger log.Logger) { func execute(ctx context.Context, name string, c Collector, instance *instance, ch chan<- prometheus.Metric, logger *slog.Logger) {
begin := time.Now() begin := time.Now()
err := c.Update(ctx, instance, ch) err := c.Update(ctx, instance, ch)
duration := time.Since(begin) duration := time.Since(begin)
@ -197,13 +196,13 @@ func execute(ctx context.Context, name string, c Collector, instance *instance,
if err != nil { if err != nil {
if IsNoDataError(err) { if IsNoDataError(err) {
level.Debug(logger).Log("msg", "collector returned no data", "name", name, "duration_seconds", duration.Seconds(), "err", err) logger.Debug("collector returned no data", "name", name, "duration_seconds", duration.Seconds(), "err", err)
} else { } else {
level.Error(logger).Log("msg", "collector failed", "name", name, "duration_seconds", duration.Seconds(), "err", err) logger.Error("collector failed", "name", name, "duration_seconds", duration.Seconds(), "err", err)
} }
success = 0 success = 0
} else { } else {
level.Debug(logger).Log("msg", "collector succeeded", "name", name, "duration_seconds", duration.Seconds()) logger.Debug("collector succeeded", "name", name, "duration_seconds", duration.Seconds())
success = 1 success = 1
} }
ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), name) ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), name)

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGDatabaseCollector struct { type PGDatabaseCollector struct {
log log.Logger log *slog.Logger
excludedDatabases []string excludedDatabases []string
} }

View File

@ -16,9 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -29,7 +28,7 @@ func init() {
} }
type PGDatabaseWraparoundCollector struct { type PGDatabaseWraparoundCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGDatabaseWraparoundCollector(config collectorConfig) (Collector, error) { func NewPGDatabaseWraparoundCollector(config collectorConfig) (Collector, error) {
@ -81,15 +80,15 @@ func (c *PGDatabaseWraparoundCollector) Update(ctx context.Context, instance *in
} }
if !datname.Valid { if !datname.Valid {
level.Debug(c.log).Log("msg", "Skipping database with NULL name") c.log.Debug("Skipping database with NULL name")
continue continue
} }
if !ageDatfrozenxid.Valid { if !ageDatfrozenxid.Valid {
level.Debug(c.log).Log("msg", "Skipping stat emission with NULL age_datfrozenxid") c.log.Debug("Skipping stat emission with NULL age_datfrozenxid")
continue continue
} }
if !ageDatminmxid.Valid { if !ageDatminmxid.Valid {
level.Debug(c.log).Log("msg", "Skipping stat emission with NULL age_datminmxid") c.log.Debug("Skipping stat emission with NULL age_datminmxid")
continue continue
} }

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGLocksCollector struct { type PGLocksCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGLocksCollector(config collectorConfig) (Collector, error) { func NewPGLocksCollector(config collectorConfig) (Collector, error) {

View File

@ -15,8 +15,8 @@ package collector
import ( import (
"context" "context"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -27,7 +27,7 @@ func init() {
} }
type PGLongRunningTransactionsCollector struct { type PGLongRunningTransactionsCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGLongRunningTransactionsCollector(config collectorConfig) (Collector, error) { func NewPGLongRunningTransactionsCollector(config collectorConfig) (Collector, error) {

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/lib/pq" "github.com/lib/pq"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGProcessIdleCollector struct { type PGProcessIdleCollector struct {
log log.Logger log *slog.Logger
} }
const processIdleSubsystem = "process_idle" const processIdleSubsystem = "process_idle"

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGReplicationSlotCollector struct { type PGReplicationSlotCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGReplicationSlotCollector(config collectorConfig) (Collector, error) { func NewPGReplicationSlotCollector(config collectorConfig) (Collector, error) {

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGRolesCollector struct { type PGRolesCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGRolesCollector(config collectorConfig) (Collector, error) { func NewPGRolesCollector(config collectorConfig) (Collector, error) {

View File

@ -15,8 +15,8 @@ package collector
import ( import (
"context" "context"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -27,7 +27,7 @@ func init() {
} }
type PGStatActivityAutovacuumCollector struct { type PGStatActivityAutovacuumCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGStatActivityAutovacuumCollector(config collectorConfig) (Collector, error) { func NewPGStatActivityAutovacuumCollector(config collectorConfig) (Collector, error) {

View File

@ -17,11 +17,10 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"log/slog"
"strings" "strings"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -32,7 +31,7 @@ func init() {
} }
type PGStatDatabaseCollector struct { type PGStatDatabaseCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGStatDatabaseCollector(config collectorConfig) (Collector, error) { func NewPGStatDatabaseCollector(config collectorConfig) (Collector, error) {
@ -299,85 +298,85 @@ func (c *PGStatDatabaseCollector) Update(ctx context.Context, instance *instance
} }
if !datid.Valid { if !datid.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no datid") c.log.Debug("Skipping collecting metric because it has no datid")
continue continue
} }
if !datname.Valid { if !datname.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no datname") c.log.Debug("Skipping collecting metric because it has no datname")
continue continue
} }
if !numBackends.Valid { if !numBackends.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no numbackends") c.log.Debug("Skipping collecting metric because it has no numbackends")
continue continue
} }
if !xactCommit.Valid { if !xactCommit.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no xact_commit") c.log.Debug("Skipping collecting metric because it has no xact_commit")
continue continue
} }
if !xactRollback.Valid { if !xactRollback.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no xact_rollback") c.log.Debug("Skipping collecting metric because it has no xact_rollback")
continue continue
} }
if !blksRead.Valid { if !blksRead.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no blks_read") c.log.Debug("Skipping collecting metric because it has no blks_read")
continue continue
} }
if !blksHit.Valid { if !blksHit.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no blks_hit") c.log.Debug("Skipping collecting metric because it has no blks_hit")
continue continue
} }
if !tupReturned.Valid { if !tupReturned.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no tup_returned") c.log.Debug("Skipping collecting metric because it has no tup_returned")
continue continue
} }
if !tupFetched.Valid { if !tupFetched.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no tup_fetched") c.log.Debug("Skipping collecting metric because it has no tup_fetched")
continue continue
} }
if !tupInserted.Valid { if !tupInserted.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no tup_inserted") c.log.Debug("Skipping collecting metric because it has no tup_inserted")
continue continue
} }
if !tupUpdated.Valid { if !tupUpdated.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no tup_updated") c.log.Debug("Skipping collecting metric because it has no tup_updated")
continue continue
} }
if !tupDeleted.Valid { if !tupDeleted.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no tup_deleted") c.log.Debug("Skipping collecting metric because it has no tup_deleted")
continue continue
} }
if !conflicts.Valid { if !conflicts.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no conflicts") c.log.Debug("Skipping collecting metric because it has no conflicts")
continue continue
} }
if !tempFiles.Valid { if !tempFiles.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no temp_files") c.log.Debug("Skipping collecting metric because it has no temp_files")
continue continue
} }
if !tempBytes.Valid { if !tempBytes.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no temp_bytes") c.log.Debug("Skipping collecting metric because it has no temp_bytes")
continue continue
} }
if !deadlocks.Valid { if !deadlocks.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no deadlocks") c.log.Debug("Skipping collecting metric because it has no deadlocks")
continue continue
} }
if !blkReadTime.Valid { if !blkReadTime.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no blk_read_time") c.log.Debug("Skipping collecting metric because it has no blk_read_time")
continue continue
} }
if !blkWriteTime.Valid { if !blkWriteTime.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no blk_write_time") c.log.Debug("Skipping collecting metric because it has no blk_write_time")
continue continue
} }
if activeTimeAvail && !activeTime.Valid { if activeTimeAvail && !activeTime.Valid {
level.Debug(c.log).Log("msg", "Skipping collecting metric because it has no active_time") c.log.Debug("Skipping collecting metric because it has no active_time")
continue continue
} }
statsResetMetric := 0.0 statsResetMetric := 0.0
if !statsReset.Valid { if !statsReset.Valid {
level.Debug(c.log).Log("msg", "No metric for stats_reset, will collect 0 instead") c.log.Debug("No metric for stats_reset, will collect 0 instead")
} }
if statsReset.Valid { if statsReset.Valid {
statsResetMetric = float64(statsReset.Time.Unix()) statsResetMetric = float64(statsReset.Time.Unix())

View File

@ -19,9 +19,9 @@ import (
"github.com/DATA-DOG/go-sqlmock" "github.com/DATA-DOG/go-sqlmock"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go" dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/promslog"
"github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/convey"
) )
@ -92,7 +92,7 @@ func TestPGStatDatabaseCollector(t *testing.T) {
go func() { go func() {
defer close(ch) defer close(ch)
c := PGStatDatabaseCollector{ c := PGStatDatabaseCollector{
log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"), log: promslog.NewNopLogger().With("collector", "pg_stat_database"),
} }
if err := c.Update(context.Background(), inst, ch); err != nil { if err := c.Update(context.Background(), inst, ch); err != nil {
@ -219,7 +219,7 @@ func TestPGStatDatabaseCollectorNullValues(t *testing.T) {
go func() { go func() {
defer close(ch) defer close(ch)
c := PGStatDatabaseCollector{ c := PGStatDatabaseCollector{
log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"), log: promslog.NewNopLogger().With("collector", "pg_stat_database"),
} }
if err := c.Update(context.Background(), inst, ch); err != nil { if err := c.Update(context.Background(), inst, ch); err != nil {
@ -368,7 +368,7 @@ func TestPGStatDatabaseCollectorRowLeakTest(t *testing.T) {
go func() { go func() {
defer close(ch) defer close(ch)
c := PGStatDatabaseCollector{ c := PGStatDatabaseCollector{
log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"), log: promslog.NewNopLogger().With("collector", "pg_stat_database"),
} }
if err := c.Update(context.Background(), inst, ch); err != nil { if err := c.Update(context.Background(), inst, ch); err != nil {
@ -489,7 +489,7 @@ func TestPGStatDatabaseCollectorTestNilStatReset(t *testing.T) {
go func() { go func() {
defer close(ch) defer close(ch)
c := PGStatDatabaseCollector{ c := PGStatDatabaseCollector{
log: log.With(log.NewNopLogger(), "collector", "pg_stat_database"), log: promslog.NewNopLogger().With("collector", "pg_stat_database"),
} }
if err := c.Update(context.Background(), inst, ch); err != nil { if err := c.Update(context.Background(), inst, ch); err != nil {

View File

@ -16,9 +16,9 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -32,7 +32,7 @@ func init() {
} }
type PGStatStatementsCollector struct { type PGStatStatementsCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGStatStatementsCollector(config collectorConfig) (Collector, error) { func NewPGStatStatementsCollector(config collectorConfig) (Collector, error) {

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGStatUserTablesCollector struct { type PGStatUserTablesCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGStatUserTablesCollector(config collectorConfig) (Collector, error) { func NewPGStatUserTablesCollector(config collectorConfig) (Collector, error) {

View File

@ -16,9 +16,8 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"log/slog"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -27,7 +26,7 @@ func init() {
} }
type PGStatWalReceiverCollector struct { type PGStatWalReceiverCollector struct {
log log.Logger log *slog.Logger
} }
const statWalReceiverSubsystem = "stat_wal_receiver" const statWalReceiverSubsystem = "stat_wal_receiver"
@ -157,55 +156,51 @@ func (c *PGStatWalReceiverCollector) Update(ctx context.Context, instance *insta
} }
} }
if !upstreamHost.Valid { if !upstreamHost.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because upstream host is null") c.log.Debug("Skipping wal receiver stats because upstream host is null")
continue continue
} }
if !slotName.Valid { if !slotName.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because slotname host is null") c.log.Debug("Skipping wal receiver stats because slotname host is null")
continue continue
} }
if !status.Valid { if !status.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because status is null") c.log.Debug("Skipping wal receiver stats because status is null")
continue continue
} }
labels := []string{upstreamHost.String, slotName.String, status.String} labels := []string{upstreamHost.String, slotName.String, status.String}
if !receiveStartLsn.Valid { if !receiveStartLsn.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because receive_start_lsn is null") c.log.Debug("Skipping wal receiver stats because receive_start_lsn is null")
continue continue
} }
if !receiveStartTli.Valid { if !receiveStartTli.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because receive_start_tli is null") c.log.Debug("Skipping wal receiver stats because receive_start_tli is null")
continue continue
} }
if hasFlushedLSN && !flushedLsn.Valid { if hasFlushedLSN && !flushedLsn.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because flushed_lsn is null") c.log.Debug("Skipping wal receiver stats because flushed_lsn is null")
continue continue
} }
if !receivedTli.Valid { if !receivedTli.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because received_tli is null") c.log.Debug("Skipping wal receiver stats because received_tli is null")
continue continue
} }
if !lastMsgSendTime.Valid { if !lastMsgSendTime.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because last_msg_send_time is null") c.log.Debug("Skipping wal receiver stats because last_msg_send_time is null")
continue continue
} }
if !lastMsgReceiptTime.Valid { if !lastMsgReceiptTime.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because last_msg_receipt_time is null") c.log.Debug("Skipping wal receiver stats because last_msg_receipt_time is null")
continue continue
} }
if !latestEndLsn.Valid { if !latestEndLsn.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because latest_end_lsn is null") c.log.Debug("Skipping wal receiver stats because latest_end_lsn is null")
continue continue
} }
if !latestEndTime.Valid { if !latestEndTime.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because latest_end_time is null") c.log.Debug("Skipping wal receiver stats because latest_end_time is null")
continue
}
if !upstreamNode.Valid {
level.Debug(c.log).Log("msg", "Skipping wal receiver stats because upstream_node is null")
continue continue
} }
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
@ -258,12 +253,16 @@ func (c *PGStatWalReceiverCollector) Update(ctx context.Context, instance *insta
latestEndTime.Float64, latestEndTime.Float64,
labels...) labels...)
if !upstreamNode.Valid {
c.log.Debug("Skipping wal receiver stats upstream_node because it is null")
} else {
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
statWalReceiverUpstreamNode, statWalReceiverUpstreamNode,
prometheus.GaugeValue, prometheus.GaugeValue,
float64(upstreamNode.Int64), float64(upstreamNode.Int64),
labels...) labels...)
} }
}
if err := rows.Err(); err != nil { if err := rows.Err(); err != nil {
return err return err
} }

View File

@ -15,8 +15,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -25,7 +25,7 @@ func init() {
} }
type PGStatioUserIndexesCollector struct { type PGStatioUserIndexesCollector struct {
log log.Logger log *slog.Logger
} }
const statioUserIndexesSubsystem = "statio_user_indexes" const statioUserIndexesSubsystem = "statio_user_indexes"

View File

@ -16,8 +16,8 @@ package collector
import ( import (
"context" "context"
"database/sql" "database/sql"
"log/slog"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -28,7 +28,7 @@ func init() {
} }
type PGStatIOUserTablesCollector struct { type PGStatIOUserTablesCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGStatIOUserTablesCollector(config collectorConfig) (Collector, error) { func NewPGStatIOUserTablesCollector(config collectorConfig) (Collector, error) {

View File

@ -15,10 +15,9 @@ package collector
import ( import (
"context" "context"
"log/slog"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -29,7 +28,7 @@ func init() {
} }
type PGXlogLocationCollector struct { type PGXlogLocationCollector struct {
log log.Logger log *slog.Logger
} }
func NewPGXlogLocationCollector(config collectorConfig) (Collector, error) { func NewPGXlogLocationCollector(config collectorConfig) (Collector, error) {
@ -59,7 +58,7 @@ func (c PGXlogLocationCollector) Update(ctx context.Context, instance *instance,
// https://wiki.postgresql.org/wiki/New_in_postgres_10#Renaming_of_.22xlog.22_to_.22wal.22_Globally_.28and_location.2Flsn.29 // https://wiki.postgresql.org/wiki/New_in_postgres_10#Renaming_of_.22xlog.22_to_.22wal.22_Globally_.28and_location.2Flsn.29
after10 := instance.version.Compare(semver.MustParse("10.0.0")) after10 := instance.version.Compare(semver.MustParse("10.0.0"))
if after10 >= 0 { if after10 >= 0 {
level.Warn(c.log).Log("msg", "xlog_location collector is not available on PostgreSQL >= 10.0.0, skipping") c.log.Warn("xlog_location collector is not available on PostgreSQL >= 10.0.0, skipping")
return nil return nil
} }

View File

@ -15,10 +15,9 @@ package collector
import ( import (
"context" "context"
"log/slog"
"sync" "sync"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus-community/postgres_exporter/config" "github.com/prometheus-community/postgres_exporter/config"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -26,11 +25,11 @@ import (
type ProbeCollector struct { type ProbeCollector struct {
registry *prometheus.Registry registry *prometheus.Registry
collectors map[string]Collector collectors map[string]Collector
logger log.Logger logger *slog.Logger
instance *instance instance *instance
} }
func NewProbeCollector(logger log.Logger, excludeDatabases []string, registry *prometheus.Registry, dsn config.DSN) (*ProbeCollector, error) { func NewProbeCollector(logger *slog.Logger, excludeDatabases []string, registry *prometheus.Registry, dsn config.DSN) (*ProbeCollector, error) {
collectors := make(map[string]Collector) collectors := make(map[string]Collector)
initiatedCollectorsMtx.Lock() initiatedCollectorsMtx.Lock()
defer initiatedCollectorsMtx.Unlock() defer initiatedCollectorsMtx.Unlock()
@ -47,7 +46,7 @@ func NewProbeCollector(logger log.Logger, excludeDatabases []string, registry *p
} else { } else {
collector, err := factories[key]( collector, err := factories[key](
collectorConfig{ collectorConfig{
logger: log.With(logger, "collector", key), logger: logger.With("collector", key),
excludeDatabases: excludeDatabases, excludeDatabases: excludeDatabases,
}) })
if err != nil { if err != nil {
@ -78,7 +77,7 @@ func (pc *ProbeCollector) Collect(ch chan<- prometheus.Metric) {
// Set up the database connection for the collector. // Set up the database connection for the collector.
err := pc.instance.setup() err := pc.instance.setup()
if err != nil { if err != nil {
level.Error(pc.logger).Log("msg", "Error opening connection to database", "err", err) pc.logger.Error("Error opening connection to database", "err", err)
return return
} }
defer pc.instance.Close() defer pc.instance.Close()

View File

@ -15,10 +15,10 @@ package config
import ( import (
"fmt" "fmt"
"log/slog"
"os" "os"
"sync" "sync"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promauto"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@ -65,7 +65,7 @@ func (ch *Handler) GetConfig() *Config {
return ch.Config return ch.Config
} }
func (ch *Handler) ReloadConfig(f string, logger log.Logger) error { func (ch *Handler) ReloadConfig(f string, logger *slog.Logger) error {
config := &Config{} config := &Config{}
var err error var err error
defer func() { defer func() {

36
go.mod
View File

@ -1,17 +1,16 @@
module github.com/prometheus-community/postgres_exporter module github.com/prometheus-community/postgres_exporter
go 1.19 go 1.23.0
require ( require (
github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/alecthomas/kingpin/v2 v2.4.0 github.com/alecthomas/kingpin/v2 v2.4.0
github.com/blang/semver/v4 v4.0.0 github.com/blang/semver/v4 v4.0.0
github.com/go-kit/log v0.2.1
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
github.com/prometheus/client_golang v1.19.0 github.com/prometheus/client_golang v1.20.5
github.com/prometheus/client_model v0.6.0 github.com/prometheus/client_model v0.6.1
github.com/prometheus/common v0.48.0 github.com/prometheus/common v0.60.1
github.com/prometheus/exporter-toolkit v0.11.0 github.com/prometheus/exporter-toolkit v0.13.1
github.com/smartystreets/goconvey v1.8.1 github.com/smartystreets/goconvey v1.8.1
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
@ -21,26 +20,27 @@ require (
require ( require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/jpillora/backoff v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kr/pretty v0.3.1 // indirect github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/mdlayher/vsock v1.2.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/prometheus/procfs v0.12.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/smarty/assertions v1.15.0 // indirect github.com/smarty/assertions v1.15.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
golang.org/x/crypto v0.21.0 // indirect golang.org/x/crypto v0.28.0 // indirect
golang.org/x/net v0.23.0 // indirect golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.5.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.18.0 // indirect golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/text v0.19.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.34.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
) )

87
go.sum
View File

@ -8,24 +8,17 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
@ -33,6 +26,8 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@ -40,23 +35,31 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= github.com/prometheus/exporter-toolkit v0.13.1 h1:Evsh0gWQo2bdOHlnz9+0Nm7/OFfIwhE2Ws4A2jIlR04=
github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= github.com/prometheus/exporter-toolkit v0.13.1/go.mod h1:ujdv2YIOxtdFxxqtloLpbqmxd5J0Le6IITUvIRSWjj0=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
@ -66,34 +69,24 @@ github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sS
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=