Class: Proceso::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/proceso/middleware.rb

Constant Summary collapse

SUBSCRIPTION =
'proceso.usage'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Middleware

Returns a new instance of Middleware.



35
36
37
38
39
40
# File 'lib/proceso/middleware.rb', line 35

def initialize(app, options = {})
  @app       = app
  @notifier  = ActiveSupport::Notifications
  @pid       = Process.pid
  @config    = ActiveSupport::InheritableOptions.new(options[:config])
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



33
34
35
# File 'lib/proceso/middleware.rb', line 33

def app
  @app
end

#configObject (readonly)

Returns the value of attribute config.



33
34
35
# File 'lib/proceso/middleware.rb', line 33

def config
  @config
end

#notifierObject (readonly)

Returns the value of attribute notifier.



33
34
35
# File 'lib/proceso/middleware.rb', line 33

def notifier
  @notifier
end

#pidObject (readonly)

Returns the value of attribute pid.



33
34
35
# File 'lib/proceso/middleware.rb', line 33

def pid
  @pid
end

Class Method Details

.loggerObject



25
26
27
28
29
# File 'lib/proceso/middleware.rb', line 25

def logger
  @@logger ||= begin
    Rails.configuration.logger || ActiveSupport::Logger.new(STDOUT)
  end
end

.start_instrument!Object



10
11
12
13
14
15
16
17
18
19
# File 'lib/proceso/middleware.rb', line 10

def start_instrument!
  logger.info "[Proceso #{Proceso::VERSION}] Proceso Middleware is activated. (#{Rails.env.to_s} mode)"
  subscribe do |name, start, finish, id, payload|
    mem_used    = (payload[:mem_used].to_f / 1024.0).round(1)
    cpu_used    = payload[:cpu_used].to_f.round(1)
    path        = payload[:request].path_info
    resp_time   = payload[:resp_time]
    logger.debug "[PROCESO] MEM: #{mem_used}KB\tCPU: #{cpu_used}\tRESP: #{resp_time}ms\tPATH: #{path}"
  end
end

.subscribe(&blk) ⇒ Object



21
22
23
# File 'lib/proceso/middleware.rb', line 21

def subscribe(&blk)
  ActiveSupport::Notifications.subscribe(SUBSCRIPTION, &blk)
end

Instance Method Details

#build_process_payloadObject



58
59
60
61
62
63
# File 'lib/proceso/middleware.rb', line 58

def build_process_payload
  mem   = process.mem_size
  cpu   = process.user_cpu_times
  resp  = Time.now.to_i
  [mem, cpu, resp]
end

#calculate_process_times(env, m1, m2, c1, c2, r1, r2) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/proceso/middleware.rb', line 65

def calculate_process_times(env, m1, m2, c1, c2, r1, r2)
  mem_used  = m2 - m1
  cpu_used  = c2 - c2
  resp_time = r2 - r1
  req       = Rack::Request.new(env)
  {
    pid:       process.pid,
    mem_used:  mem_used,
    cpu_used:  cpu_used,
    resp_time: resp_time,
    request:   req
  }
end

#call(env) ⇒ Object



42
43
44
45
46
47
# File 'lib/proceso/middleware.rb', line 42

def call(env)
  return @app.call(env) if path_excluded?(env["PATH_INFO"])
  capture_process_usage(env) do
    @app.call(env)
  end
end

#capture_process_usage(env) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/proceso/middleware.rb', line 49

def capture_process_usage(env)
  mem_1, cpu_1, resp_1 = build_process_payload
  response = yield
  mem_2, cpu_2, resp_2 = build_process_payload
  process_payload = calculate_process_times(env, mem_1, mem_2, cpu_1, cpu_2, resp_1, resp_2)
  notifier.instrument(SUBSCRIPTION, process_payload)
  response
end

#exclusionsObject



83
84
85
# File 'lib/proceso/middleware.rb', line 83

def exclusions
  config.exclusions || []
end

#path_excluded?(path) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/proceso/middleware.rb', line 87

def path_excluded?(path)
  exclusions.any? {|e| path =~ e }
end

#processObject



79
80
81
# File 'lib/proceso/middleware.rb', line 79

def process
  @process ||= Proceso::PID.new(pid)
end