module Refinery #:nodoc: # The StatsServer class provides a build in web server that provides # a view into the refinery statistics. This functionality is very # experimental. class StatsServer include Refinery::Loggable # Run the stats server. def run begin Ramaze::Log.loggers.clear # supress all Ramaze logging Ramaze.start # start the Ramaze server on port 7000 rescue NameError self.logger.warn "Install Ramaze to enable the stats server" end end if const_defined?(:Ramaze) class MainController < ::Ramaze::Controller #:nodoc: map '/' def index %( <html> <head> <title>Refinery Stats</title> <style> .widget { border: 1px solid #777; margin-bottom: 10px; padding: 4px; } .widget h2 { font-size: 14pt; margin-top: 2px; margin-bottom: 2px; } #left-column { float: left; width: 600px; } #right-column { margin-left: 610px; width: 300px; } table { background-color: #ddd; width: 100%; } table td { background-color: #eee; } table th { background-color: #ccc; } </style> </head> <body> <h1>Refinery Stats</h1> <div id="left-column"> <div class="run_time widget"> <h2>Runtime Averages</h2> #{avg_run_time} </div> <div class="errors widget"> <h2>Last 5 Errors</h2> #{errors_table} </div> <div class="completed widget"> <h2>Last 5 Completed Jobs</h2> #{completed_jobs_table} </div> </div> <div id="right-column"> <div class="overview widget"> <h2>Overview</h2> <div>#{db[:completed_jobs].count} jobs completed</div> <div>#{db[:errors].count} errors</div> </div> </div> </body> </html> ) end private def db Sequel.connect("sqlite://stats.db") end def avg_run_time rows = db[:completed_jobs].group(:host, :pid).select(:host, :pid, :AVG.sql_function(:run_time)).map do |record| %(<tr> <td>#{record[:host]}</td> <td>#{record[:pid]}</td> <td>#{sprintf("%.6f", record[:"AVG(`run_time`)"])}</td> </tr>) end.join %( <table> <tr> <th>Host</th> <th>PID</th> <th>Avg Run Time</th> </tr> #{rows} </table> ) end def completed_jobs_table jobs_list = db[:completed_jobs].limit(5).map do |record| %Q( <tr> <td>#{record[:host]}</td> <td>#{record[:pid]}</td> <td>#{record[:run_time]}</td> </tr> ) end %Q( <table> <tr> <th>Host</th> <th>PID</th> <th>Run Time</th> </tr> #{jobs_list.join} </table> ) end def errors_table errors = db[:errors].limit(5).map do |record| %(<tr> <td>#{record[:host]}</td> <td>#{record[:pid]}</td> <td>#{record[:error_class]}</td> <td>#{record[:error_message]}</td> </tr> ) end %(<table> <tr> <th>Host</th> <th>PID</th> <th>Error Class</th> <th>Error Message</th> </tr> #{errors.join} </table> ) end end end end end