pangolin_exporter

Форк
0
129 строк · 2.8 Кб
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/prometheus/client_golang/prometheus"
22
)
23

24
const locksSubsystem = "locks"
25

26
func init() {
27
	registerCollector(locksSubsystem, defaultEnabled, NewPGLocksCollector)
28
}
29

30
type PGLocksCollector struct {
31
	log log.Logger
32
}
33

34
func NewPGLocksCollector(config collectorConfig) (Collector, error) {
35
	return &PGLocksCollector{
36
		log: config.logger,
37
	}, nil
38
}
39

40
var (
41
	pgLocksDesc = prometheus.NewDesc(
42
		prometheus.BuildFQName(
43
			namespace,
44
			locksSubsystem,
45
			"count",
46
		),
47
		"Number of locks",
48
		[]string{"datname", "mode"}, nil,
49
	)
50

51
	pgLocksQuery = `
52
		SELECT 
53
		  pg_database.datname as datname,
54
		  tmp.mode as mode,
55
		  COALESCE(count, 0) as count 
56
		FROM 
57
		  (
58
		    VALUES 
59
		      ('accesssharelock'), 
60
		      ('rowsharelock'), 
61
		      ('rowexclusivelock'), 
62
		      ('shareupdateexclusivelock'), 
63
		      ('sharelock'), 
64
		      ('sharerowexclusivelock'), 
65
		      ('exclusivelock'), 
66
		      ('accessexclusivelock'), 
67
		      ('sireadlock')
68
		  ) AS tmp(mode)
69
		  CROSS JOIN pg_database 
70
		  LEFT JOIN (
71
		    SELECT 
72
		      database, 
73
		      lower(mode) AS mode, 
74
		      count(*) AS count 
75
		    FROM 
76
		      pg_locks 
77
		    WHERE 
78
		      database IS NOT NULL 
79
		    GROUP BY 
80
		      database, 
81
		      lower(mode)
82
		  ) AS tmp2 ON tmp.mode = tmp2.mode 
83
		  and pg_database.oid = tmp2.database 
84
		ORDER BY 
85
		  1
86
	`
87
)
88

89
// Update implements Collector and exposes database locks.
90
// It is called by the Prometheus registry when collecting metrics.
91
func (c PGLocksCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error {
92
	db := instance.getDB()
93
	// Query the list of databases
94
	rows, err := db.QueryContext(ctx,
95
		pgLocksQuery,
96
	)
97
	if err != nil {
98
		return err
99
	}
100
	defer rows.Close()
101

102
	var datname, mode sql.NullString
103
	var count sql.NullInt64
104

105
	for rows.Next() {
106
		if err := rows.Scan(&datname, &mode, &count); err != nil {
107
			return err
108
		}
109

110
		if !datname.Valid || !mode.Valid {
111
			continue
112
		}
113

114
		countMetric := 0.0
115
		if count.Valid {
116
			countMetric = float64(count.Int64)
117
		}
118

119
		ch <- prometheus.MustNewConstMetric(
120
			pgLocksDesc,
121
			prometheus.GaugeValue, countMetric,
122
			datname.String, mode.String,
123
		)
124
	}
125
	if err := rows.Err(); err != nil {
126
		return err
127
	}
128
	return nil
129
}
130

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

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

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

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