speed_gun 1.0.0.rc1 → 2.0.0.pre.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -18
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +61 -1
  5. data/.travis.yml +3 -4
  6. data/LICENSE.txt +17 -18
  7. data/README.md +19 -137
  8. data/Rakefile +9 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/example/rails/.gitignore +18 -0
  12. data/example/rails/Gemfile +20 -0
  13. data/example/rails/Gemfile.lock +184 -0
  14. data/example/rails/README.rdoc +28 -0
  15. data/example/rails/Rakefile +6 -0
  16. data/example/rails/app/assets/images/.keep +0 -0
  17. data/example/rails/app/assets/javascripts/application.js +15 -0
  18. data/example/rails/app/assets/javascripts/posts.coffee +3 -0
  19. data/example/rails/app/assets/stylesheets/application.css +15 -0
  20. data/example/rails/app/assets/stylesheets/posts.scss +3 -0
  21. data/example/rails/app/assets/stylesheets/scaffolds.scss +73 -0
  22. data/example/rails/app/controllers/application_controller.rb +5 -0
  23. data/example/rails/app/controllers/concerns/.keep +0 -0
  24. data/example/rails/app/controllers/posts_controller.rb +74 -0
  25. data/example/rails/app/helpers/application_helper.rb +2 -0
  26. data/example/rails/app/helpers/posts_helper.rb +2 -0
  27. data/example/rails/app/mailers/.keep +0 -0
  28. data/example/rails/app/models/.keep +0 -0
  29. data/example/rails/app/models/concerns/.keep +0 -0
  30. data/example/rails/app/models/post.rb +2 -0
  31. data/example/rails/app/views/layouts/application.html.erb +14 -0
  32. data/example/rails/app/views/posts/_form.html.erb +25 -0
  33. data/example/rails/app/views/posts/edit.html.erb +6 -0
  34. data/example/rails/app/views/posts/index.html.erb +29 -0
  35. data/example/rails/app/views/posts/index.json.jbuilder +4 -0
  36. data/example/rails/app/views/posts/new.html.erb +5 -0
  37. data/example/rails/app/views/posts/show.html.erb +14 -0
  38. data/example/rails/app/views/posts/show.json.jbuilder +1 -0
  39. data/example/rails/bin/bundle +3 -0
  40. data/example/rails/bin/rails +9 -0
  41. data/example/rails/bin/rake +9 -0
  42. data/example/rails/bin/setup +29 -0
  43. data/example/rails/bin/spring +15 -0
  44. data/example/rails/config/application.rb +26 -0
  45. data/example/rails/config/boot.rb +3 -0
  46. data/example/rails/config/database.yml +25 -0
  47. data/example/rails/config/environment.rb +5 -0
  48. data/example/rails/config/environments/development.rb +41 -0
  49. data/example/rails/config/environments/production.rb +79 -0
  50. data/example/rails/config/environments/test.rb +42 -0
  51. data/example/rails/config/initializers/assets.rb +11 -0
  52. data/example/rails/config/initializers/backtrace_silencers.rb +7 -0
  53. data/example/rails/config/initializers/cookies_serializer.rb +3 -0
  54. data/example/rails/config/initializers/filter_parameter_logging.rb +4 -0
  55. data/example/rails/config/initializers/inflections.rb +16 -0
  56. data/example/rails/config/initializers/mime_types.rb +4 -0
  57. data/example/rails/config/initializers/session_store.rb +3 -0
  58. data/example/rails/config/initializers/wrap_parameters.rb +14 -0
  59. data/example/rails/config/locales/en.yml +23 -0
  60. data/example/rails/config/routes.rb +57 -0
  61. data/example/rails/config/secrets.yml +22 -0
  62. data/example/rails/config.ru +4 -0
  63. data/example/rails/db/migrate/20160619175824_create_posts.rb +10 -0
  64. data/example/rails/db/schema.rb +23 -0
  65. data/example/rails/db/seeds.rb +7 -0
  66. data/example/rails/lib/assets/.keep +0 -0
  67. data/example/rails/lib/tasks/.keep +0 -0
  68. data/example/rails/log/.keep +0 -0
  69. data/example/rails/public/404.html +67 -0
  70. data/example/rails/public/422.html +67 -0
  71. data/example/rails/public/500.html +66 -0
  72. data/example/rails/public/favicon.ico +0 -0
  73. data/example/rails/public/robots.txt +5 -0
  74. data/example/rails/test/controllers/.keep +0 -0
  75. data/example/rails/test/controllers/posts_controller_test.rb +49 -0
  76. data/example/rails/test/fixtures/.keep +0 -0
  77. data/example/rails/test/fixtures/posts.yml +9 -0
  78. data/example/rails/test/helpers/.keep +0 -0
  79. data/example/rails/test/integration/.keep +0 -0
  80. data/example/rails/test/mailers/.keep +0 -0
  81. data/example/rails/test/models/.keep +0 -0
  82. data/example/rails/test/models/post_test.rb +7 -0
  83. data/example/rails/test/test_helper.rb +10 -0
  84. data/example/rails/vendor/assets/javascripts/.keep +0 -0
  85. data/example/rails/vendor/assets/stylesheets/.keep +0 -0
  86. data/lib/rack/speed_gun.rb +100 -0
  87. data/lib/speed_gun/app/public/report.js +58 -0
  88. data/lib/speed_gun/app/views/events.slim +11 -0
  89. data/lib/speed_gun/app/views/payload.slim +20 -0
  90. data/lib/speed_gun/app/views/report.scss +322 -0
  91. data/lib/speed_gun/app/views/report.slim +57 -0
  92. data/lib/speed_gun/app.rb +53 -0
  93. data/lib/speed_gun/config.rb +25 -32
  94. data/lib/speed_gun/event.rb +29 -39
  95. data/lib/speed_gun/profiler/action_controller_profiler.rb +3 -8
  96. data/lib/speed_gun/profiler/action_mailer_profiler.rb +7 -0
  97. data/lib/speed_gun/profiler/action_view_profiler.rb +3 -8
  98. data/lib/speed_gun/profiler/active_job_profiler.rb +6 -0
  99. data/lib/speed_gun/profiler/active_record_profiler.rb +3 -8
  100. data/lib/speed_gun/profiler/active_support_notifications_profiler.rb +9 -6
  101. data/lib/speed_gun/profiler/active_support_profiler.rb +8 -0
  102. data/lib/speed_gun/profiler/line_profiler.rb +32 -0
  103. data/lib/speed_gun/profiler/rack_profiler.rb +2 -4
  104. data/lib/speed_gun/profiler.rb +15 -9
  105. data/lib/speed_gun/railtie.rb +21 -5
  106. data/lib/speed_gun/report.rb +65 -0
  107. data/lib/speed_gun/source.rb +90 -0
  108. data/lib/speed_gun/store/file_store.rb +35 -0
  109. data/lib/speed_gun/store/memory_store.rb +7 -14
  110. data/lib/speed_gun/store.rb +10 -3
  111. data/lib/speed_gun/version.rb +9 -1
  112. data/lib/speed_gun.rb +21 -26
  113. data/speed_gun.gemspec +21 -16
  114. metadata +168 -58
  115. data/.coveralls.yml +0 -1
  116. data/lib/speed_gun/app/views/meter.html.slim +0 -4
  117. data/lib/speed_gun/middleware.rb +0 -91
  118. data/lib/speed_gun/profile.rb +0 -102
  119. data/lib/speed_gun/store/elastic_search_store.rb +0 -64
  120. data/lib/speed_gun/store/fluent_logger_store.rb +0 -29
  121. data/lib/speed_gun/store/memcache_store.rb +0 -40
  122. data/lib/speed_gun/store/multiple_store.rb +0 -23
  123. data/lib/speed_gun/store/redis_store.rb +0 -41
  124. data/lib/speed_gun/template.rb +0 -15
  125. data/spec/lib/speed_gun/config_spec.rb +0 -37
  126. data/spec/lib/speed_gun/event_spec.rb +0 -70
  127. data/spec/lib/speed_gun/middleware_spec.rb +0 -65
  128. data/spec/lib/speed_gun/profile_spec.rb +0 -41
  129. data/spec/lib/speed_gun_spec.rb +0 -52
  130. data/spec/spec_helper.rb +0 -9
  131. data/spec/support/simplecov.rb +0 -12
