appoptics_apm_mnfst 4.5.2
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 +7 -0
- data/.dockerignore +5 -0
- data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
- data/.gitignore +29 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +121 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Gemfile +29 -0
- data/LICENSE +193 -0
- data/README.md +393 -0
- data/Rakefile +230 -0
- data/appoptics_apm.gemspec +61 -0
- data/bin/appoptics_apm_config +15 -0
- data/build_gem.sh +15 -0
- data/build_gem_upload_to_packagecloud.sh +20 -0
- data/examples/SDK/01_basic_tracing.rb +67 -0
- data/examples/carrying_context.rb +220 -0
- data/ext/oboe_metal/extconf.rb +114 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm.rb +76 -0
- data/lib/appoptics_apm/api.rb +20 -0
- data/lib/appoptics_apm/api/layerinit.rb +41 -0
- data/lib/appoptics_apm/api/logging.rb +375 -0
- data/lib/appoptics_apm/api/memcache.rb +37 -0
- data/lib/appoptics_apm/api/metrics.rb +55 -0
- data/lib/appoptics_apm/api/profiling.rb +203 -0
- data/lib/appoptics_apm/api/tracing.rb +53 -0
- data/lib/appoptics_apm/api/util.rb +122 -0
- data/lib/appoptics_apm/base.rb +230 -0
- data/lib/appoptics_apm/config.rb +254 -0
- data/lib/appoptics_apm/frameworks/grape.rb +97 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +108 -0
- data/lib/appoptics_apm/frameworks/rails.rb +94 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +55 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +108 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +125 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
- data/lib/appoptics_apm/inst/curb.rb +330 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
- data/lib/appoptics_apm/inst/excon.rb +125 -0
- data/lib/appoptics_apm/inst/faraday.rb +94 -0
- data/lib/appoptics_apm/inst/grpc_client.rb +162 -0
- data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
- data/lib/appoptics_apm/inst/http.rb +73 -0
- data/lib/appoptics_apm/inst/httpclient.rb +174 -0
- data/lib/appoptics_apm/inst/memcached.rb +86 -0
- data/lib/appoptics_apm/inst/mongo.rb +246 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +199 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +48 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +65 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +90 -0
- data/lib/appoptics_apm/loading.rb +65 -0
- data/lib/appoptics_apm/logger.rb +42 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/noop/README.md +9 -0
- data/lib/appoptics_apm/noop/context.rb +26 -0
- data/lib/appoptics_apm/noop/metadata.rb +22 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/sdk/custom_metrics.rb +92 -0
- data/lib/appoptics_apm/sdk/tracing.rb +315 -0
- data/lib/appoptics_apm/support.rb +119 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +319 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/joboe_metal.rb +212 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe_metal.rb +198 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +265 -0
- data/yardoc_frontpage.md +26 -0
- metadata +266 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'open-uri'
|
|
6
|
+
require 'bundler/setup'
|
|
7
|
+
require 'rake/testtask'
|
|
8
|
+
require 'appoptics_apm/test'
|
|
9
|
+
|
|
10
|
+
Rake::TestTask.new do |t|
|
|
11
|
+
t.verbose = false
|
|
12
|
+
t.warning = false
|
|
13
|
+
t.ruby_opts = []
|
|
14
|
+
t.libs << 'test'
|
|
15
|
+
|
|
16
|
+
# Since we support so many libraries and frameworks, tests
|
|
17
|
+
# runs are segmented into gemfiles that have different
|
|
18
|
+
# sets and versions of gems (libraries and frameworks).
|
|
19
|
+
#
|
|
20
|
+
# Here we detect the Gemfile the tests are being run against
|
|
21
|
+
# and load the appropriate tests.
|
|
22
|
+
#
|
|
23
|
+
case AppOpticsAPM::Test.gemfile
|
|
24
|
+
when /delayed_job/
|
|
25
|
+
require 'delayed/tasks'
|
|
26
|
+
t.test_files = FileList['test/queues/delayed_job*_test.rb']
|
|
27
|
+
when /rails/
|
|
28
|
+
# Pre-load rails to get the major version number
|
|
29
|
+
require 'rails'
|
|
30
|
+
|
|
31
|
+
if Rails::VERSION::MAJOR == 5
|
|
32
|
+
t.test_files = FileList["test/frameworks/rails#{Rails::VERSION::MAJOR}x_test.rb"] +
|
|
33
|
+
FileList["test/frameworks/rails#{Rails::VERSION::MAJOR}x_api_test.rb"]
|
|
34
|
+
else
|
|
35
|
+
t.test_files = FileList["test/frameworks/rails#{Rails::VERSION::MAJOR}x_test.rb"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
when /frameworks/
|
|
39
|
+
t.test_files = FileList['test/frameworks/sinatra*_test.rb'] +
|
|
40
|
+
FileList['test/frameworks/padrino*_test.rb'] +
|
|
41
|
+
FileList['test/frameworks/grape*_test.rb']
|
|
42
|
+
when /libraries/
|
|
43
|
+
t.test_files = FileList['test/support/*_test.rb'] +
|
|
44
|
+
FileList['test/reporter/*_test.rb'] +
|
|
45
|
+
FileList['test/instrumentation/*_test.rb'] +
|
|
46
|
+
FileList['test/profiling/*_test.rb'] -
|
|
47
|
+
['test/instrumentation/twitter-cassandra_test.rb']
|
|
48
|
+
when /instrumentation_mocked/
|
|
49
|
+
# WebMock is interfering with other tests, so these have to run separately
|
|
50
|
+
t.test_files = FileList['test/mocked/*_test.rb']
|
|
51
|
+
when /noop/
|
|
52
|
+
t.test_files = FileList['test/noop/*_test.rb']
|
|
53
|
+
when /unit/
|
|
54
|
+
t.test_files = FileList['test/unit/*_test.rb'] +
|
|
55
|
+
FileList['test/unit/*/*_test.rb']
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if defined?(JRUBY_VERSION)
|
|
59
|
+
t.ruby_opts << ['-J-javaagent:/usr/local/tracelytics/tracelyticsagent.jar']
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
desc "Run all test suites defined by travis"
|
|
64
|
+
task "docker_tests" do
|
|
65
|
+
Dir.chdir('test/run_tests')
|
|
66
|
+
exec('docker-compose run --service-ports ruby_appoptics /code/ruby-appoptics/test/run_tests/ruby_setup.sh test')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
desc "Start docker container for testing and debugging"
|
|
70
|
+
task "docker" do
|
|
71
|
+
Dir.chdir('test/run_tests')
|
|
72
|
+
exec('docker-compose run --service-ports ruby_appoptics /code/ruby-appoptics/test/run_tests/ruby_setup.sh bash')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
desc "Fetch extension dependency files"
|
|
76
|
+
task :fetch_ext_deps do
|
|
77
|
+
swig_version = %x{swig -version} rescue ''
|
|
78
|
+
swig_version = swig_version.scan(/swig version 3.0.\d*/i)
|
|
79
|
+
if swig_version.empty?
|
|
80
|
+
$stderr.puts '== ERROR ================================================================='
|
|
81
|
+
$stderr.puts "Could not find required swig version 3.0.*, found #{swig_version.inspect}"
|
|
82
|
+
$stderr.puts 'Please install swig "~ 3.0.8" and try again.'
|
|
83
|
+
$stderr.puts '=========================================================================='
|
|
84
|
+
raise
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# The c-lib version is different from the gem version
|
|
88
|
+
oboe_version = ENV['OBOE_VERSION'] || 'latest'
|
|
89
|
+
oboe_s3_dir = "https://s3-us-west-2.amazonaws.com/rc-files-t2/c-lib/#{oboe_version}"
|
|
90
|
+
ext_src_dir = File.expand_path('ext/oboe_metal/src')
|
|
91
|
+
|
|
92
|
+
# VERSION is used by extconf.rb to download the correct liboboe when installing the gem
|
|
93
|
+
remote_file = File.join(oboe_s3_dir, 'VERSION')
|
|
94
|
+
local_file = File.join(ext_src_dir, 'VERSION')
|
|
95
|
+
puts "fetching #{remote_file} to #{local_file}"
|
|
96
|
+
open(remote_file, 'rb') do |rf|
|
|
97
|
+
content = rf.read
|
|
98
|
+
File.open(local_file, 'wb') { |f| f.puts content }
|
|
99
|
+
puts "!!!!!!! C-Lib VERSION: #{content.strip} !!!!!!!!"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# oboe and bson header files
|
|
103
|
+
FileUtils.mkdir_p(File.join(ext_src_dir, 'bson'))
|
|
104
|
+
%w(oboe.h oboe.hpp oboe_debug.h oboe.i bson/bson.h bson/platform_hacks.h).each do |filename|
|
|
105
|
+
remote_file = File.join(oboe_s3_dir, 'include', filename)
|
|
106
|
+
local_file = File.join(ext_src_dir, filename)
|
|
107
|
+
|
|
108
|
+
puts "fetching #{remote_file} to #{local_file}"
|
|
109
|
+
open(remote_file, 'rb') do |rf|
|
|
110
|
+
content = rf.read
|
|
111
|
+
File.open(local_file, 'wb') { |f| f.puts content }
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
FileUtils.cd(ext_src_dir) do
|
|
116
|
+
system('swig -c++ -ruby -module oboe_metal oboe.i')
|
|
117
|
+
FileUtils.rm('oboe.i')
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
desc "Build the gem's c extension"
|
|
122
|
+
task :compile do
|
|
123
|
+
if !defined?(JRUBY_VERSION)
|
|
124
|
+
puts "== Building the c extension against Ruby #{RUBY_VERSION}"
|
|
125
|
+
|
|
126
|
+
pwd = Dir.pwd
|
|
127
|
+
ext_dir = File.expand_path('ext/oboe_metal')
|
|
128
|
+
final_so = File.expand_path('lib/oboe_metal.so')
|
|
129
|
+
so_file = File.expand_path('ext/oboe_metal/oboe_metal.so')
|
|
130
|
+
|
|
131
|
+
Dir.chdir ext_dir
|
|
132
|
+
ENV['APPOPTICS_FROM_S3'] = 'true'
|
|
133
|
+
cmd = [Gem.ruby, 'extconf.rb']
|
|
134
|
+
sh cmd.join(' ')
|
|
135
|
+
sh '/usr/bin/env make'
|
|
136
|
+
|
|
137
|
+
File.delete(final_so) if File.exist?(final_so)
|
|
138
|
+
|
|
139
|
+
if File.exist?(so_file)
|
|
140
|
+
FileUtils.mv(so_file, final_so)
|
|
141
|
+
Dir.chdir(pwd)
|
|
142
|
+
puts "== Extension built and moved to #{final_so}"
|
|
143
|
+
else
|
|
144
|
+
Dir.chdir(pwd)
|
|
145
|
+
puts '!! Extension failed to build (see above). Have the required binary and header files been fetched?'
|
|
146
|
+
puts '!! Try the tasks in this order: clean > fetch_ext_deps > compile.'
|
|
147
|
+
end
|
|
148
|
+
else
|
|
149
|
+
puts '== Nothing to do under JRuby.'
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
desc 'Clean up extension build files'
|
|
154
|
+
task :clean do
|
|
155
|
+
if !defined?(JRUBY_VERSION)
|
|
156
|
+
pwd = Dir.pwd
|
|
157
|
+
ext_dir = File.expand_path('ext/oboe_metal')
|
|
158
|
+
symlinks = [
|
|
159
|
+
File.expand_path('lib/oboe_metal.so'),
|
|
160
|
+
File.expand_path('ext/oboe_metal/lib/liboboe.so'),
|
|
161
|
+
File.expand_path('ext/oboe_metal/lib/liboboe-1.0.so.0')
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
symlinks.each do |symlink|
|
|
165
|
+
FileUtils.rm_f symlink
|
|
166
|
+
end
|
|
167
|
+
Dir.chdir ext_dir
|
|
168
|
+
sh '/usr/bin/env make clean' if File.exist? 'Makefile'
|
|
169
|
+
|
|
170
|
+
Dir.chdir pwd
|
|
171
|
+
else
|
|
172
|
+
puts '== Nothing to do under JRuby.'
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
desc 'Remove all built files and extensions'
|
|
177
|
+
task :distclean do
|
|
178
|
+
if !defined?(JRUBY_VERSION)
|
|
179
|
+
pwd = Dir.pwd
|
|
180
|
+
ext_dir = File.expand_path('ext/oboe_metal')
|
|
181
|
+
mkmf_log = File.expand_path('ext/oboe_metal/mkmf.log')
|
|
182
|
+
symlinks = [
|
|
183
|
+
File.expand_path('lib/oboe_metal.so'),
|
|
184
|
+
File.expand_path('ext/oboe_metal/lib/liboboe.so'),
|
|
185
|
+
File.expand_path('ext/oboe_metal/lib/liboboe-1.0.so.0')
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
if File.exist? mkmf_log
|
|
189
|
+
symlinks.each do |symlink|
|
|
190
|
+
FileUtils.rm_f symlink
|
|
191
|
+
end
|
|
192
|
+
Dir.chdir ext_dir
|
|
193
|
+
sh '/usr/bin/env make distclean' if File.exist? 'Makefile'
|
|
194
|
+
|
|
195
|
+
Dir.chdir pwd
|
|
196
|
+
else
|
|
197
|
+
puts 'Nothing to distclean. (nothing built yet?)'
|
|
198
|
+
end
|
|
199
|
+
else
|
|
200
|
+
puts '== Nothing to do under JRuby.'
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
desc "Rebuild the gem's c extension"
|
|
205
|
+
task :recompile => [:distclean, :compile]
|
|
206
|
+
|
|
207
|
+
task :environment do
|
|
208
|
+
ENV['APPOPTICS_GEM_VERBOSE'] = 'true'
|
|
209
|
+
|
|
210
|
+
Bundler.require(:default, :development)
|
|
211
|
+
AppOpticsAPM::Config[:tracing_mode] = :always
|
|
212
|
+
AppOpticsAPM::Test.load_extras
|
|
213
|
+
|
|
214
|
+
if AppOpticsAPM::Test.gemfile?(:delayed_job)
|
|
215
|
+
require 'delayed/tasks'
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
task :console => :environment do
|
|
220
|
+
ARGV.clear
|
|
221
|
+
if AppOpticsAPM::Test.gemfile?(:delayed_job)
|
|
222
|
+
require './test/servers/delayed_job'
|
|
223
|
+
end
|
|
224
|
+
Pry.start
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Used when testing Resque locally
|
|
228
|
+
task 'resque:setup' => :environment do
|
|
229
|
+
require 'resque/tasks'
|
|
230
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
2
|
+
require "appoptics_apm/version"
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = %q{appoptics_apm_mnfst}
|
|
6
|
+
s.version = AppOpticsAPM::Version::STRING
|
|
7
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
|
8
|
+
|
|
9
|
+
s.license = "Librato Open License, Version 1.0"
|
|
10
|
+
|
|
11
|
+
s.authors = ["Maia Engeli", "Peter Giacomo Lombardo", "Spiros Eliopoulos"]
|
|
12
|
+
s.email = %q{support@appoptics.com}
|
|
13
|
+
s.homepage = %q{https://www.appoptics.com/}
|
|
14
|
+
s.summary = %q{AppOptics APM performance instrumentation gem for Ruby}
|
|
15
|
+
s.description = <<-EOF
|
|
16
|
+
Automatic tracing and metrics for Ruby applications. Get started at appoptics.com. @AppOptics
|
|
17
|
+
EOF
|
|
18
|
+
|
|
19
|
+
s.metadata = {
|
|
20
|
+
'changelog_uri' => 'https://github.com/appoptics/appoptics-apm-ruby/releases',
|
|
21
|
+
'documentation_uri' => 'https://docs.appoptics.com/kb/apm_tracing/ruby/',
|
|
22
|
+
'homepage_uri' => 'https://www.appoptics.com/',
|
|
23
|
+
'source_code_uri' => 'https://github.com/appoptics/appoptics-apm-ruby',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
s.extra_rdoc_files = ['LICENSE']
|
|
27
|
+
s.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(test|gemfiles)/}) }
|
|
28
|
+
s.files += ['ext/oboe_metal/src/oboe.h',
|
|
29
|
+
'ext/oboe_metal/src/oboe.hpp',
|
|
30
|
+
'ext/oboe_metal/src/oboe_debug.h',
|
|
31
|
+
'ext/oboe_metal/src/oboe_wrap.cxx',
|
|
32
|
+
'ext/oboe_metal/src/bson/bson.h',
|
|
33
|
+
'ext/oboe_metal/src/bson/platform_hacks.h',
|
|
34
|
+
'ext/oboe_metal/src/VERSION']
|
|
35
|
+
|
|
36
|
+
# TODO this is commented out util we can actually provide gems for different platforms
|
|
37
|
+
# it will create a gem that goes into noop on Darwin and other unsupported platforms
|
|
38
|
+
# s.platform = defined?(JRUBY_VERSION) ? 'java' : Gem::Platform::CURRENT
|
|
39
|
+
|
|
40
|
+
s.extensions = ['ext/oboe_metal/extconf.rb'] unless defined?(JRUBY_VERSION)
|
|
41
|
+
|
|
42
|
+
s.add_runtime_dependency('json', '>= 0')
|
|
43
|
+
s.add_runtime_dependency('no_proxy_fix', '~> 0.1.2', '>= 0.1.2')
|
|
44
|
+
|
|
45
|
+
# Development dependencies used in gem development & testing
|
|
46
|
+
s.add_development_dependency('rake', '>= 0.9.0')
|
|
47
|
+
s.add_development_dependency('simplecov', '>= 0.16.0') if ENV["SIMPLECOV_COVERAGE"]
|
|
48
|
+
s.add_development_dependency('simplecov-console', '>= 0.4.0') if ENV["SIMPLECOV_COVERAGE"]
|
|
49
|
+
|
|
50
|
+
unless defined?(JRUBY_VERSION)
|
|
51
|
+
s.add_development_dependency('byebug', '>= 8.0.0')
|
|
52
|
+
s.add_development_dependency('pry', '>= 0.10.0')
|
|
53
|
+
s.add_development_dependency('pry-byebug', '>= 3.0.0')
|
|
54
|
+
s.add_development_dependency('minitest-hooks', '>= 1.5.0')
|
|
55
|
+
else
|
|
56
|
+
s.add_development_dependency('pry', '>= 0.10.0')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
s.required_ruby_version = '>= 2.0.0'
|
|
60
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
61
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# execute this with `bundle exec appoptics_apm_config`
|
|
5
|
+
# copies the configuration template file into the current directory
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
puts "Copying the configuration template file to appoptics_apm_config_tmp.rb"
|
|
9
|
+
puts "Edit and save as appoptics_apm_config.rb"
|
|
10
|
+
|
|
11
|
+
target_file = File.join(Dir.pwd, 'appoptics_apm_config_tmp.rb')
|
|
12
|
+
temp_orig = File.join(File.dirname(File.dirname(__FILE__)),
|
|
13
|
+
'lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb')
|
|
14
|
+
|
|
15
|
+
FileUtils.copy(temp_orig, target_file)
|
data/build_gem.sh
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# builds the appoptics_apm gem for MRI.
|
|
3
|
+
|
|
4
|
+
# we currently only build for MRI, no JRuby
|
|
5
|
+
echo -e "\n=== building for MRI ===\n"
|
|
6
|
+
rm -f Gemfile.lock
|
|
7
|
+
bundle install
|
|
8
|
+
bundle exec rake distclean
|
|
9
|
+
bundle exec rake fetch_ext_deps
|
|
10
|
+
gem build appoptics_apm.gemspec
|
|
11
|
+
|
|
12
|
+
echo -e "\n=== built gems ===\n"
|
|
13
|
+
ls -la appoptics_apm*.gem
|
|
14
|
+
|
|
15
|
+
echo -e "\n=== publish to rubygems via: gem push <gem> ===\n"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# build the gem,
|
|
4
|
+
# oboe/c-lib version can be given as optional parameter
|
|
5
|
+
if [ "$1" != "" ]; then
|
|
6
|
+
OBOE_VERSION=$1 ./build_gem.sh
|
|
7
|
+
else
|
|
8
|
+
./build_gem.sh
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
# save current rbenv setting and switch to 2.4.1 for the package_cloud commands
|
|
12
|
+
current_ruby=`rbenv global`
|
|
13
|
+
rbenv global 2.4.1
|
|
14
|
+
|
|
15
|
+
# prerequisite: package_cloud token needs to be in ~/.packagecloud
|
|
16
|
+
gem=`ls -dt1 appoptics_apm-[^pre]*.gem | head -1`
|
|
17
|
+
package_cloud push solarwinds/appoptics-apm-ruby $gem
|
|
18
|
+
|
|
19
|
+
# restore ruby version
|
|
20
|
+
rbenv global $current_ruby
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
###############################################################
|
|
3
|
+
# BASIC TRACING EXAMPLES
|
|
4
|
+
###############################################################
|
|
5
|
+
|
|
6
|
+
# set APPOPTICS_SERVICE_KEY and run with
|
|
7
|
+
# `bundle exec ruby 01_basic_tracing.rb`
|
|
8
|
+
|
|
9
|
+
require 'appoptics_apm'
|
|
10
|
+
unless AppopticsAPM::SDK.appoptics_ready(10_000)
|
|
11
|
+
puts "aborting!!! Agent not ready after 10 seconds"
|
|
12
|
+
exit false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
###############################################################
|
|
17
|
+
# Starting a trace and adding a span
|
|
18
|
+
###############################################################
|
|
19
|
+
|
|
20
|
+
# USE CASE:
|
|
21
|
+
# You may want to either trace a piece of your own code or a
|
|
22
|
+
# call to a method from a gem that isn't auto-instrumented by
|
|
23
|
+
# appoptics_apm
|
|
24
|
+
|
|
25
|
+
# The first example will not create a span, because no trace has
|
|
26
|
+
# been started, but the second and third ones will.
|
|
27
|
+
|
|
28
|
+
# The string argument is the name for the span
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# AppOpticsAPM::SDK.trace()
|
|
32
|
+
# most of the time this is the method you need. It adds a span
|
|
33
|
+
# to a trace that has probably been started by rack.
|
|
34
|
+
|
|
35
|
+
# Example 1
|
|
36
|
+
def do_work
|
|
37
|
+
42
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
AppOpticsAPM::SDK.trace('simple_span') do
|
|
41
|
+
do_work
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# AppOpticsAPM::SDK.start_trace()
|
|
46
|
+
# This method starts a trace. It is handy for background jobs,
|
|
47
|
+
# workers, or scripts, that are not part of a rack application
|
|
48
|
+
|
|
49
|
+
# Example 2
|
|
50
|
+
AppOpticsAPM::SDK.start_trace('outer_span') do
|
|
51
|
+
|
|
52
|
+
AppOpticsAPM::SDK.trace('simple_span') do
|
|
53
|
+
do_work
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Example 3
|
|
59
|
+
def do_traced_work
|
|
60
|
+
AppOpticsAPM::SDK.trace('simple_span_2') do
|
|
61
|
+
do_work
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
AppOpticsAPM::SDK.start_trace('outer_span_2') do
|
|
66
|
+
do_traced_work
|
|
67
|
+
end
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
###############################################################
|
|
2
|
+
# A brief overview of AppOpticsAPM tracing context
|
|
3
|
+
###############################################################
|
|
4
|
+
#
|
|
5
|
+
# Tracing context is the state held when AppOpticsAPM 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 AppOpticsAPM to later reassemble performance data to be displayed
|
|
9
|
+
# in the AppOptics dashboard.
|
|
10
|
+
#
|
|
11
|
+
# Tracing context is non-existent until established by calling
|
|
12
|
+
# `AppOpticsAPM::API.start_trace` or `AppOpticsAPM::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 `AppOpticsAPM::API.trace` or `AppOpticsAPM::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 `AppOpticsAPM::API.log_start` as the request
|
|
22
|
+
# enters through the rack middleware via `AppOpticsAPM::Rack`.
|
|
23
|
+
#
|
|
24
|
+
# That tracing context is then continued using `AppOpticsAPM::API.trace` or
|
|
25
|
+
# `AppOpticsAPM::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 (AppOpticsAPM::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 'AppOpticsAPM::Context.toString'
|
|
37
|
+
#
|
|
38
|
+
# xtrace = AppOpticsAPM::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
|
+
# AppOpticsAPM::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
|
+
# AppOptics 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
|
+
AppOpticsAPM::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 `AppOpticsAPM::API.log_start` to start a new trace context.
|
|
92
|
+
AppOpticsAPM::API.log_start('worker_thread', :job_id => job.id)
|
|
93
|
+
|
|
94
|
+
# Do the work
|
|
95
|
+
do_the_work(job)
|
|
96
|
+
|
|
97
|
+
AppOpticsAPM::API.log_end('worker_thread')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
AppOpticsAPM::API.log_end('parent')
|
|
101
|
+
|
|
102
|
+
###############################################################
|
|
103
|
+
#
|
|
104
|
+
# This will generate two independent traces with the following
|
|
105
|
+
# topology.
|
|
106
|
+
#
|
|
107
|
+
# 'parent'
|
|
108
|
+
# ------------------------------------------------------------
|
|
109
|
+
#
|
|
110
|
+
# 'worker_thread'
|
|
111
|
+
# ------------------------------------------------------------
|
|
112
|
+
#
|
|
113
|
+
|
|
114
|
+
###############################################################
|
|
115
|
+
# Thread - with linked asynchronous traces
|
|
116
|
+
###############################################################
|
|
117
|
+
|
|
118
|
+
# Since the following example spawns a thread without waiting
|
|
119
|
+
# for it to return, we carry over the context and we mark the
|
|
120
|
+
# trace generated in that thread to be asynchronous using
|
|
121
|
+
# the `Async` flag.
|
|
122
|
+
|
|
123
|
+
AppOpticsAPM::API.log_start('parent')
|
|
124
|
+
|
|
125
|
+
# Save the context to be imported in spawned thread
|
|
126
|
+
tracing_context = AppOpticsAPM::Context.toString
|
|
127
|
+
|
|
128
|
+
# Get the work to be done
|
|
129
|
+
job = get_work
|
|
130
|
+
|
|
131
|
+
Thread.new do
|
|
132
|
+
# Restore context
|
|
133
|
+
AppOpticsAPM::Context.fromString(tracing_context)
|
|
134
|
+
|
|
135
|
+
AppOpticsAPM::API.log_entry('worker_thread')
|
|
136
|
+
|
|
137
|
+
# Do the work
|
|
138
|
+
do_the_work(job)
|
|
139
|
+
|
|
140
|
+
AppOpticsAPM::API.log_exit('worker_thread', :Async => 1)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
AppOpticsAPM::API.log_end('parent')
|
|
144
|
+
|
|
145
|
+
###############################################################
|
|
146
|
+
#
|
|
147
|
+
# This will generate a single trace with an asynchronous
|
|
148
|
+
# branch like the following
|
|
149
|
+
#
|
|
150
|
+
# 'parent'
|
|
151
|
+
# ------------------------------------------------------------
|
|
152
|
+
# \
|
|
153
|
+
# \
|
|
154
|
+
# ------------------------------------------------------
|
|
155
|
+
# 'worker_thread'
|
|
156
|
+
#
|
|
157
|
+
|
|
158
|
+
###############################################################
|
|
159
|
+
# Process via fork - with separated traces
|
|
160
|
+
###############################################################
|
|
161
|
+
|
|
162
|
+
AppOpticsAPM::API.start_trace('parent_process') do
|
|
163
|
+
# Get some work to process
|
|
164
|
+
job = get_job
|
|
165
|
+
|
|
166
|
+
# fork process to handle work
|
|
167
|
+
fork do
|
|
168
|
+
# Since fork does a complete process copy, the tracing_context still exists
|
|
169
|
+
# so we have to clear it and start again.
|
|
170
|
+
AppOpticsAPM::Context.clear
|
|
171
|
+
|
|
172
|
+
AppOpticsAPM::API.start_trace('worker_process', nil, :job_id => job.id) do
|
|
173
|
+
do_work(job)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
###############################################################
|
|
180
|
+
#
|
|
181
|
+
# This will generate two independent traces:
|
|
182
|
+
#
|
|
183
|
+
# 'parent_process'
|
|
184
|
+
# ------------------------------------------------------------
|
|
185
|
+
#
|
|
186
|
+
# 'worker_process'
|
|
187
|
+
# ------------------------------------------------------------
|
|
188
|
+
#
|
|
189
|
+
###############################################################
|
|
190
|
+
# Process via fork - with linked asynchronous traces
|
|
191
|
+
###############################################################
|
|
192
|
+
|
|
193
|
+
AppOpticsAPM::API.start_trace('parent_process') do
|
|
194
|
+
# Get some work to process
|
|
195
|
+
job = get_job
|
|
196
|
+
|
|
197
|
+
# fork process to handle work
|
|
198
|
+
fork do
|
|
199
|
+
# Since fork does a complete process copy, the tracing_context still exists
|
|
200
|
+
# although we'll have to mark these traces as asynchronous to denote
|
|
201
|
+
# that it has split off from the main program flow
|
|
202
|
+
|
|
203
|
+
AppOpticsAPM::API.trace('worker_process', :Async => 1) do
|
|
204
|
+
do_work(job)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
###############################################################
|
|
210
|
+
#
|
|
211
|
+
# This will generate a single trace with an asynchronous
|
|
212
|
+
# branch like the following
|
|
213
|
+
#
|
|
214
|
+
# 'parent_process'
|
|
215
|
+
# ------------------------------------------------------------
|
|
216
|
+
# \
|
|
217
|
+
# \
|
|
218
|
+
# ------------------------------------------------------
|
|
219
|
+
# 'worker_process'
|
|
220
|
+
#
|