forked from barttenbrinke/munin-plugins-rails
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rails_request_error
executable file
·169 lines (136 loc) · 4.54 KB
/
rails_request_error
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
#!/usr/bin/env ruby
pod=<<-POD
=head1 NAME
rails_request_error - Munin plugin to monitor the amount of errors and process blockers.
=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_request_error]
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.log_format # request-log-analyzer log format (passed to '--format')
env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
env.graph_category 'App' # Graph Category. Defaults to App.
ln -s /usr/share/munin/plugins/rails_request_error /etc/munin/plugins/rails_request_error
=head1 INTERPRETATION
Two lines are graphed, one showing the amount of errors raised and one showing the amount of process
blockers. Process blockers are requests that took longer than 1 second to complete.
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 VERSION
1.9.7
=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']
LOG_FORMAT = ENV['log_format'] ? "--format #{ENV['log_format']}" : ''
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_PREFIX = GRAPH_CATEGORY == 'App' ? 'rla' : GRAPH_CATEGORY.downcase
TEMP_FILE = "#{TEMP_PREFIX}_#{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"
require "yaml"
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 Request errors
graph_vlabel Count
graph_info The amount of request errors - railsdoctors.com
error.label error
blocker.label blocker
CONFIG
exit 0
end
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(/^#{TEMP_PREFIX}_.*\.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
status = `tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --after #{AFTER_TIME} #{LOG_FORMAT} -b --dump #{temp_file} 2>/dev/null`
unless $?.success?
$stderr.puts "failed executing request-log-analyzer. Is the gem path 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
error_value = 0
blocker_value = 0
# Walk through the
require "yaml"
rla = YAML::load_file( fetch_or_create_yaml_file(log_file, debug) )
if rla && rla["Failed requests"]
rla["Failed requests"].each do |item|
error_value += item[1]
end
end
if rla && rla["Process blockers (> 1 sec duration)"]
rla["Process blockers (> 1 sec duration)"].each do |item|
blocker_value += item[1]
end
end
puts "error.value #{error_value}"
puts "blocker.value #{blocker_value}"
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