diff --git a/lib/promenade/pitchfork/mem_stats.rb b/lib/promenade/pitchfork/mem_stats.rb new file mode 100644 index 0000000..11bb977 --- /dev/null +++ b/lib/promenade/pitchfork/mem_stats.rb @@ -0,0 +1,36 @@ +begin + require "pitchfork/mem_info" +rescue LoadError + # No pitchfork available, dont do anything +end + +module Promenade + module Pitchfork + class MemStats + Promenade.gauge :pitchfork_mem_rss do + doc "Resident Set Size of the pitchfork process, Total memory used by the process." + end + + Promenade.gauge :pitchfork_shared_mem do + doc "Shared memory of the pitchfork process, memory that is shared between multiple processes." + end + + def initialize + return unless defined?(::Pitchfork) && defined?(::Pitchfork::MemInfo) + + @mem_info = ::Pitchfork::MemInfo.new(Process.pid) + @parent_mem_info = ::Pitchfork::MemInfo.new(Process.ppid) + end + + def instrument + Promenade.metric(:pitchfork_mem_rss).set({}, @mem_info.rss) + Promenade.metric(:pitchfork_shared_mem).set({}, @mem_info.shared_memory) + end + + def self.instrument + new.instrument + rescue StandardError + end + end + end +end diff --git a/lib/promenade/pitchfork/middleware.rb b/lib/promenade/pitchfork/middleware.rb index dfea0b3..a829663 100644 --- a/lib/promenade/pitchfork/middleware.rb +++ b/lib/promenade/pitchfork/middleware.rb @@ -1,4 +1,5 @@ require "promenade/pitchfork/stats" +require "promenade/pitchfork/mem_stats" module Promenade module Pitchfork @@ -11,12 +12,17 @@ def initialize(app) def call(env) if env.key?(RACK_AFTER_REPLY) - env[RACK_AFTER_REPLY] << -> { - ::Promenade::Pitchfork::Stats.instrument - } + env[RACK_AFTER_REPLY] << -> { instrument } end @app.call(env) end + + private + + def instrument + Promenade::Pitchfork::Stats.instrument + Promenade::Pitchfork::MemStats.instrument + end end end end diff --git a/spec/promenade/pitchfork/mem_stats_spec.rb b/spec/promenade/pitchfork/mem_stats_spec.rb new file mode 100644 index 0000000..5e1df91 --- /dev/null +++ b/spec/promenade/pitchfork/mem_stats_spec.rb @@ -0,0 +1,34 @@ +require "spec_helper" +require "promenade/pitchfork/mem_stats" + +RSpec.describe Promenade::Pitchfork::MemStats do + let(:pitfork_mem_info) { class_double("Pitchfork::MemInfo") } + + before do + stub_const("Pitchfork::MemInfo", pitfork_mem_info) + allow(pitfork_mem_info).to receive(:new).and_return(pitfork_mem_info) + allow(pitfork_mem_info).to receive(:rss).and_return(100) + allow(pitfork_mem_info).to receive(:shared_memory).and_return(50) + end + + describe "#instrument" do + let(:metric) { instance_double("Promenade::Metric") } + + before do + allow(Promenade).to receive(:metric).and_return(metric) + allow(metric).to receive(:set) + end + + it "sets the metrics correctly" do + stats = Promenade::Pitchfork::MemStats.new + + expect(Promenade).to receive(:metric).with(:pitchfork_mem_rss).and_return(metric) + expect(Promenade).to receive(:metric).with(:pitchfork_shared_mem).and_return(metric) + + expect(metric).to receive(:set).with({}, 100) + expect(metric).to receive(:set).with({}, 50) + + stats.instrument + end + end +end