|
# frozen_string_literal: true |
|
|
|
# Puma plugin for sending puma and db connection stats to our monitoring systems |
|
# Taken from: https://gist.github.com/LeZuse/022c501143a5bc4b51a601ad2a1b8abc |
|
# See: https://github.com/puma/puma/issues/1512 to know more about these metrics |
|
# Docs: https://github.com/puma/puma/blob/master/docs/plugins.md |
|
|
|
require 'puma/plugin' |
|
|
|
Puma::Plugin.create do |
|
# return true if you want to send stats |
|
# return false if you want to disable this plugin |
|
def send_stats? |
|
# do not send stats on development test and beta |
|
env = Rails.env |
|
return false if %w[development test beta].include?(env) |
|
|
|
# send stats |
|
return true |
|
end |
|
|
|
def start(_launcher) |
|
return unless send_stats? |
|
|
|
in_background do |
|
stat_frequency = ENV.fetch('SERVER_STATS_FREQUENCY', 10).to_i |
|
Rails.logger.warn("Sending server stats every #{stat_frequency} seconds") |
|
|
|
loop do |
|
sleep(stat_frequency) |
|
begin |
|
all_stats = {} |
|
puma_stats = [] |
|
db_pool_stats = [] |
|
|
|
# Puma.stats: { |
|
# started_at: @started_at.utc.iso8601, |
|
# workers: @workers.size, |
|
# phase: @phase, |
|
# booted_workers: worker_status.count { |w| w[:booted] }, |
|
# old_workers: old_worker_count, |
|
# worker_status: worker_status, |
|
# } |
|
stats = JSON.parse(Puma.stats, symbolize_names: true) |
|
# get puma stats |
|
if stats[:worker_status].present? |
|
# in cluster mode, get stats from each worker |
|
# stats[:worker_status]: List of workers with their corresponding |
|
# statuses |
|
stats[:worker_status].each do |worker| |
|
# worker[:last_status]: { "backlog":0,"running":2, |
|
# "pool_capacity":2,"max_threads":2 } |
|
stat = worker[:last_status] |
|
puma_stats << stat |
|
end |
|
else |
|
puma_stats << stats |
|
end |
|
# get db pool stats |
|
db_stat = ActiveRecord::Base.connection_pool.stat |
|
# checkout_timeout is sometimes float, make int to make sure events |
|
# are not dropped by InfluxDB |
|
db_stat[:checkout_timeout] = db_stat[:checkout_timeout].to_i |
|
db_pool_stats << db_stat |
|
|
|
# build final stats hash |
|
all_stats['puma'] = puma_stats |
|
all_stats['db_pool'] = db_pool_stats |
|
# this call sends it to monitoring system |
|
ServerMetrics.push_stats(all_stats) |
|
rescue StandardError => e |
|
Rails.logger.warn(e) |
|
ensure |
|
# flush logger |
|
Rails.logger.flush |
|
end |
|
end |
|
end |
|
end |
|
end |