@@ -0,0 +1,322 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ html, body {
6
+ position: relative;
7
+ margin: 0;
8
+ padding: 0;
9
+ width: 100%;
10
+ height: 100%;
11
+ overflow: hidden;
12
+ }
13
+
14
+ .shortpath {
15
+ display: block;
16
+ font-weight: bold;
17
+ }
18
+
19
+ .fullpath {
20
+ display: block;
21
+ font-size: 20%;
22
+ font-weight: normal;
23
+ }
24
+
25
+ .duration-ms {
26
+ display: block;
27
+ position: absolute;
28
+ top: 50%;
29
+ right: 10px;
30
+ margin-top: -0.9em;
31
+ padding: 0 0.5em;
32
+ background-color: #ECEEF1;
33
+ color: #363947;
34
+ border-radius: 4px;
35
+ font-size: 80%;
36
+ line-height: 1.8;
37
+ }
38
+
39
+ #container {
40
+ position: relative;
41
+ margin: 0 auto;
42
+ width: 100%;
43
+ height: 100%;
44
+ overflow: hidden;
45
+
46
+ #report {
47
+ background-color: #58BE89;
48
+ color: #fff;
49
+
50
+ .report-id {
51
+ position: relative;
52
+ font-size: 100%;
53
+ height: 50px;
54
+ line-height: 50px;
55
+ margin: 0;
56
+ padding: 0 20px;
57
+ }
58
+
59
+ .tabs {
60
+ display: -webkit-flex;
61
+ display: flex;
62
+ -webkit-flex-direction: row;
63
+ flex-direction: row;
64
+ -webkit-flex-wrap: nowrap;
65
+ flex-wrap: nowrap;
66
+ -webkit-justify-content: space-around;
67
+ justify-content: space-around;
68
+
69
+ a {
70
+ display: block;
71
+ -webkit-flex-grow: 1; /* Safari */
72
+ flex-grow: 1;
73
+ height: 30px;
74
+ margin: 0 20px;
75
+ line-height: 30px;
76
+ font-size: 14px;
77
+ text-align: center;
78
+ color: #fff;
79
+ text-decoration: none;
80
+
81
+ &.tab-sources {
82
+ background-color: #0E7AC4;
83
+ }
84
+ &.tab-events {
85
+ background-color: #FBA848;
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ #details {
92
+ position: absolute;
93
+ top: 80px;
94
+ left: 0;
95
+ right: 0;
96
+ bottom: 0;
97
+ overflow: hidden;
98
+ }
99
+ }
100
+
101
+ #sources, #events {
102
+ display: none;
103
+ &.active {
104
+ z-index: 1;
105
+ display: block;
106
+ }
107
+ }
108
+
109
+ #sources {
110
+ font-family: monospace;
111
+ position: absolute;
112
+ top: 0;
113
+ left: 0;
114
+ right: 0;
115
+ bottom: 0;
116
+
117
+ #source-list,
118
+ #source-code {
119
+ position: absolute;
120
+ top: 0;
121
+ bottom: 0;
122
+ overflow-y: auto;
123
+ }
124
+
125
+ #source-list {
126
+ left: 0;
127
+ width: 30%;
128
+ word-break: break-all;
129
+
130
+ a {
131
+ display: block;
132
+ background-color: #0E7AC4;
133
+ color: #fff;
134
+ text-decoration: none;
135
+ padding: 10px 20px;
136
+
137
+ &.active, &:hover, &:active, &:target {
138
+ background-color: darken(#0E7AC4, 30%);
139
+ }
140
+ }
141
+ }
142
+
143
+ #source-code {
144
+ left: 30%;
145
+ right: 0;
146
+ background-color: #202223;
147
+ }
148
+ }
149
+
150
+ .clearfix:after {
151
+ content:"";
152
+ display:block;
153
+ clear:both;
154
+ }
155
+
156
+ .source {
157
+ display: none;
158
+
159
+ &.active {
160
+ display: block;
161
+ }
162
+
163
+ .filename {
164
+ font-size: 100%;
165
+ background-color: #0E7AC4;
166
+ margin: 0;
167
+
168
+ a {
169
+ display: block;
170
+ padding: 1em 2em;
171
+ color: #fff;
172
+ text-decoration: none;
173
+ }
174
+ }
175
+
176
+ .source-code {
177
+ background-color: #202223;
178
+ color: #fff;
179
+ line-height: 1.5;
180
+ }
181
+
182
+ .header {
183
+ margin-bottom: 5px;
184
+ padding-bottom: 10px;
185
+ border-bottom: 1px solid #fff;
186
+ }
187
+
188
+ .line-infos {
189
+ float: left;
190
+ padding: 10px 0;
191
+ }
192
+
193
+ .line-info {
194
+ @extend .clearfix;
195
+
196
+ & > * {
197
+ padding: 0 .5em;
198
+ float: left;
199
+ }
200
+
201
+ .line-cpu, .line-wall {
202
+ width: 6em;
203
+ text-align: right;
204
+ }
205
+
206
+ .line-allocs {
207
+ width: 6em;
208
+ text-align: right;
209
+ }
210
+
211
+ .line-calls {
212
+ width: 5em;
213
+ }
214
+
215
+ .line-no {
216
+ width: 3em;
217
+ padding: 0;
218
+
219
+ a {
220
+ display: block;
221
+ color: inherit;
222
+ text-decoration: none;
223
+ text-align: right;
224
+ }
225
+ }
226
+ }
227
+
228
+ .line-info,
229
+ .line-code {
230
+ &.focus {
231
+ font-weight: bold;
232
+ color: #F27398;
233
+ }
234
+ }
235
+
236
+ pre.line-codes {
237
+ overflow-x: auto;
238
+ margin: 0;
239
+ padding: 10px 0;
240
+
241
+ .line-code {
242
+ padding-left: 2em;
243
+ padding-right: 2em;
244
+ }
245
+ }
246
+
247
+ }
248
+
249
+ #events {
250
+ position: absolute;
251
+ top: 0;
252
+ left: 0;
253
+ right: 0;
254
+ bottom: 0;
255
+ overflow-y: auto;
256
+ background-color: #fff;
257
+ padding-bottom: 30px;
258
+ }
259
+
260
+ .event {
261
+ .event-name {
262
+ position: relative;
263
+ margin: 0;
264
+ padding: 0;
265
+ font-size: 120%;
266
+ background-color: #FBA848;
267
+
268
+ a {
269
+ display: block;
270
+ padding: 10px 20px;
271
+ color: #fff;
272
+ text-decoration: none;
273
+ }
274
+ }
275
+
276
+ .event-payload {
277
+ display: none;
278
+ }
279
+
280
+ &.expand {
281
+ .event-payload {
282
+ display: block;
283
+ }
284
+ }
285
+
286
+ .payload {
287
+ font-family: monospace;
288
+ border-collapse: collapse;
289
+ border: 0;
290
+
291
+ td {
292
+ word-break: break-all;
293
+ padding: 5px 10px;
294
+ }
295
+
296
+ td.table {
297
+ padding: 0;
298
+ }
299
+
300
+ td.payload-key {
301
+ vertical-align: top;
302
+ min-width: 12em;
303
+ background-color: #ECEEF1;
304
+ }
305
+
306
+ .backtraces {
307
+ margin: 0;
308
+ padding: 0;
309
+ list-style: none outside;
310
+
311
+ a {
312
+ display: block;
313
+ text-decoration: none;
314
+ color: #0E7AC4;
315
+ }
316
+ }
317
+ }
318
+
319
+ .event-children {
320
+ padding-left: 30px;
321
+ }
322
+ }
@@ -0,0 +1,57 @@
1
+ doctype 5
2
+ html
3
+ head
4
+ meta(charset="UTF-8")
5
+ link(rel="stylesheet" href="#{File.join(SpeedGun.config.prefix, '/report.css')}")
6
+ script(src="https://code.jquery.com/jquery-3.0.0.min.js")
7
+ script(src="#{File.join(SpeedGun.config.prefix, '/report.js')}")
8
+ title #{@report.id} - Speed Gun
9
+ body
10
+ #container
11
+ #report
12
+ h1.report-id
13
+ = @report.id
14
+ span.duration-ms= "% 4.1fms" % (@report.duration * 1000.0)
15
+ .tabs
16
+ a.tab-events(href="#events") Events
17
+ a.tab-sources(href="#sources") Sources
18
+
19
+ #details
20
+ #events.active
21
+ == partial('events', locals: { events: @events })
22
+
23
+ #sources
24
+ #source-list
25
+ - @report.sources.each do |source|
26
+ .source-link
27
+ a(href="#file-#{line_id(source.file, 0)}")
28
+ span.shortpath= File.basename(source.file)
29
+ span.fullpath= source.file
30
+ #source-code
31
+ - @report.sources.each do |source|
32
+ .source(id="file-#{line_id(source.file, 0)}")
33
+ h3.filename
34
+ a(href="#file-#{line_id(source.file, 0)}")
35
+ span.shortpath= File.basename(source.file)
36
+ span.fullpath= source.file
37
+ .source-code
38
+ .line-infos
39
+ .line-info.header
40
+ .line-cpu CPU
41
+ .line-wall Wall
42
+ .line-allocs Allocs
43
+ .line-calls Calls
44
+ .line-no No.
45
+ - source.lines.each do |line|
46
+ .line-info(id="line-#{line_id(source.file, line.line)}")
47
+ .line-cpu= "% 8.1fms" % (line.cpu / 1000.0)
48
+ .line-wall= "% 8.1fms" % ((line.wall - line.cpu) / 1000.0)
49
+ .line-allocs= line.allocations
50
+ .line-calls= "% 4d" % line.calls
51
+ .line-no
52
+ a(href="#line-#{line_id(source.file, line.line)}")= "% 5d" % line.line
53
+ pre.line-codes
54
+ .line-code.header Code
55
+ - source.lines.each do |line|
56
+ .line-code(id="line-code-#{line_id(source.file, line.line)}")= line.code
57
+
@@ -0,0 +1,53 @@
1
+ require 'sinatra/base'
2
+ require 'sinatra/partial'
3
+ require 'slim'
4
+ require 'sass'
5
+ require 'speed_gun'
6
+
7
+ class SpeedGun::App < Sinatra::Base
8
+ configure do
9
+ root_dir = File.join(File.dirname(__FILE__), 'app')
10
+ set :root, root_dir
11
+ set :public_folder, File.join(root_dir, 'public')
12
+ set :views, File.join(root_dir, 'views')
13
+ register Sinatra::Partial
14
+ set :partial_template_engine, :slim
15
+ end
16
+
17
+ helpers do
18
+ def line_id(filename, line)
19
+ Digest::SHA256.hexdigest("#{filename}:#{line}")
20
+ end
21
+ end
22
+
23
+ get '/report.css' do
24
+ content_type 'text/css', :charset => 'utf-8'
25
+ scss :report
26
+ end
27
+
28
+ get '/reports/:id' do
29
+ @report = SpeedGun.get_report(params[:id])
30
+ halt 404 unless @report
31
+
32
+ @events = treeish_events(@report.events)
33
+
34
+ slim :report
35
+ end
36
+
37
+ private
38
+
39
+ def treeish_events(events)
40
+ root = []
41
+ prev_events = []
42
+ events.sort_by(&:started_at).each do |event|
43
+ prev_events.reject! { |pv| pv.roughly_finished_at < event.started_at }
44
+ if prev_events.empty?
45
+ root.push(event)
46
+ else
47
+ prev_events.last.children.push(event)
48
+ end
49
+ prev_events.push(event)
50
+ end
51
+ root
52
+ end
53
+ end
@@ -1,50 +1,43 @@
1
- require 'hashie'
1
+ # frozen_string_literal: true
2
+ require 'logger'
2
3
  require 'speed_gun'
