mongo_profiler 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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>