pangolin_exporter
93 строки · 2.5 Кб
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
14package collector
15
16import (
17"context"
18
19"github.com/go-kit/log"
20"github.com/prometheus/client_golang/prometheus"
21)
22
23const longRunningTransactionsSubsystem = "long_running_transactions"
24
25func init() {
26registerCollector(longRunningTransactionsSubsystem, defaultDisabled, NewPGLongRunningTransactionsCollector)
27}
28
29type PGLongRunningTransactionsCollector struct {
30log log.Logger
31}
32
33func NewPGLongRunningTransactionsCollector(config collectorConfig) (Collector, error) {
34return &PGLongRunningTransactionsCollector{log: config.logger}, nil
35}
36
37var (
38longRunningTransactionsCount = prometheus.NewDesc(
39"pg_long_running_transactions",
40"Current number of long running transactions",
41[]string{},
42prometheus.Labels{},
43)
44
45longRunningTransactionsAgeInSeconds = prometheus.NewDesc(
46prometheus.BuildFQName(namespace, longRunningTransactionsSubsystem, "oldest_timestamp_seconds"),
47"The current maximum transaction age in seconds",
48[]string{},
49prometheus.Labels{},
50)
51
52longRunningTransactionsQuery = `
53SELECT
54COUNT(*) as transactions,
55MAX(EXTRACT(EPOCH FROM clock_timestamp())) AS oldest_timestamp_seconds
56FROM pg_catalog.pg_stat_activity
57WHERE state is distinct from 'idle' AND query not like 'autovacuum:%'
58`
59)
60
61func (PGLongRunningTransactionsCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error {
62db := instance.getDB()
63rows, err := db.QueryContext(ctx,
64longRunningTransactionsQuery)
65
66if err != nil {
67return err
68}
69defer rows.Close()
70
71for rows.Next() {
72var transactions, ageInSeconds float64
73
74if err := rows.Scan(&transactions, &ageInSeconds); err != nil {
75return err
76}
77
78ch <- prometheus.MustNewConstMetric(
79longRunningTransactionsCount,
80prometheus.GaugeValue,
81transactions,
82)
83ch <- prometheus.MustNewConstMetric(
84longRunningTransactionsAgeInSeconds,
85prometheus.GaugeValue,
86ageInSeconds,
87)
88}
89if err := rows.Err(); err != nil {
90return err
91}
92return nil
93}
94