speed_gun 0.0.4 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/Rakefile +6 -1
  6. data/lib/speed_gun/app/views/meter.html.slim +4 -9
  7. data/lib/speed_gun/config.rb +33 -42
  8. data/lib/speed_gun/event.rb +72 -0
  9. data/lib/speed_gun/middleware.rb +43 -43
  10. data/lib/speed_gun/profile.rb +102 -0
  11. data/lib/speed_gun/profiler/action_controller_profiler.rb +14 -0
  12. data/lib/speed_gun/profiler/action_view_profiler.rb +11 -0
  13. data/lib/speed_gun/profiler/active_record_profiler.rb +11 -0
  14. data/lib/speed_gun/profiler/active_support_notifications_profiler.rb +29 -0
  15. data/lib/speed_gun/profiler/rack_profiler.rb +7 -0
  16. data/lib/speed_gun/profiler.rb +11 -118
  17. data/lib/speed_gun/railtie.rb +7 -16
  18. data/lib/speed_gun/store/elastic_search_store.rb +64 -0
  19. data/lib/speed_gun/store/fluent_logger_store.rb +29 -0
  20. data/lib/speed_gun/store/memcache_store.rb +40 -0
  21. data/lib/speed_gun/store/memory_store.rb +23 -0
  22. data/lib/speed_gun/store/multiple_store.rb +23 -0
  23. data/lib/speed_gun/store/redis_store.rb +41 -0
  24. data/lib/speed_gun/store.rb +7 -3
  25. data/lib/speed_gun/template.rb +1 -1
  26. data/lib/speed_gun/version.rb +1 -1
  27. data/lib/speed_gun.rb +30 -39
  28. data/spec/lib/speed_gun/config_spec.rb +37 -0
  29. data/spec/lib/speed_gun/event_spec.rb +70 -0
  30. data/spec/lib/speed_gun/middleware_spec.rb +65 -0
  31. data/spec/lib/speed_gun/profile_spec.rb +41 -0
  32. data/spec/lib/speed_gun_spec.rb +52 -0
  33. data/spec/spec_helper.rb +9 -0
  34. data/spec/support/simplecov.rb +12 -0
  35. data/speed_gun.gemspec +10 -7
  36. metadata +102 -56
  37. data/app/assets/javascripts/browser.js +0 -83
  38. data/app/assets/javascripts/profiler.js +0 -45
  39. data/app/views/speed_gun/_meter.html.slim +0 -9
  40. data/lib/speed_gun/app/public/browser.js +0 -83
  41. data/lib/speed_gun/app/public/jquery-1.10.2.min.js +0 -6
  42. data/lib/speed_gun/app/public/profile.js +0 -5
  43. data/lib/speed_gun/app/public/profiler.js +0 -45
  44. data/lib/speed_gun/app/public/style.css +0 -170
  45. data/lib/speed_gun/app/views/profile.slim +0 -97
  46. data/lib/speed_gun/app.rb +0 -58
  47. data/lib/speed_gun/browser/navigation.rb +0 -23
  48. data/lib/speed_gun/browser/timing.rb +0 -92
  49. data/lib/speed_gun/browser.rb +0 -22
  50. data/lib/speed_gun/hook.rb +0 -25
  51. data/lib/speed_gun/profiler/action_controller.rb +0 -12
  52. data/lib/speed_gun/profiler/action_view.rb +0 -12
  53. data/lib/speed_gun/profiler/active_record.rb +0 -16
  54. data/lib/speed_gun/profiler/base.rb +0 -139
  55. data/lib/speed_gun/profiler/js.rb +0 -17
  56. data/lib/speed_gun/profiler/manual.rb +0 -14
  57. data/lib/speed_gun/profiler/rack.rb +0 -7
  58. data/lib/speed_gun/store/base.rb +0 -9
  59. data/lib/speed_gun/store/file.rb +0 -62
  60. data/lib/speed_gun/store/memcache.rb +0 -27
  61. data/lib/speed_gun/store/memory.rb +0 -22
  62. data/lib/speed_gun/store/redis.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c07e8960feed86caf19a06706d295b3418a8ce2e
