glimpse-performance_bar 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/glimpse/views/performance_bar.coffee +162 -0
- data/app/assets/stylesheets/glimpse/views/performance_bar.scss +27 -0
- data/app/helpers/glimpse/performance_bar_helper.rb +10 -0
- data/app/views/glimpse/results/_performance_bar.html.erb +1 -0
- data/app/views/glimpse/views/_performance_bar.html.erb +2 -0
- data/glimpse-performance_bar.gemspec +21 -0
- data/lib/glimpse/views/performance_bar.rb +6 -0
- data/lib/glimpse-performance_bar/railtie.rb +11 -0
- data/lib/glimpse-performance_bar/version.rb +5 -0
- data/lib/glimpse-performance_bar.rb +3 -0
- data/lib/rack/process_utilization.rb +143 -0
- metadata +78 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Garrett Bjerkhoel
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Glimpse::PerformanceBar
|
2
|
+
|
3
|
+
Provide a glimpse into the MySQL queries made during your application's requests.
|
4
|
+
|
5
|
+
Things this glimpse view provides:
|
6
|
+
|
7
|
+
- Total number of MySQL queries called during the request
|
8
|
+
- The duration of the queries made during the request
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'glimpse-performance_bar'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install glimpse-performance_bar
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
Add the following to your `config/initializers/glimpse.rb`:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
Glimpse.into Glimpse::Views::PerformanceBar
|
30
|
+
```
|
31
|
+
|
32
|
+
## Contributing
|
33
|
+
|
34
|
+
1. Fork it
|
35
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
36
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
37
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
38
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# The mission control window.performance.timing display area.
|
2
|
+
#
|
3
|
+
# Breaks the window.performance.timing numbers down into these groups:
|
4
|
+
#
|
5
|
+
# dns - Time looking up domain. Usually zero.
|
6
|
+
# tcp and ssl - Time used establishing tcp and ssl connections.
|
7
|
+
# redirect - Time spent redirecting since navigation began.
|
8
|
+
# app - Real server time as recorded in the app.
|
9
|
+
# latency - Extra backend and network time where browser was waiting.
|
10
|
+
# frontend - Time spent loading and rendering the DOM until interactive.
|
11
|
+
#
|
12
|
+
# Not all frontend time is counted. The page is considered ready when the
|
13
|
+
# domInteractive ready state is reached. This is before DOMContentLoaded and
|
14
|
+
# onload javascript handlers.
|
15
|
+
class PerformanceBar
|
16
|
+
# Additional app info to show with the app timing.
|
17
|
+
appInfo: null
|
18
|
+
|
19
|
+
# The pixel width we're rendering the timing graph into.
|
20
|
+
width: null
|
21
|
+
|
22
|
+
# Format a time as ms or s based on how big it is.
|
23
|
+
@formatTime: (value) ->
|
24
|
+
if value >= 1000
|
25
|
+
"#{(value / 1000).toFixed(3)}s"
|
26
|
+
else
|
27
|
+
"#{value.toFixed(0)}ms"
|
28
|
+
|
29
|
+
# Create a new PerformanceBar view bound to a given element. The el and width
|
30
|
+
# options should be provided here.
|
31
|
+
constructor: (options={}) ->
|
32
|
+
@el = $('.performance-bar')
|
33
|
+
@[k] = v for k, v of options
|
34
|
+
@width ?= @el.width()
|
35
|
+
@timing ?= window.performance.timing
|
36
|
+
|
37
|
+
# Render the performance bar in the associated element. This is a little weird
|
38
|
+
# because it includes the server-side rendering time reported with the
|
39
|
+
# response document which may not line up when using the back/forward button
|
40
|
+
# and loading from cache.
|
41
|
+
render: (serverTime=0) ->
|
42
|
+
@el.empty()
|
43
|
+
@addBar 'frontend', '#90d35b', 'domLoading', 'domInteractive'
|
44
|
+
|
45
|
+
# time spent talking with the app according to performance.timing
|
46
|
+
perfNetworkTime = (@timing.responseEnd - @timing.requestStart)
|
47
|
+
|
48
|
+
# only include serverTime if it's less than than the browser reported
|
49
|
+
# talking-to-the-app time; otherwise, assume we're loading from cache.
|
50
|
+
if serverTime and serverTime <= perfNetworkTime
|
51
|
+
networkTime = perfNetworkTime - serverTime
|
52
|
+
@addBar 'latency / receiving', '#f1faff',
|
53
|
+
@timing.requestStart + serverTime,
|
54
|
+
@timing.requestStart + serverTime + networkTime
|
55
|
+
@addBar 'app', '#90afcf',
|
56
|
+
@timing.requestStart,
|
57
|
+
@timing.requestStart + serverTime,
|
58
|
+
@appInfo
|
59
|
+
else
|
60
|
+
@addBar 'backend', '#c1d7ee', 'requestStart', 'responseEnd'
|
61
|
+
|
62
|
+
@addBar 'tcp / ssl', '#45688e', 'connectStart', 'connectEnd'
|
63
|
+
@addBar 'redirect', '#0c365e', 'redirectStart', 'redirectEnd'
|
64
|
+
@addBar 'dns', '#082541', 'domainLookupStart', 'domainLookupEnd'
|
65
|
+
|
66
|
+
@el
|
67
|
+
|
68
|
+
# Determine if the page has reached the interactive state yet.
|
69
|
+
isLoaded: ->
|
70
|
+
@timing.domInteractive
|
71
|
+
|
72
|
+
# Integer unix timestamp representing the very beginning of the graph.
|
73
|
+
start: ->
|
74
|
+
@timing.navigationStart
|
75
|
+
|
76
|
+
# Integer unix timestamp representing the very end of the graph.
|
77
|
+
end: ->
|
78
|
+
@timing.domInteractive
|
79
|
+
|
80
|
+
# Total number of milliseconds between the start and end times.
|
81
|
+
total: ->
|
82
|
+
@end() - @start()
|
83
|
+
|
84
|
+
# Helper used to add a bar to the graph.
|
85
|
+
addBar: (name, color, start, end, info) ->
|
86
|
+
start = @timing[start] if typeof start is 'string'
|
87
|
+
end = @timing[end] if typeof end is 'string'
|
88
|
+
|
89
|
+
# Skip missing stats
|
90
|
+
return unless start? and end?
|
91
|
+
|
92
|
+
time = end - start
|
93
|
+
offset = start - @start()
|
94
|
+
left = @mapH(offset)
|
95
|
+
width = @mapH(time)
|
96
|
+
|
97
|
+
bar = $("<li class='tooltip'>#{name}</li>")
|
98
|
+
title = "#{name}: #{PerformanceBar.formatTime(time)}"
|
99
|
+
title += "\n\n#{info}".replace(/\n/g, '<br/>') if info
|
100
|
+
bar.attr 'title', title
|
101
|
+
bar.css
|
102
|
+
width: "#{width}px"
|
103
|
+
left: "#{left}px"
|
104
|
+
background: color
|
105
|
+
bar.tipsy gravity: 'n', html: true
|
106
|
+
@el.append bar
|
107
|
+
|
108
|
+
# Map a time offset value to a horizontal pixel offset.
|
109
|
+
mapH: (offset) ->
|
110
|
+
offset * (@width / @total())
|
111
|
+
|
112
|
+
renderPerformanceBar = ->
|
113
|
+
resp = $('#glimpse-server_response_time')
|
114
|
+
time = Math.round(resp.data('time') * 1000)
|
115
|
+
|
116
|
+
bar = new PerformanceBar
|
117
|
+
bar.render time
|
118
|
+
|
119
|
+
span = $('<span>', {'class': 'tooltip', title: 'Total navigation time for this page.'})
|
120
|
+
.text(PerformanceBar.formatTime(bar.total()))
|
121
|
+
span.tipsy({ gravity: 'n' })
|
122
|
+
updateStatus span
|
123
|
+
|
124
|
+
|
125
|
+
updateStatus = (html) ->
|
126
|
+
$('#serverstats').html html
|
127
|
+
|
128
|
+
pjaxStart = null
|
129
|
+
$(document).on 'pjax:start', (event) ->
|
130
|
+
pjaxStart = event.timeStamp
|
131
|
+
|
132
|
+
$(document).on 'pjax:end', (event, xhr) ->
|
133
|
+
pjaxEnd = event.timeStamp
|
134
|
+
total = pjaxEnd - pjaxStart
|
135
|
+
serverTime = if xhr then parseInt(xhr.getResponseHeader('X-Runtime')) else 0
|
136
|
+
|
137
|
+
# Defer to include the timing of pjax hook evaluation
|
138
|
+
setTimeout ->
|
139
|
+
now = new Date().getTime()
|
140
|
+
bar = new PerformanceBar
|
141
|
+
timing:
|
142
|
+
requestStart: pjaxStart,
|
143
|
+
responseEnd: pjaxEnd,
|
144
|
+
domLoading: pjaxEnd,
|
145
|
+
domInteractive: now
|
146
|
+
isLoaded: -> true
|
147
|
+
start: -> pjaxStart
|
148
|
+
end: -> now
|
149
|
+
|
150
|
+
bar.render serverTime
|
151
|
+
|
152
|
+
console.log 'why u called'
|
153
|
+
span = $('<span>', {'class': 'tooltip', title: 'PJAX navigation time'})
|
154
|
+
.text(PerformanceBar.formatTime(total))
|
155
|
+
span.tipsy({ gravity: 'n' })
|
156
|
+
updateStatus span
|
157
|
+
|
158
|
+
pjaxStart = null
|
159
|
+
, 0
|
160
|
+
|
161
|
+
$ ->
|
162
|
+
renderPerformanceBar()
|
@@ -0,0 +1,27 @@
|
|
1
|
+
.performance-bar {
|
2
|
+
position: relative;
|
3
|
+
top: 2px;
|
4
|
+
display: inline-block;
|
5
|
+
width: 75px;
|
6
|
+
height: 10px;
|
7
|
+
margin: 0 0 0 5px;
|
8
|
+
list-style: none;
|
9
|
+
background-color: rgba(0, 0, 0, .5);
|
10
|
+
border: 1px solid rgba(0, 0, 0, .7);
|
11
|
+
border-radius: 2px;
|
12
|
+
box-shadow: 0 1px 0 rgba(255, 255, 255, .15);
|
13
|
+
|
14
|
+
li {
|
15
|
+
position: absolute;
|
16
|
+
top: 0;
|
17
|
+
bottom: 0;
|
18
|
+
overflow: hidden;
|
19
|
+
opacity: .8;
|
20
|
+
color: transparent;
|
21
|
+
|
22
|
+
&:hover {
|
23
|
+
opacity: 1;
|
24
|
+
cursor: default;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Glimpse
|
2
|
+
module PerformanceBarHelper
|
3
|
+
def render_server_response_time
|
4
|
+
if start_time = request.env['process.request_start']
|
5
|
+
time = "%.5f" % (Time.now - start_time)
|
6
|
+
"<span id='glimpse-server_response_time' data-time='#{time}'></span>".html_safe
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render_server_response_time %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'glimpse-performance_bar/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = 'glimpse-performance_bar'
|
8
|
+
gem.version = Glimpse::PerformanceBar::VERSION
|
9
|
+
gem.authors = ['Garrett Bjerkhoel']
|
10
|
+
gem.email = ['me@garrettbjerkhoel.com']
|
11
|
+
gem.description = %q{Provide a glimpse into the MySQL queries made during your application's requests.}
|
12
|
+
gem.summary = %q{Provide a glimpse into the MySQL queries made during your application's requests.}
|
13
|
+
gem.homepage = 'https://github.com/dewski/glimpse-performance_bar'
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.add_dependency 'glimpse'
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rack/process_utilization'
|
2
|
+
|
3
|
+
module Glimpse
|
4
|
+
module PerformanceBar
|
5
|
+
class Railtie < ::Rails::Engine
|
6
|
+
initializer 'glimpse.performance_bar.mount_process_utilization' do |app|
|
7
|
+
app.config.middleware.use Rack::ProcessUtilization
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Rack
|
2
|
+
# Middleware that tracks the amount of time this process spends processing
|
3
|
+
# requests, as opposed to being idle waiting for a connection. Statistics
|
4
|
+
# are dumped to rack.errors every 5 minutes.
|
5
|
+
#
|
6
|
+
# NOTE This middleware is not thread safe. It should only be used when
|
7
|
+
# rack.multiprocess is true and rack.multithread is false.
|
8
|
+
class ProcessUtilization
|
9
|
+
class << self
|
10
|
+
# The instance of this middleware in a single-threaded production server.
|
11
|
+
# Useful for fetching stats about the current request:
|
12
|
+
#
|
13
|
+
# o = Rack::ProcessUtilization.singleton
|
14
|
+
# time, calls = o.gc_stats if o.track_gc?
|
15
|
+
attr_accessor :singleton
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(app, opts={})
|
19
|
+
@app = app
|
20
|
+
@window = opts[:window] || 100
|
21
|
+
@horizon = nil
|
22
|
+
@requests = nil
|
23
|
+
@active_time = nil
|
24
|
+
@total_requests = 0
|
25
|
+
|
26
|
+
self.class.singleton = self
|
27
|
+
end
|
28
|
+
|
29
|
+
# time when we began sampling. this is reset every once in a while so
|
30
|
+
# averages don't skew over time.
|
31
|
+
attr_accessor :horizon
|
32
|
+
|
33
|
+
# total number of requests that have been processed by this worker since
|
34
|
+
# the horizon time.
|
35
|
+
attr_accessor :requests
|
36
|
+
|
37
|
+
# decimal number of seconds the worker has been active within a request
|
38
|
+
# since the horizon time.
|
39
|
+
attr_accessor :active_time
|
40
|
+
|
41
|
+
# total requests processed by this worker process since it started
|
42
|
+
attr_accessor :total_requests
|
43
|
+
|
44
|
+
# the amount of time since the horizon
|
45
|
+
def horizon_time
|
46
|
+
Time.now - horizon
|
47
|
+
end
|
48
|
+
|
49
|
+
# decimal number of seconds this process has been active since the horizon
|
50
|
+
# time. This is the inverse of the active time.
|
51
|
+
def idle_time
|
52
|
+
horizon_time - active_time
|
53
|
+
end
|
54
|
+
|
55
|
+
# percentage of time this process has been active since the horizon time.
|
56
|
+
def percentage_active
|
57
|
+
(active_time / horizon_time) * 100
|
58
|
+
end
|
59
|
+
|
60
|
+
# percentage of time this process has been idle since the horizon time.
|
61
|
+
def percentage_idle
|
62
|
+
(idle_time / horizon_time) * 100
|
63
|
+
end
|
64
|
+
|
65
|
+
# number of requests processed per second since the horizon
|
66
|
+
def requests_per_second
|
67
|
+
requests / horizon_time
|
68
|
+
end
|
69
|
+
|
70
|
+
# average response time since the horizon in milliseconds
|
71
|
+
def average_response_time
|
72
|
+
(active_time / requests.to_f) * 1000
|
73
|
+
end
|
74
|
+
|
75
|
+
# called exactly once before the first request is processed by a worker
|
76
|
+
def first_request
|
77
|
+
reset_horizon
|
78
|
+
end
|
79
|
+
|
80
|
+
# reset various counters before the new request
|
81
|
+
def reset_stats
|
82
|
+
@start = Time.now
|
83
|
+
end
|
84
|
+
|
85
|
+
# resets the horizon and all dependent variables
|
86
|
+
def reset_horizon
|
87
|
+
@horizon = Time.now
|
88
|
+
@active_time = 0.0
|
89
|
+
@requests = 0
|
90
|
+
end
|
91
|
+
|
92
|
+
# called immediately after a request to record statistics, update the
|
93
|
+
# procline, and dump information to the logfile
|
94
|
+
def record_request
|
95
|
+
now = Time.now
|
96
|
+
diff = (now - @start)
|
97
|
+
@active_time += diff
|
98
|
+
@requests += 1
|
99
|
+
|
100
|
+
reset_horizon if now - horizon > @window
|
101
|
+
rescue => boom
|
102
|
+
warn "ProcessUtilization#record_request failed: #{boom.inspect}"
|
103
|
+
end
|
104
|
+
|
105
|
+
# Body wrapper. Yields to the block when body is closed. This is used to
|
106
|
+
# signal when a response is fully finished processing.
|
107
|
+
class Body
|
108
|
+
def initialize(body, &block)
|
109
|
+
@body = body
|
110
|
+
@block = block
|
111
|
+
end
|
112
|
+
|
113
|
+
def each(&block)
|
114
|
+
@body.each(&block)
|
115
|
+
end
|
116
|
+
|
117
|
+
def close
|
118
|
+
@body.close if @body.respond_to?(:close)
|
119
|
+
@block.call
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Rack entry point.
|
125
|
+
def call(env)
|
126
|
+
@env = env
|
127
|
+
reset_stats
|
128
|
+
|
129
|
+
@total_requests += 1
|
130
|
+
first_request if @total_requests == 1
|
131
|
+
|
132
|
+
env['process.request_start'] = @start.to_f
|
133
|
+
env['process.total_requests'] = total_requests
|
134
|
+
|
135
|
+
# newrelic X-Request-Start
|
136
|
+
env.delete('HTTP_X_REQUEST_START')
|
137
|
+
|
138
|
+
status, headers, body = @app.call(env)
|
139
|
+
body = Body.new(body) { record_request }
|
140
|
+
[status, headers, body]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: glimpse-performance_bar
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Garrett Bjerkhoel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: glimpse
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Provide a glimpse into the MySQL queries made during your application's
|
31
|
+
requests.
|
32
|
+
email:
|
33
|
+
- me@garrettbjerkhoel.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- Gemfile
|
40
|
+
- LICENSE.txt
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- app/assets/javascripts/glimpse/views/performance_bar.coffee
|
44
|
+
- app/assets/stylesheets/glimpse/views/performance_bar.scss
|
45
|
+
- app/helpers/glimpse/performance_bar_helper.rb
|
46
|
+
- app/views/glimpse/results/_performance_bar.html.erb
|
47
|
+
- app/views/glimpse/views/_performance_bar.html.erb
|
48
|
+
- glimpse-performance_bar.gemspec
|
49
|
+
- lib/glimpse-performance_bar.rb
|
50
|
+
- lib/glimpse-performance_bar/railtie.rb
|
51
|
+
- lib/glimpse-performance_bar/version.rb
|
52
|
+
- lib/glimpse/views/performance_bar.rb
|
53
|
+
- lib/rack/process_utilization.rb
|
54
|
+
homepage: https://github.com/dewski/glimpse-performance_bar
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.8.23
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: Provide a glimpse into the MySQL queries made during your application's requests.
|
78
|
+
test_files: []
|