Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of https://github.com/zbelzer/rack-bug into zbe…

…lzer-master
  • Loading branch information...
commit 5af9fc7a1e6df835f738923e04377e7665239258 2 parents 2eb2c95 + ce30e05
@timocratic timocratic authored
View
1  lib/rack/bug.rb
@@ -79,5 +79,4 @@ def password_authorized?
actual_sha == expected_sha
end
-
end
View
3  lib/rack/bug/autoloading.rb
@@ -16,9 +16,10 @@ class Rack::Bug
autoload :MemoryPanel, "rack/bug/panels/memory_panel"
autoload :RailsInfoPanel, "rack/bug/panels/rails_info_panel"
autoload :RedisPanel, "rack/bug/panels/redis_panel"
+ autoload :MongoPanel, "rack/bug/panels/mongo_panel"
autoload :RequestVariablesPanel, "rack/bug/panels/request_variables_panel"
autoload :SQLPanel, "rack/bug/panels/sql_panel"
autoload :TemplatesPanel, "rack/bug/panels/templates_panel"
autoload :TimerPanel, "rack/bug/panels/timer_panel"
autoload :SphinxPanel, "rack/bug/panels/sphinx_panel"
-end
+end
View
44 lib/rack/bug/panels/mongo_panel.rb
@@ -0,0 +1,44 @@
+module Rack
+ class Bug
+
+ class MongoPanel < Panel
+ require "rack/bug/panels/mongo_panel/mongo_extension"
+
+ autoload :Stats, "rack/bug/panels/mongo_panel/stats"
+
+ def self.record(command, &block)
+ return block.call unless Rack::Bug.enabled?
+
+ start_time = Time.now
+ result = block.call
+ total_time = Time.now - start_time
+ stats.record_call(total_time * 1_000, command)
+ return result
+ end
+
+ def self.reset
+ Thread.current["rack.bug.mongo"] = Stats.new
+ end
+
+ def self.stats
+ Thread.current["rack.bug.mongo"] ||= Stats.new
+ end
+
+ def name
+ "mongo"
+ end
+
+ def heading
+ "Mongo: %.2fms (#{self.class.stats.queries.size} calls)" % self.class.stats.time
+ end
+
+ def content
+ result = render_template "panels/mongo", :stats => self.class.stats
+ self.class.reset
+ return result
+ end
+
+ end
+
+ end
+end
View
27 lib/rack/bug/panels/mongo_panel/mongo_extension.rb
@@ -0,0 +1,27 @@
+require 'mongo'
+
+if defined?(Mongo)
+ Mongo::Connection.class_eval do
+
+ def send_message_with_rack_bug(operation, message, log_message=nil)
+ Rack::Bug::MongoPanel.record(log_message || message) do
+ send_message_without_rack_bug(operation, message, log_message)
+ end
+ end
+ alias_method_chain :send_message, :rack_bug
+
+ def send_message_with_safe_check_with_rack_bug(operation, message, db_name, log_message=nil, last_error_params=false)
+ Rack::Bug::MongoPanel.record(log_message || message) do
+ send_message_with_safe_check_without_rack_bug(operation, message, db_name, log_message, last_error_params)
+ end
+ end
+ alias_method_chain :send_message_with_safe_check, :rack_bug
+
+ def receive_message_with_rack_bug(operation, message, log_message=nil, socket=nil)
+ Rack::Bug::MongoPanel.record(log_message || "A logger must be configured to catch receive message commands") do
+ receive_message_without_rack_bug(operation, message, log_message, socket)
+ end
+ end
+ alias_method_chain :receive_message, :rack_bug
+ end
+end
View
48 lib/rack/bug/panels/mongo_panel/stats.rb
@@ -0,0 +1,48 @@
+module Rack
+ class Bug
+ class MongoPanel
+
+ class Stats
+ class Query
+ attr_reader :time
+ attr_reader :command
+
+ def initialize(time, command)
+ @time = time
+ @command = command
+ end
+
+ def display_time
+ "%.2fms" % time
+ end
+ end
+
+ attr_reader :calls
+ attr_reader :queries
+
+ def initialize
+ @queries = []
+ @calls = 0
+ @time = 0.0
+ end
+
+ def record_call(time, command)
+ @queries << Query.new(time, command)
+ @calls += 1
+ @time += time
+ end
+
+ def display_time
+ "%.2fms" % time
+ end
+
+ def time
+ @queries.inject(0) do |memo, query|
+ memo + query.time
+ end
+ end
+ end
+
+ end
+ end
+end
View
32 lib/rack/bug/views/panels/mongo.html.erb
@@ -0,0 +1,32 @@
+<h3>Mongo Usage</h3>
+<table id="mongo_usage">
+ <tr>
+ <th>Total Calls</th>
+ <td><%= stats.calls %></td>
+
+ <th>Total Time</th>
+ <td><%= stats.display_time %></td>
+ </tr>
+</table>
+
+<% if stats.queries.any? %>
+ <h3>Breakdown</h3>
+ <table id="mongo_breakdown">
+ <thead>
+ <tr>
+ <th>Time&nbsp;(ms)</th>
+ <th>Command</th>
+ </tr>
+ </thead>
+ <tbody>
+ <% i = 1 %>
+ <% stats.queries.each do |query| %>
+ <tr class="<%= i % 2 == 0 ? "even" : "odd" %>">
+ <td><%= query.display_time %></td>
+ <td><%= query.command %></td>
+ </tr>
+ <% i += 1 %>
+ <% end %>
+ </tbody>
+ </table>
+<% end %>
View
51 spec/rack/bug/panels/mongo_panel_spec.rb
@@ -0,0 +1,51 @@
+require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
+$LOADED_FEATURES << "mongo.rb" #avoid dependency on mongo
+
+class Rack::Bug
+ describe MongoPanel do
+ before do
+ MongoPanel.reset
+ rack_env "rack-bug.panel_classes", [MongoPanel]
+ end
+
+ describe "heading" do
+ it "displays the total mongo time" do
+ response = get_via_rack "/"
+ response.should have_heading("Mongo: 0.00ms")
+ end
+ end
+
+ describe "content" do
+ describe "usage table" do
+ it "displays the total number of mongo calls" do
+ MongoPanel.record("db.user.user.find()") { }
+ response = get_via_rack "/"
+
+ # This causes a bus error:
+ # response.should have_selector("th:content('Total Calls') + td", :content => "1")
+
+ response.should have_row("#mongo_usage", "Total Calls", "1")
+ end
+
+ it "displays the total mongo time" do
+ response = get_via_rack "/"
+ response.should have_row("#mongo_usage", "Total Time", "0.00ms")
+ end
+ end
+
+ describe "breakdown" do
+ it "displays each mongo operation" do
+ MongoPanel.record("db.user.user.find()") { }
+ response = get_via_rack "/"
+ response.should have_row("#mongo_breakdown", "db.user.user.find()")
+ end
+
+ it "displays the time for mongo call" do
+ MongoPanel.record("db.user.user.find()") { }
+ response = get_via_rack "/"
+ response.should have_row("#mongo_breakdown", "db.user.user.find()", TIME_MS_REGEXP)
+ end
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.