3
4
  require 'speed_gun/store/memory_store'
4
5
 
5
- class SpeedGun::Config < Hashie::Dash
6
- # @!attribute [rw]
7
- # @return [Boolean] true if enabled speed gun
8
- property :enable, default: true
6
+ class SpeedGun::Config
7
+ DEFAULT_PREFIX = '/speed_gun'
9
8
 
10
- # @!attribute [rw]
11
- # @return [Object, nil] logger of the speed gun
12
- property :logger, default: nil
9
+ # @return [Boolean] Enabled SpeedGun
10
+ attr_accessor :enabled
11
+ attr_accessor :webapp
13
12
 
14
- # @!attribute [rw]
15
- # @return [Array<Regexp>] paths of skip the speed gun
16
- property :skip_paths, default: []
13
+ attr_accessor :store
17
14
 
18
- # @!attribute [rw]
19
- # @return [SpeedGun::Store] store of events and profiles
20
- property :store, default: SpeedGun::Store::MemoryStore.new
15
+ # @return [String] Console and API endpoint prefix
16
+ attr_accessor :prefix
21
17
 
22
- # @!attribute [rw]
23
- # @return [Boolean] true if enable auto injection
24
- property :auto_inject, default: true
18
+ attr_accessor :logger
25
19
 
26
- # @return [true]
27
- def enable!
28
- self[:enable] = true
29
- end
20
+ attr_accessor :skip_paths
21
+ attr_accessor :lineprof_paths
22
+ attr_accessor :ignored_profilers
30
23
 
