Class: FormatParser::Measurometer
- Inherits:
-
Object
- Object
- FormatParser::Measurometer
- Defined in:
- lib/measurometer.rb
Class Method Summary collapse
-
.add_distribution_value(value_path, value) ⇒ Object
Adds a distribution value (sample) under a given path.
-
.drivers ⇒ Object
Permits adding instrumentation drivers.
-
.increment_counter(counter_path, by) ⇒ Object
Increment a named counter under a given path.
-
.instrument(block_name, &blk) ⇒ Object
Runs a given block within a cascade of ‘instrument` blocks of all the added drivers.
-
.instrument_instance_method(target_class, instance_method_name_to_instrument, path_prefix) ⇒ Object
Wrap an anonymous module around an instance method in the given class to have it instrumented automatically.
Class Method Details
.add_distribution_value(value_path, value) ⇒ Object
Adds a distribution value (sample) under a given path
57 58 59 60 |
# File 'lib/measurometer.rb', line 57 def add_distribution_value(value_path, value) (@drivers || []).each { |d| d.add_distribution_value(value_path, value) } nil end |
.drivers ⇒ Object
Permits adding instrumentation drivers. Measurometer is 1-1 API compatible with Appsignal, which we use a lot. So to magically obtain all Appsignal instrumentation, add the Appsignal module as a driver.
Measurometer.drivers << Appsignal
A driver must be reentrant and thread-safe - it should be possible to have multiple ‘instrument` calls open from different threads at the same time. The driver must support the same interface as the Measurometer class itself, minus the `drivers` and `instrument_instance_method` methods.
17 18 19 20 |
# File 'lib/measurometer.rb', line 17 def drivers @drivers ||= [] @drivers end |
.increment_counter(counter_path, by) ⇒ Object
Increment a named counter under a given path
67 68 69 70 |
# File 'lib/measurometer.rb', line 67 def increment_counter(counter_path, by) (@drivers || []).each { |d| d.increment_counter(counter_path, by) } nil end |
.instrument(block_name, &blk) ⇒ Object
Runs a given block within a cascade of ‘instrument` blocks of all the added drivers.
Measurometer.instrument('do_foo') { compute! }
unfolds to
Appsignal.instrument('do_foo') do
Statsd.timing('do_foo') do
compute!
end
end
A driver must be reentrant and thread-safe - it should be possible to have multiple ‘instrument` calls open from different threads at the same time. The driver must support the same interface as the Measurometer class itself, minus the `drivers` and `instrument_instance_method` methods.
43 44 45 46 47 48 49 50 |
# File 'lib/measurometer.rb', line 43 def instrument(block_name, &blk) return yield unless @drivers && @drivers.any? # The block wrapping business is not free @drivers.inject(blk) { |outer_block, driver| -> { driver.instrument(block_name, &outer_block) } }.call end |
.instrument_instance_method(target_class, instance_method_name_to_instrument, path_prefix) ⇒ Object
Wrap an anonymous module around an instance method in the given class to have it instrumented automatically. The name of the measurement will be interpolated as:
"#{prefix}.#{rightmost_class_constant_name}.#{instance_method_name}"
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/measurometer.rb', line 81 def instrument_instance_method(target_class, instance_method_name_to_instrument, path_prefix) short_class_name = target_class.to_s.split('::').last instrumentation_name = [path_prefix, short_class_name, instance_method_name_to_instrument].join('.') instrumenter_module = Module.new do define_method(instance_method_name_to_instrument) do |*any| ::FormatParser::Measurometer.instrument(instrumentation_name) { super(*any) } end end target_class.prepend(instrumenter_module) end |