forked from barttenbrinke/munin-plugins-rails
-
Notifications
You must be signed in to change notification settings - Fork 1
/
rails_requests
executable file
·173 lines (142 loc) · 4.63 KB
/
rails_requests
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env ruby
pod=<<-POD
=head1 NAME
rails_requests - Munin plugin to monitor the amount of get, put, post and delete requests from a
rails application log.
=head1 APPLICABLE SYSTEMS
All systems that have a rails application log.
=head1 CONFIGURATION
The request-log-analyzer gem has to be intalled.
Also the script has to be able to access the rails log file and tail.
This configuration section shows the defaults of the plugin:
[rails_requests]
env.log_file '/path/to/production.log'
user www-data
command /usr/local/bin/ruby %c
Options
env.lines 50000 # Number of lines to tail
env.interval 300 # Munin interval in seconds (used for graphs and caching)
env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
ln -s /usr/share/munin/plugins/rails_requests /etc/munin/plugins/rails_requests
=head1 INTERPRETATION
All HTTP methods are stacked so that the total equals the amount of requests processed per 5 minutes.
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 VERSION
1.4
=head1 BUGS
None known
=head1 AUTHOR
Bart ten Brinke - railsdoctors.com
=head1 LICENSE
MIT
POD
# Globals
GRAPH_CATEGORY = ENV['graph_category'] || 'App'
INTERVAL = ENV['interval'] ? ENV['interval'].to_i : 300
NUMBER_OF_LINES = ENV['lines'] || 50000
LOG_FILE = ENV['log_file']
AFTER_TIME = (Time.now - INTERVAL).strftime('%Y%m%d%H%M%S')
FLOOR_TIME = Time.at((Time.now.to_f / INTERVAL).floor * INTERVAL)
TEMP_FOLDER = '/tmp'
TEMP_FILE = "rla_#{FLOOR_TIME.to_i}.yml"
REQUEST_LOG_ANALYZER = ENV['request_log_analyzer'] || '/usr/bin/request-log-analyzer'
# Check if we can run this plugin on this system
def autoconf
begin
require 'rubygems'
gem "request-log-analyzer", ">=1.1.6"
rescue Exception => e
puts "no (Gem not found: #{e})"
exit 1
end
unless `echo "test" | tail 2>/dev/null`.include?("test")
puts "no (tail command not found)"
exit 1
end
puts "yes"
exit 0
end
# Uptput the config
def config
puts <<-CONFIG
graph_category #{GRAPH_CATEGORY}
graph_title Processed requests
graph_vlabel Requests per second
graph_info The amount of requests processed by this application server - railsdoctors.com
get.label get
get.draw AREA
post.label post
post.draw STACK
put.label put
put.draw STACK
delete.label delete
delete.draw STACK
CONFIG
exit 0
end
# Fetch or create yaml cache file using request-log-analyzer
def fetch_or_create_yaml_file(log_file, debug = false)
# Clean up any old temp files left in de temp folder
Dir.new(TEMP_FOLDER).entries.each do |file_name|
if match = file_name.match(/^rla_.*\.yml/)
if match[0] != TEMP_FILE
puts "Removing old cache file: #{file_name}" if debug
File.delete(TEMP_FOLDER + "/" + file_name)
end
end
end
temp_file = TEMP_FOLDER + "/" + TEMP_FILE
# Create temp file rla if needed
unless File.exists?(temp_file)
puts "Processing the last #{NUMBER_OF_LINES} lines of #{log_file} which are less then #{INTERVAL} seconds old." if debug
p "tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null"
status = `tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null`
unless $?.success?
$stderr.puts "failed executing request-log-analyzer. Is the path to the binary correct?"
exit 1
end
else
puts "Processing cached YAML result #{temp_file}" if debug
end
return temp_file
end
# Gather information
def run(log_file, debug = false)
if log_file == "" || log_file.nil?
$stderr.puts "Filepath unspecified. Exiting"
exit 1
end
# Initialize values
get_value = 0
post_value = 0
put_value = 0
delete_value = 0
# Walk through the
File.open(fetch_or_create_yaml_file(log_file, debug)).each_line{ |line|
if match = line.match(/^\s+GET\:\s(\d+).*/)
get_value = match[1].to_i
elsif match = line.match(/^\s+POST\:\s(\d+).*/)
post_value = match[1].to_i
elsif match = line.match(/^\s+PUT\:\s(\d+).*/)
put_value = match[1].to_i
elsif match = line.match(/^\s+DELETE\:\s(\d+).*/)
delete_value = match[1].to_i
end
}
puts "get.value #{get_value / INTERVAL.to_f}"
puts "post.value #{post_value / INTERVAL.to_f}"
puts "put.value #{put_value / INTERVAL.to_f}"
puts "delete.value #{delete_value / INTERVAL.to_f}"
end
# Main
if ARGV[0] == "config"
config
elsif ARGV[0] == "autoconf"
autoconf
elsif ARGV[0] == "debug"
run(LOG_FILE || ARGV[1], true)
else
run(LOG_FILE || ARGV[0])
end