2019-02-15 15:39:39 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
module Gitlab
|
|
|
|
module Metrics
|
|
|
|
module Samplers
|
|
|
|
class UnicornSampler < BaseSampler
|
2021-03-08 18:12:59 +05:30
|
|
|
DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
|
|
|
|
|
2019-09-04 21:01:54 +05:30
|
|
|
def metrics
|
|
|
|
@metrics ||= init_metrics
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
2019-09-04 21:01:54 +05:30
|
|
|
def init_metrics
|
|
|
|
{
|
|
|
|
unicorn_active_connections: ::Gitlab::Metrics.gauge(:unicorn_active_connections, 'Unicorn active connections', {}, :max),
|
|
|
|
unicorn_queued_connections: ::Gitlab::Metrics.gauge(:unicorn_queued_connections, 'Unicorn queued connections', {}, :max),
|
|
|
|
unicorn_workers: ::Gitlab::Metrics.gauge(:unicorn_workers, 'Unicorn workers')
|
|
|
|
}
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def enabled?
|
|
|
|
# Raindrops::Linux.tcp_listener_stats is only present on Linux
|
|
|
|
unicorn_with_listeners? && Raindrops::Linux.respond_to?(:tcp_listener_stats)
|
|
|
|
end
|
|
|
|
|
|
|
|
def sample
|
|
|
|
Raindrops::Linux.tcp_listener_stats(tcp_listeners).each do |addr, stats|
|
2019-09-04 21:01:54 +05:30
|
|
|
set_unicorn_connection_metrics('tcp', addr, stats)
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
Raindrops::Linux.unix_listener_stats(unix_listeners).each do |addr, stats|
|
2019-09-04 21:01:54 +05:30
|
|
|
set_unicorn_connection_metrics('unix', addr, stats)
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
2019-09-04 21:01:54 +05:30
|
|
|
|
|
|
|
metrics[:unicorn_workers].set({}, unicorn_workers_count)
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def tcp_listeners
|
|
|
|
@tcp_listeners ||= Unicorn.listener_names.grep(%r{\A[^/]+:\d+\z})
|
|
|
|
end
|
|
|
|
|
2019-09-04 21:01:54 +05:30
|
|
|
def set_unicorn_connection_metrics(type, addr, stats)
|
|
|
|
labels = { socket_type: type, socket_address: addr }
|
|
|
|
|
|
|
|
metrics[:unicorn_active_connections].set(labels, stats.active)
|
|
|
|
metrics[:unicorn_queued_connections].set(labels, stats.queued)
|
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
def unix_listeners
|
|
|
|
@unix_listeners ||= Unicorn.listener_names - tcp_listeners
|
|
|
|
end
|
|
|
|
|
|
|
|
def unicorn_with_listeners?
|
|
|
|
defined?(Unicorn) && Unicorn.listener_names.any?
|
|
|
|
end
|
2019-09-04 21:01:54 +05:30
|
|
|
|
|
|
|
def unicorn_workers_count
|
2021-01-03 14:25:43 +05:30
|
|
|
http_servers.sum(&:worker_processes)
|
2019-09-30 21:07:59 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
# Traversal of ObjectSpace is expensive, on fully loaded application
|
|
|
|
# it takes around 80ms. The instances of HttpServers are not a subject
|
|
|
|
# to change so we can cache the list of servers.
|
|
|
|
def http_servers
|
2020-03-13 15:44:24 +05:30
|
|
|
return [] unless Gitlab::Runtime.unicorn?
|
2019-09-30 21:07:59 +05:30
|
|
|
|
|
|
|
@http_servers ||= ObjectSpace.each_object(::Unicorn::HttpServer).to_a
|
2019-09-04 21:01:54 +05:30
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|