2020-05-24 23:13:21 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module Metrics
|
|
|
|
module Samplers
|
|
|
|
class DatabaseSampler < BaseSampler
|
2021-03-08 18:12:59 +05:30
|
|
|
DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
|
2020-05-24 23:13:21 +05:30
|
|
|
|
|
|
|
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
|
2021-04-29 21:17:54 +05:30
|
|
|
METRIC_DESCRIPTIONS.to_h do |name, description|
|
2020-05-24 23:13:21 +05:30
|
|
|
[name, ::Gitlab::Metrics.gauge(:"#{METRIC_PREFIX}#{name}", description)]
|
2021-04-29 21:17:54 +05:30
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def host_stats
|
2022-01-26 12:08:38 +05:30
|
|
|
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?
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2022-01-26 12:08:38 +05:30
|
|
|
load_balancer.host_list.hosts.each do |host|
|
|
|
|
stats << { labels: labels_for_replica_host(load_balancer, host), stats: host.connection.pool.stat }
|
|
|
|
end
|
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def labels_for_class(klass)
|
|
|
|
{
|
2021-09-04 01:27:46 +05:30
|
|
|
host: klass.connection_db_config.host,
|
|
|
|
port: klass.connection_db_config.configuration_hash[:port],
|
2022-01-26 12:08:38 +05:30
|
|
|
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)
|
2020-05-24 23:13:21 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
Gitlab::Metrics::Samplers::DatabaseSampler.prepend_mod_with('Gitlab::Metrics::Samplers::DatabaseSampler')
|