Sha256: f91fda824fca117f70a0218225d961cfef567030a71c94f0d0897d8e1b51b630

Contents?: true

Size: 1.66 KB

Versions: 13

Compression:

Stored size: 1.66 KB

Contents

# frozen_string_literal: true

# see https://samsaffron.com/archive/2017/10/18/fastest-way-to-profile-a-method-in-ruby
module PrometheusExporter::Instrumentation; end

class PrometheusExporter::Instrumentation::MethodProfiler
  def self.patch(klass, methods, name)
    patches = methods.map do |method_name|
      <<~RUBY
      unless defined?(#{method_name}__mp_unpatched)
        alias_method :#{method_name}__mp_unpatched, :#{method_name}
        def #{method_name}(*args, &blk)
          unless prof = Thread.current[:_method_profiler]
            return #{method_name}__mp_unpatched(*args, &blk)
          end
          begin
            start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
            #{method_name}__mp_unpatched(*args, &blk)
          ensure
            data = (prof[:#{name}] ||= {duration: 0.0, calls: 0})
            data[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
            data[:calls] += 1
          end
        end
      end
      RUBY
    end.join("\n")

    klass.class_eval patches
  end

  def self.transfer
    result = Thread.current[:_method_profiler]
    Thread.current[:_method_profiler] = nil
    result
  end

  def self.start(transfer = nil)
    Thread.current[:_method_profiler] = transfer || {
      __start: Process.clock_gettime(Process::CLOCK_MONOTONIC)
    }
  end

  def self.clear
    Thread.current[:_method_profiler] = nil
  end

  def self.stop
    finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    if data = Thread.current[:_method_profiler]
      Thread.current[:_method_profiler] = nil
      start = data.delete(:__start)
      data[:total_duration] = finish - start
    end
    data
  end
end

Version data entries

13 entries across 13 versions & 1 rubygems

Version Path
prometheus_exporter-0.7.0 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.6.0 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.5.3 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.5.2 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.5.1 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.5.0 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.17 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.16 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.15 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.14 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.13 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.12 lib/prometheus_exporter/instrumentation/method_profiler.rb
prometheus_exporter-0.4.11 lib/prometheus_exporter/instrumentation/method_profiler.rb