31
- # @return [false]
32
- def disable!
33
- self[:enable] = false
24
+ def initialize
25
+ @enabled = true
26
+ @webapp = true
27
+ @store = SpeedGun::Store::MemoryStore.new
28
+ @prefix = DEFAULT_PREFIX
29
+ @logger = ::Logger.new(STDOUT)
30
+ @skip_paths = ['/favicon.ico']
31
+ @lineprof_paths = []
32
+ @ignored_profilers = []
34
33
  end
35
34
 
36
- # @return [Boolean] true if enabled speed gun
35
+ # @return [Boolean] Enabled SpeedGun
37
36
  def enabled?
38
- !!enable
37
+ enabled
39
38
  end
40
39
 
41
- # @return [Boolean] true if disabled speed gun
42
40
  def disabled?
43
41
  !enabled?
44
42
  end
45
-
46
- # @return [Boolean] true if enable auto injection
47
- def auto_inject?
48
- auto_inject
49
- end
50
43
  end
@@ -1,63 +1,54 @@
1
+ # frozen_string_literal: true
2
+ require 'securerandom'
1
3
  require 'speed_gun'
2
4
 
3
5
  class SpeedGun::Event
4
- def self.from_hash(id, hash)
5
- event = new(
6
- hash['name'],
7
- hash['payload'],
8
- Time.at(hash['started_at']),
9
- hash['finished_at'] ? Time.at(hash['finished_at']) : nil
10
- )
11
- event.instance_variable_set(:@id, id)
12
-
13
- event
14
- end
15
-
16
- # @return [String] event ID
6
+ # @return [String] Event ID
17
7
  attr_reader :id
