<?xml version="1.0" encoding="UTF-8"?>
<plugin-url>
  <approved type="boolean">true</approved>
  <author>Highgroove Studios</author>
  <cached-tag-list>passenger</cached-tag-list>
  <canonical-name nil="true"></canonical-name>
  <code>class PassengerMemoryStats &lt; Scout::Plugin
  def build_report
    cmd  = option(:passenger_memory_stats_command) || &quot;passenger-memory-stats&quot;
    data = `#{cmd} 2&gt;&amp;1`
    if $?.success?
      stats = parse_data(data)
      report(stats)
      stats.each do |name, total|
        short_name = name.sub(/_total\z/, &quot;&quot;)
        max        = option(&quot;max_#{short_name}&quot;).to_f
        next unless max.nonzero?
        num        = total.to_f
        mem_name   = &quot;#{name}_failure&quot;
        human_name = short_name.capitalize.
                                gsub(/_([a-z])/) { &quot; #{$1.capitalize}&quot;}.
                                gsub(&quot;Vms&quot;, &quot;VMS&quot;)
        if num &gt; max and not memory(mem_name)
          alert &quot;Maximum #{human_name} Exceeded (#{total})&quot;, ''
          remember(mem_name =&gt; true)
        elsif num &lt; max and memory(mem_name)
          alert &quot;Maximum #{human_name} Has Dropped Below Limit (#{total})&quot;, ''
          memory.delete(mem_name)
        else
          remember(mem_name =&gt; memory(mem_name))
        end
      end
    else
      error &quot;Could not get data from command&quot;, &quot;Error:  #{data}&quot;
    end
  end

  private

  def parse_data(data)
    table        = nil
    headers      = nil
    field_format = nil
    stats        = { &quot;apache_processes&quot;        =&gt; 0,
                     &quot;apache_vmsize_total&quot;     =&gt; 0.0,
                     &quot;apache_private_total&quot;    =&gt; 0.0,
                     &quot;nginx_processes&quot;         =&gt; 0,
                     &quot;nginx_vmsize_total&quot;      =&gt; 0.0,
                     &quot;nginx_private_total&quot;     =&gt; 0.0,
                     &quot;passenger_processes&quot;     =&gt; 0,
                     &quot;passenger_vmsize_total&quot;  =&gt; 0.0,
                     &quot;passenger_private_total&quot; =&gt; 0.0 }

    data.each do |line|
      line = line.gsub(/\e\[\d+m/,'')
      if line =~ /^\s*-+\s+(Apache|Passenger|Nginx)\s+processes/
        table        = $1.downcase
        headers      = nil
        field_format = nil
      elsif table and line =~ /^\s*###\s+Processes:\s*(\d+)/
        stats[&quot;#{table}_processes&quot;] = $1
      elsif table and line =~ /^[A-Za-z]/
        headers      = line.scan(/\S+\s*/)
        field_format = headers.map { |h| &quot;A#{h.size - 1}&quot; }.join(&quot;x&quot;).
                               sub(/\d+\z/, &quot;*&quot;)
        headers.map! { |h| h.strip.downcase }
      elsif table and headers and line =~ /^\d/
        fields = Hash[*headers.zip(line.strip.unpack(field_format)).flatten]
        stats[&quot;#{table}_vmsize_total&quot;] += as_mb(fields[&quot;vmsize&quot;])
        stats[&quot;#{table}_private_total&quot;] += as_mb(fields[&quot;private&quot;])
      end
    end

    stats.each_key do |field|
      if field =~ /(?:vmsize|private)_total\z/
        stats[field] = &quot;#{stats[field]} MB&quot;
      end
    end

    stats
  end

  def as_mb(memory_string)
    num = memory_string.to_f
    case memory_string
    when /\bB/i
      num / (1024 * 1024).to_f
    when /\bKB/i
      num / 1024.0
    when /\bGB/i
      num * 1024
    else
      num
    end
  end
end
</code>
  <created-at type="datetime">2008-08-22T08:49:33-07:00</created-at>
  <default-triggers type="yaml" nil="true"></default-triggers>
  <description>&lt;p&gt;Tracks &quot;Phusion Passenger's&quot;:http://www.modrails.com VM size, process count, and the amount of private memory it has squirreled away. You can also elect to be emailed if any of these statistics crosses a line you indicate.  As an added bonus, this plugin also tracks the same statistics for the Apache instance managing Passenger.&lt;/p&gt;
&lt;p&gt;
The passenger-memory-stats program recommends that you run it with super user privileges to gain more information. This plugin is usable without the extra access rights, but you will need to add them if you want the full details.
 &lt;/p&gt;
&lt;p&gt;
Note that *you need to edit the sudoers file on your server to allow the Scout agent to run @passenger-memory-stats@ without a password*. You will need to address this access issue on your server. &quot;Learn how here&quot;:https://scoutapp.com/plugin_urls/82-phusion-passenger-monitor/help_entries/91
 &lt;/p&gt;</description>
  <featured type="boolean">false</featured>
  <id type="integer">82</id>
  <metadata type="yaml">--- |
options:
  passenger_memory_stats_command:
    name: The Passenger Memory Stats Command
    notes: The full path to the passenger-memory-stats command.
    default: /usr/bin/passenger-memory-stats
  max_apache_processes:
    name: Max Apache Processes
    notes: If Apache's process count is larger than this amount, an alert is generated.  Use 0 to disable this check.
    default: 0
  max_apache_vmsize:
    name: Max Apache VMSize (MB)
    notes: If Apache's memory is larger than this amount, an alert is generated.  Use 0 to disable this check.
    default: 2000
  max_apache_private:
    name: Max Apache Private Memory (MB)
    notes: If Apache's private memory is larger than this amount, an alert is generated.  Use 0 to disable this check.
    default: 0
  max_passenger_processes:
    name: Max Passenger Processes
    notes: If Passenger's process count is larger than this amount, an alert is generated.  Use 0 to disable this check.
    default: 0
  max_passenger_vmsize:
    name: Max Passenger VMSize (MB)
    notes: If Passenger's memory is larger than this amount, an alert is generated.  Use 0 to disable this check.
    default: 500
  max_passenger_private:
    name: Max Passenger Private Memory (MB)
    notes: If Passenger's private memory is larger than this amount, an alert is generated.  Use 0 to disable this check.
    default: 0

</metadata>
  <name>Phusion Passenger Monitor</name>
  <plugins-count type="integer">121</plugins-count>
  <rating-avg type="decimal">0.0</rating-avg>
  <rating-count type="integer">0</rating-count>
  <rating-total type="integer">0</rating-total>
  <readme>Passenger Memory Stats
======================

Created by [Highgroove Studios LLC](http://www.highgroove.com)

Compatibility 
-------------

Works on Linux.

Sudo Usage
----------

The passenger-memory-stats program recommends that you run it would super user privileges to gain more information.  This plugin is usable without the extra access rights, but you will need to add them if you want the full details.

It's important to note though that it is not safe for you to transmit your super user password to us.  You will need to address this access issue on your server.

Our recommended procedure to handle this is:

1. Edit the sudoers file on your server to allow the user that runs the scout client listed in your crontab to be able to run passenger-memory-stats without a password
2. Login into Scout and edit your plugin settings to add sudo in front of the command name
</readme>
  <schema type="yaml" nil="true"></schema>
  <scout-version type="integer">2</scout-version>
  <short-description>Tracks Passenger's VM size, process count, and the amount of private memory it has squirreled away. You can also elect to be emailed if any of these statistics crosses a line you indicate.</short-description>
  <tested-platforms>linux</tested-platforms>
  <total-usage-count type="integer">0</total-usage-count>
  <updated-at type="datetime">2010-03-03T21:16:53-08:00</updated-at>
  <url>http://github.com/highgroove/scout-plugins/raw/5bb58ea082496cbbef5f8d1bb0d84a2a82b0297a/passenger_memory_stats/passenger_memory_stats.rb</url>
</plugin-url>