4
- data.tar.gz: aef33393a26ad7f812960adf25e225eb0216195f
3
+ metadata.gz: a38f7425f4a2a540896f5b7a966cc5585c28de8c
4
+ data.tar.gz: 5475d18a057f641dd22f573bded80f1f5ffde58d
5
5
  SHA512:
6
- metadata.gz: bbf60d69bed4567f0e323a3018ed9f36212f37c0a7bb9d9f7b9f279fc59df400b0c0fb55b3e50c0bba8d1bf055c114d6b75594c4e175b73368edf8a6b2446cfa
7
- data.tar.gz: 1fdc3c2b9e5edadafb1a0b0eee4738d73e5aeb9d10bd4e9ac882eb1ed5e7b0e763653924b5f96e7d746f425ffd6c9ec537b31cd72309f72d2d6f7f902ffb6a5d
6
+ metadata.gz: 520937f45fcee60a4f24d187d85ccfc204b0c059dd3604ac0196db7880e5b46cf8fc011da5e26b513560ac62a252543af734e27862c8c64871253e805db72382
7
+ data.tar.gz: 24f430cd3d83e1eb25d31db0de0004ae359b1745e8f548cd46ac9d724af9d571ccf26e007dfef870007520c71a173dd0458a499fcba07d7864a97b01f2285a83
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - ruby-head
4
+ - 2.1.0
5
+ - 2.0.0
6
+ - 1.9.3
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -1,9 +1,4 @@
1
- #speed_gun(data-speed-gun-endpoint="#{SpeedGun.config.prefix}/profile" data-speed-gun-id="#{SpeedGun.current.id}" data-rack-ms="#{SpeedGun.current.profiles.first.elapsed_time * 1000}")
2
- - if SpeedGun.config.show_button?
3
- #speed_gun_button(style="position: fixed; bottom: 10px; right: 10px;")
4
- a#toggle_speed_gun(href="#{File.join(SpeedGun.config.prefix, 'profile', SpeedGun.current.id)}" target="_blank" style="display: block; padding: 2px 5px; font-size: 9px; line-height: 2; box-shadow: 0 0 2px #333; background-color: #fff; color: #333; text-decoration: none; border-radius: 3px;")
5
- span#speed_gun_total(style="vertical-align: middle;")
6
- - unless SpeedGun.config.no_include_jquery?
7
- script(type="text/javascript" src="#{SpeedGun.config.prefix}/jquery-1.10.2.min.js")
8
- script(type="text/javascript" src="#{SpeedGun.config.prefix}/browser.js")
9
- script(type="text/javascript" src="#{SpeedGun.config.prefix}/profiler.js")
1
+ div.speed-gun(style="position: fixed; bottom: -1px; right: -1px; border: 1px solid #999; border-radius: 3px 0 0 0; background-color: white; font-size: 9px;")
2
+ a(href="#" style="display: block; padding: 5px 10px")
3
+ = "%0.2f" % (duration * 1000)
4
+ | ms
@@ -1,59 +1,50 @@
1
+ require 'hashie'
1
2
  require 'speed_gun'
3
+ require 'speed_gun/store/memory_store'
2
4
 
3
- class SpeedGun::Config < Hash
4
- def enable?
5
- enable && enable_if.call
6
- end
7
-
8
- def enable
9
- fetch(:enable, true)
10
- end
5
+ class SpeedGun::Config < Hashie::Dash
6
+ # @!attribute [rw]
7
+ # @return [Boolean] true if enabled speed gun
8
+ property :enable, default: true
11
9
 
12
- def enable_if
13
- self[:enable_if] ||= -> { true }
14
- end
10
+ # @!attribute [rw]
11
+ # @return [Object, nil] logger of the speed gun
12
+ property :logger, default: nil
15
13
 
16
- def prefix
17
- self[:prefix] ||= '/speed_gun'
18
- end
14
+ # @!attribute [rw]
15
+ # @return [Array<Regexp>] paths of skip the speed gun
16
+ property :skip_paths, default: []
19
17
 
20
- def prefix_regexp
21
- self[:prefix_regexp] ||= /^#{Regexp.escape(prefix)}/x
22
- end
18
+ # @!attribute [rw]
19
+ # @return [SpeedGun::Store] store of events and profiles
20
+ property :store, default: SpeedGun::Store::MemoryStore.new
23
21
 