18
-
19
- # @return [String] event name
8
+ # @return [String] Event name
20
9
  attr_reader :name
21
-
22
- # @return [Hashie::Mash] payload
10
+ # @return [Hash] Event payload
23
11
  attr_reader :payload
24
-
25
- # @return [Time] start time
12
+ # @return [Time] Started time of event
26
13
  attr_reader :started_at
27
-
28
- # @return [Time, nil] finish time
14
+ # @return [Time, nil] Finished time of event
29
15
  attr_reader :finished_at
16
+ attr_reader :children
17
+
18
+ def self.from_hash(hash, id = nil)
19
+ new(
20
+ hash['name'],
21
+ hash['payload'],
22
+ Time.at(hash['started_at'].to_f),
23
+ hash['finished_at'] ? Time.at(hash['finished_at']) : nil
24
+ ).tap do |event|
25
+ event.instance_variable_set(:@id, id) if id
26
+ end
27
+ end
30
28
 
31
- # @param name [String] event name
32
- # @param payload [Hash] payload
33
- # @param started_at [Time] start time
34
- # @param finished_at [Time, nil] finish time
35
- # @return [SpeedGun::Event] instance of SpeedGun::Event
36
29
  def initialize(name, payload = {}, started_at = Time.now, finished_at = nil)
