skylight 0.0.16 → 0.1.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +3 -19
- data/bin/skylight +0 -2
- data/lib/skylight.rb +52 -42
- data/lib/skylight/api.rb +34 -0
- data/lib/skylight/cli.rb +68 -57
- data/lib/skylight/compat.rb +19 -5
- data/lib/skylight/config.rb +219 -98
- data/lib/skylight/gc.rb +109 -0
- data/lib/skylight/instrumenter.rb +53 -70
- data/lib/skylight/messages.rb +19 -0
- data/lib/skylight/messages/annotation.rb +13 -0
- data/lib/skylight/messages/base.rb +24 -0
- data/lib/skylight/messages/batch.rb +11 -0
- data/lib/skylight/messages/endpoint.rb +12 -0
- data/lib/skylight/messages/event.rb +12 -0
- data/lib/skylight/messages/hello.rb +53 -0
- data/lib/skylight/messages/span.rb +21 -0
- data/lib/skylight/messages/trace.rb +162 -0
- data/lib/skylight/middleware.rb +2 -4
- data/lib/skylight/normalizers.rb +89 -0
- data/lib/skylight/normalizers/default.rb +22 -0
- data/lib/skylight/normalizers/process_action.rb +19 -0
- data/lib/skylight/normalizers/render_collection.rb +14 -0
- data/lib/skylight/normalizers/render_partial.rb +14 -0
- data/lib/skylight/normalizers/render_template.rb +14 -0
- data/lib/skylight/{normalize → normalizers}/send_file.rb +15 -15
- data/lib/skylight/normalizers/sql.rb +25 -0
- data/lib/skylight/railtie.rb +21 -41
- data/lib/skylight/subscriber.rb +29 -19
- data/lib/skylight/util/clock.rb +8 -21
- data/lib/skylight/util/http.rb +93 -46
- data/lib/skylight/util/logging.rb +66 -0
- data/lib/skylight/util/queue.rb +7 -3
- data/lib/skylight/util/task.rb +154 -0
- data/lib/skylight/{compat → vendor/active_support}/notifications.rb +56 -24
- data/lib/skylight/{compat → vendor/active_support}/notifications/fanout.rb +19 -26
- data/lib/skylight/{compat → vendor/active_support}/notifications/instrumenter.rb +25 -18
- data/lib/skylight/vendor/active_support/per_thread_registry.rb +52 -0
- data/lib/skylight/vendor/beefcake.rb +256 -0
- data/lib/skylight/vendor/beefcake/buffer.rb +112 -0
- data/lib/skylight/vendor/beefcake/decode.rb +107 -0
- data/lib/skylight/vendor/beefcake/encode.rb +115 -0
- data/lib/skylight/vendor/{highline.rb → cli/highline.rb} +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/color_scheme.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/compatibility.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/import.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/menu.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/question.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/simulate.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/string_extensions.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/style.rb +0 -0
- data/lib/skylight/vendor/{highline → cli/highline}/system_extensions.rb +0 -0
- data/lib/skylight/vendor/{thor.rb → cli/thor.rb} +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/create_file.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/create_link.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/directory.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/empty_directory.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/file_manipulation.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/actions/inject_into_file.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/base.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/command.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/core_ext/hash_with_indifferent_access.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/core_ext/io_binary_read.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/core_ext/ordered_hash.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/error.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/group.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/invocation.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/argument.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/arguments.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/option.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/parser/options.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/rake_compat.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/runner.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell/basic.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell/color.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/shell/html.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/util.rb +0 -0
- data/lib/skylight/vendor/{thor → cli/thor}/version.rb +0 -0
- data/lib/skylight/vendor/thread_safe.rb +126 -0
- data/lib/skylight/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
- data/lib/skylight/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
- data/lib/skylight/version.rb +2 -1
- data/lib/skylight/worker.rb +12 -154
- data/lib/skylight/worker/builder.rb +72 -0
- data/lib/skylight/worker/collector.rb +124 -0
- data/lib/skylight/worker/connection.rb +77 -0
- data/lib/skylight/worker/embedded.rb +6 -0
- data/lib/skylight/worker/server.rb +307 -0
- data/lib/skylight/worker/standalone.rb +356 -0
- metadata +89 -77
- data/lib/skylight/connection.rb +0 -25
- data/lib/skylight/json_proto.rb +0 -88
- data/lib/skylight/normalize.rb +0 -63
- data/lib/skylight/normalize/default.rb +0 -17
- data/lib/skylight/normalize/process_action.rb +0 -17
- data/lib/skylight/normalize/render_collection.rb +0 -11
- data/lib/skylight/normalize/render_partial.rb +0 -14
- data/lib/skylight/normalize/render_template.rb +0 -13
- data/lib/skylight/normalize/sql.rb +0 -26
- data/lib/skylight/normalize/start_processing.rb +0 -12
- data/lib/skylight/sanity_checker.rb +0 -73
- data/lib/skylight/trace.rb +0 -160
- data/lib/skylight/util/atomic.rb +0 -73
- data/lib/skylight/util/bytes.rb +0 -40
- data/lib/skylight/util/ewma.rb +0 -32
- data/lib/skylight/util/uuid.rb +0 -33
data/lib/skylight/util/queue.rb
CHANGED
@@ -27,13 +27,17 @@ module Skylight
|
|
27
27
|
@mutex.synchronize { __length }
|
28
28
|
end
|
29
29
|
|
30
|
-
# Returns
|
30
|
+
# Returns the number of items in the queue or nil if the queue is full
|
31
31
|
def push(obj)
|
32
|
+
ret = nil
|
33
|
+
|
32
34
|
@mutex.synchronize do
|
33
|
-
return
|
35
|
+
return if __length == @max
|
34
36
|
@values[@produce] = obj
|
35
37
|
@produce = (@produce + 1) % @max
|
36
38
|
|
39
|
+
ret = __length
|
40
|
+
|
37
41
|
# Wakeup a blocked thread
|
38
42
|
begin
|
39
43
|
t = @waiting.shift
|
@@ -43,7 +47,7 @@ module Skylight
|
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
46
|
-
|
50
|
+
ret
|
47
51
|
end
|
48
52
|
|
49
53
|
def pop(timeout = nil)
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Skylight
|
4
|
+
module Util
|
5
|
+
class Task
|
6
|
+
SHUTDOWN = :__SK_TASK_SHUTDOWN
|
7
|
+
|
8
|
+
include Util::Logging
|
9
|
+
|
10
|
+
def initialize(size, timeout = 0.1, &blk)
|
11
|
+
@pid = Process.pid
|
12
|
+
@thread = nil
|
13
|
+
@size = size
|
14
|
+
@lock = Mutex.new
|
15
|
+
@timeout = timeout
|
16
|
+
@blk = blk
|
17
|
+
end
|
18
|
+
|
19
|
+
def submit(msg, pid = Process.pid)
|
20
|
+
return unless @pid
|
21
|
+
|
22
|
+
spawn(pid)
|
23
|
+
|
24
|
+
return unless q = @queue
|
25
|
+
|
26
|
+
!!q.push(msg)
|
27
|
+
end
|
28
|
+
|
29
|
+
def spawn(pid = Process.pid)
|
30
|
+
unless spawned?
|
31
|
+
__spawn(pid)
|
32
|
+
end
|
33
|
+
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def spawned?
|
38
|
+
!!@thread
|
39
|
+
end
|
40
|
+
|
41
|
+
def running?
|
42
|
+
spawned? && @pid
|
43
|
+
end
|
44
|
+
|
45
|
+
def shutdown(timeout = 5)
|
46
|
+
t = nil
|
47
|
+
m = false
|
48
|
+
|
49
|
+
@lock.synchronize do
|
50
|
+
t = @thread
|
51
|
+
|
52
|
+
if q = @queue
|
53
|
+
m = true
|
54
|
+
q.push(SHUTDOWN)
|
55
|
+
@pid = nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
return true if timeout && timeout < 0
|
60
|
+
return true unless t
|
61
|
+
|
62
|
+
ret = nil
|
63
|
+
|
64
|
+
begin
|
65
|
+
ret = !!t.join(timeout)
|
66
|
+
ensure
|
67
|
+
if !ret && m
|
68
|
+
begin
|
69
|
+
t.kill # FORCE KILL!!!
|
70
|
+
rescue ThreadError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
ret
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def __spawn(pid)
|
81
|
+
@lock.synchronize do
|
82
|
+
return if spawned? && @pid == pid
|
83
|
+
@pid = Process.pid
|
84
|
+
@queue = Util::Queue.new(@size)
|
85
|
+
@thread = Thread.new do
|
86
|
+
begin
|
87
|
+
unless work
|
88
|
+
@queue = nil
|
89
|
+
end
|
90
|
+
|
91
|
+
finish
|
92
|
+
rescue Exception => e
|
93
|
+
error "failed to execute task; msg=%s", e.message
|
94
|
+
t { e.backtrace.join("\n") }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
def work
|
103
|
+
return unless q = @queue
|
104
|
+
|
105
|
+
while @pid
|
106
|
+
if msg = q.pop(@timeout)
|
107
|
+
return true if SHUTDOWN == msg
|
108
|
+
|
109
|
+
unless __handle(msg)
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
else
|
113
|
+
return unless @queue
|
114
|
+
# just a tick
|
115
|
+
unless __handle(msg)
|
116
|
+
return false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Drain the queue
|
122
|
+
while msg = q.pop(0)
|
123
|
+
return true if SHUTDOWN == msg
|
124
|
+
|
125
|
+
unless __handle(msg)
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
def __handle(msg)
|
134
|
+
begin
|
135
|
+
handle(msg)
|
136
|
+
rescue Exception => e
|
137
|
+
error "error handling event; msg=%s; event=%p", e.message, msg
|
138
|
+
t { e.backtrace.join("\n") }
|
139
|
+
sleep 1
|
140
|
+
true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def handle(msg)
|
145
|
+
return true unless @blk
|
146
|
+
@blk.call(msg)
|
147
|
+
end
|
148
|
+
|
149
|
+
def finish
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -1,22 +1,24 @@
|
|
1
|
-
require 'skylight/
|
2
|
-
require 'skylight/
|
1
|
+
require 'skylight/vendor/active_support/notifications/instrumenter'
|
2
|
+
require 'skylight/vendor/active_support/notifications/fanout'
|
3
|
+
require 'skylight/vendor/active_support/per_thread_registry'
|
3
4
|
|
4
5
|
module ActiveSupport
|
5
6
|
# = Notifications
|
6
7
|
#
|
7
|
-
# <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
|
8
|
+
# <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
|
9
|
+
# Ruby.
|
8
10
|
#
|
9
11
|
# == Instrumenters
|
10
12
|
#
|
11
13
|
# To instrument an event you just need to do:
|
12
14
|
#
|
13
|
-
# ActiveSupport::Notifications.instrument(
|
14
|
-
# render :
|
15
|
+
# ActiveSupport::Notifications.instrument('render', extra: :information) do
|
16
|
+
# render text: 'Foo'
|
15
17
|
# end
|
16
18
|
#
|
17
19
|
# That executes the block first and notifies all subscribers once done.
|
18
20
|
#
|
19
|
-
# In the example above
|
21
|
+
# In the example above +render+ is the name of the event, and the rest is called
|
20
22
|
# the _payload_. The payload is a mechanism that allows instrumenters to pass
|
21
23
|
# extra information to subscribers. Payloads consist of a hash whose contents
|
22
24
|
# are arbitrary and generally depend on the event.
|
@@ -24,25 +26,35 @@ module ActiveSupport
|
|
24
26
|
# == Subscribers
|
25
27
|
#
|
26
28
|
# You can consume those events and the information they provide by registering
|
27
|
-
# a subscriber.
|
29
|
+
# a subscriber.
|
30
|
+
#
|
31
|
+
# ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload|
|
32
|
+
# name # => String, name of the event (such as 'render' from above)
|
33
|
+
# start # => Time, when the instrumented block started execution
|
34
|
+
# finish # => Time, when the instrumented block ended execution
|
35
|
+
# id # => String, unique ID for this notification
|
36
|
+
# payload # => Hash, the payload
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# For instance, let's store all "render" events in an array:
|
28
40
|
#
|
29
41
|
# events = []
|
30
42
|
#
|
31
|
-
# ActiveSupport::Notifications.subscribe(
|
43
|
+
# ActiveSupport::Notifications.subscribe('render') do |*args|
|
32
44
|
# events << ActiveSupport::Notifications::Event.new(*args)
|
33
45
|
# end
|
34
46
|
#
|
35
47
|
# That code returns right away, you are just subscribing to "render" events.
|
36
48
|
# The block is saved and will be called whenever someone instruments "render":
|
37
49
|
#
|
38
|
-
# ActiveSupport::Notifications.instrument(
|
39
|
-
# render :
|
50
|
+
# ActiveSupport::Notifications.instrument('render', extra: :information) do
|
51
|
+
# render text: 'Foo'
|
40
52
|
# end
|
41
53
|
#
|
42
54
|
# event = events.first
|
43
55
|
# event.name # => "render"
|
44
56
|
# event.duration # => 10 (in milliseconds)
|
45
|
-
# event.payload # => { :
|
57
|
+
# event.payload # => { extra: :information }
|
46
58
|
#
|
47
59
|
# The block in the <tt>subscribe</tt> call gets the name of the event, start
|
48
60
|
# timestamp, end timestamp, a string with a unique identifier for that event
|
@@ -63,7 +75,7 @@ module ActiveSupport
|
|
63
75
|
# module ActionController
|
64
76
|
# class PageRequest
|
65
77
|
# def call(name, started, finished, unique_id, payload)
|
66
|
-
# Rails.logger.debug [
|
78
|
+
# Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
|
67
79
|
# end
|
68
80
|
# end
|
69
81
|
# end
|
@@ -73,15 +85,15 @@ module ActiveSupport
|
|
73
85
|
# resulting in the following output within the logs including a hash with the payload:
|
74
86
|
#
|
75
87
|
# notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 {
|
76
|
-
# :
|
77
|
-
# :
|
78
|
-
# :
|
79
|
-
# :
|
80
|
-
# :
|
81
|
-
# :
|
82
|
-
# :
|
83
|
-
# :
|
84
|
-
# :
|
88
|
+
# controller: "Devise::SessionsController",
|
89
|
+
# action: "new",
|
90
|
+
# params: {"action"=>"new", "controller"=>"devise/sessions"},
|
91
|
+
# format: :html,
|
92
|
+
# method: "GET",
|
93
|
+
# path: "/login/sign_in",
|
94
|
+
# status: 200,
|
95
|
+
# view_runtime: 279.3080806732178,
|
96
|
+
# db_runtime: 40.053
|
85
97
|
# }
|
86
98
|
#
|
87
99
|
# You can also subscribe to all events whose name matches a certain regexp:
|
@@ -142,9 +154,9 @@ module ActiveSupport
|
|
142
154
|
notifier.publish(name, *args)
|
143
155
|
end
|
144
156
|
|
145
|
-
def instrument(name, payload = {}
|
157
|
+
def instrument(name, payload = {})
|
146
158
|
if notifier.listening?(name)
|
147
|
-
instrumenter.instrument(name, payload
|
159
|
+
instrumenter.instrument(name, payload) { yield payload if block_given? }
|
148
160
|
else
|
149
161
|
yield payload if block_given?
|
150
162
|
end
|
@@ -166,7 +178,27 @@ module ActiveSupport
|
|
166
178
|
end
|
167
179
|
|
168
180
|
def instrumenter
|
169
|
-
|
181
|
+
InstrumentationRegistry.instrumenter_for(notifier)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# This class is a registry which holds all of the +Instrumenter+ objects
|
186
|
+
# in a particular thread local. To access the +Instrumenter+ object for a
|
187
|
+
# particular +notifier+, you can call the following method:
|
188
|
+
#
|
189
|
+
# InstrumentationRegistry.instrumenter_for(notifier)
|
190
|
+
#
|
191
|
+
# The instrumenters for multiple notifiers are held in a single instance of
|
192
|
+
# this class.
|
193
|
+
class InstrumentationRegistry # :nodoc:
|
194
|
+
extend ActiveSupport::PerThreadRegistry
|
195
|
+
|
196
|
+
def initialize
|
197
|
+
@registry = {}
|
198
|
+
end
|
199
|
+
|
200
|
+
def instrumenter_for(notifier)
|
201
|
+
@registry[notifier] ||= Instrumenter.new(notifier)
|
170
202
|
end
|
171
203
|
end
|
172
204
|
|
@@ -1,4 +1,9 @@
|
|
1
1
|
require 'mutex_m'
|
2
|
+
begin
|
3
|
+
require 'thread_safe'
|
4
|
+
rescue LoadError
|
5
|
+
require 'skylight/vendor/thread_safe'
|
6
|
+
end
|
2
7
|
|
3
8
|
module ActiveSupport
|
4
9
|
module Notifications
|
@@ -11,7 +16,7 @@ module ActiveSupport
|
|
11
16
|
|
12
17
|
def initialize
|
13
18
|
@subscribers = []
|
14
|
-
@listeners_for =
|
19
|
+
@listeners_for = ThreadSafe::Cache.new
|
15
20
|
super
|
16
21
|
end
|
17
22
|
|
@@ -39,16 +44,14 @@ module ActiveSupport
|
|
39
44
|
listeners_for(name).each { |s| s.finish(name, id, payload) }
|
40
45
|
end
|
41
46
|
|
42
|
-
def measure(name, id, payload)
|
43
|
-
listeners_for(name).each { |s| s.measure(name, id, payload) }
|
44
|
-
end
|
45
|
-
|
46
47
|
def publish(name, *args)
|
47
48
|
listeners_for(name).each { |s| s.publish(name, *args) }
|
48
49
|
end
|
49
50
|
|
50
51
|
def listeners_for(name)
|
51
|
-
|
52
|
+
# this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
|
53
|
+
@listeners_for[name] || synchronize do
|
54
|
+
# use synchronisation when accessing @subscribers
|
52
55
|
@listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
|
53
56
|
end
|
54
57
|
end
|
@@ -63,12 +66,10 @@ module ActiveSupport
|
|
63
66
|
|
64
67
|
module Subscribers # :nodoc:
|
65
68
|
def self.new(pattern, listener)
|
66
|
-
if listener.respond_to?(:
|
67
|
-
subscriber = Timed.new pattern, listener
|
68
|
-
elsif listener.respond_to?(:measure)
|
69
|
+
if listener.respond_to?(:start) and listener.respond_to?(:finish)
|
69
70
|
subscriber = Evented.new pattern, listener
|
70
71
|
else
|
71
|
-
subscriber =
|
72
|
+
subscriber = Timed.new pattern, listener
|
72
73
|
end
|
73
74
|
|
74
75
|
unless pattern
|
@@ -82,6 +83,13 @@ module ActiveSupport
|
|
82
83
|
def initialize(pattern, delegate)
|
83
84
|
@pattern = pattern
|
84
85
|
@delegate = delegate
|
86
|
+
@can_publish = delegate.respond_to?(:publish)
|
87
|
+
end
|
88
|
+
|
89
|
+
def publish(name, *args)
|
90
|
+
if @can_publish
|
91
|
+
@delegate.publish name, *args
|
92
|
+
end
|
85
93
|
end
|
86
94
|
|
87
95
|
def start(name, id, payload)
|
@@ -92,10 +100,6 @@ module ActiveSupport
|
|
92
100
|
@delegate.finish name, id, payload
|
93
101
|
end
|
94
102
|
|
95
|
-
def measure(name, id, payload)
|
96
|
-
@delegate.measure(name, id, payload)
|
97
|
-
end
|
98
|
-
|
99
103
|
def subscribed_to?(name)
|
100
104
|
@pattern === name.to_s
|
101
105
|
end
|
@@ -106,14 +110,7 @@ module ActiveSupport
|
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
109
|
-
class
|
110
|
-
def measure(name, id, payload)
|
111
|
-
start(name, id, payload)
|
112
|
-
finish(name, id, payload)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
class Timed < LegacyEvented
|
113
|
+
class Timed < Evented
|
117
114
|
def initialize(pattern, delegate)
|
118
115
|
@timestack = []
|
119
116
|
super
|
@@ -146,10 +143,6 @@ module ActiveSupport
|
|
146
143
|
@delegate.finish name, id, payload
|
147
144
|
end
|
148
145
|
|
149
|
-
def measure(name, id, payload)
|
150
|
-
@delegate.measure name, id, payload
|
151
|
-
end
|
152
|
-
|
153
146
|
def publish(name, *args)
|
154
147
|
@delegate.publish name, *args
|
155
148
|
end
|
@@ -2,38 +2,45 @@ require 'securerandom'
|
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
4
|
module Notifications
|
5
|
-
#
|
5
|
+
# Instrumenters are stored in a thread local.
|
6
6
|
class Instrumenter
|
7
7
|
attr_reader :id
|
8
8
|
|
9
9
|
def initialize(notifier)
|
10
|
-
@id
|
10
|
+
@id = unique_id
|
11
11
|
@notifier = notifier
|
12
12
|
end
|
13
13
|
|
14
14
|
# Instrument the given block by measuring the time taken to execute it
|
15
15
|
# and publish it. Notice that events get sent even if an error occurs
|
16
|
-
# in the passed-in block
|
16
|
+
# in the passed-in block.
|
17
17
|
def instrument(name, payload={})
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
@notifier.finish(name, @id, payload)
|
27
|
-
end
|
28
|
-
else
|
29
|
-
@notifier.measure(name, @id, payload)
|
18
|
+
start name, payload
|
19
|
+
begin
|
20
|
+
yield payload
|
21
|
+
rescue Exception => e
|
22
|
+
payload[:exception] = [e.class.name, e.message]
|
23
|
+
raise e
|
24
|
+
ensure
|
25
|
+
finish name, payload
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
29
|
+
# Send a start notification with +name+ and +payload+.
|
30
|
+
def start(name, payload)
|
31
|
+
@notifier.start name, @id, payload
|
32
|
+
end
|
33
|
+
|
34
|
+
# Send a finish notification with +name+ and +payload+.
|
35
|
+
def finish(name, payload)
|
36
|
+
@notifier.finish name, @id, payload
|
37
|
+
end
|
38
|
+
|
33
39
|
private
|
34
|
-
|
35
|
-
|
36
|
-
|
40
|
+
|
41
|
+
def unique_id
|
42
|
+
SecureRandom.hex(10)
|
43
|
+
end
|
37
44
|
end
|
38
45
|
|
39
46
|
class Event
|