24
- def store
25
- self[:store] ||= SpeedGun::Store::Memory.new
26
- end
22
+ # @!attribute [rw]
23
+ # @return [Boolean] true if enable auto injection
24
+ property :auto_inject, default: true
27
25
 
28
- def auto_inject?
29
- fetch(:auto_inject, true)
26
+ # @return [true]
27
+ def enable!
28
+ self[:enable] = true
30
29
  end
31
30
 
32
- def backtrace_remove
33
- self[:backtrace_remove] ||= ''
31
+ # @return [false]
32
+ def disable!
33
+ self[:enable] = false
34
34
  end
35
35
 
36
- def backtrace_includes
37
- self[:backtrace_includes] ||= []
36
+ # @return [Boolean] true if enabled speed gun
37
+ def enabled?
38
+ !!enable
38
39
  end
39
40
 
40
- def show_button?
41
- fetch(:show_button, true)
41
+ # @return [Boolean] true if disabled speed gun
42
+ def disabled?
43
+ !enabled?
42
44
  end
43
45
 
44
- def no_include_jquery?
45
- fetch(:no_include_jquery, false)
46
- end
47
-
48
- def skip_paths
49
- self[:skip_paths] ||= [/favicon/]
50
- end
51
-
52
- def force_profile?
53
- fetch(:force_profile, true)
54
- end
55
-
56
- def authorize_proc
57
- self[:authorize_proc] ||= ->(request) { true }
46
+ # @return [Boolean] true if enable auto injection
47
+ def auto_inject?
48
+ auto_inject
58
49
  end
59
50
  end
@@ -0,0 +1,72 @@
1
+ require 'speed_gun'
2
+
3
+ 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
17
+ attr_reader :id
18
+
19
+ # @return [String] event name
20
+ attr_reader :name
21
+
22
+ # @return [Hashie::Mash] payload
23
+ attr_reader :payload
24
+
25
+ # @return [Time] start time
26
+ attr_reader :started_at
27
+
28
+ # @return [Time, nil] finish time
29
+ attr_reader :finished_at
30
+
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
+ def initialize(name, payload = {}, started_at = Time.now, finished_at = nil)
37
+ @id = SecureRandom.uuid
38
+ @name = name
39
+ @payload = Hashie::Mash.new(payload)
40
+ @started_at = started_at
41
+ @finished_at = finished_at
42
+ end
43
+
44
+ # Finish event
45
+ #
46
+ # @return [Time] finish time
47
+ def finish!
48
+ @finished_at = Time.now
49
+ end
50
+
51
+ # @return [true, false] true if the event is finished
52
+ def finished?
53
+ !@finished_at.nil?
54
+ end
55
+
56
+ # Time duration of the event
57
+ #
58
+ # @return [Float] a duration of the event
59
+ def duration
60
+ finished? ? finished_at.to_f - started_at.to_f : -1
61
+ end
62
+
63
+ def to_hash
64
+ {
65
+ 'name' => name,
66
+ 'payload' => payload,
67
+ 'started_at' => started_at.to_f,
68
+ 'finished_at' => finished? ? finished_at.to_f : nil,
69
+ 'duration' => duration
70
+ }
71
+ end
72
+ end
@@ -1,60 +1,70 @@
1
1
  require 'speed_gun'
2
- require 'speed_gun/app'
3
- require 'speed_gun/profiler'
4
- require 'speed_gun/profiler/rack'
5
2
  require 'speed_gun/template'
3
+ require 'speed_gun/profiler/rack_profiler'
6
4
 
7
5
  class SpeedGun::Middleware
8
- BODY_END_REGEXP = /<\/(?:body|html)>/
6
+ BODY_END_REGEXP = /<\/(?:body|html)>/i
9
7
 
8
+ # @param app [#call] Rack application
9
+ # @return [SpeedGun::Middleware] a instance of SpeedGun::Middleware
10
10
  def initialize(app)
11
11
  @app = app
12
12
  end
13
13
 
14
+ # Handle rack request
15
+ #
16
+ # @return [Rack::Response]
14
17
  def call(env)