37
30
  @id = SecureRandom.uuid
38
- @name = name
39
- @payload = Hashie::Mash.new(payload)
31
+ @name = name.to_s
32
+ @payload = payload
40
33
  @started_at = started_at
41
34
  @finished_at = finished_at
35
+ @children = []
42
36
  end
43
37
 
44
- # Finish event
45
- #
46
- # @return [Time] finish time
47
38
  def finish!
48
39
  @finished_at = Time.now
49
40
  end
50
41
 
51
- # @return [true, false] true if the event is finished
52
42
  def finished?
53
- !@finished_at.nil?
43
+ @finished_at
44
+ end
45
+
46
+ def roughly_finished_at
47
+ finished_at || started_at
54
48
  end
55
49
 
56
- # Time duration of the event
57
- #
58
- # @return [Float] a duration of the event
59
50
  def duration
60
- finished? ? finished_at.to_f - started_at.to_f : -1
51
+ finished_at ? finished_at.to_f - started_at.to_f : 0
61
52
  end
62
53
 
63
54
  def to_hash
@@ -65,8 +56,7 @@ class SpeedGun::Event
65
56
  'name' => name,
66
57
  'payload' => payload,
67
58
  'started_at' => started_at.to_f,
68
- 'finished_at' => finished? ? finished_at.to_f : nil,
69
- 'duration' => duration
59
+ 'finished_at' => finished? ? finished_at.to_f : nil
70
60
  }
