mongo_profiler 0.0.1 → 0.0.2

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.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Cantero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-17 00:00:00.000000000 Z
11
+ date: 2014-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -39,21 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: mongo
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '='
46
- - !ruby/object:Gem::Version
47
- version: 1.9.2
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '='
53
- - !ruby/object:Gem::Version
54
- version: 1.9.2
55
- - !ruby/object:Gem::Dependency
56
- name: bson_ext
42
+ name: mongoid
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - '>='
@@ -136,7 +122,21 @@ dependencies:
136
122
  - - '>='
137
123
  - !ruby/object:Gem::Version
138
124
  version: '0'
139
- description: A Ruby profiling tool for MongoDB
125
+ - !ruby/object:Gem::Dependency
126
+ name: database_cleaner
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Ruby profiling tool for MongoDB
140
140
  email:
141
141
  - pablo@pablocantero.com
142
142
  executables: []
@@ -145,6 +145,7 @@ extra_rdoc_files: []
145
145
  files:
146
146
  - .gitignore
147
147
  - .rspec
148
+ - .travis.yml
148
149
  - Gemfile
149
150
  - Gemfile.lock
150
151
  - LICENSE.txt
@@ -154,25 +155,23 @@ files:
154
155
  - assets/mongo_profiler_group_details.png
155
156
  - assets/mongo_profiler_query_details.png
156
157
  - assets/mongo_profiler_query_details_backtrace.png
157
- - config.ru
158
158
  - lib/mongo_profiler.rb
159
159
  - lib/mongo_profiler/caller.rb
160
- - lib/mongo_profiler/extensions/mongo/cursor.rb
161
- - lib/mongo_profiler/payload.rb
162
- - lib/mongo_profiler/profiler.rb
163
- - lib/mongo_profiler/stats.rb
160
+ - lib/mongo_profiler/extensions/moped.rb
161
+ - lib/mongo_profiler/models/profile.rb
162
+ - lib/mongo_profiler/models/profile_group.rb
163
+ - lib/mongo_profiler/util.rb
164
164
  - lib/mongo_profiler/version.rb
165
165
  - lib/mongo_profiler/web.rb
166
166
  - lib/mongo_profiler/web_helpers.rb
167
167
  - mongo_profiler.gemspec
168
168
  - spec/mongo_profiler/caller_spec.rb
169
- - spec/mongo_profiler/extensions/mongo/cursor_spec.rb
170
- - spec/mongo_profiler/payload_spec.rb
171
- - spec/mongo_profiler/profiler_spec.rb
172
- - spec/mongo_profiler/stats_spec.rb
169
+ - spec/mongo_profiler/models/profile_spec.rb
170
+ - spec/mongo_profiler/util_spec.rb
173
171
  - spec/mongo_profiler/web_helpers_spec.rb
174
172
  - spec/mongo_profiler/web_spec.rb
175
173
  - spec/mongo_profiler_spec.rb
174
+ - spec/mongoid.yml
176
175
  - spec/spec_helper.rb
177
176
  - web/assets/fonts/glyphicons-halflings-regular.eot
178
177
  - web/assets/fonts/glyphicons-halflings-regular.svg
@@ -187,7 +186,6 @@ files:
187
186
  - web/assets/stylesheets/bootstrap.min.css
188
187
  - web/assets/stylesheets/highlight/default.css
189
188
  - web/assets/stylesheets/highlight/github.css
190
- - web/views/group_id.erb
191
189
  - web/views/index.erb
192
190
  - web/views/layout.erb
193
191
  - web/views/show.erb
@@ -217,11 +215,10 @@ specification_version: 4
217
215
  summary: Ruby profiling tool for MongoDB
218
216
  test_files:
219
217
  - spec/mongo_profiler/caller_spec.rb
220
- - spec/mongo_profiler/extensions/mongo/cursor_spec.rb
221
- - spec/mongo_profiler/payload_spec.rb
222
- - spec/mongo_profiler/profiler_spec.rb
223
- - spec/mongo_profiler/stats_spec.rb
218
+ - spec/mongo_profiler/models/profile_spec.rb
219
+ - spec/mongo_profiler/util_spec.rb
224
220
  - spec/mongo_profiler/web_helpers_spec.rb
