ifad-munin-plugins-rails 0.2.13

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in munin-plugins-rails.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,16 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ifad-munin-plugins-rails (0.2.12)
5
+ request-log-analyzer (~> 1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ request-log-analyzer (1.12.8)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ ifad-munin-plugins-rails!
data/README.rdoc ADDED
@@ -0,0 +1,77 @@
1
+ = Munin-Rails-Plugins
2
+ Collection of Concise Munin plugins for Rails server environments.
3
+ This will make monitoring your rails app a piece of cake.
4
+
5
+ This project contains munin plugins that not only work in munin, but are also concise (see references).
6
+ Most things in this repository rely heavily on the request-log-analyzer gem.
7
+ The project has recenly been converted into a gem. If you are looking for the loose scripts, please checkout: https://github.com/barttenbrinke/munin-plugins-rails/tree/master/munin.
8
+
9
+ == What's in the box?
10
+ * passenger_memory_stats - Munin plugin to monitor the memory usage of passenger application servers.
11
+ * pasenger_queue - Montoring of passenger queue lenth.
12
+ * passenger_status - Running, active and maximum number of passenger instances as well as sessions.
13
+ * rails_database_time - Min, avg, max of database times.
14
+ * rails_request_duration - Min, avg, max of the total request durations.
15
+ * rails_request_error - Application errors and process blocker counters.
16
+ * rails_requests - Get, put, post and delete requests.
17
+ * rails_view_render_time - Min, avg and max view render times.
18
+
19
+ For screenshots, head over to: http://barttenbrinke.github.com/munin-plugins-rails/
20
+
21
+ == Installation
22
+ Installing should be as easy as
23
+
24
+ $ gem install munin-plugins-rails
25
+
26
+ After that you have two options.
27
+ You can add the passenger plugins that will monitor the server as a whole by running:
28
+ $ sudo request-log-analyzer-munin install
29
+
30
+ This will create the necessary symlinks in /etc/munin/plugins and create reasonable configurations in /etc/munin/plugin-conf.d/*
31
+
32
+ * munin_passenger_memory_stats
33
+ * munin_passenger_queue
34
+ * munin_passenger_status
35
+
36
+ Which you can customize as needed. Please note that passenger-memory-status currently only works on Linux (http://bit.ly/krKO2x).
37
+
38
+ The other option is to add a specific application's logfile. To do this, run:
39
+
40
+ $ sudo request-log-analyzer-munin add <app_name> <path_to_log_file>
41
+
42
+ * app_name: this will be the prefix for the graphs and the munin plugins so it should be a valid identifier (/[A-Za-z0-9_]*/).
43
+ * path_to_log_file: this is the path to the log file against which request-log-analyzer will run
44
+
45
+ After running this command you'll have appropriate symlinks in /etc/munin/plugins and a set of configuration files in /etc/munin/plugin-conf.d:
46
+
47
+ * app_name_munin_rails_database_time
48
+ * app_name_munin_rails_request_duration
49
+ * app_name_munin_rails_request_error
50
+ * app_name_munin_rails_requests
51
+ * app_name_munin_rails_view_render_time
52
+
53
+ For more detailed information, see the documentation embedded in the plugins.
54
+ Remember to restart munin-node.
55
+
56
+ $ sudo /etc/init.d/munin-node restart
57
+
58
+ == Troubleshooting
59
+ * Specify the format of your logfile in the munin conf (i.e: <tt>env.log_format rails3</tt>).
60
+ * <tt>sudo gem install request-log-analyzer</tt>
61
+ * Check if the paths in the plugin configuration are correct.
62
+ * Use munin-run to test the plugin with the <tt>--debug</tt> option.
63
+ * Make sure the specified user is allowed to write to <tt>/tmp</tt> and read your rails logfile.
64
+
65
+ If you encounter performance problems with your app, please take a look at the request-log-analyzer wiki on
66
+ examples on how to drill down to the core of your problem. If you want to hire an expert, please visit us at
67
+ http://railsdoctors.com or mail me at: bart@railsdoctors.com
68
+
69
+ Happy monitoring!
70
+
71
+ == Additional information
72
+ * Railsdoctors: http://railsdoctors.com
73
+ * Request-log-analzer: http://github.com/wvanbergen/request-log-analyzer/
74
+ * Screenshots http://barttenbrinke.github.com/munin-plugins-rails/
75
+ * Munin: http://munin.projects.linpro.no/wiki/ConcisePlugins
76
+ * Munin Plugin Starter http://www.packtpub.com/munin-plugin-starter/book
77
+ * License: MIT
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.12
@@ -0,0 +1,30 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
5
+
6
+ require 'munin-plugins-rails'
7
+
8
+ if ARGV.length > 0
9
+ Munin::Command.new.run(ARGV)
10
+ else
11
+ puts "Request-log-analyzer-munin, by Andrew Eberbach & Bart ten Brinke - version 0.2.10"
12
+ puts
13
+ puts "This gem automatates munin-plugin configurations for monitoring of rails apps using"
14
+ puts "the request-log-analyzer gem"
15
+ puts
16
+ puts "Usage: request-log-analyzer-munin [install|appname] <OPTIONS>"
17
+ puts
18
+ puts
19
+ puts "To install passenger plugins:"
20
+ puts " request-log-analyzer-munin install"
21
+ puts
22
+ puts "To install railsplugins:"
23
+ puts " request-log-analyzer-munin <app-name> <log-file>"
24
+ puts
25
+ puts "Examples:"
26
+ puts " request-log-analyzer-munin install"
27
+ puts " request-log-analyzer-munin MyAwesomeApp /srv/my_app/current/log/production.log"
28
+ puts
29
+ exit(0)
30
+ end
@@ -0,0 +1,81 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+ module Munin
4
+ class Command
5
+ def run(args)
6
+ if args.first == "install"
7
+ install_passenger_plugins
8
+ elsif args.first == "add"
9
+ args.shift
10
+ install_application(args)
11
+ end
12
+ end
13
+ PASSENGER_PLUGINS = %W{munin_passenger_memory_stats munin_passenger_queue munin_passenger_status}
14
+ RAILS_PLUGINS = %W{munin_rails_database_time munin_rails_request_duration munin_rails_request_error munin_rails_requests munin_rails_view_render_time}
15
+
16
+ PASSENGER_PLUGIN_CONFIG = <<-DATA
17
+ [<%= plugin_target_name %>]
18
+ user root
19
+ command <%= ruby_path %> %c
20
+ env.passenger_status passenger-status
21
+ env.passenger_memory_stats passenger-memory-stats
22
+ env.graph_category <%= graph_category %>
23
+ DATA
24
+
25
+ RAILS_PLUGIN_CONFIG = <<-DATA
26
+ [<%= plugin_target_name %>]
27
+ env.log_file <%= options[:log_file] %>
28
+ user root
29
+ command <%= ruby_path %> %c
30
+ env.request_log_analyzer request-log-analyzer
31
+ env.graph_category <%= graph_category %>
32
+ DATA
33
+
34
+ PASSENGER_CATEGORY = "Passenger"
35
+
36
+ def install_application(args)
37
+ app_name = args.shift
38
+ log_file = args.shift
39
+ ruby_path = "/usr/bin/env GEM_PATH=#{`echo $GEM_PATH`[0...-1]} GEM_HOME=#{`echo $GEM_HOME`[0...-1]} PATH=#{`echo $PATH`[0...-1]} ruby"
40
+ RAILS_PLUGINS.each do |plugin|
41
+ plugin_target_name = [app_name, plugin].join("_")
42
+ add_plugin(plugin, plugin_target_name)
43
+ add_plugin_config(plugin_target_name, app_name, ruby_path, RAILS_PLUGIN_CONFIG, :log_file => log_file)
44
+ end
45
+ end
46
+
47
+ def install_passenger_plugins
48
+ ruby_path = "/usr/bin/env GEM_PATH=#{`echo $GEM_PATH`[0...-1]} GEM_HOME=#{`echo $GEM_HOME`[0...-1]} PATH=#{`echo $PATH`[0...-1]} ruby"
49
+ PASSENGER_PLUGINS.each do |plugin|
50
+ add_plugin(plugin, plugin)
51
+ add_plugin_config(plugin, PASSENGER_CATEGORY, ruby_path, PASSENGER_PLUGIN_CONFIG)
52
+ end
53
+ end
54
+
55
+ def add_plugin_config(plugin_target_name, graph_category, ruby_path, config_template, options = {})
56
+ FileUtils.mkdir_p(munin_plugin_config_path)
57
+ template = ERB.new config_template
58
+ File.open(File.join(munin_plugin_config_path, plugin_target_name), "w+") do |file|
59
+ file << template.result(binding)
60
+ end
61
+ end
62
+
63
+ def add_plugin(plugin_file, plugin_target_name = nil)
64
+ FileUtils.mkdir_p(munin_plugins_path)
65
+ plugin_target_name ||= plugin_file
66
+ `ln -nsf "#{File.join(munin_dir, plugin_file)}" "#{munin_plugins_path}/#{plugin_target_name}"`
67
+ end
68
+
69
+ def munin_plugins_path
70
+ "/etc/munin/plugins"
71
+ end
72
+
73
+ def munin_plugin_config_path
74
+ "/etc/munin/plugin-conf.d"
75
+ end
76
+
77
+ def munin_dir
78
+ File.join(File.dirname(__FILE__), "..", "..", "munin")
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,44 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class PassengerMemoryStats < RequestLogAnalyzerPlugin
5
+ def ensure_configuration
6
+ require_passenger_gem
7
+ require_passenger_memory_stats
8
+
9
+ super
10
+ end
11
+
12
+ def config
13
+ memory_info = open('/proc/meminfo', 'r') do |lines|
14
+ lines.inject({}) do |h, line|
15
+ matched = line.match(/^([\w_\(\)]+):\s+(\d+)/)
16
+ h[matched[1].to_sym] = matched[2].to_i * 1024
17
+ h
18
+ end
19
+ end
20
+ upper_limit = memory_info[:MemTotal]
21
+ puts <<-CONFIG
22
+ graph_category #{graph_category}
23
+ graph_title Passenger memory stats
24
+ graph_vlabel Bytes
25
+ graph_args --base 1000 -l 0 --upper-limit #{upper_limit}
26
+ graph_info The memory used by passenger instances on this application server
27
+
28
+ memory.label memory
29
+ CONFIG
30
+ exit 0
31
+ end
32
+
33
+ # Collect the data
34
+ # <tt>debug</tt> Show debug information
35
+ def run
36
+ stats = run_command(passenger_memory_stats, debug)
37
+
38
+ #### Total private dirty RSS: 81.81 MB
39
+ stats =~ /RSS:\s*([\d\.]+)\s*MB\Z/m
40
+ memory = ($1.to_f * 1024 * 1024).to_i
41
+ puts "memory.value #{memory}"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class PassengerQueue < RequestLogAnalyzerPlugin
5
+ def ensure_configuration
6
+ require_passenger_status
7
+ super
8
+ end
9
+
10
+ def config
11
+ puts <<-CONFIG
12
+ graph_category #{graph_category}
13
+ graph_title Passenger queue
14
+ graph_vlabel count
15
+ graph_args --base 1000 -l 0
16
+ graph_info The amount of requests waiting on global queue
17
+
18
+ requests.label requests
19
+ CONFIG
20
+ exit 0
21
+ end
22
+
23
+ def run
24
+ status = run_command(passenger_status, debug)
25
+ status =~ /Waiting on global queue:\s+(\d+)/
26
+ puts "requests.value #{$1}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class PassengerStatus < RequestLogAnalyzerPlugin
5
+ def ensure_configuration
6
+ require_passenger_status
7
+ super
8
+ end
9
+
10
+ def config
11
+ status = `#{passenger_status}`
12
+
13
+ status =~ /max\s+=\s+(\d+)/
14
+ upper_limit = $1 || 150
15
+
16
+ puts <<-CONFIG
17
+ graph_category #{graph_category}
18
+ graph_title Passenger status
19
+ graph_vlabel count
20
+ graph_args --base 1000 -l 0 --upper-limit #{upper_limit}
21
+ graph_info The amount of active passengers on this application server - railsdoctors.com
22
+
23
+ sessions.label sessions
24
+ max.label max processes
25
+ running.label running processes
26
+ active.label active processes
27
+ CONFIG
28
+ exit 0
29
+ end
30
+
31
+ def run
32
+ status = run_command(passenger_status, debug)
33
+
34
+ status =~ /max\s+=\s+(\d+)/
35
+ puts "max.value #{$1}"
36
+
37
+ status =~ /count\s+=\s+(\d+)/
38
+ puts "running.value #{$1}"
39
+
40
+ status =~ /active\s+=\s+(\d+)/
41
+ puts "active.value #{$1}"
42
+
43
+ total_sessions = 0
44
+ status.scan(/Sessions: (\d+)/).flatten.each { |count| total_sessions += count.to_i }
45
+ puts "sessions.value #{total_sessions}"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RailsDatabaseTime < RailsPlugin
5
+ def config
6
+ puts <<-CONFIG
7
+ graph_category #{graph_category}
8
+ graph_title Database time
9
+ graph_vlabel Seconds
10
+ graph_args --base 1000 -l 0
11
+ graph_info The minimum, maximum and average database times - railsdoctors.com
12
+
13
+ min.label min
14
+ max.label max
15
+ average.label avg
16
+ CONFIG
17
+ exit 0
18
+ end
19
+
20
+ # Gather information
21
+ def run
22
+ ensure_log_file
23
+
24
+ # Initialize values
25
+ max_value = 0
26
+ min_value = 1.0/0.0
27
+ cumulative = 0
28
+ hits = 0
29
+
30
+ rla = parse_request_log_analyzer_data
31
+
32
+ if rla && rla["Database time"]
33
+ rla["Database time"].each do |item|
34
+ max_value = item[1][:max] if item[1][:max] > max_value
35
+ min_value = item[1][:min] if item[1][:min] < min_value
36
+ hits += item[1][:hits]
37
+ cumulative += item[1][:sum]
38
+ end
39
+ else
40
+ hits = 1
41
+ min_value = 0
42
+ end
43
+
44
+ # Report in seconds
45
+ puts "max.value #{max_value}"
46
+ puts "min.value #{min_value}"
47
+ puts "average.value #{cumulative / hits.to_f}"
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,49 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RailsRequestDuration < RailsPlugin
5
+ def config
6
+ puts <<-CONFIG
7
+ graph_category #{graph_category}
8
+ graph_title Request time
9
+ graph_vlabel Seconds
10
+ graph_args --base 1000 -l 0
11
+ graph_info The minimum, maximum and average request times - railsdoctors.com
12
+
13
+ min.label min
14
+ max.label max
15
+ average.label avg
16
+ CONFIG
17
+ exit 0
18
+ end
19
+
20
+ # Gather information
21
+ def run
22
+ ensure_log_file
23
+
24
+ # Initialize values
25
+ max_value = 0
26
+ min_value = 1.0/0.0
27
+ cumulative = 0
28
+ hits = 0
29
+
30
+ rla = parse_request_log_analyzer_data
31
+
32
+ if rla && rla["Request duration"]
33
+ rla["Request duration"].each do |item|
34
+ max_value = item[1][:max] if item[1][:max] > max_value
35
+ min_value = item[1][:min] if item[1][:min] < min_value
36
+ hits += item[1][:hits]
37
+ cumulative += item[1][:sum]
38
+ end
39
+ else
40
+ hits = 1
41
+ min_value = 0
42
+ end
43
+
44
+ puts "max.value #{max_value}"
45
+ puts "min.value #{min_value}"
46
+ puts "average.value #{cumulative / hits.to_f}"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,44 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RailsRequestError < RailsPlugin
5
+ def config
6
+ puts <<-CONFIG
7
+ graph_category #{graph_category}
8
+ graph_title Request errors
9
+ graph_vlabel Count
10
+ graph_info The amount of request errors - railsdoctors.com
11
+
12
+ error.label error
13
+ blocker.label blocker
14
+ CONFIG
15
+ exit 0
16
+ end
17
+
18
+ # Gather information
19
+ def run
20
+ ensure_log_file
21
+
22
+ # Initialize values
23
+ error_value = 0
24
+ blocker_value = 0
25
+
26
+ rla = parse_request_log_analyzer_data
27
+
28
+ if rla && rla["Failed requests"]
29
+ rla["Failed requests"].each do |item|
30
+ error_value += item[1]
31
+ end
32
+ end
33
+
34
+ if rla && rla["Process blockers (> 1 sec duration)"]
35
+ rla["Process blockers (> 1 sec duration)"].each do |item|
36
+ blocker_value += item[1]
37
+ end
38
+ end
39
+
40
+ puts "error.value #{error_value}"
41
+ puts "blocker.value #{blocker_value}"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RailsRequests < RailsPlugin
5
+ def config
6
+ puts <<-CONFIG
7
+ graph_category #{graph_category}
8
+ graph_title Processed requests
9
+ graph_vlabel Requests per second
10
+ graph_info The amount of requests processed by this application server - railsdoctors.com
11
+
12
+ get.label get
13
+ get.draw AREA
14
+ post.label post
15
+ post.draw STACK
16
+ put.label put
17
+ put.draw STACK
18
+ delete.label delete
19
+ delete.draw STACK
20
+ CONFIG
21
+ exit 0
22
+ end
23
+
24
+ # Gather information
25
+ def run
26
+ ensure_log_file
27
+
28
+ # Initialize values
29
+ get_value = 0
30
+ post_value = 0
31
+ put_value = 0
32
+ delete_value = 0
33
+
34
+ # Walk through the
35
+ File.open(get_request_log_analyzer_file).each_line{ |line|
36
+ if match = line.match(/^\s+GET\:\s(\d+).*/)
37
+ get_value = match[1].to_i
38
+ elsif match = line.match(/^\s+POST\:\s(\d+).*/)
39
+ post_value = match[1].to_i
40
+ elsif match = line.match(/^\s+PUT\:\s(\d+).*/)
41
+ put_value = match[1].to_i
42
+ elsif match = line.match(/^\s+DELETE\:\s(\d+).*/)
43
+ delete_value = match[1].to_i
44
+ end
45
+ }
46
+
47
+ puts "get.value #{get_value / interval.to_f}"
48
+ puts "post.value #{post_value / interval.to_f}"
49
+ puts "put.value #{put_value / interval.to_f}"
50
+ puts "delete.value #{delete_value / interval.to_f}"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,49 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RailsViewRenderTime < RailsPlugin
5
+ def config
6
+ puts <<-CONFIG
7
+ graph_category #{graph_category}
8
+ graph_title View render times
9
+ graph_vlabel Seconds
10
+ graph_args --base 1000 -l 0
11
+ graph_info The minimum, maximum and average view render times - railsdoctors.com
12
+
13
+ min.label min
14
+ max.label max
15
+ average.label avg
16
+ CONFIG
17
+ exit 0
18
+ end
19
+
20
+ # Gather information
21
+ def run
22
+ ensure_log_file
23
+
24
+ # Initialize values
25
+ max_value = 0
26
+ min_value = 1.0/0.0
27
+ cumulative = 0
28
+ hits = 0
29
+
30
+ rla = parse_request_log_analyzer_data
31
+
32
+ if rla && rla["View rendering time"]
33
+ rla["View rendering time"].each do |item|
34
+ max_value = item[1][:max] if item[1][:max] > max_value
35
+ min_value = item[1][:min] if item[1][:min] < min_value
36
+ hits += item[1][:hits]
37
+ cumulative += item[1][:sum]
38
+ end
39
+ else
40
+ hits = 1
41
+ min_value = 0
42
+ end
43
+
44
+ puts "max.value #{max_value}"
45
+ puts "min.value #{min_value}"
46
+ puts "average.value #{cumulative / hits.to_f}"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,85 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RailsPlugin < RequestLogAnalyzerPlugin
5
+
6
+ attr_accessor :interval
7
+ attr_accessor :number_of_lines
8
+ attr_accessor :log_file
9
+ attr_accessor :log_format
10
+ attr_accessor :after_time
11
+ attr_accessor :floor_time
12
+ attr_accessor :temp_folder
13
+ attr_accessor :temp_prefix
14
+ attr_accessor :temp_file_name
15
+ attr_accessor :request_log_analyzer
16
+
17
+ def handle_arguments(args, environment)
18
+ super
19
+
20
+ self.interval = environment['interval'] ? environment['interval'].to_i : 300
21
+ self.number_of_lines = environment['lines'] || 50000
22
+ self.log_file = environment['log_file'] || args[0]
23
+ self.log_format = environment['log_format'] ? "--format #{environment['log_format']}" : ''
24
+ self.after_time = (Time.now - interval).strftime('%Y%m%d%H%M%S')
25
+ self.floor_time = Time.at((Time.now.to_f / interval).floor * interval)
26
+
27
+ self.temp_folder = '/tmp'
28
+ self.temp_prefix = graph_category == 'App' ? 'rla' : graph_category.downcase
29
+ self.temp_file_name = "#{temp_prefix}_#{floor_time.to_i}.yml"
30
+ self.request_log_analyzer = environment['request_log_analyzer'] || '/usr/bin/request-log-analyzer'
31
+ end
32
+
33
+ def parse_request_log_analyzer_data
34
+ YAML::load_file( get_request_log_analyzer_file )
35
+ end
36
+
37
+ def get_request_log_analyzer_file
38
+ fetch_or_create_yaml_file(log_file, debug)
39
+ end
40
+
41
+ def ensure_configuration
42
+ require_request_log_analyzer_gem
43
+ require_yaml_gem
44
+ require_tail_command
45
+
46
+ super
47
+ end
48
+
49
+ def ensure_log_file
50
+ if log_file == "" || log_file.nil?
51
+ $stderr.puts "Filepath unspecified. Exiting"
52
+ exit 1
53
+ end
54
+ end
55
+
56
+ def fetch_or_create_yaml_file(log_file, debug = false)
57
+ # Clean up any old temp files left in de temp folder
58
+ Dir.new(temp_folder).entries.each do |file_name|
59
+ if match = file_name.match(/^#{temp_prefix}_.*\.yml/)
60
+ if match[0] != temp_file_name
61
+ puts "Removing old cache file: #{file_name}" if debug
62
+ File.delete(temp_folder + "/" + file_name)
63
+ end
64
+ end
65
+ end
66
+
67
+ temp_file = temp_folder + "/" + temp_file_name
68
+
69
+ # Create temp file rla if needed
70
+ unless File.exists?(temp_file)
71
+ puts "Processing the last #{number_of_lines} lines of #{log_file} which are less then #{interval} seconds old." if debug
72
+ status = `tail -n #{number_of_lines} #{log_file} | #{request_log_analyzer} - --after #{after_time} #{log_format} -b --dump #{temp_file}`
73
+
74
+ unless $?.success?
75
+ $stderr.puts "failed executing request-log-analyzer. Is the gem path correct?"
76
+ exit 1
77
+ end
78
+ else
79
+ puts "Processing cached YAML result #{temp_file}" if debug
80
+ end
81
+
82
+ return temp_file
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,117 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+ module Munin
4
+ class RequestLogAnalyzerPlugin
5
+ attr_accessor :graph_category
6
+ attr_accessor :passenger_memory_stats
7
+ attr_accessor :passenger_status
8
+ attr_accessor :debug
9
+ attr_accessor :environment
10
+
11
+ def initialize(args, environment)
12
+ handle_arguments(args, environment)
13
+ ensure_configuration
14
+
15
+ if args[0] == "config"
16
+ config
17
+ elsif args[0] == "autoconf"
18
+ autoconf
19
+ end
20
+ end
21
+
22
+ def handle_arguments(args, environment)
23
+ self.environment = environment
24
+ self.graph_category = environment['graph_category'] || 'App'
25
+
26
+ if args[0] == "debug"
27
+ args.shift
28
+ self.debug = true
29
+ end
30
+ end
31
+
32
+ def require_passenger_gem
33
+ require_gem("passenger", ">=2.0")
34
+ end
35
+
36
+ def run_command(command, debug = false)
37
+ result = `#{command}`
38
+
39
+ unless $?.success?
40
+ $stderr.puts "failed executing #{command}"
41
+ exit 1
42
+ end
43
+
44
+ puts result if debug
45
+
46
+ result
47
+ end
48
+
49
+ def require_request_log_analyzer_gem
50
+ require_gem("request-log-analyzer", ">=1.1.6")
51
+ end
52
+
53
+ def require_yaml_gem
54
+ begin
55
+ require 'yaml'
56
+ rescue Exception => e
57
+ puts "no (yaml not found)"
58
+ exit 1
59
+ end
60
+ end
61
+
62
+ def require_command(command_name)
63
+ status = `#{command_name}`
64
+ unless $?.success?
65
+ puts "no (error when excuting #{command_name})"
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ def require_tail_command
71
+ unless `echo "test" | tail 2>/dev/null`.include?("test")
72
+ puts "no (tail command not found)"
73
+ exit 1
74
+ end
75
+ end
76
+
77
+ def require_passenger_status
78
+ self.passenger_status = environment['passenger_status'] || '/usr/local/bin/passenger-status'
79
+ #to use if you have multiple passenger on the host like phusion passenger standalone
80
+ if environment['apache_pid_file']
81
+ self.passenger_status = "cat #{environment['apache_pid_file']} | xargs -0 #{passenger_status}"
82
+ end
83
+
84
+ require_command(passenger_status)
85
+ end
86
+
87
+ def require_passenger_memory_stats
88
+ self.passenger_memory_stats = environment['passenger_memory_stats'] || '/usr/local/bin/passenger-memory-stats'
89
+
90
+ require_command(passenger_memory_stats)
91
+ end
92
+
93
+ def require_gem(gemname, version = nil)
94
+ begin
95
+ require 'rubygems'
96
+ if version
97
+ gem gemname, version
98
+ else
99
+ gem gemname
100
+ end
101
+ rescue Exception => e
102
+ puts "no (Gem not found: #{e})"
103
+ exit 1
104
+ end
105
+ end
106
+
107
+ def ensure_configuration
108
+
109
+ end
110
+
111
+ def autoconf
112
+ ensure_configuration
113
+ puts "yes"
114
+ exit 0
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,7 @@
1
+ require 'munin/request_log_analyzer_plugin'
2
+ require 'munin/rails_plugin'
3
+ require 'munin/command'
4
+
5
+ Dir.glob(File.join(File.dirname(__FILE__), "munin", "plugins", "*.rb")).each do |file|
6
+ require file
7
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ passenger_memory_stats - Munin plugin to monitor the memory usage of passenger application servers.
6
+ Monitors the memory consumed by passenger instances.
7
+
8
+ =head1 APPLICABLE SYSTEMS
9
+ All systems that have passenger installed.
10
+
11
+ =head1 CONFIGURATION
12
+ The plugin needs to execute passenger-memory-stats.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [passenger_*]
16
+ user root
17
+ command /usr/local/bin/ruby %c
18
+
19
+ Options
20
+ env.passenger_memory_stats '/path/to/passenger-memory-stats' # Path to passenger memory status.
21
+ env.graph_category 'App' # Graph Category. Defaults to App.
22
+
23
+ ln -s /usr/share/munin/plugins/passenger_memory_stats /etc/munin/plugins/passenger_memory_stats
24
+
25
+ =head1 INTERPRETATION
26
+ The plugin shows the memory consumed by passenger instances.
27
+
28
+ =head1 MAGIC MARKERS
29
+ #%# family=auto
30
+ #%# capabilities=autoconf
31
+
32
+ =head1 VERSION
33
+ 1.9.7
34
+
35
+ =head1 BUGS
36
+ None known
37
+
38
+ =head1 AUTHOR
39
+ Ilya Lityuga
40
+ Bart ten Brinke - railsdoctors.com
41
+
42
+ =head1 LICENSE
43
+ MIT
44
+
45
+ POD
46
+ require 'rubygems'
47
+ require 'munin-plugins-rails'
48
+ Munin::PassengerMemoryStats.new(ARGV, ENV).run
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ #coding: utf-8
3
+ pod=<<-POD
4
+
5
+ =head1 NAME
6
+ passenger_queue - Munin plugin to monitor passenger queue.
7
+ Monitors the amount of requests in global queue.
8
+
9
+ =head1 APPLICABLE SYSTEMS
10
+ All systems that have passenger installed.
11
+
12
+ =head1 CONFIGURATION
13
+ The plugin needs to execute passenger-status.
14
+ This configuration section shows the defaults of the plugin:
15
+
16
+ [passenger_*]
17
+ user root
18
+ command /usr/local/bin/ruby %c
19
+
20
+ Options
21
+ env.passenger_status '/path/to/passenger-status' # Path to passenger-status
22
+ env.apache_pid_file '/path/to/apache2.pid' # Path to passenger-status (like /var/run/apache2.pid)
23
+ env.graph_category 'App' # Graph Category. Defaults to App.
24
+
25
+ ln -s /usr/share/munin/plugins/passenger_queue /etc/munin/plugins/passenger_queue
26
+
27
+ =head1 INTERPRETATION
28
+ The plugin shows the current number of requests waiting on global queue.
29
+
30
+ =head1 MAGIC MARKERS
31
+ #%# family=auto
32
+ #%# capabilities=autoconf
33
+
34
+ =head1 VERSION
35
+ 1.9.7
36
+
37
+ =head1 BUGS
38
+ None known
39
+
40
+ =head1 AUTHOR
41
+ Michaël Witrant - http://michael.witrant.com/
42
+ Bart ten Brinke - railsdoctors.com
43
+ Daniel Manges - http://gist.github.com/20319
44
+
45
+ =head1 LICENSE
46
+ MIT
47
+
48
+ POD
49
+ require 'rubygems'
50
+ require 'munin-plugins-rails'
51
+
52
+ Munin::PassengerQueue.new(ARGV, ENV).run
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ passenger_status - Munin plugin to monitor passenger application servers.
6
+ Monitors the amount of sessions and running, active and maximum amount of passenger instances.
7
+
8
+ =head1 APPLICABLE SYSTEMS
9
+ All systems that have passenger installed.
10
+
11
+ =head1 CONFIGURATION
12
+ The plugin needs to execute passenger-status.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [passenger_*]
16
+ user root
17
+ command /usr/local/bin/ruby %c
18
+
19
+ Options
20
+ env.passenger_status '/path/to/passenger-status' # Path to passenger-status
21
+ env.graph_category 'App' # Graph Category. Defaults to App.
22
+ env.apache_pid_file '/var/run/apache2.pid' # Use if you want to monitor multiple installations.
23
+
24
+ ln -s /usr/share/munin/plugins/passenger_status /etc/munin/plugins/passenger_status
25
+
26
+ =head1 INTERPRETATION
27
+ The plugin shows the maximum, active and current number of running passenger instances.
28
+
29
+ =head1 MAGIC MARKERS
30
+ #%# family=auto
31
+ #%# capabilities=autoconf
32
+
33
+ =head1 VERSION
34
+ 1.9.7.1
35
+
36
+ =head1 BUGS
37
+ None known
38
+
39
+ =head1 AUTHOR
40
+ Bart ten Brinke - railsdoctors.com
41
+ Daniel Manges - http://gist.github.com/20319
42
+
43
+ =head1 LICENSE
44
+ MIT
45
+
46
+ POD
47
+ require 'rubygems'
48
+ require 'munin-plugins-rails'
49
+
50
+ Munin::PassengerStatus.new(ARGV, ENV).run
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_database_time - Munin plugin to monitor the minimum, average and maximum database times.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_database_time]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+ log_format rails3
20
+
21
+ Options
22
+ env.lines 50000 # Number of lines to tail
23
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
24
+ env.log_format # request-log-analyzer log format (passed to '--format')
25
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
26
+ env.graph_category 'App' # Graph Category. Defaults to App.
27
+
28
+ ln -s /usr/share/munin/plugins/rails_database_time /etc/munin/plugins/rails_database_time
29
+
30
+ =head1 INTERPRETATION
31
+ Three lines are graphed, showing the minimum, average and maximum database times.
32
+
33
+ =head1 MAGIC MARKERS
34
+ #%# family=auto
35
+ #%# capabilities=autoconf
36
+
37
+ =head1 VERSION
38
+ 1.9.7
39
+
40
+ =head1 BUGS
41
+ None known
42
+
43
+ =head1 AUTHOR
44
+ Bart ten Brinke - railsdoctors.com
45
+
46
+ =head1 LICENSE
47
+ MIT
48
+
49
+ POD
50
+ require 'rubygems'
51
+ require 'munin-plugins-rails'
52
+
53
+ Munin::RailsDatabaseTime.new(ARGV, ENV).run
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_request_duration - Munin plugin to monitor the minimum, average and maximum request duration.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_request_duration]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+ log_format rails3
20
+
21
+ Options
22
+ env.lines 50000 # Number of lines to tail
23
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
24
+ env.log_format # request-log-analyzer log format (passed to '--format')
25
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
26
+ env.graph_category 'App' # Graph Category. Defaults to App.
27
+
28
+ ln -s /usr/share/munin/plugins/rails_request_duration /etc/munin/plugins/rails_request_duration
29
+
30
+ =head1 INTERPRETATION
31
+ Three lines are graphed, showing the minimum, average and maximum request times.
32
+
33
+ =head1 MAGIC MARKERS
34
+ #%# family=auto
35
+ #%# capabilities=autoconf
36
+
37
+ =head1 VERSION
38
+ 1.9.7
39
+
40
+ =head1 BUGS
41
+ None known
42
+
43
+ =head1 AUTHOR
44
+ Bart ten Brinke - railsdoctors.com
45
+
46
+ =head1 LICENSE
47
+ MIT
48
+
49
+ POD
50
+ require 'rubygems'
51
+ require 'munin-plugins-rails'
52
+
53
+ Munin::RailsRequestDuration.new(ARGV, ENV).run
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_request_error - Munin plugin to monitor the amount of errors and process blockers.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_request_error]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+ log_format rails3
20
+
21
+ Options
22
+ env.lines 50000 # Number of lines to tail
23
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
24
+ env.log_format # request-log-analyzer log format (passed to '--format')
25
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
26
+ env.graph_category 'App' # Graph Category. Defaults to App.
27
+
28
+ ln -s /usr/share/munin/plugins/rails_request_error /etc/munin/plugins/rails_request_error
29
+
30
+ =head1 INTERPRETATION
31
+ Two lines are graphed, one showing the amount of errors raised and one showing the amount of process
32
+ blockers. Process blockers are requests that took longer than 1 second to complete.
33
+
34
+ =head1 MAGIC MARKERS
35
+ #%# family=auto
36
+ #%# capabilities=autoconf
37
+
38
+ =head1 VERSION
39
+ 1.9.7
40
+
41
+ =head1 BUGS
42
+ None known
43
+
44
+ =head1 AUTHOR
45
+ Bart ten Brinke - railsdoctors.com
46
+
47
+ =head1 LICENSE
48
+ MIT
49
+
50
+ POD
51
+ require 'rubygems'
52
+ require 'munin-plugins-rails'
53
+
54
+ Munin::RailsRequestError.new(ARGV, ENV).run
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_requests - Munin plugin to monitor the amount of get, put, post and delete requests from a
6
+ rails application log.
7
+
8
+ =head1 APPLICABLE SYSTEMS
9
+ All systems that have a rails application log.
10
+
11
+ =head1 CONFIGURATION
12
+ The request-log-analyzer gem has to be intalled.
13
+ Also the script has to be able to access the rails log file and tail.
14
+ This configuration section shows the defaults of the plugin:
15
+
16
+ [rails_requests]
17
+ env.log_file '/path/to/production.log'
18
+ user www-data
19
+ command /usr/local/bin/ruby %c
20
+ log_format rails3
21
+
22
+ Options
23
+ env.lines 50000 # Number of lines to tail
24
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
25
+ env.log_format # request-log-analyzer log format (passed to '--format')
26
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
27
+ env.graph_category 'App' # Graph Category. Defaults to App.
28
+
29
+ ln -s /usr/share/munin/plugins/rails_requests /etc/munin/plugins/rails_requests
30
+
31
+ =head1 INTERPRETATION
32
+ All HTTP methods are stacked so that the total equals the amount of requests processed per 5 minutes.
33
+
34
+ =head1 MAGIC MARKERS
35
+ #%# family=auto
36
+ #%# capabilities=autoconf
37
+
38
+ =head1 VERSION
39
+ 1.9.7
40
+
41
+ =head1 BUGS
42
+ None known
43
+
44
+ =head1 AUTHOR
45
+ Bart ten Brinke - railsdoctors.com
46
+
47
+ =head1 LICENSE
48
+ MIT
49
+
50
+ POD
51
+ require 'rubygems'
52
+ require 'munin-plugins-rails'
53
+
54
+ Munin::RailsRequests.new(ARGV, ENV).run
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_view_render_time - Munin plugin to monitor the minimum, average and maximum view render times.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_view_render_time]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+ log_format rails3
20
+
21
+ Options
22
+ env.lines 50000 # Number of lines to tail
23
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
24
+ env.log_format # request-log-analyzer log format (passed to '--format')
25
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
26
+ env.graph_category 'App' # Graph Category. Defaults to App.
27
+
28
+ ln -s /usr/share/munin/plugins/rails_view_render_time /etc/munin/plugins/rails_view_render_time
29
+
30
+ =head1 INTERPRETATION
31
+ Three lines are graphed, showing the minimum, average and maximum view render times.
32
+
33
+ =head1 MAGIC MARKERS
34
+ #%# family=auto
35
+ #%# capabilities=autoconf
36
+
37
+ =head1 VERSION
38
+ 1.9.7
39
+
40
+ =head1 BUGS
41
+ None known
42
+
43
+ =head1 AUTHOR
44
+ Bart ten Brinke - railsdoctors.com
45
+
46
+ =head1 LICENSE
47
+ MIT
48
+
49
+ POD
50
+ require 'rubygems'
51
+ require 'munin-plugins-rails'
52
+
53
+ Munin::RailsViewRenderTime.new(ARGV, ENV).run
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = "ifad-munin-plugins-rails"
3
+ gem.version = "0.2.13"
4
+ gem.authors = ["Andrew Eberbach", "Bart ten Brinke", "Marcello Barnaba"]
5
+ gem.email = ["andrew@ebertech.ca", "", "vjt@openssl.it" ]
6
+
7
+ gem.description = "Plugins for Munin that use passenger and Request Log Analyzer"
8
+ gem.summary = gem.description
9
+
10
+ gem.files = `git ls-files`.split($/)
11
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
12
+ gem.require_paths = ["lib"]
13
+
14
+ gem.add_dependency('request-log-analyzer', '~> 1')
15
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ifad-munin-plugins-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.13
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Eberbach
9
+ - Bart ten Brinke
10
+ - Marcello Barnaba
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2013-03-06 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: request-log-analyzer
18
+ requirement: &84285230 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: '1'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *84285230
27
+ description: Plugins for Munin that use passenger and Request Log Analyzer
28
+ email:
29
+ - andrew@ebertech.ca
30
+ - ''
31
+ - vjt@openssl.it
32
+ executables:
33
+ - request-log-analyzer-munin
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - Gemfile.lock
40
+ - README.rdoc
41
+ - Rakefile
42
+ - VERSION
43
+ - bin/request-log-analyzer-munin
44
+ - lib/munin-plugins-rails.rb
45
+ - lib/munin/command.rb
46
+ - lib/munin/plugins/passenger_memory_stats.rb
47
+ - lib/munin/plugins/passenger_queue.rb
48
+ - lib/munin/plugins/passenger_status.rb
49
+ - lib/munin/plugins/rails_database_time.rb
50
+ - lib/munin/plugins/rails_request_duration.rb
51
+ - lib/munin/plugins/rails_request_error.rb
52
+ - lib/munin/plugins/rails_requests.rb
53
+ - lib/munin/plugins/rails_view_render_time.rb
54
+ - lib/munin/rails_plugin.rb
55
+ - lib/munin/request_log_analyzer_plugin.rb
56
+ - munin-plugins-rails.gemspec
57
+ - munin/munin_passenger_memory_stats
58
+ - munin/munin_passenger_queue
59
+ - munin/munin_passenger_status
60
+ - munin/munin_rails_database_time
61
+ - munin/munin_rails_request_duration
62
+ - munin/munin_rails_request_error
63
+ - munin/munin_rails_requests
64
+ - munin/munin_rails_view_render_time
65
+ homepage:
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.10
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Plugins for Munin that use passenger and Request Log Analyzer
89
+ test_files: []