Last active
September 25, 2015 01:48
-
-
Save susatadahiro/843281 to your computer and use it in GitHub Desktop.
munin plugins: rails log time(total, view, db) at rails3.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
munin-plugin: rails_response_time | |
# original source: http://blog.tkmr.org/tatsuya/show/420-munin-rails | |
# rails_log_chopper | |
$ ruby ./script/rails_log_monitor.rb -l log/rails_log_monitor.log | |
# munin_plugin | |
$ sudo ln -s /usr/share/munin/plugins/rails_response_time /etc/munin/plugins/avg_response_time | |
$ sudo ln -s /usr/share/munin/plugins/rails_response_time /etc/munin/plugins/max_response_time | |
$ sudo /etc/init.d/munin-node restart |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
check process rails_log with pidfile /home/ubuntu/apps/dtr/shared/pids/rails_log_monitor.pid | |
start program = "/home/ubuntu/apps/dtr/shared/script/rails_log start" with timeout 60 seconds | |
stop program = "/home/ubuntu/apps/dtr/shared/script/rails_log stop" | |
group rails |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# munin plugin to render rails response time graphs | |
# link to /etc/munin/plugins/avg_response_time and /etc/munin/plugins/max_response_time | |
require 'open-uri' | |
PORT = ENV['PORT'] || "8888" | |
def config | |
title = File.basename($0).split('_').map{|s| s.capitalize }.join(' ') | |
upper_limit = "3000" | |
upper_limit = "1000" if title.downcase.match(/^avg/) | |
upper_limit = "3000" if title.downcase.match(/^max/) | |
config=<<__END_CONFIG__ | |
graph_title #{title} | |
graph_vlabel response time [ms] | |
graph_category rails | |
graph_args --lower-limit 0 --upper-limit #{upper_limit} | |
db.label db | |
db.draw AREA | |
view.label view | |
view.draw STACK | |
total.label total | |
total.draw LINE1 | |
__END_CONFIG__ | |
puts config | |
end | |
def get_data(read_only=false) | |
qs = read_only ? '?debug' : '' | |
puts open("http://127.0.0.1:#{PORT}/#{File.basename($0)}#{qs}").read | |
end | |
case ARGV.first | |
when 'config' | |
config | |
when 'debug' | |
get_data(true) | |
else | |
get_data | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# munin plugin to render rails response time graphs | |
# link to /etc/munin/plugins/avg_response_time and /etc/munin/plugins/max_response_time | |
require 'open-uri' | |
PORT = ENV['PORT'] || "8888" | |
def config | |
title = File.basename($0).split('_').map{|s| s.capitalize }.join(' ') | |
upper_limit = "3000" | |
upper_limit = "1000" if title.downcase.match(/^avg/) | |
upper_limit = "3000" if title.downcase.match(/^max/) | |
config=<<__END_CONFIG__ | |
graph_title #{title} | |
graph_vlabel response time [ms] | |
graph_category rails | |
graph_args --lower-limit 0 --upper-limit #{upper_limit} | |
db.label db | |
db.draw AREA | |
view.label view | |
view.draw STACK | |
total.label total | |
total.draw LINE1 | |
__END_CONFIG__ | |
puts config | |
end | |
def get_data(read_only=false) | |
qs = read_only ? '?debug' : '' | |
puts open("http://127.0.0.1:#{PORT}/#{File.basename($0)}#{qs}").read | |
end | |
case ARGV.first | |
when 'config' | |
config | |
when 'debug' | |
get_data(true) | |
else | |
get_data | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
PID_FILE=/home/ubuntu/apps/dtr/shared/pids/rails_log_monitor.pid | |
SH_LOG=/home/ubuntu/apps/dtr/shared/log/rails_log_monitor.log | |
case $1 in | |
start) | |
echo $$ > ${PID_FILE}; | |
exec /usr/local/rvm/bin/rvm-shell 1.9.2 -c "ruby /home/ubuntu/apps/dtr/shared/script/rails_log_monitor.rb -d -e production" >> ${SH_LOG} 2>&1 | |
;; | |
stop) | |
kill `cat ${PID_FILE}` ;; | |
*) | |
echo "usage: rails_log {start|stop}" ;; | |
esac | |
exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# daemon to scrape response times from rails logs | |
# | |
# Completed in 521ms (View: 142, DB: 364) | 200 OK [https://xxx.com/] | |
# | |
require 'rubygems' | |
require 'file/tail' | |
require 'mongrel' | |
require 'yaml' | |
require 'kconv' | |
RAILS_ENV = ENV['RAILS_ENV'] || "production" | |
PORT = ENV['PORT'] || "8888" | |
IGNORE_PATTERNS = %r{heartbeat}.freeze | |
class Accumulator | |
def initialize | |
@values = Array.new() | |
@max = 0 | |
end | |
def add( n ) | |
@values << n | |
@max = n if n > @max | |
end | |
def average(read_only=false) | |
return_value = if @values.length == 0 | |
nil | |
else | |
@values.inject(0) {|sum,value| sum + value } / @values.length | |
end | |
@values = Array.new() unless read_only | |
return_value | |
end | |
def max(read_only=false) | |
return_value = @max | |
@max = 0 unless read_only | |
return_value | |
end | |
def count | |
@values.length | |
end | |
alias_method :length, :count | |
alias_method :size, :count | |
end | |
LOGFILE = File.join(File.dirname(__FILE__), '..', 'log', "#{RAILS_ENV}.log") | |
$response_data = { :total => Accumulator.new(), | |
# :rendering => Accumulator.new(), | |
:view => Accumulator.new(), | |
:db => Accumulator.new() } | |
Thread.abort_on_exception = true | |
logtail = Thread.new do | |
File::Tail::Logfile.tail(LOGFILE) do |line| | |
if line.toutf8 =~ /^Completed/ | |
# STDOUT.puts line | |
line.match(/^Completed .* in ([0-9.]+)ms \(Views: ([0-9.]+)ms \| ActiveRecord: ([0-9.]+)ms\)/) | |
total = $1 | |
view = $2 | |
db = $3 | |
# STDOUT.puts "---" | |
# STDOUT.puts total | |
# STDOUT.puts view | |
# STDOUT.puts db | |
if total and view and db | |
$response_data[:total].add(total.to_f) | |
$response_data[:view].add(view.to_f) | |
$response_data[:db].add(db.to_f) | |
end | |
end | |
end | |
end | |
class ResponseTimeHandler < Mongrel::HttpHandler | |
def initialize(method) | |
@method = method | |
end | |
def process(request, response) | |
response.start(200) do |head,out| | |
debug = Mongrel::HttpRequest.query_parse(request.params["QUERY_STRING"]).has_key? "debug" | |
head["Content-Type"] = "text/plain" | |
output = $response_data.map do |k,v| | |
value = v.send(@method, debug) | |
formatted = value.nil? ? 'U' : sprintf('%.5f', value) | |
"#{k}.value #{formatted}" | |
end.join("\n") | |
output << "\n" | |
out.write output | |
end | |
end | |
end | |
h = Mongrel::HttpServer.new("127.0.0.1", PORT) | |
h.register("/avg_response_time", ResponseTimeHandler.new(:average)) | |
h.register("/max_response_time", ResponseTimeHandler.new(:max)) | |
h.run.join |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# using webrick not mongrel | |
# daemon to scrape response times from rails logs | |
require 'rubygems' | |
require 'file/tail' | |
require 'webrick' | |
require 'yaml' | |
RAILS_ENV = ENV['RAILS_ENV'] || "production" | |
PORT = ENV['PORT'] || "8888" | |
IGNORE_PATTERNS = %r{heartbeat}.freeze | |
#STDOUT.puts "--starting" | |
class Accumulator | |
def initialize | |
@values = Array.new() | |
@max = 0 | |
end | |
def add( n ) | |
@values << n | |
@max = n if n > @max | |
end | |
def average(read_only=false) | |
return_value = if @values.length == 0 | |
nil | |
else | |
@values.inject(0) {|sum,value| sum + value } / @values.length | |
end | |
@values = Array.new() unless read_only | |
return_value | |
end | |
def max(read_only=false) | |
return_value = @max | |
@max = 0 unless read_only | |
return_value | |
end | |
def count | |
@values.length | |
end | |
alias_method :length, :count | |
alias_method :size, :count | |
end | |
#STDOUT.puts "--loggile" | |
LOGFILE = File.join(File.dirname(__FILE__), '..', 'log', "#{RAILS_ENV}.log") | |
#STDOUT.puts LOGFILE | |
$response_data = { :total => Accumulator.new(), | |
# :rendering => Accumulator.new(), | |
:view => Accumulator.new(), | |
:db => Accumulator.new() } | |
#STDOUT.puts "--tailing" | |
Thread.abort_on_exception = true | |
logtail = Thread.new do | |
File::Tail::Logfile.tail(LOGFILE) do |line| | |
line = line.force_encoding('UTF-8') | |
if line =~ /^Completed/ | |
# STDOUT.puts line | |
line.match(/^Completed .* in ([0-9.]+)ms \(Views: ([0-9.]+)ms \| ActiveRecord: ([0-9.]+)ms\)/) | |
total = $1 | |
view = $2 | |
db = $3 | |
if total and view and db | |
$response_data[:total].add(total.to_f) | |
$response_data[:view].add(view.to_f) | |
$response_data[:db].add(db.to_f) | |
end | |
end | |
end | |
end | |
srv = WEBrick::HTTPServer.new({ #:DocumentRoot => '/dev/shm', | |
:BindAddress => '127.0.0.1', | |
:Port => PORT}) | |
srv.mount_proc('/avg_response_time'){|req, res| | |
output = $response_data.map do |k,v| | |
if req.query["debug"] | |
debug = true | |
else | |
debug = false | |
end | |
value = v.send(:average, debug) | |
# value = v.average | |
formatted = value.nil? ? 'U' : sprintf('%.5f', value) | |
"#{k}.value #{formatted}" | |
end.join("\n") | |
output << "\n" | |
res.body = output | |
res.content_length = res.body.size | |
} | |
srv.mount_proc('/max_response_time'){|req, res| | |
output = $response_data.map do |k,v| | |
if req.query["debug"] | |
debug = true | |
else | |
debug = false | |
end | |
value = v.send(:max, debug) | |
formatted = value.nil? ? 'U' : sprintf('%.5f', value) | |
"#{k}.value #{formatted}" | |
end.join("\n") | |
output << "\n" | |
res.body = output | |
res.content_length = res.body.size | |
} | |
Signal.trap(:INT){ srv.shutdown } | |
srv.start |
rails_log_monitor.rb:61:in block (2 levels) in <main>': undefined method
toutf8' for "\n":String (NoMethodError)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
/home/ubuntu/apps/dtr/shared/script/rails_log_monitor.rb:61:in `block (2 levels) in
': invalid byte sequence in US-ASCII (ArgumentError)