oboe 2.7.18-java → 2.7.19-java
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 +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +20 -0
- data/README.md +1 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +225 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +125 -0
- data/examples/tracing_background_jobs.rb +52 -0
- data/examples/tracing_forked_processes.rb +100 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/lib/oboe/inst/dalli.rb +16 -5
- data/lib/oboe/util.rb +1 -0
- data/lib/oboe/version.rb +1 -1
- data/oboe.gemspec +7 -1
- data/test/instrumentation/dalli_test.rb +7 -0
- metadata +53 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33955fe50b8e7ee846ccb2ceb23a941c9234ecff
|
4
|
+
data.tar.gz: 4853c7efeaecad88636fed0ffad00f776078bc15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cf1195690e7cb9c9ba6a6ef6de3f965a8c6ea4300fc7536b99020423167314b3b57bfbe10f8b66efa87961296a8741807c18fc6888cd507654ffffce2541e49
|
7
|
+
data.tar.gz: 732866a1c7932065e6c32f12d97c12e2251ba16abf21043447ed1a57bfc40dd7a5d15390bf0e0b59918f5513fabb14eea03db285e5e1418d41c51d6d623526b5
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,26 @@ https://github.com/appneta/oboe-ruby/releases
|
|
4
4
|
|
5
5
|
Dates in this file are in the format MM/DD/YYYY.
|
6
6
|
|
7
|
+
# oboe 2.7.19
|
8
|
+
|
9
|
+
__Note that this will be the last release for the oboe gem. The gem
|
10
|
+
will be renamed to _traceview_ and all future updates will be to that
|
11
|
+
other gem.__
|
12
|
+
|
13
|
+
This version will show a post-install warning message stating this. A
|
14
|
+
final version of this gem will be released with only a deprecation
|
15
|
+
warning.
|
16
|
+
|
17
|
+
This patch release includes the following fix:
|
18
|
+
|
19
|
+
* Report TraceMode in __Init: #120
|
20
|
+
* Add RemoteHost reporting to Dalli Instrumentation: #119
|
21
|
+
|
22
|
+
Pushed to Rubygems:
|
23
|
+
|
24
|
+
https://rubygems.org/gems/oboe/versions/2.7.19
|
25
|
+
https://rubygems.org/gems/oboe/versions/2.7.19-java
|
26
|
+
|
7
27
|
# oboe 2.7.18
|
8
28
|
|
9
29
|
This patch release includes the following fix:
|
data/README.md
CHANGED
@@ -9,6 +9,7 @@ It has the ability to report performance metrics on an array of libraries, datab
|
|
9
9
|
|
10
10
|
It requires a [TraceView](http://www.appneta.com/products/traceview/) account to view metrics. Get yours, [it's free](http://www.appneta.com/products/traceview-free-account/).
|
11
11
|
|
12
|
+
[](https://www.omniref.com/ruby/gems/oboe)
|
12
13
|
[](http://badge.fury.io/rb/oboe)
|
13
14
|
[](https://travis-ci.org/appneta/oboe-ruby)
|
14
15
|
[](https://codeclimate.com/github/appneta/oboe-ruby)
|
data/examples/DNT.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
By default, the TraceView oboe gem will not trace routes with extensions
|
2
|
+
for common static files. Examples of such files may be images,
|
3
|
+
javascript, pdfs and text files.
|
4
|
+
|
5
|
+
This is done by using the regular expression stored in
|
6
|
+
`Oboe::Config[:dnt_regexp]`:
|
7
|
+
|
8
|
+
.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|svg|less)$
|
9
|
+
|
10
|
+
This string is used as a regular expression and is tested against
|
11
|
+
candidate URLs to be instrumented.
|
12
|
+
|
13
|
+
To replace the pattern in use, you can update this regular expression
|
14
|
+
string. Here are some examples.
|
15
|
+
|
16
|
+
If you prefer that you want your javascript and CSS files instrumented,
|
17
|
+
you can update `Oboe::Config[:dnt_regexp]` with an updated regexp
|
18
|
+
pattern (without the "js" and "css" entries):
|
19
|
+
|
20
|
+
.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|flv|swf|ttf|woff|svg|less)$
|
21
|
+
|
22
|
+
If you prefer to not instrument all javascript files except for one
|
23
|
+
named `show.js`, you could put this assignment into your initializer,
|
24
|
+
rackup file or application.rb (note that this example uses a standard
|
25
|
+
regexp [negative
|
26
|
+
look-behind](http://www.regular-expressions.info/lookaround.html) that
|
27
|
+
isn't supported in Ruby 1.8):
|
28
|
+
|
29
|
+
Oboe::Config[:dnt_regexp] = "(\.js$)(?<!show.js)"
|
30
|
+
|
31
|
+
Since this pattern is used with the standard Ruby Regexp class, you can
|
32
|
+
use any Regexp supported pattern. See the documentation on Ruby Regexp
|
33
|
+
[here](https://www.omniref.com/ruby/2.2.0/symbols/Regexp?d=380181456&n=0#doc_uncollapsed=true&d=380181456&n=0)
|
34
|
+
or you can also view the oboe gem [source code documentation for this
|
35
|
+
feature](https://github.com/appneta/oboe-ruby/blob/master/lib/oboe/config.rb#L74).
|
@@ -0,0 +1,225 @@
|
|
1
|
+
###############################################################
|
2
|
+
# A brief overview of TraceView tracing context
|
3
|
+
###############################################################
|
4
|
+
#
|
5
|
+
# Tracing context is the state held when TraceView is instrumenting a
|
6
|
+
# transaction, block, request etc.. This context is advanced as
|
7
|
+
# new blocks are instrumented and this chain of context is used
|
8
|
+
# by TraceView to later reassemble performance data to be displayed
|
9
|
+
# in the TraceView dashboard.
|
10
|
+
#
|
11
|
+
# Tracing context is non-existent until established by calling
|
12
|
+
# `Oboe::API.start_trace` or `Oboe::API.log_start`. Those methods
|
13
|
+
# are part of the high-level and low-level API respectively.
|
14
|
+
#
|
15
|
+
# After a tracing context is established, that context can be
|
16
|
+
# continued by calling `Oboe::API.trace` or `Oboe::API.log_entry`.
|
17
|
+
# These methods will advance an existing context but not start
|
18
|
+
# new one.
|
19
|
+
#
|
20
|
+
# For example, when a web request comes into a stack, a tracing
|
21
|
+
# context is established using `Oboe::API.log_start` as the request
|
22
|
+
# enters through the rack middleware via `::Oboe::Rack`.
|
23
|
+
#
|
24
|
+
# That tracing context is then continued using `Oboe::API.trace` or
|
25
|
+
# `Oboe::API.log_entry` for each subsequent layer such as Rails,
|
26
|
+
# ActiveRecord, Redis, Memcache, ActionView, Mongo (etc...) until
|
27
|
+
# finally request processing is complete and the tracing context
|
28
|
+
# is cleared (Oboe::Context.clear)
|
29
|
+
#
|
30
|
+
|
31
|
+
###############################################################
|
32
|
+
# Carrying Context
|
33
|
+
###############################################################
|
34
|
+
#
|
35
|
+
# The tracing context exists in the form of an X-Trace string and
|
36
|
+
# can be retrieved using 'Oboe::Context.toString'
|
37
|
+
#
|
38
|
+
# xtrace = Oboe::Context.toString
|
39
|
+
#
|
40
|
+
# => "1B4EDAB9E028CA3C81BCD57CC4644B4C4AE239C7B713F0BCB9FAD6D562"
|
41
|
+
#
|
42
|
+
# Tracing context can also be picked up from a pre-existing
|
43
|
+
# X-Trace string:
|
44
|
+
#
|
45
|
+
# xtrace = "1B4EDAB9E028CA3C81BCD57CC4644B4C4AE239C7B713F0BCB9FAD6D562"
|
46
|
+
#
|
47
|
+
# Oboe::Context.fromString(xtrace)
|
48
|
+
#
|
49
|
+
# With these two methods, context can be passed across threads,
|
50
|
+
# processes (via fork) and in requests (such as external HTTP
|
51
|
+
# requests where the X-Trace is inserted in request headers).
|
52
|
+
#
|
53
|
+
#
|
54
|
+
|
55
|
+
###############################################################
|
56
|
+
# Two Options for Spawned Tracing
|
57
|
+
###############################################################
|
58
|
+
#
|
59
|
+
# When your application needs to instrument code that forks,
|
60
|
+
# spawns a thread or does something in-parallel, you have the
|
61
|
+
# option to either link those child traces to the parent or
|
62
|
+
# trace them as individuals (but with identifying information).
|
63
|
+
#
|
64
|
+
# Linking parent and child has it's benefits as in the
|
65
|
+
# TraceView dashboard, you will see how a process may spawn
|
66
|
+
# a task in parallel and in a single view see the performance
|
67
|
+
# of both.
|
68
|
+
#
|
69
|
+
# The limitation of this is that this is only useful if your
|
70
|
+
# parent process spawns only a limited number of child traces.
|
71
|
+
#
|
72
|
+
# If your parent process is spawning many child tasks (e.g.
|
73
|
+
# twenty, hundreds, thousands or more) it's best to trace those
|
74
|
+
# child tasks as individuals and pass in identifier Key-Values
|
75
|
+
# (such as task ID, job ID etc..)
|
76
|
+
#
|
77
|
+
# In the examples below, I show implementations of both linked
|
78
|
+
# asynchronous traces and separated independent traces.
|
79
|
+
|
80
|
+
###############################################################
|
81
|
+
# Thread - with separated traces
|
82
|
+
###############################################################
|
83
|
+
|
84
|
+
Oboe::API.log_start('parent')
|
85
|
+
|
86
|
+
# Get the work to be done
|
87
|
+
job = get_work
|
88
|
+
|
89
|
+
Thread.new do
|
90
|
+
# This is a new thread so there is no pre-existing context so
|
91
|
+
# we'll call `Oboe::API.log_start` to start a new trace context.
|
92
|
+
Oboe::API.log_start('worker_thread', { :job_id => job.id })
|
93
|
+
|
94
|
+
# Do the work
|
95
|
+
do_the_work(job)
|
96
|
+
|
97
|
+
Oboe::API.log_end('worker_thread')
|
98
|
+
end
|
99
|
+
|
100
|
+
Oboe::API.log_end('parent')
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
###############################################################
|
105
|
+
#
|
106
|
+
# This will generate two independent traces with the following
|
107
|
+
# topology.
|
108
|
+
#
|
109
|
+
# 'parent'
|
110
|
+
# ------------------------------------------------------------
|
111
|
+
#
|
112
|
+
# 'worker_thread'
|
113
|
+
# ------------------------------------------------------------
|
114
|
+
#
|
115
|
+
|
116
|
+
###############################################################
|
117
|
+
# Thread - with linked asynchronous traces
|
118
|
+
###############################################################
|
119
|
+
|
120
|
+
# Since the following example spawns a thread without waiting
|
121
|
+
# for it to return, we carry over the context and we mark the
|
122
|
+
# trace generated in that thread to be asynchronous using
|
123
|
+
# the `Async` flag.
|
124
|
+
|
125
|
+
Oboe::API.log_start('parent')
|
126
|
+
|
127
|
+
# Save the context to be imported in spawned thread
|
128
|
+
tracing_context = Oboe::Context.toString
|
129
|
+
|
130
|
+
# Get the work to be done
|
131
|
+
job = get_work
|
132
|
+
|
133
|
+
Thread.new do
|
134
|
+
# Restore context
|
135
|
+
Oboe::Context.fromString(tracing_context)
|
136
|
+
|
137
|
+
Oboe::API.log_entry('worker_thread')
|
138
|
+
|
139
|
+
# Do the work
|
140
|
+
do_the_work(job)
|
141
|
+
|
142
|
+
Oboe::API.log_exit('worker_thread', { 'Async' => 1 })
|
143
|
+
end
|
144
|
+
|
145
|
+
Oboe::API.log_end('parent')
|
146
|
+
|
147
|
+
###############################################################
|
148
|
+
#
|
149
|
+
# This will generate a single trace with an asynchronous
|
150
|
+
# branch like the following
|
151
|
+
#
|
152
|
+
# 'parent'
|
153
|
+
# ------------------------------------------------------------
|
154
|
+
# \
|
155
|
+
# \
|
156
|
+
# ------------------------------------------------------
|
157
|
+
# 'worker_thread'
|
158
|
+
#
|
159
|
+
|
160
|
+
###############################################################
|
161
|
+
# Process via fork - with separated traces
|
162
|
+
###############################################################
|
163
|
+
|
164
|
+
Oboe::API.start_trace('parent_process') do
|
165
|
+
|
166
|
+
# Get some work to process
|
167
|
+
job = get_job
|
168
|
+
|
169
|
+
# fork process to handle work
|
170
|
+
fork do
|
171
|
+
# Since fork does a complete process copy, the tracing_context still exists
|
172
|
+
# so we have to clear it and start again.
|
173
|
+
Oboe::Context.clear
|
174
|
+
|
175
|
+
Oboe::API.start_trace('worker_process', { :job_id => job.id }) do
|
176
|
+
do_work(job)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
###############################################################
|
183
|
+
#
|
184
|
+
# This will generate two independent traces:
|
185
|
+
#
|
186
|
+
# 'parent_process'
|
187
|
+
# ------------------------------------------------------------
|
188
|
+
#
|
189
|
+
# 'worker_process'
|
190
|
+
# ------------------------------------------------------------
|
191
|
+
#
|
192
|
+
###############################################################
|
193
|
+
# Process via fork - with linked asynchronous traces
|
194
|
+
###############################################################
|
195
|
+
|
196
|
+
Oboe::API.start_trace('parent_process') do
|
197
|
+
|
198
|
+
# Get some work to process
|
199
|
+
job = get_job
|
200
|
+
|
201
|
+
# fork process to handle work
|
202
|
+
fork do
|
203
|
+
# Since fork does a complete process copy, the tracing_context still exists
|
204
|
+
# although we'll have to mark these traces as asynchronous to denote
|
205
|
+
# that it has split off from the main program flow
|
206
|
+
|
207
|
+
Oboe::API.trace('worker_process', { 'Async' => 1 }) do
|
208
|
+
do_work(job)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
###############################################################
|
215
|
+
#
|
216
|
+
# This will generate a single trace with an asynchronous
|
217
|
+
# branch like the following
|
218
|
+
#
|
219
|
+
# 'parent_process'
|
220
|
+
# ------------------------------------------------------------
|
221
|
+
# \
|
222
|
+
# \
|
223
|
+
# ------------------------------------------------------
|
224
|
+
# 'worker_process'
|
225
|
+
#
|
@@ -0,0 +1,17 @@
|
|
1
|
+
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
|
2
|
+
threads_count = Integer(ENV['MAX_THREADS'] || 5)
|
3
|
+
threads threads_count, threads_count
|
4
|
+
|
5
|
+
preload_app!
|
6
|
+
|
7
|
+
rackup DefaultRackup
|
8
|
+
port ENV['PORT'] || 3000
|
9
|
+
environment ENV['RACK_ENV'] || 'development'
|
10
|
+
|
11
|
+
on_worker_boot do
|
12
|
+
::Oboe.reconnect! if defined?(::Oboe)
|
13
|
+
end
|
14
|
+
|
15
|
+
on_worker_shutdown do
|
16
|
+
::Oboe.disconnect! if defined?(::Oboe)
|
17
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#
|
2
|
+
# This sample demonstrates how to instrument a main loop that
|
3
|
+
# retrieves work and spawn threads that do the actual work
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'math'
|
7
|
+
require 'oboe'
|
8
|
+
|
9
|
+
Oboe::Config[:tracing_mode] = :always
|
10
|
+
Oboe::Config[:verbose] = true
|
11
|
+
|
12
|
+
# The parent process/loop which collects data
|
13
|
+
while true do
|
14
|
+
|
15
|
+
# For each loop, we instrument the work retrieval. These traces
|
16
|
+
# will show up as layer 'get_the_work'.
|
17
|
+
Oboe::API.start_trace('get_the_work') do
|
18
|
+
|
19
|
+
work = get_the_work
|
20
|
+
|
21
|
+
# Loop through work and pass to `do_the_work` method
|
22
|
+
# that spawns a thread each time
|
23
|
+
work.each do |j|
|
24
|
+
|
25
|
+
# In the new Thread block, the Oboe tracing context isn't there
|
26
|
+
# so we carry it over manually and pass it to the `start_trace`
|
27
|
+
# method.
|
28
|
+
|
29
|
+
# In the TraceView dashboard, this will show up as parent traces
|
30
|
+
# (layer 'get_the_work') with child traces (layer 'do_the_work').
|
31
|
+
|
32
|
+
tracing_context = Oboe::Context.toString
|
33
|
+
|
34
|
+
Thread.new do
|
35
|
+
result = nil
|
36
|
+
|
37
|
+
Oboe::API.start_trace('do_the_work', tracing_context, { 'Async' => 1 }) do
|
38
|
+
result = do_the_work(j)
|
39
|
+
end
|
40
|
+
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
##
|
49
|
+
# get_the_work
|
50
|
+
#
|
51
|
+
# Method to retrieve work to do
|
52
|
+
#
|
53
|
+
def get_the_work
|
54
|
+
# We'll just return random integers as a
|
55
|
+
# fake work load
|
56
|
+
w = []
|
57
|
+
w << rand(25)
|
58
|
+
w << rand(25)
|
59
|
+
w << rand(25)
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# do_the_work
|
64
|
+
#
|
65
|
+
# The work-horse method
|
66
|
+
#
|
67
|
+
def do_the_work(job_to_do)
|
68
|
+
i = job_to_do
|
69
|
+
i * Math::PI
|
70
|
+
end
|
71
|
+
|
72
|
+
####################################################
|
73
|
+
# Notes
|
74
|
+
####################################################
|
75
|
+
|
76
|
+
# The above code generates a trace for each loop of the parent data collection process.
|
77
|
+
# Those traces have the layer name of `get_the_work` and will show up in the TraceView
|
78
|
+
# dashboard as such.
|
79
|
+
#
|
80
|
+
# Then as threads are spawned to process individual bits of work, we carry over the
|
81
|
+
# `tracing_context` and start a new asynchronous trace using `start_trace`. (An
|
82
|
+
# asynchronous trace is noted by passing the `Async` Hash key with a value of `1`).
|
83
|
+
#
|
84
|
+
# In the TraceView dashboard, the two traces (parent and child; or one to many) will
|
85
|
+
# be linked and displayed together as a single trace.
|
86
|
+
|
87
|
+
####################################################
|
88
|
+
# Caveats
|
89
|
+
####################################################
|
90
|
+
|
91
|
+
# If the main loop is retrieving many jobs (work) to process on each loop then
|
92
|
+
# linking the traces may not be the best strategy as such large relationships
|
93
|
+
# are difficult to display correctly in the TraceView dashboard and provide little
|
94
|
+
# added value.
|
95
|
+
#
|
96
|
+
# If there are more than 8 - 12 threads spawned from each loop, then you may want to consider
|
97
|
+
# NOT carrying over tracing context into the spawned threads.
|
98
|
+
#
|
99
|
+
# In this case, you can simply omit `tracing_context` and passing it to `start_trace` in
|
100
|
+
# the `Thread.new` block. (lines 32 + 37). Also remove the `{ Async => 1 }` Hash!
|
101
|
+
#
|
102
|
+
# This will produce two sets of traces with two the layer names 'get_the_work' +
|
103
|
+
# 'do_the_work'.
|
104
|
+
#
|
105
|
+
# In the TraceView dashboard, you can then separate or unify these traces into
|
106
|
+
# independent applications. e.g. job processor, data retrieval, thread worker etc...
|
107
|
+
#
|
108
|
+
# An implementation of the work loop without carrying over tracing context would look
|
109
|
+
# like the following:
|
110
|
+
#
|
111
|
+
# work.each do |j|
|
112
|
+
# Thread.new do
|
113
|
+
# result = nil
|
114
|
+
#
|
115
|
+
# Oboe::API.start_trace('do_the_work') do
|
116
|
+
# result = do_the_work(j)
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# result
|
120
|
+
# end
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# If anything isn't clear, please don't hesitate to reach us at support (traceviewsupport@appneta.com)
|
124
|
+
# or on IRC #appneta @ freenode.
|
125
|
+
#
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.require
|
5
|
+
|
6
|
+
# Make sure oboe is at the bottom of your Gemfile.
|
7
|
+
# This is likely redundant but just in case.
|
8
|
+
require 'oboe'
|
9
|
+
|
10
|
+
# Tracing mode can be 'never', 'through' (to follow upstream) or 'always'
|
11
|
+
Oboe::Config[:tracing_mode] = 'always'
|
12
|
+
|
13
|
+
#
|
14
|
+
# Update April 9, 2015 - this is done automagically now
|
15
|
+
# and doesn't have to be called manually
|
16
|
+
#
|
17
|
+
# Load library instrumentation to auto-capture stuff we know about...
|
18
|
+
# e.g. ActiveRecord, Cassandra, Dalli, Redis, memcache, mongo
|
19
|
+
# Oboe::Ruby.load
|
20
|
+
|
21
|
+
# Some KVs to report to the dashboard
|
22
|
+
report_kvs = {}
|
23
|
+
report_kvs[:command_line_params] = ARGV.to_s
|
24
|
+
report_kvs[:user_id] = `whoami`
|
25
|
+
|
26
|
+
Oboe::API.start_trace('my_background_job', nil, report_kvs ) do
|
27
|
+
#
|
28
|
+
# Initialization code
|
29
|
+
#
|
30
|
+
|
31
|
+
tasks = get_all_tasks
|
32
|
+
|
33
|
+
tasks.each do |t|
|
34
|
+
# Optional: Here we embed another 'trace' to separate actual
|
35
|
+
# work for each task. In the TV dashboard, this will show
|
36
|
+
# up as a large 'my_background_job' parent layer with many
|
37
|
+
# child 'task" layers.
|
38
|
+
Oboe::API.trace('task', { :task_id => t.id }) do
|
39
|
+
t.perform
|
40
|
+
end
|
41
|
+
end
|
42
|
+
#
|
43
|
+
# cleanup code
|
44
|
+
#
|
45
|
+
end
|
46
|
+
|
47
|
+
# Note that we use 'start_trace' in the outer block and 'trace' for
|
48
|
+
# any sub-blocks of code we wish to instrument. The arguments for
|
49
|
+
# both methods vary slightly. Details in RubyDoc:
|
50
|
+
# https://www.omniref.com/ruby/gems/oboe/2.7.10.1/symbols/Oboe::API::Tracing#tab=Methods
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#
|
2
|
+
# This sample demonstrates how to instrument a main loop that
|
3
|
+
# retrieves work and calls fork to do the actual work
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'math'
|
7
|
+
require 'oboe'
|
8
|
+
|
9
|
+
Oboe::Config[:tracing_mode] = :always
|
10
|
+
Oboe::Config[:verbose] = true
|
11
|
+
|
12
|
+
# The parent process/loop which collects data
|
13
|
+
while true do
|
14
|
+
|
15
|
+
# For each loop, we instrument the work retrieval. These traces
|
16
|
+
# will show up as layer 'get_the_work'.
|
17
|
+
Oboe::API.start_trace('get_the_work') do
|
18
|
+
|
19
|
+
work = get_the_work
|
20
|
+
|
21
|
+
# Loop through work and pass to `do_the_work` method
|
22
|
+
# that spawns a thread each time
|
23
|
+
work.each do |job|
|
24
|
+
fork do
|
25
|
+
# Since the context is copied from the parent process, we clear it
|
26
|
+
# and start a new trace via `Oboe::API.start_trace`.
|
27
|
+
Oboe::Context.clear
|
28
|
+
result = nil
|
29
|
+
|
30
|
+
Oboe::API.start_trace('do_the_work', :job_id => job.id) do
|
31
|
+
result = do_the_work(job)
|
32
|
+
end
|
33
|
+
|
34
|
+
result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# get_the_work
|
42
|
+
#
|
43
|
+
# Method to retrieve work to do
|
44
|
+
#
|
45
|
+
def get_the_work
|
46
|
+
# We'll just return random integers as a
|
47
|
+
# fake work load
|
48
|
+
w = []
|
49
|
+
w << rand(25)
|
50
|
+
w << rand(25)
|
51
|
+
w << rand(25)
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# do_the_work
|
56
|
+
#
|
57
|
+
# The work-horse method
|
58
|
+
#
|
59
|
+
def do_the_work(job_to_do)
|
60
|
+
i = job_to_do
|
61
|
+
i * Math::PI
|
62
|
+
end
|
63
|
+
|
64
|
+
#########################################################################
|
65
|
+
# Notes
|
66
|
+
#########################################################################
|
67
|
+
|
68
|
+
# If your parent process only forks a small number of processes per loop (< 5..10),
|
69
|
+
# you may want to mark the child traces as asynchronous and have them directly
|
70
|
+
# linked to the parent tracing context.
|
71
|
+
#
|
72
|
+
# The benefit of this is that instead of having two independent traces (parent
|
73
|
+
# and child), you will have a single view of the parent trace showing the
|
74
|
+
# spawned child process and it's performance in the TraceView dashboard.
|
75
|
+
#
|
76
|
+
# To do this:
|
77
|
+
# 1. Don't clear the context in the child process
|
78
|
+
# 2. Use `Oboe::API.trace` instead
|
79
|
+
# 3. Pass the `Async` flag to mark this child as asynchronous
|
80
|
+
#
|
81
|
+
while true do
|
82
|
+
Oboe::API.start_trace('get_the_work') do
|
83
|
+
|
84
|
+
work = get_the_work
|
85
|
+
|
86
|
+
work.each do |job|
|
87
|
+
fork do
|
88
|
+
result = nil
|
89
|
+
# 1 Don't clear context
|
90
|
+
# 2 Use `Oboe::API.trace` instead
|
91
|
+
# 3 Pass the Async flag
|
92
|
+
Oboe::API.trace('do_the_work', { :job_id => job.id, 'Async' => 1 }) do
|
93
|
+
result = do_the_work(job)
|
94
|
+
end
|
95
|
+
|
96
|
+
result
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
|
2
|
+
timeout 15
|
3
|
+
preload_app true
|
4
|
+
|
5
|
+
before_fork do |server, worker|
|
6
|
+
Signal.trap 'TERM' do
|
7
|
+
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
|
8
|
+
Process.kill 'QUIT', Process.pid
|
9
|
+
end
|
10
|
+
|
11
|
+
defined?(ActiveRecord::Base) and
|
12
|
+
ActiveRecord::Base.connection.disconnect!
|
13
|
+
|
14
|
+
defined?(::Oboe) and
|
15
|
+
::Oboe.disconnect!
|
16
|
+
end
|
17
|
+
|
18
|
+
after_fork do |server, worker|
|
19
|
+
Signal.trap 'TERM' do
|
20
|
+
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
|
21
|
+
end
|
22
|
+
|
23
|
+
defined?(ActiveRecord::Base) and
|
24
|
+
ActiveRecord::Base.establish_connection
|
25
|
+
|
26
|
+
defined?(::Oboe) and
|
27
|
+
::Oboe.reconnect!
|
28
|
+
end
|
data/lib/oboe/inst/dalli.rb
CHANGED
@@ -25,15 +25,23 @@ module Oboe
|
|
25
25
|
def perform_with_oboe(*all_args, &blk)
|
26
26
|
op, key, *args = *all_args
|
27
27
|
|
28
|
+
report_kvs = {}
|
29
|
+
report_kvs[:KVOp] = op
|
30
|
+
report_kvs[:KVKey] = key
|
31
|
+
if @servers.is_a?(Array) && !@servers.empty?
|
32
|
+
report_kvs[:RemoteHost] = @servers.join(", ")
|
33
|
+
end
|
34
|
+
|
28
35
|
if Oboe.tracing? && !Oboe.tracing_layer_op?(:get_multi)
|
29
|
-
Oboe::API.trace('memcache',
|
36
|
+
Oboe::API.trace('memcache', report_kvs) do
|
30
37
|
result = perform_without_oboe(*all_args, &blk)
|
31
38
|
|
32
|
-
|
33
|
-
|
34
|
-
|
39
|
+
# Clear the hash for a potential info event
|
40
|
+
report_kvs.clear
|
41
|
+
report_kvs[:KVHit] = memcache_hit?(result) if op == :get && key.class == String
|
42
|
+
report_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:dalli][:collect_backtraces]
|
35
43
|
|
36
|
-
Oboe::API.log('memcache', 'info',
|
44
|
+
Oboe::API.log('memcache', 'info', report_kvs) unless report_kvs.empty?
|
37
45
|
result
|
38
46
|
end
|
39
47
|
else
|
@@ -49,6 +57,9 @@ module Oboe
|
|
49
57
|
begin
|
50
58
|
info_kvs[:KVKeyCount] = keys.flatten.length
|
51
59
|
info_kvs[:KVKeyCount] = (info_kvs[:KVKeyCount] - 1) if keys.last.is_a?(Hash) || keys.last.nil?
|
60
|
+
if @servers.is_a?(Array) && !@servers.empty?
|
61
|
+
info_kvs[:RemoteHost] = @servers.join(", ")
|
62
|
+
end
|
52
63
|
rescue
|
53
64
|
Oboe.logger.debug "[oboe/debug] Error collecting info keys: #{e.message}"
|
54
65
|
Oboe.logger.debug e.backtrace
|
data/lib/oboe/util.rb
CHANGED
@@ -172,6 +172,7 @@ module Oboe
|
|
172
172
|
platform_info['Ruby.Version'] = RUBY_VERSION
|
173
173
|
platform_info['Ruby.Oboe.Version'] = ::Oboe::Version::STRING
|
174
174
|
platform_info['RubyHeroku.Oboe.Version'] = ::OboeHeroku::Version::STRING if defined?(::OboeHeroku)
|
175
|
+
platform_info['Ruby.TraceMode.Version'] = ::Oboe::Config[:tracing_mode]
|
175
176
|
|
176
177
|
# Report the framework in use
|
177
178
|
if defined?(::RailsLts)
|
data/lib/oboe/version.rb
CHANGED
data/oboe.gemspec
CHANGED
@@ -12,7 +12,11 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.email = %q{traceviewsupport@appneta.com}
|
13
13
|
s.homepage = %q{http://www.appneta.com/products/traceview/}
|
14
14
|
s.summary = %q{AppNeta TraceView performance instrumentation gem for Ruby}
|
15
|
-
s.description = %q{
|
15
|
+
s.description = %q{
|
16
|
+
The oboe gem provides TraceView instrumentation for MRI Ruby, JRuby and related frameworks.
|
17
|
+
|
18
|
+
Note that this gem has been deprecated and all future updates will be relases as the 'traceview' gem.
|
19
|
+
}
|
16
20
|
|
17
21
|
s.extra_rdoc_files = ["LICENSE"]
|
18
22
|
s.files = `git ls-files`.split("\n")
|
@@ -25,5 +29,7 @@ Gem::Specification.new do |s|
|
|
25
29
|
s.add_development_dependency('rake', '>= 0')
|
26
30
|
|
27
31
|
s.required_ruby_version = '>= 1.8.6'
|
32
|
+
|
33
|
+
s.post_install_message = File.read('./rename_warning.txt')
|
28
34
|
end
|
29
35
|
|
@@ -36,6 +36,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
36
36
|
traces[1].has_key?("KVKey").must_equal true
|
37
37
|
traces[1]['Layer'].must_equal "memcache"
|
38
38
|
traces[1]['KVKey'].must_equal "some_key"
|
39
|
+
traces[1]['RemoteHost'].must_equal "127.0.0.1:11211"
|
39
40
|
end
|
40
41
|
|
41
42
|
it 'should trace get' do
|
@@ -50,6 +51,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
50
51
|
|
51
52
|
traces[1]['KVOp'].must_equal "get"
|
52
53
|
traces[1]['KVKey'].must_equal "some_key"
|
54
|
+
traces[1]['RemoteHost'].must_equal "127.0.0.1:11211"
|
53
55
|
traces[2]['Label'].must_equal "info"
|
54
56
|
traces[2].has_key?('KVHit').must_equal true
|
55
57
|
traces[3]['Label'].must_equal "exit"
|
@@ -67,6 +69,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
67
69
|
|
68
70
|
traces[1]['KVOp'].must_equal "get_multi"
|
69
71
|
traces[2]['Label'].must_equal "info"
|
72
|
+
traces[2]['RemoteHost'].must_equal "127.0.0.1:11211"
|
70
73
|
traces[2].has_key?('KVKeyCount').must_equal true
|
71
74
|
traces[2].has_key?('KVHitCount').must_equal true
|
72
75
|
traces[3]['Label'].must_equal "exit"
|
@@ -86,6 +89,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
86
89
|
|
87
90
|
traces[1]['KVOp'].must_equal "incr"
|
88
91
|
traces[1]['KVKey'].must_equal "dalli_key_counter"
|
92
|
+
traces[1]['RemoteHost'].must_equal "127.0.0.1:11211"
|
89
93
|
traces[2]['Label'].must_equal "exit"
|
90
94
|
end
|
91
95
|
|
@@ -103,6 +107,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
103
107
|
|
104
108
|
traces[1]['KVOp'].must_equal "decr"
|
105
109
|
traces[1]['KVKey'].must_equal "dalli_key_counter"
|
110
|
+
traces[1]['RemoteHost'].must_equal "127.0.0.1:11211"
|
106
111
|
traces[2]['Label'].must_equal "exit"
|
107
112
|
end
|
108
113
|
|
@@ -120,6 +125,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
120
125
|
|
121
126
|
traces[1]['KVOp'].must_equal "replace"
|
122
127
|
traces[1]['KVKey'].must_equal "some_key"
|
128
|
+
traces[1]['RemoteHost'].must_equal "127.0.0.1:11211"
|
123
129
|
traces[2]['Label'].must_equal "exit"
|
124
130
|
end
|
125
131
|
|
@@ -137,6 +143,7 @@ describe Oboe::Inst::Dalli < ::MiniTest::Spec do
|
|
137
143
|
|
138
144
|
traces[1]['KVOp'].must_equal "delete"
|
139
145
|
traces[1]['KVKey'].must_equal "some_key"
|
146
|
+
traces[1]['RemoteHost'].must_equal "127.0.0.1:11211"
|
140
147
|
end
|
141
148
|
|
142
149
|
it "should obey :collect_backtraces setting when true" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oboe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.7.
|
4
|
+
version: 2.7.19
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Peter Giacomo Lombardo
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-05-
|
12
|
+
date: 2015-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -39,7 +39,11 @@ dependencies:
|
|
39
39
|
version: '0'
|
40
40
|
prerelease: false
|
41
41
|
type: :development
|
42
|
-
description:
|
42
|
+
description: |2
|
43
|
+
|
44
|
+
The oboe gem provides TraceView instrumentation for MRI Ruby, JRuby and related frameworks.
|
45
|
+
|
46
|
+
Note that this gem has been deprecated and all future updates will be relases as the 'traceview' gem.
|
43
47
|
email: traceviewsupport@appneta.com
|
44
48
|
executables: []
|
45
49
|
extensions: []
|
@@ -56,6 +60,14 @@ files:
|
|
56
60
|
- LICENSE
|
57
61
|
- README.md
|
58
62
|
- Rakefile
|
63
|
+
- examples/DNT.md
|
64
|
+
- examples/carrying_context.rb
|
65
|
+
- examples/instrumenting_metal_controller.rb
|
66
|
+
- examples/puma_on_heroku_config.rb
|
67
|
+
- examples/tracing_async_threads.rb
|
68
|
+
- examples/tracing_background_jobs.rb
|
69
|
+
- examples/tracing_forked_processes.rb
|
70
|
+
- examples/unicorn_on_heroku_config.rb
|
59
71
|
- ext/oboe_metal/extconf.rb
|
60
72
|
- ext/oboe_metal/noop/noop.c
|
61
73
|
- ext/oboe_metal/src/bson/bson.h
|
@@ -173,7 +185,44 @@ homepage: http://www.appneta.com/products/traceview/
|
|
173
185
|
licenses:
|
174
186
|
- AppNeta Open License, Version 1.0
|
175
187
|
metadata: {}
|
176
|
-
post_install_message:
|
188
|
+
post_install_message: |2+
|
189
|
+
|
190
|
+
=========================================================================
|
191
|
+
AppNeta TraceView
|
192
|
+
|
193
|
+
Note that this will be the final release for the oboe gem. The gem
|
194
|
+
will be renamed to 'traceview' and all future updates will be made
|
195
|
+
to that other gem.
|
196
|
+
|
197
|
+
Please update your Gemfiles by replacing the 'oboe' gem with the
|
198
|
+
'traceview' gem.
|
199
|
+
|
200
|
+
Gemfile:
|
201
|
+
XXX gem 'oboe'
|
202
|
+
--> gem 'traceview'
|
203
|
+
|
204
|
+
Any Oboe specific calls will still work as usual in the new gem
|
205
|
+
although a single deprecation warning will be output on the
|
206
|
+
first use call.
|
207
|
+
|
208
|
+
We will support these legacy calls for a minimum of 1 year but
|
209
|
+
possibly indefinitely.
|
210
|
+
|
211
|
+
Oboe calls can be updated to use the TraceView module instead:
|
212
|
+
|
213
|
+
Oboe::Config --> TraceView::Config
|
214
|
+
Oboe::API --> TraceView::API
|
215
|
+
OboeMethodProfiling --> TraceViewMethodProfiling
|
216
|
+
Oboe::Context --> TraceView::Context
|
217
|
+
|
218
|
+
Thanks for using TraceView! Happy tracing!
|
219
|
+
|
220
|
+
Best,
|
221
|
+
The TraceView Team
|
222
|
+
|
223
|
+
tldr; The gem is being renamed to traceview. Update your Gemfiles!
|
224
|
+
=========================================================================
|
225
|
+
|
177
226
|
rdoc_options: []
|
178
227
|
require_paths:
|
179
228
|
- lib
|