15
- return SpeedGun::App.call(env) if under_speed_gun?(env)
18
+ if with_speed_gun?(env)
19
+ call_with_speed_gun(env)
20
+ else
21
+ call_without_speed_gun(env)
22
+ end
23
+ end
16
24
 
17
- SpeedGun.current = SpeedGun::Profiler.new(env) if SpeedGun.enable?
25
+ private
18
26
 
19
- call_with_speed_gun(env)
20
- ensure
21
- SpeedGun.current = nil
27
+ def with_speed_gun?(env)
28
+ SpeedGun.enabled? && !skip?(env['PATH_INFO'])
22
29
  end
23
30
 
24
- private
31
+ def skip?(path)
32
+ SpeedGun.config.skip_paths.any? { |regexp| regexp.match(path) }
33
+ end
25
34
 
26
- def call_with_speed_gun(env)
27
- remove_conditional_get_headers(env)
35
+ def call_without_speed_gun(env)
36
+ @app.call(env)
37
+ end
28
38
 
29
- status, headers, body = *SpeedGun.current.profile(:rack) { @app.call(env) }
39
+ def call_with_speed_gun(env)
40
+ SpeedGun.current_profile = SpeedGun::Profile.new
41
+ SpeedGun.current_profile.request_method = env['REQUEST_METHOD'].to_s.upcase
42
+ SpeedGun.current_profile.path = env['PATH_INFO'].to_s
43
+ SpeedGun.current_profile.query = env['QUERY_STRING'].to_s
30
44
 
31
- if SpeedGun.active?
32
- inject_header(headers)
33
- SpeedGun.current.dump
45
+ response = SpeedGun::Profiler::RackProfier.profile do
46
+ call_without_speed_gun(env)
34
47
  end
35
48
 
36
- if SpeedGun.config.auto_inject? && SpeedGun.active?
37
- inject_body(status, headers, body)
38
- else
39
- return [status, headers, body]
40
- end
41
- end
49
+ SpeedGun.current_profile.status = response[0]
42
50
 
43
- def remove_conditional_get_headers(env)
44
- return if !SpeedGun.config.force_profile? && SpeedGun.active?
51
+ if SpeedGun.current_profile.active?
52
+ inject_header(response[1])
53
+ if SpeedGun.current_profile.config.auto_inject?
54
+ response = inject_body(*response)
55
+ end
56
+ end
45
57
 
46
- env['HTTP_IF_MODIFIED_SINCE'] = ''
47
- env['HTTP_IF_NONE_MATCH'] = ''
58
+ response
59
+ ensure
60
+ if SpeedGun.current_profile.active?
61
+ SpeedGun.config.store.save(SpeedGun.current_profile)
62
+ end
63
+ SpeedGun.discard_profile!
48
64
  end
49
65
 
50
66
  def inject_header(headers)
51
- if SpeedGun.config.force_profile?
52
- headers.delete('ETag')
53
- headers.delete('Date')
54
- headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
55
- end
56
-
57
- headers['X-SPEEDGUN-ID'] = SpeedGun.current.id
67
+ headers['X-SpeedGun-Profile-Id'] = SpeedGun.current_profile.id
58
68
  end
59
69
 
60
70
  def inject_body(status, headers, body)
@@ -78,14 +88,4 @@ class SpeedGun::Middleware
78
88
  SpeedGun::Template.render + matched
79
89
  end
80
90
  end
81
-
82
- def under_speed_gun?(env)
83
- if SpeedGun.config.prefix_regexp.match(env['PATH_INFO'])
84
- env['PATH_INFO'] =
85
- env['PATH_INFO'].sub(SpeedGun.config.prefix_regexp, '')
86
- true
87
- else
88
- false
89
- end
90
- end
91
91
  end
