Module: UsageTracker

Defined in:
lib/usage_tracker/middleware.rb,
lib/usage_tracker.rb,
lib/usage_tracker/log.rb,
lib/usage_tracker/runner.rb,
lib/usage_tracker/adapter.rb,
lib/usage_tracker/context.rb,
lib/usage_tracker/railtie.rb,
lib/usage_tracker/reactor.rb,
lib/usage_tracker/adapters/couchdb.rb,
lib/usage_tracker/adapters/mongodb.rb

Overview

This middleware extracts some data from the incoming request and sends it to the reactor, that parses and stores it.

Defined Under Namespace

Modules: Adapters, Context, Reactor Classes: Adapter, Error, Log, Middleware, Railtie

Class Method Summary collapse

Class Method Details

.adapterObject



55
56
57
# File 'lib/usage_tracker.rb', line 55

def adapter
  @adapter or raise "Not connected to the database adapter"
end

.connect!Object

Connects to the configured CouchDB and memoizes the CouchRest::Database connection into an instance variable and calls load_views!

Raises RuntimeError if the connection could not be established



65
66
67
68
# File 'lib/usage_tracker.rb', line 65

def connect!
  @adapter = Adapter::new settings
  @database = @adapter.database
end

.databaseObject



51
52
53
# File 'lib/usage_tracker.rb', line 51

def database
  @database or raise "Not connected to the database"
end

.envObject

Memoizes the current environment



14
15
16
# File 'lib/usage_tracker.rb', line 14

def env
  @env ||= ENV['RAILS_ENV'] || ARGV[0] || 'development'
end

.log(message = nil) ⇒ Object



89
90
91
92
# File 'lib/usage_tracker.rb', line 89

def log(message = nil)
  @log ||= Log.new
  message ? @log.info(message) : @log
end

.raise(message) ⇒ Object



94
95
96
97
# File 'lib/usage_tracker.rb', line 94

def raise(message)
  log.error message
  Kernel.raise Error, message
end

.run!Object

Code to run inside EventMachine



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/usage_tracker.rb', line 71

def run! 
  host, port = UsageTracker.settings.host, UsageTracker.settings.port

  unless (1024..65535).include? port.to_i
    raise "Please set a listening port between 1024 and 65535"
  end

  EventMachine.open_datagram_socket host, port, Reactor
  log "Listening on #{host}:#{port} UDP"
  write_pid!
end

.settingsObject

Memoizes settings from the ./config/usage_tracker.yml file, relative from __FILE__ and searches for the “usage_tracker” configuration block. Raises RuntimeError if it cannot find the configuration.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/usage_tracker.rb', line 23

def settings
  @settings ||= begin
    log "Loading #{env} environment"

    rc_file  = Pathname.new('.').join('config', 'usage_tracker.yml')
    settings = YAML.load(rc_file.read)[env] if rc_file.exist?

    if settings.blank?
      raise "Configuration missing for #{env}"
    elsif settings.values_at(*%w(adapter database listen)).any?(&:blank?)
      raise "Incomplete configuration: please set the 'adapter', 'database' and 'listen' keys"
    end

    host, port = settings.delete('listen').split(':')

    if [host, port].any? {|x| x.strip.empty?}
      raise "Please specify where to listen as host:port"
    end

    settings['host'], settings['port'] = host, port.to_i

    settings['log_level'] ||= :warn
    log.level = settings['log_level']

    OpenStruct.new settings
  end
end

.sigexit(sig) ⇒ Object

Setup signal handlers

* INT, TERM: graceful exit
* USR1     : rotate logs


22
23
24
25
# File 'lib/usage_tracker/runner.rb', line 22

def self.sigexit(sig)
  log "Received SIG#{sig}"
  EventMachine.stop_event_loop
end

.write_pid!(pid = $$) ⇒ Object



83
84
85
86
87
# File 'lib/usage_tracker.rb', line 83

def write_pid!(pid = $$)
  dir = Pathname.new('.').join('tmp', 'pids')
  dir = Pathname.new(Dir.tmpdir) unless dir.directory?
  dir.join('usage_tracker.pid').open('w+') {|f| f.write(pid)}
end