Module: Metrics::Rails

Extended by:
SingleForwardable
Defined in:
lib/metrics/rails.rb,
lib/metrics/rails/group.rb,
lib/metrics/rails/worker.rb,
lib/metrics/rails/helpers.rb,
lib/metrics/rails/railtie.rb,
lib/metrics/rails/version.rb,
lib/metrics/rails/aggregator.rb,
lib/metrics/rails/subscribers.rb,
lib/metrics/rails/counter_cache.rb

Defined Under Namespace

Modules: Helpers Classes: Aggregator, CounterCache, Group, Railtie, Worker

Constant Summary collapse

CONFIG_SETTABLE =
%w{api_key email flush_interval prefix source}
FORKING_SERVERS =
[:unicorn, :passenger]
VERSION =
"0.2.0"

Class Method Summary collapse

Class Method Details

.aggregateObject

access to internal aggregator object



44
45
46
# File 'lib/metrics/rails.rb', line 44

def aggregate
  @aggregator_cache ||= Aggregator.new
end

.api_endpoint=(endpoint) ⇒ Object

set custom api endpoint



49
50
51
# File 'lib/metrics/rails.rb', line 49

def api_endpoint=(endpoint)
  @api_endpoint = endpoint
end

.check_configObject

detect / update configuration



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/metrics/rails.rb', line 59

def check_config
  if self.config_file && File.exists?(self.config_file)
    configs = YAML.load_file(config_file)
    if env_specific = configs[::Rails.env]
      settable = CONFIG_SETTABLE & env_specific.keys
      settable.each { |key| self.send("#{key}=", env_specific[key]) }
    end
  end
  self.api_key = ENV['METRICS_API_KEY'] if ENV['METRICS_API_KEY']
  self.email = ENV['METRICS_EMAIL'] if ENV['METRICS_EMAIL']
end

.check_workerObject

check to see if we’ve forked into a process where a worker isn’t running yet, if so start it up!



73
74
75
76
77
78
79
# File 'lib/metrics/rails.rb', line 73

def check_worker
  if @pid != $$
    start_worker
    #aggregate.clear
    #counters.clear
  end
end

.clientObject

access to client instance



54
55
56
# File 'lib/metrics/rails.rb', line 54

def client
  @client ||= prepare_client
end

.countersObject

access to internal counters object



82
83
84
# File 'lib/metrics/rails.rb', line 82

def counters
  @counter_cache ||= CounterCache.new
end

.delete_allObject

remove any accumulated but unsent metrics



87
88
89
90
# File 'lib/metrics/rails.rb', line 87

def delete_all
  aggregate.delete_all
  counters.delete_all
end

.flushObject

send all current data to Metrics



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/metrics/rails.rb', line 93

def flush
  logger.debug "[metrics-rails] flushing #{Process.pid} (#{Time.now}):"
  queue = client.new_queue(:source => qualified_source)
  # thread safety is handled internally for both stores
  counters.flush_to(queue)
  aggregate.flush_to(queue)
  logger.debug queue.queued
  queue.submit unless queue.empty?
rescue Exception => error
  logger.error "[metrics-rails] submission failed permanently, worker exiting: #{error}"
end

.group(prefix) {|group| ... } ⇒ Object

Yields:



105
106
107
108
# File 'lib/metrics/rails.rb', line 105

def group(prefix)
  group = Group.new(prefix)
  yield group
end

.loggerObject



110
111
112
# File 'lib/metrics/rails.rb', line 110

def logger
  @logger ||= ::Rails.logger
end

.qualified_sourceObject

source including process pid



115
116
117
# File 'lib/metrics/rails.rb', line 115

def qualified_source
  "#{source}.#{$$}"
end

.setupObject

run once during Rails startup sequence



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/metrics/rails.rb', line 120

def setup
  check_config
  #return unless self.email && self.api_key
  logger.info "[metrics-rails] starting up with #{app_server}..."
  @pid = $$
  if forking_server?
    install_worker_check
  else
    start_worker # start immediately
  end
end

.sourceObject



132
133
134
# File 'lib/metrics/rails.rb', line 132

def source
  @source ||= Socket.gethostname
end

.source=(src) ⇒ Object

set a custom source



137
138
139
# File 'lib/metrics/rails.rb', line 137

def source=(src)
  @source = src
end

.start_workerObject

start the worker thread, one is needed per process. if this process has been forked from an one with an active worker thread we don’t need to worry about cleanup as only the forking thread is copied.



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/metrics/rails.rb', line 145

def start_worker
  return if @worker # already running
  @pid = $$
  logger.debug "[metrics-rails] >> starting up worker for pid #{@pid}..."
  @worker = Thread.new do
    worker = Worker.new
    worker.run_periodically(self.flush_interval) do
      flush
    end
  end
end