0
# Rack adapter to log stats to a Rack application
0
def initialize(app, path='/stats')
0
+ @template = ERB.new(TEMPLATE)
0
- @
server = env['SERVER_SOFTWARE']0
+ @
last_request = Rack::Request.new(env)0
request_started_at = Time.now
0
@requests_finished += 1
0
- @last_request_path = env['PATH_INFO']
0
@last_request_time = Time.now - request_started_at
0
- body << '<h1>Server stats</h1>'
0
- body << "<li>#{@requests} requests</li>"
0
- body << "<li>#{@requests_finished} requests finished</li>"
0
- body << "<li>#{@requests - @requests_finished} errors</li>"
0
- body << "<li>#{Time.now - @start_time} uptime</li>"
0
- body << "<li>Running on #{@server}</li>"
0
- body << '<h2>Last request</h2>'
0
- body << "<li>#{@last_request_path}</li>"
0
- body << "<li>Took #{@last_request_time} sec</li>"
0
- body << '</body></html>'
0
+ body = @template.result(binding)
0
'Content-Type' => 'text/html',
0
'Content-Length' => body.size.to_s
0
+ def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
0
+ from_time = from_time.to_time if from_time.respond_to?(:to_time)
0
+ to_time = to_time.to_time if to_time.respond_to?(:to_time)
0
+ distance_in_minutes = (((to_time - from_time).abs)/60).round
0
+ distance_in_seconds = ((to_time - from_time).abs).round
0
+ case distance_in_minutes
0
+ return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
0
+ case distance_in_seconds
0
+ when 0..4 then 'less than 5 seconds'
0
+ when 5..9 then 'less than 10 seconds'
0
+ when 10..19 then 'less than 20 seconds'
0
+ when 20..39 then 'half a minute'
0
+ when 40..59 then 'less than a minute'
0
+ when 2..44 then "#{distance_in_minutes} minutes"
0
+ when 45..89 then 'about 1 hour'
0
+ when 90..1439 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
0
+ when 1440..2879 then '1 day'
0
+ when 2880..43199 then "#{(distance_in_minutes / 1440).round} days"
0
+ when 43200..86399 then 'about 1 month'
0
+ when 86400..525599 then "#{(distance_in_minutes / 43200).round} months"
0
+ when 525600..1051199 then 'about 1 year'
0
+ else "over #{(distance_in_minutes / 525600).round} years"
0
+# Taken from Rack::ShowException
0
+# adapted from Django <djangoproject.com>
0
+# Copyright (c) 2005, the Lawrence Journal-World
0
+# Used under the modified BSD license:
0
+# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
0
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
0
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
0
+ <meta name="robots" content="NONE,NOARCHIVE" />
0
+ <title>Thin Stats</title>
0
+ <style type="text/css">
0
+ html * { padding:0; margin:0; }
0
+ body * { padding:10px 20px; }
0
+ body * * { padding:0; }
0
+ body { font:small sans-serif; }
0
+ body>div { border-bottom:1px solid #ddd; }
0
+ h1 { font-weight:normal; }
0
+ h2 { margin-bottom:.8em; }
0
+ h2 span { font-size:80%; color:#666; font-weight:normal; }
0
+ h3 { margin:1em 0 .5em 0; }
0
+ h4 { margin:0 0 .5em 0; font-weight: normal; }
0
+ border:1px solid #ccc; border-collapse: collapse; background:white; }
0
+ tbody td, tbody th { vertical-align:top; padding:2px 3px; }
0
+ padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
0
+ font-weight:normal; font-size:11px; border:1px solid #ddd; }
0
+ tbody th { text-align:right; color:#666; padding-right:.5em; }
0
+ table.vars { margin:5px 0 2px 40px; }
0
+ table.vars td, table.req td { font-family:monospace; }
0
+ table td.code { width:100%;}
0
+ table td.code div { overflow:hidden; }
0
+ table.source th { color:#666; }
0
+ font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
0
+ ul.traceback { list-style-type:none; }
0
+ ul.traceback li.frame { margin-bottom:1em; }
0
+ div.context { margin: 10px 0; }
0
+ padding-left:30px; margin:0 10px; list-style-position: inside; }
0
+ font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
0
+ div.context ol.context-line li { color:black; background-color:#ccc; }
0
+ div.context ol.context-line li span { float: right; }
0
+ div.commands { margin-left: 40px; }
0
+ div.commands a { color:black; text-decoration:none; }
0
+ #summary { background: #ffc; }
0
+ #summary h2 { font-weight: normal; color: #666; }
0
+ #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
0
+ #summary ul#quicklinks li { float: left; padding: 0 1em; }