pangolin_exporter

Форк
0
/
pg_database_wraparound.go 
115 строк · 3.1 Кб
1
// Copyright 2023 The Prometheus Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13

14
package collector
15

16
import (
17
	"context"
18
	"database/sql"
19

20
	"github.com/go-kit/log"
21
	"github.com/go-kit/log/level"
22
	"github.com/prometheus/client_golang/prometheus"
23
)
24

25
const databaseWraparoundSubsystem = "database_wraparound"
26

27
func init() {
28
	registerCollector(databaseWraparoundSubsystem, defaultDisabled, NewPGDatabaseWraparoundCollector)
29
}
30

31
type PGDatabaseWraparoundCollector struct {
32
	log log.Logger
33
}
34

35
func NewPGDatabaseWraparoundCollector(config collectorConfig) (Collector, error) {
36
	return &PGDatabaseWraparoundCollector{log: config.logger}, nil
37
}
38

39
var (
40
	databaseWraparoundAgeDatfrozenxid = prometheus.NewDesc(
41
		prometheus.BuildFQName(namespace, databaseWraparoundSubsystem, "age_datfrozenxid_seconds"),
42
		"Age of the oldest transaction ID that has not been frozen.",
43
		[]string{"datname"},
44
		prometheus.Labels{},
45
	)
46
	databaseWraparoundAgeDatminmxid = prometheus.NewDesc(
47
		prometheus.BuildFQName(namespace, databaseWraparoundSubsystem, "age_datminmxid_seconds"),
48
		"Age of the oldest multi-transaction ID that has been replaced with a transaction ID.",
49
		[]string{"datname"},
50
		prometheus.Labels{},
51
	)
52

53
	databaseWraparoundQuery = `
54
	SELECT
55
		datname,
56
		age(d.datfrozenxid) as age_datfrozenxid,
57
		mxid_age(d.datminmxid) as age_datminmxid
58
	FROM
59
		pg_catalog.pg_database d
60
	WHERE
61
		d.datallowconn
62
	`
63
)
64

65
func (c *PGDatabaseWraparoundCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error {
66
	db := instance.getDB()
67
	rows, err := db.QueryContext(ctx,
68
		databaseWraparoundQuery)
69

70
	if err != nil {
71
		return err
72
	}
73
	defer rows.Close()
74

75
	for rows.Next() {
76
		var datname sql.NullString
77
		var ageDatfrozenxid, ageDatminmxid sql.NullFloat64
78

79
		if err := rows.Scan(&datname, &ageDatfrozenxid, &ageDatminmxid); err != nil {
80
			return err
81
		}
82

83
		if !datname.Valid {
84
			level.Debug(c.log).Log("msg", "Skipping database with NULL name")
85
			continue
86
		}
87
		if !ageDatfrozenxid.Valid {
88
			level.Debug(c.log).Log("msg", "Skipping stat emission with NULL age_datfrozenxid")
89
			continue
90
		}
91
		if !ageDatminmxid.Valid {
92
			level.Debug(c.log).Log("msg", "Skipping stat emission with NULL age_datminmxid")
93
			continue
94
		}
95

96
		ageDatfrozenxidMetric := ageDatfrozenxid.Float64
97

98
		ch <- prometheus.MustNewConstMetric(
99
			databaseWraparoundAgeDatfrozenxid,
100
			prometheus.GaugeValue,
101
			ageDatfrozenxidMetric, datname.String,
102
		)
103

104
		ageDatminmxidMetric := ageDatminmxid.Float64
105
		ch <- prometheus.MustNewConstMetric(
106
			databaseWraparoundAgeDatminmxid,
107
			prometheus.GaugeValue,
108
			ageDatminmxidMetric, datname.String,
109
		)
110
	}
111
	if err := rows.Err(); err != nil {
112
		return err
113
	}
114
	return nil
115
}
116

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.