71
61
  end
72
62
  end
@@ -1,14 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun/profiler/active_support_notifications_profiler'
2
3
 
3
- class SpeedGun::Profiler::ActionControllerProfiler <
4
- SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
-
4
+ class SpeedGun::Profiler::ActionControllerProfiler < SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
6
5
  subscribe(
7
- /^(process_action|send_file|send_data|redirect_to)\.action_controller$/,
6
+ %r{\.action_controller$},
8
7
  [:request]
9
8
  )
10
-
11
- def self.name
12
- 'action_controller'
13
- end
14
9
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ require 'speed_gun/profiler/active_support_notifications_profiler'
3
+
4
+ class SpeedGun::Profiler::ActionMailerProfiler < SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
+ subscribe %r{\.action_mailer$}
6
+ end
7
+
@@ -1,11 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun/profiler/active_support_notifications_profiler'
2
3
 
3
- class SpeedGun::Profiler::ActionViewProfiler <
4
- SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
-
6
- subscribe /^!(render_template|render_partial)\.action_view$/
7
-
8
- def self.name
9
- 'action_view'
10
- end
4
+ class SpeedGun::Profiler::ActionViewProfiler < SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
+ subscribe %r{\.action_view$}
11
6
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ require 'speed_gun/profiler/active_support_notifications_profiler'
3
+
4
+ class SpeedGun::Profiler::ActiveJobProfiler < SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
+ subscribe %r{\.active_job$}
6
+ end
@@ -1,11 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun/profiler/active_support_notifications_profiler'
2
3
 
3
- class SpeedGun::Profiler::ActiveRecordProfiler <
4
- SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
-
6
- subscribe(/\.active_record$/, [:binds])
7
-
8
- def self.name
9
- 'active_record'
10
- end
4
+ class SpeedGun::Profiler::ActiveRecordProfiler < SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
+ subscribe(%r{\.active_record$}, [:binds])
11
6
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'speed_gun/profiler'
2
3
 
3
4
  class SpeedGun::Profiler::ActiveSupportNotificatiosProfiler < SpeedGun::Profiler
@@ -8,10 +9,8 @@ class SpeedGun::Profiler::ActiveSupportNotificatiosProfiler < SpeedGun::Profiler
8
9
  end
9
10
  end
10
11
 
11
- def self.record(event, name, started, ended, id, payload, ignore_payload)
12
- name = "#{self.name}.#{name.sub(event, '\1')}"
13
-
14
- payload.symbolize_keys!
12
+ def self.record(event, name, started, ended, _id, payload, ignore_payload)
13
+ payload = payload.symbolize_keys
15
14
 
16
15
  ignore_payload.each do |key|
17
16
  payload.delete(key)
@@ -20,10 +19,14 @@ class SpeedGun::Profiler::ActiveSupportNotificatiosProfiler < SpeedGun::Profiler
20
19
  payload[:backtrace] = backtrace
21
20
 
22
21
  event = SpeedGun::Event.new(name, payload, started, ended)
23
- SpeedGun.current_profile.record!(event)
22
+ SpeedGun.current_report.record(event)
24
23
  end
25
24
 
26
25
  def self.backtrace
27
- Rails.backtrace_cleaner.clean(caller[2..-1])
26
+ Rails.backtrace_cleaner.clean(caller[2..-1]).map do |called|
27
+ filename, line, trace = *called.split(':', 3)
28
+ filename = File.expand_path(filename)
29
+ [filename, line.to_i, trace]
30
+ end
28
31
  end
29
32
  end