union_station_hooks_core 1.0.2 → 2.0.0
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.
- checksums.yaml +8 -8
- data/lib/union_station_hooks_core/api.rb +2 -2
- data/lib/union_station_hooks_core/request_reporter/basics.rb +68 -4
- data/lib/union_station_hooks_core/request_reporter/misc.rb +85 -11
- data/lib/union_station_hooks_core/request_reporter/view_rendering.rb +19 -4
- data/lib/union_station_hooks_core/request_reporter.rb +8 -0
- data/lib/union_station_hooks_core/version_data.rb +3 -3
- data/lib/union_station_hooks_core.rb +7 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NGUzYzY0ODI2NjJhZTdjZDliOWJjOWQyZTFhZDM3MzVjODFhYWUzYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjBjOGIzYjU3NmYwYjkzNzJhOTA4ZTU1MWJkNDQ2MmFhYzIyODZiMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ODhmNDg4NTgwNDNjMjgwNjIyYjIwY2VjNzI1ZjZiZTI4MGUxOWE1NTZlODYy
|
10
|
+
NTI1N2U4MzJkYzk0NDdkZGJhN2U5MzNjOTg3NDY5YmI2MWQwNDFlMmRhMGJk
|
11
|
+
MTQyMzFiNmM0NmEyOTU1NTcyOGY4NjNhOGU3YWFjNzEzNWRlYmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OTJhNDI4YzJkNjhhYTkyODc2NjNmOTllMzM2NWUwNjlhY2IxNzhhMzlkNWVj
|
14
|
+
MzY0ZmJjZDlmYWVmYmRkMzNhMWRiMGFlNTAzMDRjMGI5ODJiMDk4NmFjYzAy
|
15
|
+
ZTk5MzE0ZjgwZTliOTQ1NTI5YjM2OTQ3NWRiNDQyODJkZTVjNTA=
|
@@ -123,9 +123,9 @@ module UnionStationHooks
|
|
123
123
|
# etc. The exact information contained in the object is operating
|
124
124
|
# system specific, hence why the object is meant to be opaque.
|
125
125
|
#
|
126
|
-
# See {RequestReporter#
|
126
|
+
# See {RequestReporter#log_controller_action} for an example of
|
127
127
|
# an API method which expects timing information.
|
128
|
-
# `RequestReporter#
|
128
|
+
# `RequestReporter#log_controller_action` expects you to
|
129
129
|
# provide timing information about a controller action. That timing
|
130
130
|
# information is supposed to be obtained by calling
|
131
131
|
# `UnionStationHooks.now`.
|
@@ -52,7 +52,7 @@ module UnionStationHooks
|
|
52
52
|
# @private
|
53
53
|
GC_SUPPORTS_CLEAR_STATS = GC.respond_to?(:clear_stats)
|
54
54
|
|
55
|
-
#
|
55
|
+
# Logs the beginning of a Rack request. This is automatically called
|
56
56
|
# from {UnionStationHooks.begin_rack_request} (and thus automatically
|
57
57
|
# from Passenger).
|
58
58
|
#
|
@@ -62,9 +62,16 @@ module UnionStationHooks
|
|
62
62
|
@transaction.log_activity_begin('app request handler processing')
|
63
63
|
end
|
64
64
|
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
65
|
+
# Logs the end of a Rack request. This means that the Rack response body
|
66
|
+
# has been written out, and that the `#close` has been called on the Rack
|
67
|
+
# response body.
|
68
|
+
#
|
69
|
+
# This does not necessarily indicate that any buffering mechanism in
|
70
|
+
# between the app and the client (e.g. Nginx, or the Passenger core) is
|
71
|
+
# done flushing the response to the client.
|
72
|
+
#
|
73
|
+
# This is automatically called from {UnionStationHooks.begin_rack_request}
|
74
|
+
# (and thus automatically from Passenger).
|
68
75
|
#
|
69
76
|
# @private
|
70
77
|
def log_request_end(uncaught_exception_raised_during_request = false)
|
@@ -128,5 +135,62 @@ module UnionStationHooks
|
|
128
135
|
end
|
129
136
|
|
130
137
|
# rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
138
|
+
|
139
|
+
# Logs that the application server is about to write out the Rack
|
140
|
+
# response body.
|
141
|
+
#
|
142
|
+
# This call *must* be followed by a call to {#log_writing_rack_body_end}
|
143
|
+
# some time later.
|
144
|
+
#
|
145
|
+
# This is automatically called by Passenger's Rack handler.
|
146
|
+
#
|
147
|
+
# @private
|
148
|
+
# @return An ID to be passed later to {#log_writing_rack_body_end}.
|
149
|
+
def log_writing_rack_body_begin
|
150
|
+
return do_nothing_on_null(:log_writing_rack_body_begin) if null?
|
151
|
+
@transaction.log_activity_begin('writing out response body')
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
|
155
|
+
# Logs that the application server is done writing out the Rack
|
156
|
+
# response body. This does not necessarily indicate that any buffering
|
157
|
+
# mechanism in between the app and the client (e.g. Nginx, or the Passenger
|
158
|
+
# core) is done flushing the response to the client.
|
159
|
+
#
|
160
|
+
# This is automatically called by Passenger's Rack handler.
|
161
|
+
#
|
162
|
+
# @private
|
163
|
+
def log_writing_rack_body_end(id)
|
164
|
+
return do_nothing_on_null(:log_writing_rack_body_end) if null?
|
165
|
+
@transaction.log_activity_end('writing out response body')
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
|
169
|
+
# Logs that the application server is about to call `#close` on the
|
170
|
+
# Rack body object.
|
171
|
+
#
|
172
|
+
# This call *must* be followed by a call to {#log_closing_rack_body_end}
|
173
|
+
# some time later.
|
174
|
+
#
|
175
|
+
# This is automatically called by Passenger's Rack handler.
|
176
|
+
#
|
177
|
+
# @private
|
178
|
+
# @return An ID to be passed later to {#log_closing_rack_body_end}.
|
179
|
+
def log_closing_rack_body_begin
|
180
|
+
return do_nothing_on_null(:log_closing_rack_body_begin) if null?
|
181
|
+
@transaction.log_activity_begin('closing rack body object')
|
182
|
+
nil
|
183
|
+
end
|
184
|
+
|
185
|
+
# Logs that the application server is done calling `#close` on the
|
186
|
+
# Rack body object.
|
187
|
+
#
|
188
|
+
# This is automatically called by Passenger's Rack handler.
|
189
|
+
#
|
190
|
+
# @private
|
191
|
+
def log_closing_rack_body_end(id)
|
192
|
+
return do_nothing_on_null(:log_closing_rack_body_end) if null?
|
193
|
+
@transaction.log_activity_end('closing rack body object')
|
194
|
+
end
|
131
195
|
end
|
132
196
|
end
|
@@ -21,7 +21,6 @@
|
|
21
21
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
22
|
# THE SOFTWARE.
|
23
23
|
|
24
|
-
require 'digest/md5'
|
25
24
|
UnionStationHooks.require_lib 'utils'
|
26
25
|
|
27
26
|
module UnionStationHooks
|
@@ -41,20 +40,82 @@ module UnionStationHooks
|
|
41
40
|
# @return The return value of the block.
|
42
41
|
# @yield The block is expected to perform the activity.
|
43
42
|
# @example
|
44
|
-
# reporter.
|
43
|
+
# reporter.log_user_activity_block('Preheat cache') do
|
45
44
|
# calculate_preheat_values.each_pair do |key, value|
|
46
45
|
# Rails.cache.write(key, value)
|
47
46
|
# end
|
48
47
|
# end
|
49
|
-
def
|
48
|
+
def log_user_activity_block(name, &block)
|
50
49
|
if null?
|
51
|
-
do_nothing_on_null(:
|
50
|
+
do_nothing_on_null(:log_user_activity_block)
|
52
51
|
yield
|
53
52
|
else
|
54
|
-
@transaction.log_activity_block(
|
53
|
+
@transaction.log_activity_block(next_user_activity_name,
|
54
|
+
name, &block)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
# Logs the begin of a user-defined activity, for display in the
|
59
|
+
# activity timeline.
|
60
|
+
#
|
61
|
+
# An activity is a block in the activity timeline in the Union Station
|
62
|
+
# user interace. It has a name, a begin time and an end time.
|
63
|
+
#
|
64
|
+
# This form logs only the name and the begin time. You *must* also
|
65
|
+
# call {#log_user_activity_end} later with the same name to log the end
|
66
|
+
# time.
|
67
|
+
#
|
68
|
+
# @param name The name that should show up in the activity timeline.
|
69
|
+
# It can be any arbitrary name but may not contain newlines.
|
70
|
+
# @return id An ID which you must pass to {#log_user_activity_end} later.
|
71
|
+
def log_user_activity_begin(name)
|
72
|
+
return do_nothing_on_null(:log_user_activity_begin) if null?
|
73
|
+
id = next_user_activity_name
|
74
|
+
@transaction.log_activity_begin(id, UnionStationHooks.now, name)
|
75
|
+
id
|
76
|
+
end
|
77
|
+
|
78
|
+
# Logs the end of a user-defined activity, for display in the
|
79
|
+
# activity timeline.
|
80
|
+
#
|
81
|
+
# An activity is a block in the activity timeline in the Union Station
|
82
|
+
# user interace. It has a name, a begin time and an end time.
|
83
|
+
#
|
84
|
+
# This form logs only the name and the end time. You *must* also
|
85
|
+
# have called {#log_user_activity_begin} earlier with the same name to log
|
86
|
+
# the begin time.
|
87
|
+
#
|
88
|
+
# @param id The ID which you obtained from {#log_user_activity_begin}
|
89
|
+
# earlier.
|
90
|
+
# @param [Boolean] has_error Whether an uncaught
|
91
|
+
# exception occurred during the activity.
|
92
|
+
def log_user_activity_end(id, has_error = false)
|
93
|
+
return do_nothing_on_null(:log_user_activity_end) if null?
|
94
|
+
@transaction.log_activity_end(id, UnionStationHooks.now, has_error)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Logs a user-defined activity, for display in the activity timeline.
|
98
|
+
#
|
99
|
+
# An activity is a block in the activity timeline in the Union Station
|
100
|
+
# user interace. It has a name, a begin time and an end time.
|
101
|
+
#
|
102
|
+
# Unlike {#log_user_activity_block}, this form does not expect a block.
|
103
|
+
# However, you are expected to pass timing information.
|
104
|
+
#
|
105
|
+
# @param name The name that should show up in the activity timeline.
|
106
|
+
# It can be any arbitrary name but may not contain newlines.
|
107
|
+
# @param [TimePoint or Time] begin_time The time at which this activity
|
108
|
+
# begun. See {UnionStationHooks.now} to learn more.
|
109
|
+
# @param [TimePoint or Time] end_time The time at which this activity
|
110
|
+
# ended. See {UnionStationHooks.now} to learn more.
|
111
|
+
# @param [Boolean] has_error Whether an uncaught
|
112
|
+
# exception occurred during the activity.
|
113
|
+
def log_user_activity(name, begin_time, end_time, has_error = false)
|
114
|
+
return do_nothing_on_null(:log_user_activity) if null?
|
115
|
+
@transaction.log_activity(next_user_activity_name,
|
116
|
+
begin_time, end_time, name, has_error)
|
117
|
+
end
|
118
|
+
|
58
119
|
# Logs a benchmarking activity, for display in the activity timeline.
|
59
120
|
#
|
60
121
|
# An activity is a block in the activity timeline in the Union Station
|
@@ -71,8 +132,8 @@ module UnionStationHooks
|
|
71
132
|
# displayed in the acitivity timeline. This method measures the time before
|
72
133
|
# and after the block runs.
|
73
134
|
#
|
74
|
-
# The difference between this method and {#
|
75
|
-
# method generates timeline blocks of a different color, as to
|
135
|
+
# The difference between this method and {#log_user_activity_block} is that
|
136
|
+
# this method generates timeline blocks of a different color, as to
|
76
137
|
# differentiate user-defined activities from benchmark activities.
|
77
138
|
#
|
78
139
|
# If your app is a Rails app, then the `union_station_hooks_rails` gem
|
@@ -98,13 +159,13 @@ module UnionStationHooks
|
|
98
159
|
do_nothing_on_null(:log_benchmark_block)
|
99
160
|
yield
|
100
161
|
else
|
101
|
-
|
162
|
+
log_user_activity_block("Benchmark: #{title}", &block)
|
102
163
|
end
|
103
164
|
end
|
104
165
|
|
105
166
|
# Logs an exception that occurred during a request.
|
106
167
|
#
|
107
|
-
# If {#
|
168
|
+
# If {#log_controller_action_block} or {#log_controller_action}
|
108
169
|
# was called during the same request, then the information passed to
|
109
170
|
# those methods will be included in the exception report.
|
110
171
|
#
|
@@ -154,8 +215,7 @@ module UnionStationHooks
|
|
154
215
|
end_time = options[:end_time]
|
155
216
|
query = options[:query]
|
156
217
|
|
157
|
-
|
158
|
-
@transaction.log_activity("DB BENCHMARK: #{digest}",
|
218
|
+
@transaction.log_activity(next_database_query_name,
|
159
219
|
begin_time, end_time, "#{name}\n#{query}")
|
160
220
|
end
|
161
221
|
|
@@ -214,5 +274,19 @@ module UnionStationHooks
|
|
214
274
|
@transaction.message("Cache miss: #{name}")
|
215
275
|
end
|
216
276
|
end
|
277
|
+
|
278
|
+
private
|
279
|
+
|
280
|
+
def next_user_activity_name
|
281
|
+
result = @next_user_activity_number
|
282
|
+
@next_user_activity_number += 1
|
283
|
+
"user activity #{result}"
|
284
|
+
end
|
285
|
+
|
286
|
+
def next_database_query_name
|
287
|
+
result = @next_database_query_number
|
288
|
+
@next_database_query_number += 1
|
289
|
+
"database query #{result}"
|
290
|
+
end
|
217
291
|
end
|
218
292
|
end
|
@@ -36,14 +36,17 @@ module UnionStationHooks
|
|
36
36
|
# if your application is a Rails app. It will call this on every view
|
37
37
|
# or partial rendering.
|
38
38
|
#
|
39
|
+
# @param [String] name Name of the view, template or partial that is being
|
40
|
+
# rendered.
|
39
41
|
# @yield The given block is expected to perform the actual view rendering.
|
40
42
|
# @return The return value of the block.
|
41
|
-
def log_view_rendering_block(&block)
|
43
|
+
def log_view_rendering_block(name, &block)
|
42
44
|
if null?
|
43
45
|
do_nothing_on_null(:log_view_rendering_block)
|
44
46
|
yield
|
45
47
|
else
|
46
|
-
log_activity_block(
|
48
|
+
@transaction.log_activity_block(next_view_rendering_name,
|
49
|
+
name, &block)
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
@@ -58,6 +61,8 @@ module UnionStationHooks
|
|
58
61
|
# {#log_view_rendering_block} for you if your application is a Rails app.
|
59
62
|
# It will call this on every view or partial rendering.
|
60
63
|
#
|
64
|
+
# @option options [String] :name Name of the view, template or partial
|
65
|
+
# that is being rendered.
|
61
66
|
# @option options [TimePoint or Time] :begin_time The time at which this
|
62
67
|
# view rendering begun. See {UnionStationHooks.now} to learn more.
|
63
68
|
# @option options [TimePoint or Time] :end_time The time at which this view
|
@@ -66,11 +71,21 @@ module UnionStationHooks
|
|
66
71
|
# exception occurred during the view rendering. Default: false.
|
67
72
|
def log_view_rendering(options)
|
68
73
|
return do_nothing_on_null(:log_view_rendering) if null?
|
74
|
+
Utils.require_key(options, :name)
|
69
75
|
Utils.require_key(options, :begin_time)
|
70
76
|
Utils.require_key(options, :end_time)
|
71
77
|
|
72
|
-
@transaction.log_activity(
|
73
|
-
options[:
|
78
|
+
@transaction.log_activity(next_view_rendering_name,
|
79
|
+
options[:begin_time], options[:end_time],
|
80
|
+
options[:name], options[:has_error])
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def next_view_rendering_name
|
86
|
+
result = @next_view_rendering_number
|
87
|
+
@next_view_rendering_number += 1
|
88
|
+
"view rendering #{result}"
|
74
89
|
end
|
75
90
|
end
|
76
91
|
end
|
@@ -91,6 +91,11 @@ module UnionStationHooks
|
|
91
91
|
# You can check whether the null mode is active by calling {#null?}.
|
92
92
|
#
|
93
93
|
# Closing a RequestReporter also causes it to enter the null mode.
|
94
|
+
#
|
95
|
+
# ## Thread-safety
|
96
|
+
#
|
97
|
+
# RequestReporter is *not* thread-safe. If you access it concurrently, be sure
|
98
|
+
# to wrap its operations in a mutex.
|
94
99
|
class RequestReporter
|
95
100
|
# Returns a new RequestReporter object. You should not call
|
96
101
|
# `RequestReporter.new` directly. See "Obtaining a RequestReporter"
|
@@ -106,6 +111,9 @@ module UnionStationHooks
|
|
106
111
|
@app_group_name = app_group_name
|
107
112
|
@key = key
|
108
113
|
@transaction = continue_transaction
|
114
|
+
@next_view_rendering_number = 1
|
115
|
+
@next_user_activity_number = 1
|
116
|
+
@next_database_query_number = 1
|
109
117
|
end
|
110
118
|
|
111
119
|
# Indicates that no further information will be logged for this
|
@@ -277,6 +277,11 @@ module UnionStationHooks
|
|
277
277
|
# @raise RuntimeError
|
278
278
|
def check_initialized
|
279
279
|
if should_initialize? && !initialized?
|
280
|
+
return if !config.fetch(:check_initialized, true)
|
281
|
+
|
282
|
+
# We end each error message with two newlines so that in Passenger
|
283
|
+
# error reports in the exception class is shown on a new line, after
|
284
|
+
# the message.
|
280
285
|
if defined?(::Rails)
|
281
286
|
raise 'The Union Station hooks are not initialized. Please ensure ' \
|
282
287
|
'that you have an initializer file ' \
|
@@ -284,14 +289,14 @@ module UnionStationHooks
|
|
284
289
|
"this:\n\n" \
|
285
290
|
" if defined?(UnionStationHooks)\n" \
|
286
291
|
" UnionStationHooks.initialize!\n" \
|
287
|
-
|
292
|
+
" end\n\n"
|
288
293
|
else
|
289
294
|
raise 'The Union Station hooks are not initialized. Please ensure ' \
|
290
295
|
'that the following code is called during application ' \
|
291
296
|
"startup:\n\n" \
|
292
297
|
" if defined?(UnionStationHooks)\n" \
|
293
298
|
" UnionStationHooks.initialize!\n" \
|
294
|
-
|
299
|
+
" end\n\n"
|
295
300
|
end
|
296
301
|
end
|
297
302
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: union_station_hooks_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hongli Lai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Union Station Ruby hooks core code.
|
14
14
|
email: info@phusion.nl
|