@@ -0,0 +1,102 @@
1
+ require 'securerandom'
2
+ require 'speed_gun'
3
+ require 'speed_gun/event'
4
+
5
+ class SpeedGun::Profile
6
+ def self.from_hash(id, hash)
7
+ profile = new
8
+
9
+ hash['events'].map! do |event_id|
10
+ SpeedGun.config.store.load(SpeedGun::Event, event_id)
11
+ end
12
+
13
+ hash['id'] = id
14
+ hash.delete('duration')
15
+ hash.each_pair do |key, val|
16
+ profile.instance_variable_set(:"@#{key}", val)
17
+ end
18
+
19
+ profile
20
+ end
21
+
22
+ # @return [String] profile ID
23
+ attr_reader :id
24
+
25
+ # @return [Array<SpeedGun::Event>] recorded events
26
+ attr_reader :events
27
+
28
+ # @return [SpeedGun::Config] the config of the profile
29
+ attr_reader :config
30
+
31
+ # @return [Integer] status code of the response
32
+ attr_accessor :status
33
+
34
+ # @return [String] method of the request
35
+ attr_accessor :request_method
36
+
37
+ # @return [String] path of the request
38
+ attr_accessor :path
39
+
40
+ # @return [String] query of the request
41
+ attr_accessor :query
42
+
43
+ # @return [SpeedGun::Profile] instance of SpeedGun::Profile
44
+ def initialize(config = SpeedGun.config.dup)
45
+ @id = SecureRandom.uuid
46
+ @events = []
47
+ @config = config
48
+ @active = true
49
+ end
50
+
51
+ # Record an event
52
+ #
53
+ # @param event [SpeedGun::Event] record event
54
+ # @return [Array<SpeedGun::Event>] recorded events
55
+ def record!(event)
56
+ config.logger.debug(
57
+ "[SpeedGun] Record Event: #{event.name}: #{'%0.2f' % (event.duration * 1000)}ms"
58
+ ) if config.logger
59
+ config.store.save(event) if active?
60
+ @events.push(event)
61
+ end
62
+
63
+ def active?
64
+ @active
65
+ end
66
+
67
+ def deactive?
68
+ !active?
69
+ end
70
+
71
+ def activate!
72
+ @active = true
73
+ end
74
+
75
+ def deactivate!
76
+ @active = false
77
+ end
78
+
79
+ def earliest_started_at
80
+ @events.sort_by(&:started_at).first.started_at
81
+ end
82
+
83
+ def latest_finished_at
84
+ @events.sort_by { |event| event.finished_at || 0 }.last.finished_at
85
+ end
86
+
87
+ def duration
88
+ finished_at = latest_finished_at
89
+ finished_at ? finished_at - earliest_started_at : 0
90
+ end
91
+
92
+ def to_hash
93
+ {
94
+ 'events' => events.map(&:id),
95
+ 'status' => status,
96
+ 'request_method' => request_method,
97
+ 'path' => path,
98
+ 'query' => query,
99
+ 'duration' => duration
100
+ }
101
+ end
102
+ end
@@ -0,0 +1,14 @@
1
+ require 'speed_gun/profiler/active_support_notifications_profiler'
2
+
3
+ class SpeedGun::Profiler::ActionControllerProfiler <
4
+ SpeedGun::Profiler::ActiveSupportNotificatiosProfiler
5
+
6
+ subscribe(
7
+ /^(process_action|send_file|send_data|redirect_to)\.action_controller$/,
8
+ [:request]
9
+ )
10
+
11
+ def self.name
12
+ 'action_controller'
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ require 'speed_gun/profiler/active_support_notifications_profiler'
2
+
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
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'speed_gun/profiler/active_support_notifications_profiler'
2
+
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
11
+ end
@@ -0,0 +1,29 @@
1
+ require 'speed_gun/profiler'
2
+
3
+ class SpeedGun::Profiler::ActiveSupportNotificatiosProfiler < SpeedGun::Profiler
4
+ def self.subscribe(event, ignore_payload = [])
5
+ klass = self
6
+ ActiveSupport::Notifications.subscribe(event) do |*args|
7
+ klass.record(event, *args, ignore_payload)
8
+ end
9
+ end
10
+
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!
15
+
16
+ ignore_payload.each do |key|
17
+ payload.delete(key)
18
+ end
19
+
20
+ payload[:backtrace] = backtrace
21
+
22
+ event = SpeedGun::Event.new(name, payload, started, ended)
23
+ SpeedGun.current_profile.record!(event)
24
+ end
25
+
26
+ def self.backtrace
27
+ Rails.backtrace_cleaner.clean(caller[2..-1])
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ require 'speed_gun/profiler'
2
+
3
+ class SpeedGun::Profiler::RackProfier < SpeedGun::Profiler
4
+ def self.name
5
+ 'rack.total'
6
+ end
7
+ end
@@ -1,128 +1,21 @@
1
1
  require 'speed_gun'
