Permalink
Browse files

Log REE metrics when available

  • Loading branch information...
1 parent bf0a15c commit b5957aa4cd21d45134dfd82aae25ac3f188ae74c @brynary brynary committed Aug 25, 2009
View
@@ -1,18 +1,34 @@
-require "benchmark"
+module Oink
+ autoload :Formatter, "oink/formatter"
+ autoload :Log, "oink/log"
+ autoload :MethodTracker, "oink/method_tracker"
+ autoload :Metrics, "oink/metrics"
+ autoload :Middleware, "oink/middleware"
-require "oink/middleware"
-require "oink/memory_usage"
-require "oink/measure"
-require "oink/broadcaster"
-require "oink/rails/sql_extensions"
-require "oink/rails/active_record_extensions"
-require "oink/rails/cache_extensions"
-require "oink/log"
+ def self.measure(name, &block)
+ result = nil
-module Oink
+ tms = Benchmark.measure do
+ result = block.call
+ end
+
+ metrics(name).each { |metric| metric.add_time(tms) }
+ return result
+ end
+
+ def self.incr(name)
+ metrics(name).each(&:incr)
+ end
+
+ def self.metrics(name)
+ active_logs.map { |log| log.metric(name) }.compact
+ end
- def self.broadcaster
- Broadcaster.new(active_logs)
+ def self.with_log(log)
+ active_logs.push(log)
+ result = yield
+ active_logs.pop
+ return result
end
def self.active_logs
@@ -1,18 +0,0 @@
-module Oink
-
- class Broadcaster
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
- include Measure
-
- def initialize(receivers = [])
- @receivers = receivers
- end
-
- def method_missing(method_name, *args, &block)
- @receivers.map do |receiver|
- receiver.__send__(method_name, *args, &block)
- end
- end
- end
-
-end
View
@@ -0,0 +1,24 @@
+module Oink
+ module Formatter
+ def self.format_value(value)
+ case value
+ when nil
+ "-"
+ when Float
+ "%.2f" % value
+ when Time
+ value.strftime("%T")
+ when String
+ quote(value)
+ else
+ value.to_s
+ end
+ end
+
+ def self.quote(value)
+ '"' +
+ String(value).gsub('"', '"' * 2) +
+ '"'
+ end
+ end
+end
View
@@ -1,112 +1,78 @@
+require "benchmark"
+
module Oink
class Log
- include Measure
- def initialize(fields, logger)
- @values = {}
+ def initialize(logger, extra_metadata = [])
@logger = logger
- @fields = default_fields + fields.map { |f| f.to_s }
-
- @logger.info date_header
- @logger.info fields_header
+ @metadata = %w[transaction date time] + extra_metadata
+ Metrics::Extensions.add_to(self)
+ write_headers
end
- def []=(key, value)
- @values[key.to_s] = value
+ def write_headers
+ write_header "Start-Date", Time.now.utc.strftime("%F %T")
+ write_header "Fields", (@metadata + metrics.map(&:field_names)).join(" ")
end
- def [](key)
- @values[key.to_s]
+ def write_header(name, value)
+ @logger.info "# #{name}: #{value}"
end
- def incr(key)
- @values[key.to_s] ||= 0
- @values[key.to_s] += 1
+ def reset
+ @values = {
+ :transaction => generate_transaction_id,
+ :date => Time.now.utc.to_date,
+ :time => Time.now.utc
+ }
end
- def transaction(&block)
- self[:transaction] = generate_transaction_id
- self[:date] = Date.new(Time.now.utc.year, Time.now.utc.month, Time.now.utc.day)
- self[:time] = Time.now.utc
- Oink.active_logs.push(self)
- measure(&block)
- Oink.active_logs.pop
- @logger.info log_line
- @values = {}
+ def add(metric)
+ @metrics ||= {}
+ @metrics[metric.name] = metric
end
- def measure(prefix = nil, &block)
- result = nil
-
- tms = Benchmark.measure do
- result = block.call
- end
-
- add_time(prefix, tms)
-
- return result
+ def metric(name)
+ @metrics[name]
end
- def add_time(prefix, tms)
- prefix = prefix.to_s + "_" if prefix
+ def []=(key, value)
+ @values[key.to_sym] = value
+ end
- self[prefix.to_s + "usr_time"] ||= 0.0
- self[prefix.to_s + "usr_time"] += tms.utime * 1_000
+ def transaction(&block)
+ reset
- self[prefix.to_s + "sys_time"] ||= 0.0
- self[prefix.to_s + "sys_time"] += tms.stime * 1_000
+ metrics.each(&:start)
+ result = Oink.with_log(self, &block)
+ metrics.each(&:stop)
- self[prefix.to_s + "real_time"] ||= 0.0
- self[prefix.to_s + "real_time"] += tms.real * 1_000
+ @logger.info log_line
+ return result
end
protected
- def default_fields
- %w[transaction date time usr_time sys_time real_time]
- end
-
- def date_header
- "# Start-Date: " + Time.now.utc.strftime("%F %T")
- end
-
- def fields_header
- "# Fields: " + @fields.join(" ")
+ def metrics
+ @metrics.values.sort_by { |m| m.name.to_s }
end
def log_line
- old_line
- end
-
- def old_line
- @fields.map do |field|
- format_value(@values[field])
+ (field_values + metric_values).map do |value|
+ Formatter.format_value(value)
end.join(" ")
end
- def generate_transaction_id
- "#{Time.now.to_i}-#{ActiveSupport::SecureRandom.hex(10)}"
+ def field_values
+ @metadata.map { |field| @values[field.to_sym] }
end
- def format_value(value)
- case value
- when nil
- "-"
- when Float
- "%.2f" % value
- when Time
- value.strftime("%T")
- when String
- quote(value)
- else
- value.to_s
- end
+ def metric_values
+ metrics.map(&:values).flatten
end
- def quote(value)
- '"' +
- String(value).gsub('"', '"' * 2) +
- '"'
+ def generate_transaction_id
+ "#{Time.now.to_i}-#{ActiveSupport::SecureRandom.hex(10)}"
end
end
View
@@ -1,15 +0,0 @@
-module Oink
- module Measure
- def measure(prefix = nil, &block)
- result = nil
-
- tms = Benchmark.measure do
- result = block.call
- end
-
- add_time(prefix, tms)
-
- return result
- end
- end
-end
@@ -1,7 +0,0 @@
-module Oink
- class MemoryUsage
- def self.kilobytes
- `ps -o rss= -p #{$$}`.to_i
- end
- end
-end
@@ -0,0 +1,26 @@
+module Oink
+ module MethodTracker
+
+ def add_method_timer(timer, method_name)
+ class_eval <<-SRC, __FILE__, __LINE__
+ def #{method_name}_with_stats_timer(*args, &block)
+ Oink.measure(#{timer.inspect}) do
+ #{method_name}_without_stats_timer(*args, &block)
+ end
+ end
+ alias_method_chain #{method_name.inspect}, :stats_timer
+ SRC
+ end
+
+ def add_method_incr(incr_name, method_name)
+ class_eval <<-SRC, __FILE__, __LINE__
+ def #{method_name}_with_stats_incr_#{incr_name}(*args, &block)
+ Oink.incr(#{incr_name.inspect})
+ #{method_name}_without_stats_incr_#{incr_name}(*args, &block)
+ end
+ alias_method_chain #{method_name.inspect}, :stats_incr_#{incr_name}
+ SRC
+ end
+
+ end
+end
View
@@ -0,0 +1,11 @@
+module Oink
+ module Metrics
+ autoload :Change, "oink/metrics/change"
+ autoload :Counter, "oink/metrics/counter"
+ autoload :Extensions, "oink/metrics/extensions"
+ autoload :Global, "oink/metrics/global"
+ autoload :GlobalTimer, "oink/metrics/global_timer"
+ autoload :Metric, "oink/metrics/metric"
+ autoload :Timer, "oink/metrics/timer"
+ end
+end
@@ -0,0 +1,35 @@
+module Oink
+ module Metrics
+
+ class Change < Metric
+
+ def initialize(name, metric)
+ @name = name
+ @metric = metric
+ end
+
+ def start
+ @initial = @metric.values
+ end
+
+ def stop
+ @final = @metric.values
+ end
+
+ def field_names
+ @metric.field_names
+ end
+
+ def values
+ result = []
+
+ @final.each_with_index do |value, i|
+ result << value - @initial[i]
+ end
+
+ result
+ end
+
+ end
+ end
+end
@@ -0,0 +1,22 @@
+module Oink
+ module Metrics
+
+ class Counter < Metric
+
+ def start
+ @count = nil
+ end
+
+ def incr
+ @count ||= 0
+ @count += 1
+ end
+
+ def values
+ [@count]
+ end
+
+ end
+
+ end
+end
@@ -0,0 +1,18 @@
+module Oink
+ module Metrics
+ module Extensions
+ autoload :ActiveRecord, "oink/metrics/extensions/active_record"
+ autoload :GC, "oink/metrics/extensions/garbage_collection"
+ autoload :Memcached, "oink/metrics/extensions/memcached"
+ autoload :Memory, "oink/metrics/extensions/memory"
+ autoload :Objects, "oink/metrics/extensions/objects"
+ autoload :Time, "oink/metrics/extensions/time"
+
+ def self.add_to(log)
+ [ActiveRecord, GC, Memcached, Memory, Objects, Time].each do |metric_module|
+ metric_module.add_to(log)
+ end
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit b5957aa

Please sign in to comment.