appoptics_apm 4.0.6 → 4.0.7
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/.travis.yml +6 -4
- data/Dockerfile_alpine +67 -0
- data/README.md +93 -44
- data/appoptics_apm.gemspec +1 -2
- data/docker-compose.yml +23 -1
- data/lib/appoptics_apm.rb +1 -1
- data/lib/appoptics_apm/api/tracing.rb +1 -0
- data/lib/appoptics_apm/base.rb +3 -2
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +1 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +1 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +17 -5
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +16 -4
- data/lib/appoptics_apm/logger.rb +2 -1
- data/lib/appoptics_apm/version.rb +1 -1
- data/ruby_setup.sh +2 -2
- data/run_tests_docker.rb +10 -3
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 075662979a96c233661f6043362df2bf8febad26
|
|
4
|
+
data.tar.gz: 8dd4bd8daed4d2148311d4d375f88a7968a19b22
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e74260bd8fceb642c221e69b82e81fdb5741c979de47f55d60c4a87b514ef6e78d53752a94917606d57e34543a1ff37890da7fb172906fcd4ce6721519fc32cd
|
|
7
|
+
data.tar.gz: 6666c8f48a79bcd2be93a0163b76eb8815569251d83684ccef38f2b0fae4f6e4c4299b45f144577577edb3982735120472e4423a4aecb9e7f8a6dc9546ffe663
|
data/.travis.yml
CHANGED
|
@@ -9,7 +9,7 @@ rvm:
|
|
|
9
9
|
- 2.5.0
|
|
10
10
|
- 2.4.3
|
|
11
11
|
- 2.3.6
|
|
12
|
-
- 1.9.3
|
|
12
|
+
- 1.9.3 # soon not supported anymore
|
|
13
13
|
# - jruby-9.0.5.0
|
|
14
14
|
|
|
15
15
|
gemfile:
|
|
@@ -18,8 +18,9 @@ gemfile:
|
|
|
18
18
|
- gemfiles/instrumentation_mocked.gemfile
|
|
19
19
|
- gemfiles/instrumentation_mocked_oldgems.gemfile
|
|
20
20
|
- gemfiles/frameworks.gemfile
|
|
21
|
-
- gemfiles/rails32.gemfile
|
|
21
|
+
# - gemfiles/rails32.gemfile # We currently are not supporting Rails 3.2
|
|
22
22
|
- gemfiles/rails42.gemfile
|
|
23
|
+
# - gemfiles/rails50.gemfile
|
|
23
24
|
- gemfiles/rails51.gemfile
|
|
24
25
|
- gemfiles/delayed_job.gemfile
|
|
25
26
|
|
|
@@ -63,15 +64,16 @@ matrix:
|
|
|
63
64
|
- gemfile: gemfiles/delayed_job.gemfile
|
|
64
65
|
env: DBTYPE=mysql2
|
|
65
66
|
|
|
66
|
-
# Rails 3.2 is not compatible with Ruby >=
|
|
67
|
+
# Rails 3.2 is not compatible with Ruby >= 2.4
|
|
68
|
+
# We currently are not supporting Rails 3.2
|
|
67
69
|
- rvm: 2.5.0
|
|
68
70
|
gemfile: gemfiles/rails32.gemfile
|
|
69
71
|
- rvm: 2.4.3
|
|
70
72
|
gemfile: gemfiles/rails32.gemfile
|
|
71
73
|
|
|
74
|
+
# Rails 5 requires Ruby >= 2.2
|
|
72
75
|
- rvm: 1.9.3
|
|
73
76
|
gemfile: gemfiles/rails50.gemfile
|
|
74
|
-
|
|
75
77
|
- rvm: 1.9.3
|
|
76
78
|
gemfile: gemfiles/rails51.gemfile
|
|
77
79
|
|
data/Dockerfile_alpine
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
FROM ruby:2.4-alpine3.7
|
|
2
|
+
|
|
3
|
+
# Use this Dockerfile to create the gem
|
|
4
|
+
# > docker build -f Dockerfile_alpine -t ruby_alpine .
|
|
5
|
+
# > docker run --rm -v `pwd`:/code/ruby-appoptics ruby_alpine /bin/bash -l -c 'cd /code/ruby-appoptics'
|
|
6
|
+
|
|
7
|
+
# install OS packages
|
|
8
|
+
RUN apk update
|
|
9
|
+
RUN apk add --upgrade \
|
|
10
|
+
bash \
|
|
11
|
+
build-base \
|
|
12
|
+
curl \
|
|
13
|
+
curl-dev \
|
|
14
|
+
linux-headers \
|
|
15
|
+
git \
|
|
16
|
+
pcre \
|
|
17
|
+
pcre-dev \
|
|
18
|
+
readline-dev \
|
|
19
|
+
openjdk8 \
|
|
20
|
+
zlib-dev \
|
|
21
|
+
less \
|
|
22
|
+
swig \
|
|
23
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
24
|
+
|
|
25
|
+
# rbenv setup
|
|
26
|
+
# use rbenv-default-gems to automatically install bundler for each ruby version
|
|
27
|
+
RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv \
|
|
28
|
+
&& git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build \
|
|
29
|
+
&& git clone https://github.com/rbenv/rbenv-default-gems.git ~/.rbenv/plugins/rbenv-default-gems \
|
|
30
|
+
&& echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile \
|
|
31
|
+
&& echo 'eval "$(rbenv init -)"' >> ~/.profile \
|
|
32
|
+
&& echo 'bundler' > ~/.rbenv/default-gems
|
|
33
|
+
|
|
34
|
+
# install rubies to build our gem against
|
|
35
|
+
RUN source ~/.profile
|
|
36
|
+
&& rbenv install 1.9.3-p551 \
|
|
37
|
+
&& rbenv install 2.3.1 \
|
|
38
|
+
&& rbenv install 2.4.1
|
|
39
|
+
&& rbenv install jruby-9.0.5.0
|
|
40
|
+
|
|
41
|
+
# install swig 3.0.8
|
|
42
|
+
RUN curl -SL http://kent.dl.sourceforge.net/project/swig/swig/swig-3.0.8/swig-3.0.8.tar.gz \
|
|
43
|
+
| tar xzC /tmp \
|
|
44
|
+
&& cd /tmp/swig-3.0.8 \
|
|
45
|
+
&& ./configure && make && make install \
|
|
46
|
+
&& cd \
|
|
47
|
+
&& rm -rf /tmp/swig-3.0.8
|
|
48
|
+
|
|
49
|
+
RUN apk add --upgrade \
|
|
50
|
+
redis \
|
|
51
|
+
memcached \
|
|
52
|
+
postgresql \
|
|
53
|
+
openrc
|
|
54
|
+
&& rc-service postgresql start \
|
|
55
|
+
&& echo "psql --command \"CREATE USER docker WITH SUPERUSER PASSWORD 'docker';\"" >> /tmp/config \
|
|
56
|
+
&& echo "createdb -O docker travis_ci_test" >> /tmp/config \
|
|
57
|
+
&& su postgres -c "bash /tmp/config" \
|
|
58
|
+
&& rm -f /tmp/config
|
|
59
|
+
|
|
60
|
+
RUN apk add --update mysql-client mysql mariadb
|
|
61
|
+
|
|
62
|
+
ENV PATH="/root/.rbenv/bin:/root/.rbenv/shims:$PATH"
|
|
63
|
+
ENV RUBY_ENV=test
|
|
64
|
+
ENV DOCKER_PSQL_PASS=docker
|
|
65
|
+
ENV APPOPTICS_OS_ARCH=alpine-x86_64
|
|
66
|
+
|
|
67
|
+
CMD bash
|
data/README.md
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
# Welcome to the AppOpticsAPM Ruby Gem
|
|
1
|
+
# Welcome to the AppOpticsAPM Ruby Gem````
|
|
2
2
|
|
|
3
3
|
The appoptics_apm gem provides [AppOptics APM](https://www.appoptics.com/) performance instrumentation for Ruby.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
It has the ability to report performance metrics on an array of libraries, databases and frameworks such as Rails,
|
|
7
|
+
It has the ability to report performance metrics on an array of libraries, databases and frameworks such as Rails,
|
|
8
|
+
Mongo, Memcache, ActiveRecord, Cassandra, Rack, Resque
|
|
9
|
+
[and more](http://docs.appoptics.solarwinds.com/Instrumentation/ruby.html#ruby-support-matrix).
|
|
8
10
|
|
|
9
|
-
It requires an [AppOptics](https://www.appoptics.com/) account to view metrics. Get yours,
|
|
11
|
+
It requires an [AppOptics](https://www.appoptics.com/) account to view metrics. Get yours,
|
|
12
|
+
[it's free](https://https://my.appoptics.com/sign_up).
|
|
10
13
|
|
|
11
14
|
[](https://badge.fury.io/rb/appoptics_apm)
|
|
12
15
|
[](https://travis-ci.com/librato/ruby-appoptics)
|
|
13
16
|
[](https://codeclimate.com/github/librato/ruby-appoptics)
|
|
14
17
|
|
|
15
|
-
_Note: The repository name has been changed to ruby-appoptics. Please update your github remotes with
|
|
18
|
+
_Note: The repository name has been changed to ruby-appoptics. Please update your github remotes with
|
|
19
|
+
`git remote set-url origin git@github.com:librato/ruby-appoptics.git`._
|
|
16
20
|
|
|
17
21
|
# Installation
|
|
18
22
|
|
|
19
|
-
_Before installing the gem below, make sure that you have the
|
|
23
|
+
_Before installing the gem below, make sure that you have the
|
|
24
|
+
[dependencies](http://docs.appoptics.com/kb/apm_tracing/ruby/install#dependencies) installed on your host first._
|
|
20
25
|
|
|
21
26
|
The appoptics_apm gem is [available on Rubygems](https://rubygems.org/gems/appoptics_apm) and can be installed with:
|
|
22
27
|
|
|
@@ -51,13 +56,16 @@ If you're reporting to production, only set `APPOPTICS_SERVICE_KEY`
|
|
|
51
56
|
|
|
52
57
|

|
|
53
58
|
|
|
54
|
-
No special steps are needed to instrument Ruby on Rails. Once part of the bundle, the appoptics gem will automatically
|
|
59
|
+
No special steps are needed to instrument Ruby on Rails. Once part of the bundle, the appoptics gem will automatically
|
|
60
|
+
detect Rails and instrument on stack initialization.
|
|
55
61
|
|
|
56
|
-
*Note: You will still need to decide on your `tracing_mode` depending on whether you are running with an instrumented
|
|
62
|
+
*Note: You will still need to decide on your `tracing_mode` depending on whether you are running with an instrumented
|
|
63
|
+
Apache or nginx in front of your Rails stack. See below for more details.*
|
|
57
64
|
|
|
58
65
|
### The Install Generator
|
|
59
66
|
|
|
60
|
-
The appoptics_apm gem provides a Rails generator used to seed an initializer where you can configure and control
|
|
67
|
+
The appoptics_apm gem provides a Rails generator used to seed an initializer where you can configure and control
|
|
68
|
+
`tracing_mode` and [other options](http://docs.appoptics.com/kb/apm_tracing/ruby/configure).
|
|
61
69
|
|
|
62
70
|
To run the install generator run:
|
|
63
71
|
|
|
@@ -82,7 +90,8 @@ AppOpticsAPM
|
|
|
82
90
|
AppOpticsAPM
|
|
83
91
|
```
|
|
84
92
|
|
|
85
|
-
Make sure that the appoptics_apm gem is loaded _after_ Sinatra either by listing `gem 'appoptics_apm'` after Sinatra in
|
|
93
|
+
Make sure that the appoptics_apm gem is loaded _after_ Sinatra either by listing `gem 'appoptics_apm'` after Sinatra in
|
|
94
|
+
your Gemfile or calling the `require 'appoptics_gem'` directive after Sinatra is loaded.
|
|
86
95
|
|
|
87
96
|
With this, the appoptics_apm gem will automatically detect Sinatra on boot and instrument key components.
|
|
88
97
|
|
|
@@ -90,7 +99,8 @@ With this, the appoptics_apm gem will automatically detect Sinatra on boot and i
|
|
|
90
99
|
|
|
91
100
|

|
|
92
101
|
|
|
93
|
-
As long as the appoptics_apm gem is in your `Gemfile` (inserted after the `gem 'padrino'` directive) and you are calling
|
|
102
|
+
As long as the appoptics_apm gem is in your `Gemfile` (inserted after the `gem 'padrino'` directive) and you are calling
|
|
103
|
+
`Bundler.require`, the appoptics_apm gem will automatically instrument Padrino applications.
|
|
94
104
|
|
|
95
105
|
If you need to set `AppOpticsAPM::Config` values on stack boot, you can do so by adding the following
|
|
96
106
|
to your `config/boot.rb` file:
|
|
@@ -120,7 +130,8 @@ You can instrument your Grape application by adding the following code to your `
|
|
|
120
130
|
end
|
|
121
131
|
```
|
|
122
132
|
|
|
123
|
-
Make sure that the appoptics gem is loaded _after_ Grape either by listing `gem 'appoptics_apm'` after Grape in your
|
|
133
|
+
Make sure that the appoptics gem is loaded _after_ Grape either by listing `gem 'appoptics_apm'` after Grape in your
|
|
134
|
+
Gemfile or calling the `require 'appoptics_apm'` directive after Grape is loaded.
|
|
124
135
|
|
|
125
136
|
You must explicitly tell your Grape application to use AppOpticsAPM::Rack for tracing to occur.
|
|
126
137
|
|
|
@@ -137,17 +148,22 @@ Bundler.require
|
|
|
137
148
|
require 'appoptics_apm'
|
|
138
149
|
```
|
|
139
150
|
|
|
140
|
-
From here, you can use the Tracing API to instrument areas of code using `AppOpticsAPM::API.start_trace` (see below).
|
|
151
|
+
From here, you can use the Tracing API to instrument areas of code using `AppOpticsAPM::API.start_trace` (see below).
|
|
152
|
+
If you prefer to instead dive directly into code, take a look at
|
|
153
|
+
[this example](https://gist.github.com/pglombardo/8550713) of an instrumented Ruby script.
|
|
141
154
|
|
|
142
|
-
Once inside of the `AppOpticsAPM::API.start_trace` block, performance metrics will be automatically collected for all
|
|
155
|
+
Once inside of the `AppOpticsAPM::API.start_trace` block, performance metrics will be automatically collected for all
|
|
156
|
+
supported libraries and gems (Redis, Mongo, ActiveRecord etc..).
|
|
143
157
|
|
|
144
158
|
# Custom Tracing
|
|
145
159
|
|
|
146
|
-
You can add even more visibility into any part of your application or scripts by adding custom instrumentation. If you
|
|
160
|
+
You can add even more visibility into any part of your application or scripts by adding custom instrumentation. If you
|
|
161
|
+
want to see the performance of an existing method see Method Profiling. To trace blocks of code see the Tracing API.
|
|
147
162
|
|
|
148
163
|
## The Tracing API
|
|
149
164
|
|
|
150
|
-
You can instrument any arbitrary block of code using `AppOpticsAPM::API.trace`. The code and any supported calls for
|
|
165
|
+
You can instrument any arbitrary block of code using `AppOpticsAPM::API.trace`. The code and any supported calls for
|
|
166
|
+
libraries that we support, will automatically get traced and reported to your dashboard.
|
|
151
167
|
|
|
152
168
|
```ruby
|
|
153
169
|
# layer_name will show up in the AppOptics app dashboard
|
|
@@ -166,41 +182,53 @@ AppOpticsAPM::API.trace(layer_name, report_kvs) do
|
|
|
166
182
|
end
|
|
167
183
|
```
|
|
168
184
|
|
|
169
|
-
`AppOpticsAPM::API.trace` is used within the context of a request. It will follow the upstream state of the request
|
|
185
|
+
`AppOpticsAPM::API.trace` is used within the context of a request. It will follow the upstream state of the request
|
|
186
|
+
being traced. i.e. the block of code will only be traced when the parent request is being traced.
|
|
170
187
|
|
|
171
188
|
This tracing state of a request can also be queried by using `AppOpticsAPM.tracing?`.
|
|
172
189
|
|
|
173
|
-
If you need to instrument code outside the context of a request (such as a cron job, background job or an arbitrary
|
|
190
|
+
If you need to instrument code outside the context of a request (such as a cron job, background job or an arbitrary
|
|
191
|
+
ruby script), use `AppOpticsAPM::API.start_trace` instead which will initiate new traces based on configuration and probability (based on the sample rate).
|
|
174
192
|
|
|
175
|
-
Find more details in the [RubyDoc page](http://rdoc.info/gems/appoptics/AppOpticsAPM/API/Tracing) or in
|
|
193
|
+
Find more details in the [RubyDoc page](http://rdoc.info/gems/appoptics/AppOpticsAPM/API/Tracing) or in
|
|
194
|
+
[this example](https://gist.github.com/pglombardo/8550713) on how to use the Tracing API in an independent Ruby script.
|
|
176
195
|
|
|
177
196
|
## Tracing Methods
|
|
178
197
|
|
|
179
|
-
With AppOptics, you can profile any method in your application or even in the Ruby language using
|
|
198
|
+
With AppOptics, you can profile any method in your application or even in the Ruby language using
|
|
199
|
+
`AppOpticsAPM::API.profile_method`.
|
|
180
200
|
|
|
181
|
-
If, for example, you wanted to see the performance for the `Array::sort`, you could simply call the following in your
|
|
201
|
+
If, for example, you wanted to see the performance for the `Array::sort`, you could simply call the following in your
|
|
202
|
+
startup code:
|
|
182
203
|
|
|
183
204
|
```
|
|
184
205
|
AppOpticsAPM::API.profile_method(Array, :sort)
|
|
185
206
|
```
|
|
186
207
|
|
|
187
|
-
For full documentation, options and reporting custom KVs, see our documentation on
|
|
208
|
+
For full documentation, options and reporting custom KVs, see our documentation on
|
|
209
|
+
[method profiling](http://docs.appoptics.solarwinds.com/Instrumentation/ruby.html#ruby-function-profiling).
|
|
188
210
|
|
|
189
211
|
# Support
|
|
190
212
|
|
|
191
|
-
If you find a bug or would like to request an enhancement, feel free to file an issue. For all other support requests,
|
|
213
|
+
If you find a bug or would like to request an enhancement, feel free to file an issue. For all other support requests,
|
|
214
|
+
see our [support portal](https://tracelytics.freshdesk.com).
|
|
192
215
|
|
|
193
216
|
# Contributing
|
|
194
217
|
|
|
195
|
-
You are obviously a person of great sense and intelligence. We happily appreciate all contributions to the appoptics
|
|
218
|
+
You are obviously a person of great sense and intelligence. We happily appreciate all contributions to the appoptics
|
|
219
|
+
gem whether it is documentation, a bug fix, new instrumentation for a library or framework or anything else we haven't
|
|
220
|
+
thought of.
|
|
196
221
|
|
|
197
|
-
We welcome you to send us PRs. We also humbly request that any new instrumentation submissions have corresponding tests
|
|
222
|
+
We welcome you to send us PRs. We also humbly request that any new instrumentation submissions have corresponding tests
|
|
223
|
+
that accompany them. This way we don't break any of your additions when we (and others) make changes after the fact.
|
|
198
224
|
|
|
199
225
|
## Developer Resources
|
|
200
226
|
|
|
201
|
-
We have made a large effort to expose as much technical information as possible to assist developers wishing to
|
|
227
|
+
We have made a large effort to expose as much technical information as possible to assist developers wishing to
|
|
228
|
+
contribute to the appoptics gem. Below is a good source for information and help for developers:
|
|
202
229
|
|
|
203
|
-
* The [AppOptics Knowledge Base](https://docs.appoptics.com/kb/apm_tracing) has a large collection of technical articles
|
|
230
|
+
* The [AppOptics Knowledge Base](https://docs.appoptics.com/kb/apm_tracing) has a large collection of technical articles
|
|
231
|
+
or, if needed, you can submit a support request directly to the team.
|
|
204
232
|
|
|
205
233
|
If you have any questions or ideas, don't hesitate to contact us anytime.
|
|
206
234
|
|
|
@@ -225,13 +253,20 @@ gem build appoptics_apm.gemspec
|
|
|
225
253
|
|
|
226
254
|
## Writing Custom Instrumentation
|
|
227
255
|
|
|
228
|
-
Custom instrumentation for a library, database or other service can be authored fairly easily. Generally,
|
|
256
|
+
Custom instrumentation for a library, database or other service can be authored fairly easily. Generally,
|
|
257
|
+
instrumentation of a library is done by wrapping select operations of that library and timing their execution using the
|
|
258
|
+
AppOpticsAPM Tracing API which then reports the metrics to the users' AppOptics dashboard.
|
|
229
259
|
|
|
230
|
-
Here, I'll use a stripped down version of the Dalli instrumentation (`lib/appoptics/inst/dalli.rb`) as a quick example
|
|
260
|
+
Here, I'll use a stripped down version of the Dalli instrumentation (`lib/appoptics/inst/dalli.rb`) as a quick example
|
|
261
|
+
of how to instrument a client library (the dalli gem).
|
|
231
262
|
|
|
232
|
-
The Dalli gem nicely routes all memcache operations through a single `perform` operation. Wrapping this method allows
|
|
263
|
+
The Dalli gem nicely routes all memcache operations through a single `perform` operation. Wrapping this method allows
|
|
264
|
+
us to capture all Dalli operations called by an application.
|
|
233
265
|
|
|
234
|
-
First, we define a module (AppOpticsAPM::Inst::Dalli) and our own custom `perform_with_appoptics` method that we will
|
|
266
|
+
First, we define a module (AppOpticsAPM::Inst::Dalli) and our own custom `perform_with_appoptics` method that we will
|
|
267
|
+
use as a wrapper around Dalli's `perform` method. We also declare an `included` method which automatically gets called
|
|
268
|
+
when this module is included by another.
|
|
269
|
+
See ['included' Ruby reference documentation](https://www.omniref.com/ruby/2.2.1/symbols/Module/included).
|
|
235
270
|
|
|
236
271
|
```ruby
|
|
237
272
|
module AppOpticsAPM
|
|
@@ -272,7 +307,8 @@ module AppOpticsAPM
|
|
|
272
307
|
end
|
|
273
308
|
```
|
|
274
309
|
|
|
275
|
-
Second, we tail onto the end of the instrumentation file a simple `::Dalli::Client.module_eval` call to tell the Dalli
|
|
310
|
+
Second, we tail onto the end of the instrumentation file a simple `::Dalli::Client.module_eval` call to tell the Dalli
|
|
311
|
+
module to include our newly defined instrumentation module. Doing this will invoke our previously defined `included` method.
|
|
276
312
|
|
|
277
313
|
```ruby
|
|
278
314
|
if defined?(Dalli) and AppOpticsAPM::Config[:dalli][:enabled]
|
|
@@ -282,31 +318,41 @@ if defined?(Dalli) and AppOpticsAPM::Config[:dalli][:enabled]
|
|
|
282
318
|
end
|
|
283
319
|
```
|
|
284
320
|
|
|
285
|
-
Third, in our wrapper method, we capture the arguments passed in, collect the operation and key information into a local
|
|
321
|
+
Third, in our wrapper method, we capture the arguments passed in, collect the operation and key information into a local
|
|
322
|
+
hash and then invoke the `AppOpticsAPM::API.trace` method to time the execution of the original operation.
|
|
286
323
|
|
|
287
|
-
The `AppOpticsAPM::API.trace` method calls Dalli's native operation and reports the timing metrics and your custom
|
|
324
|
+
The `AppOpticsAPM::API.trace` method calls Dalli's native operation and reports the timing metrics and your custom
|
|
325
|
+
`report_kvs` up to AppOptics servers to be shown on the user's dashboard.
|
|
288
326
|
|
|
289
327
|
Some other tips and guidelines:
|
|
290
328
|
|
|
291
|
-
* You can point your Gemfile directly at your cloned appoptics gem source by using
|
|
329
|
+
* You can point your Gemfile directly at your cloned appoptics gem source by using
|
|
330
|
+
`gem 'appoptics', :path => '/path/to/ruby-appoptics'`
|
|
292
331
|
|
|
293
|
-
* If instrumenting a library, database or service, place your new instrumentation file into the `lib/appoptics/inst/`
|
|
332
|
+
* If instrumenting a library, database or service, place your new instrumentation file into the `lib/appoptics/inst/`
|
|
333
|
+
directory. From there, the appoptics gem will detect it and automatically load the instrumentation file.
|
|
294
334
|
|
|
295
|
-
* If instrumenting a new framework, place your instrumentation file in `lib/appoptics/frameworks`. Refer to the Rails
|
|
335
|
+
* If instrumenting a new framework, place your instrumentation file in `lib/appoptics/frameworks`. Refer to the Rails
|
|
336
|
+
instrumentation for on ideas on how to load the appoptics gem correctly in your framework.
|
|
296
337
|
|
|
297
|
-
* Review other existing instrumentation similar to the one you wish to author. `lib/appoptics/inst/` is a great place
|
|
338
|
+
* Review other existing instrumentation similar to the one you wish to author. `lib/appoptics/inst/` is a great place
|
|
339
|
+
to start.
|
|
298
340
|
|
|
299
|
-
* Depending on the configured `:sample_rate`, not all requests will be traced. Use `AppOpticsAPM.tracing?` to determine
|
|
341
|
+
* Depending on the configured `:sample_rate`, not all requests will be traced. Use `AppOpticsAPM.tracing?` to determine
|
|
342
|
+
of this is a request that is being traced.
|
|
300
343
|
|
|
301
344
|
* Performance is paramount. Make sure that your wrapped methods don't slow down users applications.
|
|
302
345
|
|
|
303
|
-
* Include tests with your instrumentation. See `test/instrumentation/` for some examples of existing instrumentation
|
|
346
|
+
* Include tests with your instrumentation. See `test/instrumentation/` for some examples of existing instrumentation
|
|
347
|
+
tests.
|
|
304
348
|
|
|
305
349
|
## Compiling the C extension
|
|
306
350
|
|
|
307
|
-
The appoptics gem utilizes a C extension to interface with a core library bundled in with the gem which handles
|
|
351
|
+
The appoptics gem utilizes a C extension to interface with a core library bundled in with the gem which handles
|
|
352
|
+
reporting the trace and performance data back to AppOptics servers.
|
|
308
353
|
|
|
309
|
-
C extensions are usually built on `gem install` but when working out of a local git repository, it's required that you
|
|
354
|
+
C extensions are usually built on `gem install` but when working out of a local git repository, it's required that you
|
|
355
|
+
manually build this C extension for the gem to function.
|
|
310
356
|
|
|
311
357
|
To make this simpler, we've included a few rake tasks to automate this process:
|
|
312
358
|
|
|
@@ -318,13 +364,15 @@ rake recompile # Rebuild the gem's c extension
|
|
|
318
364
|
|
|
319
365
|
To see the code related to the C extension, take a look at `ext/oboe_metal/extconf.rb` for details.
|
|
320
366
|
|
|
321
|
-
You can read more about Ruby gems with C extensions in the
|
|
367
|
+
You can read more about Ruby gems with C extensions in the
|
|
368
|
+
[Rubygems Guides](http://guides.rubygems.org/gems-with-extensions/).
|
|
322
369
|
|
|
323
370
|
## Running the Tests
|
|
324
371
|
|
|
325
372
|

|
|
326
373
|
|
|
327
|
-
The tests bundled with the gem are implemented using [Minitest](https://github.com/seattlerb/minitest). The tests are
|
|
374
|
+
The tests bundled with the gem are implemented using [Minitest](https://github.com/seattlerb/minitest). The tests are
|
|
375
|
+
currently used to validate the sanity of the traces generated and basic gem functionality.
|
|
328
376
|
|
|
329
377
|
After a bundle install, the tests can be run as:
|
|
330
378
|
|
|
@@ -332,7 +380,8 @@ After a bundle install, the tests can be run as:
|
|
|
332
380
|
bundle exec rake test
|
|
333
381
|
```
|
|
334
382
|
|
|
335
|
-
This will run a full end-to-end test suite that covers all supported libraries and databases. Note that this requires
|
|
383
|
+
This will run a full end-to-end test suite that covers all supported libraries and databases. Note that this requires
|
|
384
|
+
all of the supported software (Cassandra, Memcache, Mongo etc.) to be installed, configured and available.
|
|
336
385
|
|
|
337
386
|
Since this is overly burdensome for casual users, you can run just the tests that you're interested in.
|
|
338
387
|
|
data/appoptics_apm.gemspec
CHANGED
|
@@ -36,8 +36,7 @@ Gem::Specification.new do |s|
|
|
|
36
36
|
unless defined?(JRUBY_VERSION)
|
|
37
37
|
case RUBY_VERSION
|
|
38
38
|
when /^1\.9/
|
|
39
|
-
s.add_development_dependency('debugger', '>=
|
|
40
|
-
s.add_development_dependency('pry', '>= 0.10.0')
|
|
39
|
+
s.add_development_dependency('pry-debugger', '>= 0.2.3')
|
|
41
40
|
when /^2\./
|
|
42
41
|
s.add_development_dependency('byebug', '>= 8.0.0')
|
|
43
42
|
s.add_development_dependency('pry', '>= 0.10.0')
|
data/docker-compose.yml
CHANGED
|
@@ -34,6 +34,28 @@ services:
|
|
|
34
34
|
- MYSQL_HOST=mysql
|
|
35
35
|
- APPOPTICS_MONGO_SERVER=mongo
|
|
36
36
|
|
|
37
|
+
ruby_appoptics_apm_alpine:
|
|
38
|
+
container_name: ruby_appoptics_apm_alpine
|
|
39
|
+
image: ruby_alpine
|
|
40
|
+
build:
|
|
41
|
+
context: .
|
|
42
|
+
dockerfile: ./Dockerfile_alpine
|
|
43
|
+
cpu_quota: 100000 # 1 cpu, assumes cpu_period of 1 second
|
|
44
|
+
mem_limit: 1G
|
|
45
|
+
volumes:
|
|
46
|
+
- .:/code/ruby-appoptics_apm
|
|
47
|
+
depends_on:
|
|
48
|
+
- wait
|
|
49
|
+
links:
|
|
50
|
+
- wait
|
|
51
|
+
environment:
|
|
52
|
+
- APPOPTICS_RABBITMQ_SERVER=rabbitmq
|
|
53
|
+
- DOCKER_MYSQL_PASS=admin
|
|
54
|
+
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
|
55
|
+
- MYSQL_ROOT_PASSWORD=admin
|
|
56
|
+
- MYSQL_HOST=mysql
|
|
57
|
+
- APPOPTICS_MONGO_SERVER=mongo
|
|
58
|
+
|
|
37
59
|
rabbitmq:
|
|
38
60
|
container_name: rabbitmq
|
|
39
61
|
image: rabbitmq:3-management
|
|
@@ -53,7 +75,7 @@ services:
|
|
|
53
75
|
|
|
54
76
|
mongo:
|
|
55
77
|
container_name: mongo
|
|
56
|
-
image: mongo
|
|
78
|
+
image: mongo:3.4
|
|
57
79
|
ports:
|
|
58
80
|
- "27017:27017"
|
|
59
81
|
|
data/lib/appoptics_apm.rb
CHANGED
data/lib/appoptics_apm/base.rb
CHANGED
|
@@ -19,6 +19,7 @@ module AppOpticsAPM
|
|
|
19
19
|
# ActiveRecord 3.1 and above
|
|
20
20
|
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_insert)
|
|
21
21
|
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_query)
|
|
22
|
+
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_update)
|
|
22
23
|
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_delete)
|
|
23
24
|
end
|
|
24
25
|
end
|
|
@@ -17,6 +17,7 @@ module AppOpticsAPM
|
|
|
17
17
|
|
|
18
18
|
# ActiveRecord 3.1 and up
|
|
19
19
|
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_query)
|
|
20
|
+
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_update)
|
|
20
21
|
AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_delete)
|
|
21
22
|
|
|
22
23
|
else
|
|
@@ -61,7 +61,7 @@ module AppOpticsAPM
|
|
|
61
61
|
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
62
62
|
|
|
63
63
|
opts = extract_trace_details(sql, name)
|
|
64
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
64
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
65
65
|
execute_without_appoptics(sql, name)
|
|
66
66
|
end
|
|
67
67
|
else
|
|
@@ -73,7 +73,7 @@ module AppOpticsAPM
|
|
|
73
73
|
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
74
74
|
|
|
75
75
|
opts = extract_trace_details(sql, name, binds)
|
|
76
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
76
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
77
77
|
exec_query_without_appoptics(sql, name, binds)
|
|
78
78
|
end
|
|
79
79
|
else
|
|
@@ -85,7 +85,7 @@ module AppOpticsAPM
|
|
|
85
85
|
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
86
86
|
|
|
87
87
|
opts = extract_trace_details(sql, name, binds)
|
|
88
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
88
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
89
89
|
exec_delete_without_appoptics(sql, name, binds)
|
|
90
90
|
end
|
|
91
91
|
else
|
|
@@ -93,11 +93,23 @@ module AppOpticsAPM
|
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
def exec_update_with_appoptics(sql, name = nil, binds = [])
|
|
97
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
98
|
+
|
|
99
|
+
opts = extract_trace_details(sql, name, binds)
|
|
100
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
101
|
+
exec_update_without_appoptics(sql, name, binds)
|
|
102
|
+
end
|
|
103
|
+
else
|
|
104
|
+
exec_update_without_appoptics(sql, name, binds)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
96
108
|
def exec_insert_with_appoptics(sql, name = nil, binds = [], *args)
|
|
97
109
|
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
98
110
|
|
|
99
111
|
opts = extract_trace_details(sql, name, binds)
|
|
100
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
112
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
101
113
|
exec_insert_without_appoptics(sql, name, binds, *args)
|
|
102
114
|
end
|
|
103
115
|
else
|
|
@@ -107,7 +119,7 @@ module AppOpticsAPM
|
|
|
107
119
|
|
|
108
120
|
def begin_db_transaction_with_appoptics
|
|
109
121
|
if AppOpticsAPM.tracing?
|
|
110
|
-
AppOpticsAPM::API.trace('activerecord', { :Query => 'BEGIN', :Flavor => :mysql }) do
|
|
122
|
+
AppOpticsAPM::API.trace('activerecord', { :Query => 'BEGIN', :Flavor => :mysql }, :ar_started) do
|
|
111
123
|
begin_db_transaction_without_appoptics
|
|
112
124
|
end
|
|
113
125
|
else
|
|
@@ -61,10 +61,10 @@ module AppOpticsAPM
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def exec_query_with_appoptics(sql, name = nil, binds = [], prepare: false)
|
|
64
|
-
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
64
|
+
if AppOpticsAPM.tracing? && AppOpticsAPM.layer_op != :ar_started && !ignore_payload?(name)
|
|
65
65
|
|
|
66
66
|
opts = extract_trace_details(sql, name, binds)
|
|
67
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
67
|
+
AppOpticsAPM::API.trace('activerecord', opts) do
|
|
68
68
|
exec_query_without_appoptics(sql, name, binds)
|
|
69
69
|
end
|
|
70
70
|
else
|
|
@@ -76,7 +76,7 @@ module AppOpticsAPM
|
|
|
76
76
|
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
77
77
|
|
|
78
78
|
opts = extract_trace_details(sql, name, binds)
|
|
79
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
79
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
80
80
|
exec_insert_without_appoptics(sql, name, binds, *args)
|
|
81
81
|
end
|
|
82
82
|
else
|
|
@@ -88,13 +88,25 @@ module AppOpticsAPM
|
|
|
88
88
|
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
89
89
|
|
|
90
90
|
opts = extract_trace_details(sql, name, binds)
|
|
91
|
-
AppOpticsAPM::API.trace('activerecord', opts
|
|
91
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
92
92
|
exec_delete_without_appoptics(sql, name, binds)
|
|
93
93
|
end
|
|
94
94
|
else
|
|
95
95
|
exec_delete_without_appoptics(sql, name, binds)
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
|
+
|
|
99
|
+
def exec_update_with_appoptics(sql, name = nil, binds = [])
|
|
100
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
101
|
+
|
|
102
|
+
opts = extract_trace_details(sql, name, binds)
|
|
103
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
104
|
+
exec_update_without_appoptics(sql, name, binds)
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
exec_update_without_appoptics(sql, name, binds)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
98
110
|
end # Utils
|
|
99
111
|
end
|
|
100
112
|
end
|
data/lib/appoptics_apm/logger.rb
CHANGED
data/ruby_setup.sh
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# used by run_tests_docker.sh
|
|
4
4
|
# call with:
|
|
5
|
-
# docker-compose run --service-ports
|
|
6
|
-
# docker-compose run --service-ports
|
|
5
|
+
# docker-compose run --service-ports ruby_appoptics_apm /code/ruby-appoptics_apm/ruby_setup.sh <ruby-version> <gemfile> <DBNAME=mysql2> <true|false>
|
|
6
|
+
# docker-compose run --service-ports ruby_appoptics_apm /code/ruby-appoptics_apm/ruby_setup.sh 2.4.1 gemfiles/libraries.gemfile
|
|
7
7
|
|
|
8
8
|
cd /code/ruby-appoptics_apm/
|
|
9
9
|
|
data/run_tests_docker.rb
CHANGED
|
@@ -18,15 +18,22 @@ travis = YAML.load_file('.travis.yml')
|
|
|
18
18
|
matrix = []
|
|
19
19
|
travis['rvm'].each do |rvm|
|
|
20
20
|
travis['gemfile'].each do |gemfile|
|
|
21
|
-
|
|
21
|
+
travis['env'].each do |env|
|
|
22
|
+
matrix << { "rvm" => rvm, "gemfile" => gemfile, 'env' => env}
|
|
23
|
+
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
travis['matrix']['exclude'].each do |h|
|
|
28
|
+
matrix.delete_if do |m|
|
|
29
|
+
m == m.merge(h)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
26
32
|
|
|
27
33
|
matrix.each do |args|
|
|
28
34
|
args['rvm'] = '1.9.3-p551' if args['rvm'] =~ /1.9.3/
|
|
29
|
-
`docker-compose run --rm --service-ports ruby_appoptics_apm /code/ruby-appoptics_apm/ruby_setup.sh #{args['rvm']} #{args['gemfile']}`
|
|
35
|
+
`docker-compose run --rm --service-ports ruby_appoptics_apm /code/ruby-appoptics_apm/ruby_setup.sh #{args['rvm']} #{args['gemfile']} #{args['env']}`
|
|
36
|
+
puts "docker-compose run --rm --service-ports ruby_appoptics_apm /code/ruby-appoptics_apm/ruby_setup.sh #{args['rvm']} #{args['gemfile']} #{args['env']}"
|
|
30
37
|
end
|
|
31
38
|
|
|
32
39
|
# `docker-compose down --rmi all`
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appoptics_apm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Maia Engeli
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2018-03-
|
|
13
|
+
date: 2018-03-28 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: json
|
|
@@ -100,6 +100,7 @@ files:
|
|
|
100
100
|
- CHANGELOG.md
|
|
101
101
|
- CONFIG.md
|
|
102
102
|
- Dockerfile
|
|
103
|
+
- Dockerfile_alpine
|
|
103
104
|
- Dockerfile_test
|
|
104
105
|
- Gemfile
|
|
105
106
|
- LICENSE
|