2
- require 'speed_gun/store'
3
- require 'speed_gun/browser'
4
- require 'speed_gun/hook'
5
- require 'securerandom'
6
- require 'msgpack'
7
- require 'multi_json'
8
2
 
3
+ # @abstract
9
4
  class SpeedGun::Profiler
10
- PROFILERS = {}
11
-
12
- def self.load(id)
13
- src = SpeedGun.store[id]
14
-
15
- return nil unless src
16
-
17
- restore(src)
18
- end
19
-
20
- def self.restore(src)
21
- data = src.kind_of?(String) ? MessagePack.unpack(src) : src
22
-
23
- profiler = new({})
24
- profiler.restore_by_hash(data)
25
-
26
- profiler
27
- end
28
-
29
- def initialize(env)
30
- @id = SecureRandom.uuid
31
- @path = env['PATH_INFO']
32
- @query = env['QUERY_STRING']
33
- @env = env
34
- @requested_at = Time.now
35
- @profiles = []
36
- @browser = nil
37
- @active = true
38
- @now_profile = nil
39
- end
40
- attr_reader :id, :path, :query, :env, :requested_at, :profiles, :browser
41
- attr_accessor :now_profile
42
-
43
- def profile(type, *args, &block)
44
- profiler = PROFILERS[type]
45
-
46
- if profiler
47
- profiler.profile(self, *args, &block)
48
- else
49
- yield
50
- end
51
- end
52
-
53
- def skip?
54
- SpeedGun.config.skip_paths.any? { |prefix| prefix.match(@path) }
55
- end
56
-
57
- def active?
58
- @active && !skip?
59
- end
60
-
61
- def activate!
62
- @active = true
5
+ def self.profile(*args, &block)
6
+ new.profile(*args, &block)
63
7
  end
64
8
 
65
- def deactivate!
66
- @active = false
67
- end
9
+ def profile(name = self.class.name, payload = {}, &block)
10
+ starts_at = Time.now
68
11
 
69
- def dump
70
- SpeedGun.store[id] = to_msgpack
12
+ ret = yield
71
13
 
72
- SpeedGun::Hook.invoke_all(self)
73
- end
74
-
75
- def browser=(hash)
76
- @browser = SpeedGun::Browser.new(hash)
77
- end
78
-
79
- def as_msgpack(*args)
80
- {
81
- id: @id,
82
- path: @path,
83
- query: @query,
84
- env: msgpackable_env,
85
- requested_at: @requested_at.to_i,
86
- profiles: @profiles.map { |profile| profile.as_msgpack(*args) },
87
- browser: @browser ? @browser.as_msgpack(*args) : nil,
88
- }
89
- end
90
-
91
- def to_msgpack(*args)
92
- as_msgpack(*args).to_msgpack(*args)
93
- end
14
+ event = SpeedGun::Event.new(
15
+ name, payload, starts_at, Time.now
16
+ )
17
+ SpeedGun.current_profile.record!(event)
94
18
 
95
- def to_json(*args)
96
- MultiJson.dump(as_msgpack(*args))
97
- end
98
-
99
- def restore_by_hash(hash)
100
- hash.each_pair do |key, val|
101
- instance_variable_set(:"@#{key}", restore_attribute(key, val))
102
- end
103
- end
104
-
105
- def restore_attribute(key, val)
106
- case key
107
- when 'requested_at'
108
- Time.at(val)
109
- when 'profiles'
110
- val.map { |profile| SpeedGun::Profiler::Base.load(profile) }
111
- when 'browser'
112
- val ? SpeedGun::Browser.new(val) : val
113
- else
114
- val
115
- end
116
- end
117
-
118
- private
119
-
120
- def msgpackable_env
121
- env = {}
122
- @env.each_pair { |key, val| env[key] = val if key[0] =~ /[A-Z]/ }
123
- env
19
+ return ret
124
20
  end
125
21
  end
126
-
127
- require 'speed_gun/profiler/manual'
128
- require 'speed_gun/profiler/js'