1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
# frozen_string_literal: true
module Gitlab
module Metrics
module Samplers
class DatabaseSampler < BaseSampler
DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
METRIC_PREFIX = 'gitlab_database_connection_pool_'
METRIC_DESCRIPTIONS = {
size: 'Total connection pool capacity',
connections: 'Current connections in the pool',
busy: 'Connections in use where the owner is still alive',
dead: 'Connections in use where the owner is not alive',
idle: 'Connections not in use',
waiting: 'Threads currently waiting on this queue'
}.freeze
def metrics
@metrics ||= init_metrics
end
def sample
host_stats.each do |host_stat|
METRIC_DESCRIPTIONS.each_key do |metric|
metrics[metric].set(host_stat[:labels], host_stat[:stats][metric])
end
end
end
private
def init_metrics
METRIC_DESCRIPTIONS.to_h do |name, description|
[name, ::Gitlab::Metrics.gauge(:"#{METRIC_PREFIX}#{name}", description)]
end
end
def host_stats
connection_class_stats + replica_host_stats
end
def connection_class_stats
Gitlab::Database.database_base_models.each_value.with_object([]) do |base_model, stats|
next unless base_model.connected?
stats << { labels: labels_for_class(base_model), stats: base_model.connection_pool.stat }
end
end
def replica_host_stats
Gitlab::Database::LoadBalancing.each_load_balancer.with_object([]) do |load_balancer, stats|
next if load_balancer.primary_only?
load_balancer.host_list.hosts.each do |host|
stats << { labels: labels_for_replica_host(load_balancer, host), stats: host.connection.pool.stat }
end
end
end
def labels_for_class(klass)
{
host: klass.connection_db_config.host,
port: klass.connection_db_config.configuration_hash[:port],
class: klass.to_s,
db_config_name: klass.connection_db_config.name
}
end
def labels_for_replica_host(load_balancer, host)
{
host: host.host,
port: host.port,
class: load_balancer.configuration.primary_connection_specification_name,
db_config_name: Gitlab::Database.db_config_name(host.connection)
}
end
end
end
end
end
Gitlab::Metrics::Samplers::DatabaseSampler.prepend_mod_with('Gitlab::Metrics::Samplers::DatabaseSampler')
|