Class: PrometheusExporter::Instrumentation::MethodProfiler
- Inherits:
-
Object
- Object
- PrometheusExporter::Instrumentation::MethodProfiler
- Defined in:
- lib/prometheus_exporter/instrumentation/method_profiler.rb
Class Method Summary collapse
- .clear ⇒ Object
- .define_methods_on_module(klass, methods, name) ⇒ Object
- .patch(klass, methods, name, instrument:) ⇒ Object
- .patch_using_alias_method(klass, methods, name) ⇒ Object
- .patch_using_prepend(klass, methods, name) ⇒ Object
- .start(transfer = nil) ⇒ Object
- .stop ⇒ Object
- .transfer ⇒ Object
Class Method Details
.clear ⇒ Object
29 30 31 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 29 def self.clear Thread.current[:_method_profiler] = nil end |
.define_methods_on_module(klass, methods, name) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 43 def self.define_methods_on_module(klass, methods, name) patch_source_line = __LINE__ + 3 patches = methods.map { |method_name| " def \#{method_name}(...)\n unless prof = Thread.current[:_method_profiler]\n return super\n end\n begin\n start = Process.clock_gettime(Process::CLOCK_MONOTONIC)\n super\n ensure\n data = (prof[:\#{name}] ||= {duration: 0.0, calls: 0})\n data[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start\n data[:calls] += 1\n end\n end\n RUBY\n\n klass.module_eval(patches, __FILE__, patch_source_line)\nend\n" }.join("\n") |
.patch(klass, methods, name, instrument:) ⇒ Object
8 9 10 11 12 13 14 15 16 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 8 def self.patch(klass, methods, name, instrument:) if instrument == :alias_method patch_using_alias_method(klass, methods, name) elsif instrument == :prepend patch_using_prepend(klass, methods, name) else raise ArgumentError, "instrument must be :alias_method or :prepend" end end |
.patch_using_alias_method(klass, methods, name) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 71 def self.patch_using_alias_method(klass, methods, name) patch_source_line = __LINE__ + 3 patches = methods.map { |method_name| " unless defined?(\#{method_name}__mp_unpatched)\n alias_method :\#{method_name}__mp_unpatched, :\#{method_name}\n\n def \#{method_name}(...)\n unless prof = Thread.current[:_method_profiler]\n return \#{method_name}__mp_unpatched(...)\n end\n\n begin\n start = Process.clock_gettime(Process::CLOCK_MONOTONIC)\n \#{method_name}__mp_unpatched(...)\n ensure\n data = (prof[:\#{name}] ||= {duration: 0.0, calls: 0})\n data[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start\n data[:calls] += 1\n end\n end\n end\n RUBY\n\n klass.class_eval(patches, __FILE__, patch_source_line)\nend\n" }.join("\n") |
.patch_using_prepend(klass, methods, name) ⇒ Object
65 66 67 68 69 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 65 def self.patch_using_prepend(klass, methods, name) prepend_instrument = Module.new define_methods_on_module(prepend_instrument, methods, name) klass.prepend(prepend_instrument) end |
.start(transfer = nil) ⇒ Object
24 25 26 27 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 24 def self.start(transfer = nil) Thread.current[:_method_profiler] = transfer || { __start: Process.clock_gettime(Process::CLOCK_MONOTONIC) } end |
.stop ⇒ Object
33 34 35 36 37 38 39 40 41 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 33 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 |
.transfer ⇒ Object
18 19 20 21 22 |
# File 'lib/prometheus_exporter/instrumentation/method_profiler.rb', line 18 def self.transfer result = Thread.current[:_method_profiler] Thread.current[:_method_profiler] = nil result end |