225
221
  - spec/mongo_profiler/web_spec.rb
226
222
  - spec/mongo_profiler_spec.rb
223
+ - spec/mongoid.yml
227
224
  - spec/spec_helper.rb
data/config.ru DELETED
@@ -1,13 +0,0 @@
1
- require 'pry-byebug'
2
- require 'mongo'
3
- require 'mongo_profiler'
4
-
5
- require 'mongo_profiler/web'
6
-
7
- CONNECTION = Mongo::MongoClient.new
8
- DB = CONNECTION.db('mongo_profiler-database')
9
- COLL = DB['example-collection']
10
-
11
- MongoProfiler.connect('localhost', 27017, 'mongo_profiler-database')
12
-
13
- run MongoProfiler::Web
@@ -1,38 +0,0 @@
1
- Mongo::Cursor.class_eval do
2
- alias_method :original_send_initial_query, :send_initial_query
3
-
4
- def send_initial_query
5
- beginning_time = Time.now
6
- original_send_initial_query
7
- total_time = Time.now - beginning_time
8
- begin
9
- _caller = MongoProfiler::Caller.new(caller)
10
-
11
- return if MongoProfiler.should_skip?(instrument_payload, _caller) || MongoProfiler.disabled?
12
-
13
- result = {}
14
-
15
- result[:total_time] = total_time
16
-
17
- # the payload sent to mongo
18
- result[:instrument_payload] = JSON.dump(instrument_payload)
19
-
20
- result[:file] = _caller.file
21
- result[:line] = _caller.line
22
- result[:method] = _caller.method
23
-
24
- result[:extra_attrs] = MongoProfiler.extra_attrs
25
-
26
- # TODO rename `_caller` object instance to something more meaningful in this context
27
- result[:backtrace] = _caller._caller
28
-
29
- MongoProfiler.log(result)
30
-
31
- if stats_client = MongoProfiler.stats_client
32
- stats_client.populate(_caller, total_time)
33
- end
34
- rescue => e
35
- p "MongoProfiler: #{e.message}"
36
- end
37
- end
38
- end
@@ -1,33 +0,0 @@
1
- module MongoProfiler
2
- class Payload
3
- attr_reader :payload
4
-
5
- def initialize(payload)
6
- @payload = (payload || {}).dup.with_indifferent_access
7
- end
8
-
9
- def system_database?
10
- !payload['database'].to_s.match(/^admin|system/).nil?
11
- end
12
-
13
- def system_collection?
14
- !payload['collection'].to_s.match(/^mongo_|system/).nil?
15
- end
16
-
17
- def system_count?
18
- !payload['selector'].to_h['count'].to_s.match(/^mongo_|system/).nil?
19
- end
20
-
21
- def system_distinct?
22
- !payload['selector'].to_h['distinct'].to_s.match(/^mongo_|system/).nil?
23
- end
24
-
25
- def system_command?
26
- payload['collection'] == '$cmd' && !(payload['selector'].to_h.has_key?('count') || payload['selector'].to_h.has_key?('distinct'))
27
- end
28
-
29
- def system_any?
30
- system_database? || system_collection? || system_count? || system_distinct? || system_command?
31
- end
32
- end
33
- end
@@ -1,4 +0,0 @@
1
- module MongoProfiler
2
- class Profiler
3
- end
4
- end
@@ -1,25 +0,0 @@
1
- module MongoProfiler
2
- class Stats
3
- def initialize(stats_client)
4
- @stats_client = stats_client
5
- end
6
-
7
- def populate(_caller, total_time)
8
- file = sanitaze_stat_key _caller.file.split('/').last
9
- method = sanitaze_stat_key _caller.method
10
-
11
- stat_name = "mongo_profiler.#{MongoProfiler.application_name}.#{file}.#{method}"
12
-
13
- total_time_ms = total_time * 1000
14
-
15
- @stats_client.increment stat_name
16
- @stats_client.timing stat_name, total_time_ms
17
- end
18
-
19
- private
20
-
21
- def sanitaze_stat_key(key)
22
- key.gsub(/\W/, '_')
23
- end
24
- end
25
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Mongo::Cursor' do
4
- let(:collection) { COLL }
5
-
6
- describe '#send_initial_query' do
7
- context 'when enabled' do
8
- let(:stats_client) { double('StatsD client').as_null_object }
9
-
10
- before do
11
- MongoProfiler.enable!
12
-
13
- MongoProfiler.stats_client = stats_client
14
- end
15
-
16
- it 'populate stats' do
17
- expect(stats_client).to receive(:increment).with(any_args)
18
- expect(stats_client).to receive(:timing).with(any_args)
19
-
20
- collection.find_one
21
- end
22
-
23
- it 'creates a profiler entry' do
24
- expect {
25
- collection.insert(test: 'test')
26
- expect(collection.find_one['test']).to eq 'test'
27
- }.to change { MongoProfiler.collection.count }.by(1)
28
- end
29
- end
30
-
31
- context 'when disabled' do
32
- before { MongoProfiler.disable! }
33
-
34
- it 'skips profiler entry' do
35
- expect {
36
- collection.insert(test: 'test')
37
- expect(collection.find_one['test']).to eq 'test'
38
- }.to_not change { MongoProfiler.collection.count }
39
- end
40
- end
41
- end
42
- end
@@ -1,111 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module MongoProfiler
4
- describe Payload do
5
- subject { described_class.new(payload) }
6
-
7
- describe '#system_database?' do
8
- context 'when admin' do
9
- let(:payload) { { database: 'admin' } }
10
-
11
- its(:system_database?) { should be_true }
12
- end
13
-
14
- context 'when system' do
15
- let(:payload) { { database: 'system' } }
16
-
17
- its(:system_database?) { should be_true }
18
- end
19
-
20
- context 'when other' do
21
- let(:payload) { { database: 'other' } }
22
-
23
- its(:system_database?) { should be_false }
24
- end
25
- end
26
-
27
- describe '#system_collection?' do
28
- context 'when admin' do
29
- let(:payload) { { collection: 'mongo_profiler' } }
30
-
31
- its(:system_collection?) { should be_true }
32
- end
33
-
34
- context 'when system' do
35
- let(:payload) { { collection: 'system' } }
36
-
37
- its(:system_collection?) { should be_true }
38
- end
39
-
40
- context 'when other' do
41
- let(:payload) { { collection: 'other' } }
42
-
43
- its(:system_collection?) { should be_false }
44
- end
45
- end
46
-
47
- describe '#system_count?' do
48
- context 'when admin' do
49
- let(:payload) { { selector: { count: 'mongo_profiler' } } }
50
-
51
- its(:system_count?) { should be_true }
52
- end
53
-
54
- context 'when system' do
55
- let(:payload) { { selector: { count: 'system' } } }
56
-
57
- its(:system_count?) { should be_true }
58
- end
59
-
60
- context 'when other' do
61
- let(:payload) { { selector: { count: 'other' } } }
62
-
63
- its(:system_count?) { should be_false }
64
- end
65
- end
66
-
67
- describe '#system_distinct?' do
68
- context 'when admin' do
69
- let(:payload) { { selector: { distinct: 'mongo_profiler' } } }
70
-
71
- its(:system_distinct?) { should be_true }
72
- end
73
-
74
- context 'when system' do
75
- let(:payload) { { selector: { distinct: 'system' } } }
76
-
77
- its(:system_distinct?) { should be_true }
78
- end
79
-
80
- context 'when other' do
81
- let(:payload) { { selector: { distinct: 'other' } } }
82
-
83
- its(:system_distinct?) { should be_false }
84
- end
85
- end
86
-
87
- describe '#system_command?' do
88
- context 'when count' do
89
- let(:payload) { { collection: '$cmd', selector: { count: 'something' } } }
90
-
91
- its(:system_command?) { should be_false }
92
- end
93
-
94
- context 'when distinct' do
95
- let(:payload) { { collection: '$cmd', selector: { distinct: 'something' } } }
96
-
97
- its(:system_command?) { should be_false }
98
- end
99
-
100
- context 'when other' do
101
- let(:payload) { { collection: '$cmd', selector: { getnonce: -1 } } }
102
-
103
- its(:system_command?) { should be_true }
104
- end
105
- end
106
-
107
- describe '#system_any?' do
108
- pending
109
- end
110
- end
111
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module MongoProfiler
4
- describe Profiler do
5
- before { MongoProfiler.application_name = 'project' }
6
-
7
- end
8
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module MongoProfiler
4
- describe Stats do
5
- let(:stats_client) { double 'StatsD Client' }
6
- subject { Stats.new(stats_client) }
7
-
8
- before { MongoProfiler.application_name = 'project' }
9
-
10
- describe '#populate' do
11
- let(:_caller) { MongoProfiler::Caller.new(backtrace) }
12
- let(:backtrace) {
13
- [
14
- "/Users/pablo/workspace/project/spec/mongo_ruby_profiler_spec.rb:7:in `new'",
15
- "/Users/pablo/.gem/ruby/2.0.0/gems/rspec-core-2.14.4/lib/rspec/core/memoized_helpers.rb:199:in `block (2 levels) in let'",
16
- "/Users/pablo/.gem/ruby/2.0.0/gems/rspec-core-2.14.4/lib/rspec/core/memoized_helpers.rb:199:in `fetch'",
17
- "/Users/pablo/.gem/ruby/2.0.0/gems/rspec-core-2.14.4/lib/rspec/core/memoized_helpers.rb:199:in `block in let'"
18
- ]
19
- }
20
-
21
- it 'populates increment and timing' do
22
- expect(stats_client).to receive(:increment).with('mongo_profiler.project.mongo_ruby_profiler_spec_rb.new')
23
- expect(stats_client).to receive(:timing).with('mongo_profiler.project.mongo_ruby_profiler_spec_rb.new', 5000)
24
-
25
- subject.populate(_caller, 5)
26
- end
27
- end
28
- end
29
- end
@@ -1,53 +0,0 @@
1
- <h2 class="page-header">Group Id: <%= @group_id %></h2>
2
-
3
- <% if @sample_profile %>
4
- <div class="row">
5
- <table class="table table-bordered">
6
- <thead>
7
- <th>Application</th>
8
- <th>Total Queries</th>
9
- <th>Total Time</th>
10
- <th>Avg Total Time</th>
11
- <% @sample_profile['extra_attrs'].to_h.keys.each do |key| %>
12
- <th><%= key %></th>
13
- <% end %>
14
- </thead>
15
- <tbody>
16
- <tr>
17
- <td><%= @sample_profile['application_name'] %></td>
18
- <td><%= @profiles_count %></td>
19
- <td><%= @profiles_total_time %></td>
20
- <td><%= @profiles_total_time / @profiles_count %></td>
21
- <% @sample_profile['extra_attrs'].to_h.keys.each do |key| %>
22
- <td><%= @sample_profile['extra_attrs'][key.to_s] %></td>
23
- <% end %>
24
- </tr>
25
- </tbody>
26
- </table>
27
- </div>
28
- <% end %>
29
-
30
- <div class="row">
31
- <table class="table table-bordered">
32
- <thead>
33
- <th>File Name</th>
34
- <th>Method</th>
35
- <th>Total Time</th>
36
- <th>Instrument Payload</th>
37
- <th>&nbsp;</th>
38
- </thead>
39
- <% @grouped_profiles.each_with_index do |(method, profiles), grouped_index| %>
40
- <tbody class="<%= (grouped_index % 2 == 0) ? 'tbody-gray' : '' %>">
41
- <% profiles.each do |profile| %>
42
- <tr>
43
- <td><%= profile['file'].split('/').last %>:<%= profile['line'] %></td>
44
- <td><%= profile['method'] %></td>
45
- <td><%= profile['total_time'] %></td>
46
- <td><pre><code><%= profile['instrument_payload'] %></code></pre></td>
47
- <td><a href="<%= root_path %>profiler/<%= profile['_id'] %>" class="btn btn-default"><span class="glyphicon glyphicon-eye-open"></span></td>
48
- </tr>
49
- <% end %>
50
- </tbody>
51
- <% end %>
52
- </table>
53
- </div>