Class: PassengerMonitor::Monitor

Inherits:
Object
  • Object
show all
Defined in:
lib/passenger_monitor/monitor.rb

Constant Summary collapse

DEFAULT_MEMORY_LIMIT =

Default allowed memory limit for a passenger worker (MB)

150
DEFAULT_LOG_FILE =

Default log file name

'passenger_monitoring.log'
DEFAULT_WAIT_TIME =

default waiting time after graceful kill attempt to kill process forcefully

10
DEFAULT_PROCESS_NAME_REGEX =

Passenger Process Name Regex

/Passenger RubyApp:/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ Monitor

Sets memory limit, log file, wait time, process name regex and logger



29
30
31
32
33
34
35
# File 'lib/passenger_monitor/monitor.rb', line 29

def initialize(params = {})
  @memory_limit = fetch_memory_limit(params)
  @log_file = fetch_log_file(params)
  @wait_time = fetch_wait_time(params)
  @process_name_regex = fetch_process_name_regex(params)
  @logger = Logger.new(@log_file)
end

Class Method Details

.run(config = {}) ⇒ Object

Initialize the service and apply a check on all passenger processes given configurations (defaults to ‘{}`)

Parameters:

config

Hash which includes the configurations keys i.e.

1. :memory_limit - allowed memory limit for a passenger worker
2. :log_file - the name of the log file
3. :wait_time - the time to wait to kill the worker forcefully
4. :process_name_regex - regex for the passenger worker of the application


23
24
25
# File 'lib/passenger_monitor/monitor.rb', line 23

def self.run(config = {})
  new(config).check
end

Instance Method Details

#checkObject

Checks memory of all the passenger processes and for bloadted workers it creates thread for each to kill it.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/passenger_monitor/monitor.rb', line 40

def check
  @logger.info 'Checking bloated Passenger workers'

  threads = []

  passenger_workers_details.each_line do |line|
    next unless (line =~ @process_name_regex)

    pid, memory_usage =  extract_stats(line)

    # If a given passenger process is bloated try to
    # kill it gracefully and if it fails, force killing it
    if bloated?(pid, memory_usage)
      threads << Thread.new { self.handle_bloated_process(pid) }
    end
  end

  threads.map(&:join)
  @logger.info 'Finished checking for bloated Passenger workers'
end

#handle_bloated_process(pid) ⇒ Object

Handles bloated processes:

1. Kill it gracefully
2. Wait for the given time
3. if it still exists then kill it forcefully.

Parameters:

pid

Process ID.



71
72
73
74
75
# File 'lib/passenger_monitor/monitor.rb', line 71

def handle_bloated_process(pid)
  kill(pid)
  wait
  kill!(pid) if process_running?(pid)
end