module SemanticLogger::Loggable::ClassMethods

def logger_measure_method(method_name,

0.0005 ms per method call. If `level` is not met
0.009 ms per method call. If `min_duration` is not met
0.044 ms per method call.
Approximate overhead when logging a method call with a metric:

Any valid options that can be passed to measure.
options: [Hash]

The name of the method that should be measured.
method_name: [Symbol]
Parameters:

Measure and log the performance of an instance method.
def logger_measure_method(method_name,
                          min_duration: 0.0,
                          metric: "#{name}/#{method_name}",
                          log_exception: :partial,
                          on_exception_level: nil,
                          message: "##{method_name}",
                          level: :info)
  # unless visibility = Utils.method_visibility(self, method_name)
  #   logger.warn("Unable to measure method: #{name}##{method_name} since it does not exist")
  #   return false
  # end
  index = Levels.index(level)
  logger_measure_module.module_eval(<<~MEASURE_METHOD, __FILE__, __LINE__ + 1)
    def #{method_name}(*args, &block)
      if logger.send(:level_index) <= #{index}
        logger.send(
          :measure_method,
          index:              #{index},
          level:              #{level.inspect},
          message:            #{message.inspect},
          min_duration:       #{min_duration},
          metric:             #{metric.inspect},
          log_exception:      #{log_exception.inspect},
          on_exception_level: #{on_exception_level.inspect}
        ) do
          super(*args, &block)
        end
      else
        super(*args, &block)
      end
    end
  MEASURE_METHOD
  # {"#{visibility} :#{method_name}" unless visibility == :public}
  true
end

def logger_measure_module

Dynamic Module to intercept method calls for measuring purposes.
def logger_measure_module
  if const_defined?(:SemanticLoggerMeasure, _search_ancestors = false)
    const_get(:SemanticLoggerMeasure)
  else
    mod = const_set(:SemanticLoggerMeasure, Module.new)
    prepend mod
    mod
  end
end