From d0197481c5984a5e44f7724277d12b51dc755364 Mon Sep 17 00:00:00 2001 From: Dmitriy Salakhutdinov Date: Thu, 21 Nov 2024 18:14:29 +0500 Subject: [PATCH] feat: requests_wait_time metric suppoert --- Gemfile | 6 +- lib/puma/plugin/yabeda.rb | 11 ++-- lib/yabeda/puma/plugin/statistics.rb | 4 +- spec/integration/clustered_spec.rb | 38 ++++++------ .../puma/plugin/statistics/parser_spec.rb | 59 +++++++++++-------- 5 files changed, 65 insertions(+), 53 deletions(-) diff --git a/Gemfile b/Gemfile index ca35907..c2d3adf 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,10 @@ -source "https://rubygems.org" +source 'https://rubygems.org' gem 'yabeda-prometheus' # Specify your gem's dependencies in yabeda-puma.gemspec gemspec -puma_version = ENV.fetch("PUMA_VERSION", "~> 6.0") +puma_version = ENV.fetch('PUMA_VERSION', '~> 6.0') puma_version = "~> #{puma_version}.0" if puma_version.match?(/^\d+$/) -gem "puma", puma_version +gem 'puma', puma_version, git: 'https://github.com/dsalahutdinov/puma.git', branch: :add_preprocess_time diff --git a/lib/puma/plugin/yabeda.rb b/lib/puma/plugin/yabeda.rb index 97eef6a..e8bd8d9 100644 --- a/lib/puma/plugin/yabeda.rb +++ b/lib/puma/plugin/yabeda.rb @@ -1,11 +1,11 @@ -require 'yabeda/puma/plugin.rb' +require 'yabeda/puma/plugin' Puma::Plugin.create do def start(launcher) clustered = (launcher.options[:workers] || 0) > 0 control_url = launcher.options[:control_url] - raise StandardError, "Puma control app is not activated" if control_url == nil + raise StandardError, 'Puma control app is not activated' if control_url.nil? Yabeda::Puma::Plugin.tap do |puma| puma.control_url = control_url @@ -15,10 +15,14 @@ def start(launcher) Yabeda.configure do group :puma - gauge :backlog, tags: %i[index], comment: 'Number of established but unaccepted connections in the backlog', aggregation: :most_recent + gauge :backlog, tags: %i[index], comment: 'Number of established but unaccepted connections in the backlog', + aggregation: :most_recent gauge :running, tags: %i[index], comment: 'Number of running worker threads', aggregation: :most_recent gauge :pool_capacity, tags: %i[index], comment: 'Number of allocatable worker threads', aggregation: :most_recent gauge :max_threads, tags: %i[index], comment: 'Maximum number of worker threads', aggregation: :most_recent + gauge :requests_count, tags: %i[index], comment: 'Number of total request processed', aggregation: :most_recent + gauge :requests_wait_time, tags: %i[index], comment: 'Time requests are waiting before adding to todo-backlog', + aggregation: :most_recent if clustered gauge :workers, comment: 'Number of configured workers', aggregation: :most_recent @@ -37,4 +41,3 @@ def start(launcher) end end end - diff --git a/lib/yabeda/puma/plugin/statistics.rb b/lib/yabeda/puma/plugin/statistics.rb index ef8d505..497fa7c 100644 --- a/lib/yabeda/puma/plugin/statistics.rb +++ b/lib/yabeda/puma/plugin/statistics.rb @@ -2,8 +2,8 @@ module Yabeda module Puma module Plugin module Statistics - METRICS = [:backlog, :running, :pool_capacity, :max_threads] - CLUSTERED_METRICS = [:booted_workers, :old_workers, :workers] + METRICS = %i[backlog running pool_capacity max_threads requests_count requests_wait_time] + CLUSTERED_METRICS = %i[booted_workers old_workers workers] end end end diff --git a/spec/integration/clustered_spec.rb b/spec/integration/clustered_spec.rb index 14a7017..2a5b2d8 100644 --- a/spec/integration/clustered_spec.rb +++ b/spec/integration/clustered_spec.rb @@ -1,15 +1,15 @@ -require "net/http" -require "timeout" +require 'net/http' +require 'timeout' require 'tempfile' -require "puma" -require "puma/events" -require "puma/detect" -require "puma/cli" +require 'puma' +require 'puma/events' +require 'puma/detect' +require 'puma/cli' require 'rack' RSpec.describe Yabeda::Puma::Plugin do def next_port(incr = 1) - @next_port = 9000 if @next_port == nil + @next_port = 9000 if @next_port.nil? @next_port += incr end @@ -23,7 +23,7 @@ def next_port(incr = 1) @events = Puma::Events.strings end - @events.on_booted { @ready << "!" } + @events.on_booted { @ready << '!' } end after(:each) do @@ -38,9 +38,9 @@ def wait_booted describe '/metrics' do let(:port) { next_port } it do - cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:#{port}", - "-C", "spec/configs/puma.rb", - "spec/configs/lobster.ru"], *[@log_writer, @events].compact + cli = Puma::CLI.new ['-b', "tcp://127.0.0.1:#{port}", + '-C', 'spec/configs/puma.rb', + 'spec/configs/lobster.ru'], *[@log_writer, @events].compact t = Thread.new do Thread.current.abort_on_exception = true @@ -58,14 +58,16 @@ def wait_booted http.request request end - expect(response.body).to match("puma_backlog\\\{index=\"\\\d+\\\"\\\} \\\d+") - expect(response.body).to match("puma_running\\\{index=\"\\\d+\\\"\\\} \\\d+") - expect(response.body).to match("puma_pool_capacity\\\{index=\"\\\d+\\\"\\\} \\\d+") - expect(response.body).to match("puma_max_threads\\\{index=\"\\\d+\\\"\\\} \\\d+") + expect(response.body).to match("puma_backlog\\\{index=\"\\\d+\\\"\\\} \\\d+") + expect(response.body).to match("puma_running\\\{index=\"\\\d+\\\"\\\} \\\d+") + expect(response.body).to match("puma_pool_capacity\\\{index=\"\\\d+\\\"\\\} \\\d+") + expect(response.body).to match("puma_max_threads\\\{index=\"\\\d+\\\"\\\} \\\d+") + expect(response.body).to match("requests_count\\\{index=\"\\\d+\\\"\\\} \\\d+") + expect(response.body).to match("requests_wait_time\\\{index=\"\\\d+\\\"\\\} \\\d+") - expect(response.body).to include("puma_workers 2") - expect(response.body).to include("puma_booted_workers 2") - expect(response.body).to include("puma_old_workers 0") + expect(response.body).to include('puma_workers 2') + expect(response.body).to include('puma_booted_workers 2') + expect(response.body).to include('puma_old_workers 0') end end end diff --git a/spec/yabeda/puma/plugin/statistics/parser_spec.rb b/spec/yabeda/puma/plugin/statistics/parser_spec.rb index 9000b68..f780758 100644 --- a/spec/yabeda/puma/plugin/statistics/parser_spec.rb +++ b/spec/yabeda/puma/plugin/statistics/parser_spec.rb @@ -2,7 +2,6 @@ require 'yabeda/puma/plugin/statistics/parser' RSpec.describe Yabeda::Puma::Plugin::Statistics::Parser do - describe '#parse' do subject(:statistics) { described_class.new(clustered: clustered, data: data).call } @@ -10,17 +9,18 @@ let(:clustered) { true } let(:data) do { - "workers"=>2, "phase"=>0, "booted_workers"=>2, "old_workers"=>0, - "worker_status"=>[ - {"pid"=>13, "index"=>0, "phase"=>0, "booted"=>true, "last_checkin"=>"2019-03-31T13:04:28Z", - "last_status"=>{ - "backlog"=>0, "running"=>5, "pool_capacity"=>5, "max_threads"=>5 - }}, - {"pid"=>17, "index"=>1, "phase"=>0, "booted"=>true, "last_checkin"=>"2019-03-31T13:04:28Z", - "last_status"=>{ - "backlog"=>0, "running"=>5, "pool_capacity"=>5, "max_threads"=>5 - } - } + 'workers' => 2, 'phase' => 0, 'booted_workers' => 2, 'old_workers' => 0, + 'worker_status' => [ + { 'pid' => 13, 'index' => 0, 'phase' => 0, 'booted' => true, 'last_checkin' => '2019-03-31T13:04:28Z', + 'last_status' => { + 'backlog' => 0, 'running' => 5, 'pool_capacity' => 5, 'max_threads' => 5, + 'requests_count' => 1, 'requests_wait_time' => 5 + } }, + { 'pid' => 17, 'index' => 1, 'phase' => 0, 'booted' => true, 'last_checkin' => '2019-03-31T13:04:28Z', + 'last_status' => { + 'backlog' => 0, 'running' => 5, 'pool_capacity' => 5, 'max_threads' => 5, + 'requests_count' => 2, 'requests_wait_time' => 6 + } } ] } end @@ -32,34 +32,41 @@ { name: 'old_workers', labels: {}, value: 0 }, { name: 'workers', labels: {}, value: 2 }, - { name: 'backlog', labels: {index: 0}, value: 0 }, - { name: 'running', labels: {index: 0}, value: 5 }, - { name: 'pool_capacity', labels: {index: 0}, value: 5 }, - { name: 'max_threads', labels: {index: 0}, value: 5 }, + { name: 'backlog', labels: { index: 0 }, value: 0 }, + { name: 'running', labels: { index: 0 }, value: 5 }, + { name: 'pool_capacity', labels: { index: 0 }, value: 5 }, + { name: 'max_threads', labels: { index: 0 }, value: 5 }, + { name: 'requests_count', labels: { index: 0 }, value: 1 }, + { name: 'requests_wait_time', labels: { index: 0 }, value: 5 }, - { name: 'backlog', labels: {index: 1}, value: 0 }, - { name: 'running', labels: {index: 1}, value: 5 }, - { name: 'pool_capacity', labels: {index: 1}, value: 5 }, - { name: 'max_threads', labels: {index: 1}, value: 5 } + { name: 'backlog', labels: { index: 1 }, value: 0 }, + { name: 'running', labels: { index: 1 }, value: 5 }, + { name: 'pool_capacity', labels: { index: 1 }, value: 5 }, + { name: 'max_threads', labels: { index: 1 }, value: 5 }, + { name: 'requests_count', labels: { index: 1 }, value: 2 }, + { name: 'requests_wait_time', labels: { index: 1 }, value: 6 } ] ) end end - context 'when puma is unclustered' do let(:clustered) { false } let(:data) do - {"backlog"=>0, "running"=>5, "pool_capacity"=>4, "max_threads"=>5} + { 'backlog' => 0, 'running' => 5, 'pool_capacity' => 4, 'max_threads' => 5, 'requests_count' => 1, + 'requests_wait_time' => 5 } end it do expect(statistics).to match_array( [ - { name: 'backlog', labels: {index: 0}, value: 0 }, - { name: 'running', labels: {index: 0}, value: 5 }, - { name: 'pool_capacity', labels: {index: 0}, value: 4 }, - { name: 'max_threads', labels: {index: 0}, value: 5 } + { name: 'backlog', labels: { index: 0 }, value: 0 }, + { name: 'running', labels: { index: 0 }, value: 5 }, + { name: 'pool_capacity', labels: { index: 0 }, value: 4 }, + { name: 'max_threads', labels: { index: 0 }, value: 5 }, + { name: 'requests_count', labels: { index: 0 }, value: 1 }, + { name: 'requests_wait_time', labels: { index: 0 }, value: 5 } + ] ) end