appoptics_apm 4.11.1 → 4.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +31 -22
- data/appoptics_apm.gemspec +12 -12
- data/examples/sdk_examples.rb +142 -0
- data/ext/oboe_metal/extconf.rb +1 -1
- data/ext/oboe_metal/src/VERSION +1 -1
- data/lib/appoptics_apm/api/metrics.rb +3 -1
- data/lib/appoptics_apm/sdk/custom_metrics.rb +2 -2
- data/lib/appoptics_apm/test.rb +1 -1
- data/lib/appoptics_apm/version.rb +1 -1
- metadata +8 -93
- data/examples/SDK/01_basic_tracing.rb +0 -68
- data/examples/carrying_context.rb +0 -220
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d253a9e5a6be4b11234dc7c761fe700c4ee8ca0d9e254a492de1dd978f80e05
|
4
|
+
data.tar.gz: 45fee16fc9023d5c1e626778cbfd067608b74e0cd70db43376196c6db0d75418
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d28d01c42520a2245013ac8441880251e5037cf4fbd7523caeba159eee241acd36b32c1a709d95334c98cb44d885f30c3e39c0f3e020ef6b16581aabe461d5d
|
7
|
+
data.tar.gz: 1cc6d1af93479adcb85535e86a791bd7c8eb4806517718612b0c42cf860654a2b07f8d69cc6ac3cc91747ee698dfa85f089d2065f1da7bc5b3cdeb3b68fbbdeb
|
data/Gemfile
CHANGED
@@ -1,29 +1,38 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
|
-
|
2
|
+
|
3
|
+
# this Gemfile is very minimal
|
4
|
+
# use rake commands or gemfiles in the gemfiles directory for testing
|
5
|
+
|
6
|
+
gem 'rake', '>= 0.9.0'
|
3
7
|
|
4
8
|
group :development, :test do
|
5
|
-
gem '
|
6
|
-
gem '
|
7
|
-
gem '
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
gem '
|
11
|
-
gem '
|
12
|
-
gem '
|
13
|
-
gem '
|
14
|
-
gem '
|
15
|
-
gem '
|
16
|
-
gem '
|
17
|
-
gem '
|
18
|
-
gem '
|
19
|
-
gem '
|
20
|
-
gem '
|
9
|
+
# gem 'benchmark-ips', '>= 2.7.2'
|
10
|
+
# gem 'bson'
|
11
|
+
# gem 'byebug', '>= 8.0.0'
|
12
|
+
# gem 'debugger', :platform => :mri_19
|
13
|
+
# gem 'get_process_mem'
|
14
|
+
gem 'irb', '>= 1.0.0' # if RUBY_VERSION >= '2.6.0'
|
15
|
+
# gem 'memory_profiler'
|
16
|
+
# gem 'minitest'
|
17
|
+
# gem 'minitest-debugger', :require => false
|
18
|
+
# gem 'minitest-focus', '>=1.1.2'
|
19
|
+
# gem 'minitest-hooks', '>= 1.5.0'
|
20
|
+
# gem 'minitest-reporters', '< 1.0.18'
|
21
|
+
# gem 'mocha'
|
22
|
+
# gem 'puma'
|
23
|
+
# gem 'rack-test'
|
24
|
+
# gem 'rubocop', require: false
|
25
|
+
# gem 'ruby-debug', :platforms => :jruby
|
26
|
+
# gem 'ruby-prof'
|
27
|
+
# gem 'simplecov', '>= 0.16.0'
|
28
|
+
# gem 'simplecov-console'
|
29
|
+
# gem 'webmock' if RUBY_VERSION >= '2.0.0'
|
21
30
|
|
22
|
-
if defined?(JRUBY_VERSION)
|
23
|
-
|
24
|
-
else
|
25
|
-
|
26
|
-
end
|
31
|
+
# if defined?(JRUBY_VERSION)
|
32
|
+
# gem 'sinatra', :require => false
|
33
|
+
# else
|
34
|
+
# gem 'sinatra'
|
35
|
+
# end
|
27
36
|
end
|
28
37
|
|
29
38
|
gemspec
|
data/appoptics_apm.gemspec
CHANGED
@@ -42,21 +42,21 @@ Automatic tracing and metrics for Ruby applications. Get started at appoptics.co
|
|
42
42
|
|
43
43
|
s.extensions = ['ext/oboe_metal/extconf.rb'] unless defined?(JRUBY_VERSION)
|
44
44
|
|
45
|
-
s.add_runtime_dependency('json', '
|
45
|
+
s.add_runtime_dependency('json', '~> 2.3')
|
46
46
|
s.add_runtime_dependency('no_proxy_fix', '~> 0.1.2', '>= 0.1.2')
|
47
47
|
|
48
48
|
# Development dependencies used in gem development & testing
|
49
|
-
s.add_development_dependency('rake', '>= 0.9.0')
|
50
|
-
s.add_development_dependency('simplecov', '>= 0.16.0') if ENV["SIMPLECOV_COVERAGE"]
|
51
|
-
s.add_development_dependency('simplecov-console', '>= 0.4.0') if ENV["SIMPLECOV_COVERAGE"]
|
52
|
-
s.add_development_dependency('irb', '>= 1.0.0') if RUBY_VERSION >= '2.6.0'
|
53
|
-
|
54
|
-
unless defined?(JRUBY_VERSION)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
49
|
+
# s.add_development_dependency('rake', '>= 0.9.0')
|
50
|
+
# s.add_development_dependency('simplecov', '>= 0.16.0') if ENV["SIMPLECOV_COVERAGE"]
|
51
|
+
# s.add_development_dependency('simplecov-console', '>= 0.4.0') if ENV["SIMPLECOV_COVERAGE"]
|
52
|
+
# s.add_development_dependency('irb', '>= 1.0.0') if RUBY_VERSION >= '2.6.0'
|
53
|
+
#
|
54
|
+
# unless defined?(JRUBY_VERSION)
|
55
|
+
# s.add_development_dependency('byebug', '>= 8.0.0')
|
56
|
+
# s.add_development_dependency('minitest-hooks', '>= 1.5.0')
|
57
|
+
# s.add_development_dependency('minitest-focus', '>=1.1.2')
|
58
|
+
# s.add_development_dependency('benchmark-ips', '>= 2.7.2')
|
59
|
+
# end
|
60
60
|
|
61
61
|
s.required_ruby_version = '>= 2.4.0'
|
62
62
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# Copyright (c) 2020 SolarWinds, LLC.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
###############################################################
|
5
|
+
# SDK EXAMPLES
|
6
|
+
###############################################################
|
7
|
+
# The uses cases of the SDK include:
|
8
|
+
# - tracing a piece of your own code
|
9
|
+
# - tracing a method call of a gem that is not auto-instrumented
|
10
|
+
# by appoptics_apm
|
11
|
+
#
|
12
|
+
# SDK documentation:
|
13
|
+
# https://rubydoc.info/gems/appoptics_apm/AppOpticsAPM/SDK
|
14
|
+
|
15
|
+
###############################################################
|
16
|
+
# Prerequisits
|
17
|
+
# export APPOPTICS_SERVICE_KEY=<API token>:<service_name>
|
18
|
+
# `bundle exec ruby sdk_examples.rb`
|
19
|
+
# 5 traced requests will show up at https://my.appoptics.com/
|
20
|
+
###############################################################
|
21
|
+
|
22
|
+
require 'appoptics_apm'
|
23
|
+
|
24
|
+
unless AppOpticsAPM::SDK.appoptics_ready?(10_000)
|
25
|
+
puts "aborting!!! Agent not ready after 10 seconds"
|
26
|
+
exit false
|
27
|
+
end
|
28
|
+
|
29
|
+
###############################################################
|
30
|
+
### ADD A SPAN
|
31
|
+
###############################################################
|
32
|
+
#
|
33
|
+
# AppOpticsAPM::SDK.trace()
|
34
|
+
# This method adds a span to a trace that has been started either
|
35
|
+
# by the auto-instrumentation of the gem handling incoming requests
|
36
|
+
# or the SDK method `start_trace`.
|
37
|
+
# If this method is called outside of the context of a started
|
38
|
+
# trace no spans will be created.
|
39
|
+
#
|
40
|
+
# The argument is the name for the span
|
41
|
+
|
42
|
+
AppOpticsAPM::SDK.trace('span_name') do
|
43
|
+
[9, 6, 12, 2, 7, 1, 9, 3, 4, 14, 5, 8].sort
|
44
|
+
end
|
45
|
+
|
46
|
+
###############################################################
|
47
|
+
# START A TRACE, ADD A SPAN, AND LOG AN INFO EVENT
|
48
|
+
###############################################################
|
49
|
+
#
|
50
|
+
# AppOpticsAPM::SDK.start_trace()
|
51
|
+
# This method starts a trace. It is handy for background jobs,
|
52
|
+
# workers, or scripts, that are not part of a rack application
|
53
|
+
|
54
|
+
AppOpticsAPM::SDK.start_trace('outer_span') do
|
55
|
+
AppOpticsAPM::SDK.trace('first_child_span') do
|
56
|
+
[9, 6, 12, 2, 7, 1, 9, 3, 4, 14, 5, 8].sort
|
57
|
+
AppOpticsAPM::SDK.log_info({ some: :fancy, hash: :to, send: 1 })
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
###############################################################
|
62
|
+
# LOG AN ERROR EVENT
|
63
|
+
###############################################################
|
64
|
+
#
|
65
|
+
# AppOpticsAPM::SDK.log_exception()
|
66
|
+
# This method adds an error event to the trace, which will be
|
67
|
+
# displayed and counted as exception on the appoptics dashboard.
|
68
|
+
|
69
|
+
def do_raise
|
70
|
+
raise StandardError.new("oops")
|
71
|
+
end
|
72
|
+
|
73
|
+
AppOpticsAPM::SDK.start_trace('with_error') do
|
74
|
+
begin
|
75
|
+
do_raise
|
76
|
+
rescue => e
|
77
|
+
AppOpticsAPM::SDK.log_exception(e)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
###############################################################
|
82
|
+
# TRACE A METHOD
|
83
|
+
###############################################################
|
84
|
+
#
|
85
|
+
# AppOpticsAPM::SDK.trace_method()
|
86
|
+
# This creates a span every time the defined method is run.
|
87
|
+
# The method can be of any (accessible) type (instance,
|
88
|
+
# singleton, private, protected etc.).
|
89
|
+
|
90
|
+
module ExampleModule
|
91
|
+
def self.do_sum(a, b)
|
92
|
+
a + b
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
AppOpticsAPM::SDK.trace_method(ExampleModule,
|
97
|
+
:do_sum,
|
98
|
+
{ name: 'computation', backtrace: true },
|
99
|
+
{ CustomKey: "some_info"})
|
100
|
+
|
101
|
+
AppOpticsAPM::SDK.start_trace('trace_a_method') do
|
102
|
+
ExampleModule.do_sum(1, 2)
|
103
|
+
ExampleModule.do_sum(3, 4)
|
104
|
+
end
|
105
|
+
|
106
|
+
###############################################################
|
107
|
+
# SET A CUSTOM TRANSACTION NAME
|
108
|
+
###############################################################
|
109
|
+
#
|
110
|
+
# AppOpticsAPM::SDK.set_transaction_name()
|
111
|
+
#
|
112
|
+
# this method can be called anytime after a trace has been started to add a
|
113
|
+
# custom name for the whole transaction.
|
114
|
+
# In case of a controller the trace is usually started in rack.
|
115
|
+
|
116
|
+
class FakeController
|
117
|
+
def create(params)
|
118
|
+
# @fake = fake.new(params.permit(:type, :title))
|
119
|
+
# @fake.save
|
120
|
+
AppOpticsAPM::SDK.set_transaction_name("fake.#{params[:type]}")
|
121
|
+
# redirect_to @fake
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
AppOpticsAPM::SDK.start_trace('set_transaction_name') do
|
126
|
+
FakeController.new.create(type: 'news')
|
127
|
+
end
|
128
|
+
|
129
|
+
###############################################################
|
130
|
+
# LOG INJECTION OF TRACE_ID
|
131
|
+
###############################################################
|
132
|
+
#
|
133
|
+
# AppOpticsAPM::SDK.current_trace
|
134
|
+
# This method creates an object with the current trace ID and
|
135
|
+
# helper methods to add the ID to logs for cross-referencing.
|
136
|
+
|
137
|
+
AppOpticsAPM::Config[:log_traceId] = :always
|
138
|
+
|
139
|
+
AppOpticsAPM::SDK.start_trace('log_trace_id') do
|
140
|
+
trace = AppOpticsAPM::SDK.current_trace
|
141
|
+
AppOpticsAPM.logger.warn "Some log message #{trace.for_log}"
|
142
|
+
end
|
data/ext/oboe_metal/extconf.rb
CHANGED
@@ -49,7 +49,7 @@ while retries > 0
|
|
49
49
|
begin
|
50
50
|
# download
|
51
51
|
# TODO warning: calling URI.open via Kernel#open is deprecated, call URI.open directly or use URI#open
|
52
|
-
# ____
|
52
|
+
# ____ URI.open is not supported in 2.4.5, let's use open until we can deprecate 2.4.5
|
53
53
|
download = open(ao_item, 'rb')
|
54
54
|
IO.copy_stream(download, clib)
|
55
55
|
|
data/ext/oboe_metal/src/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
10.0.0
|
@@ -45,6 +45,8 @@ module AppOpticsAPM
|
|
45
45
|
AppOpticsAPM.transaction_name
|
46
46
|
elsif kvs['Controller'] && kvs['Action']
|
47
47
|
[kvs['Controller'], kvs['Action']].join('.')
|
48
|
+
elsif kvs[:Controller] && kvs[:Action]
|
49
|
+
[kvs[:Controller], kvs[:Action]].join('.')
|
48
50
|
else
|
49
51
|
"custom-#{span}"
|
50
52
|
end
|
@@ -52,4 +54,4 @@ module AppOpticsAPM
|
|
52
54
|
|
53
55
|
end
|
54
56
|
end
|
55
|
-
end
|
57
|
+
end
|
@@ -29,7 +29,7 @@ module AppOpticsAPM
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
# === Returns:
|
32
|
-
# *
|
32
|
+
# * 0 on success, error code on failure
|
33
33
|
#
|
34
34
|
def increment_metric(name, count = 1, with_hostname = false, tags_kvs = {})
|
35
35
|
return true unless AppOpticsAPM.loaded
|
@@ -62,7 +62,7 @@ module AppOpticsAPM
|
|
62
62
|
# end
|
63
63
|
#
|
64
64
|
# === Returns:
|
65
|
-
# *
|
65
|
+
# * 0 on success, error code on failure
|
66
66
|
#
|
67
67
|
def summary_metric(name, value, count = 1, with_hostname = false, tags_kvs = {})
|
68
68
|
return true unless AppOpticsAPM.loaded
|
data/lib/appoptics_apm/test.rb
CHANGED
@@ -54,7 +54,7 @@ module AppOpticsAPM
|
|
54
54
|
if ENV.key?('TRAVIS_PSQL_PASS')
|
55
55
|
ENV['DATABASE_URL'] = "postgresql://postgres:#{ENV['TRAVIS_PSQL_PASS']}@127.0.0.1:5432/travis_ci_test"
|
56
56
|
elsif ENV.key?('DOCKER_PSQL_PASS')
|
57
|
-
ENV['DATABASE_URL'] = "postgresql://docker:#{ENV['DOCKER_PSQL_PASS']}
|
57
|
+
ENV['DATABASE_URL'] = "postgresql://docker:#{ENV['DOCKER_PSQL_PASS']}@#{ENV['PSQL_HOST']}:5432/travis_ci_test"
|
58
58
|
else
|
59
59
|
ENV['DATABASE_URL'] = 'postgresql://postgres@127.0.0.1:5432/travis_ci_test'
|
60
60
|
end
|
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.11.
|
4
|
+
version: 4.11.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maia Engeli
|
@@ -10,22 +10,22 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-05-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- - "
|
19
|
+
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '2.3'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- - "
|
26
|
+
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: '
|
28
|
+
version: '2.3'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: no_proxy_fix
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -46,94 +46,10 @@ dependencies:
|
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 0.1.2
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: rake
|
51
|
-
requirement: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - ">="
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: 0.9.0
|
56
|
-
type: :development
|
57
|
-
prerelease: false
|
58
|
-
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
requirements:
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 0.9.0
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: irb
|
65
|
-
requirement: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 1.0.0
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
requirements:
|
74
|
-
- - ">="
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: 1.0.0
|
77
|
-
- !ruby/object:Gem::Dependency
|
78
|
-
name: byebug
|
79
|
-
requirement: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - ">="
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: 8.0.0
|
84
|
-
type: :development
|
85
|
-
prerelease: false
|
86
|
-
version_requirements: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - ">="
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: 8.0.0
|
91
|
-
- !ruby/object:Gem::Dependency
|
92
|
-
name: minitest-hooks
|
93
|
-
requirement: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - ">="
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: 1.5.0
|
98
|
-
type: :development
|
99
|
-
prerelease: false
|
100
|
-
version_requirements: !ruby/object:Gem::Requirement
|
101
|
-
requirements:
|
102
|
-
- - ">="
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: 1.5.0
|
105
|
-
- !ruby/object:Gem::Dependency
|
106
|
-
name: minitest-focus
|
107
|
-
requirement: !ruby/object:Gem::Requirement
|
108
|
-
requirements:
|
109
|
-
- - ">="
|
110
|
-
- !ruby/object:Gem::Version
|
111
|
-
version: 1.1.2
|
112
|
-
type: :development
|
113
|
-
prerelease: false
|
114
|
-
version_requirements: !ruby/object:Gem::Requirement
|
115
|
-
requirements:
|
116
|
-
- - ">="
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: 1.1.2
|
119
|
-
- !ruby/object:Gem::Dependency
|
120
|
-
name: benchmark-ips
|
121
|
-
requirement: !ruby/object:Gem::Requirement
|
122
|
-
requirements:
|
123
|
-
- - ">="
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: 2.7.2
|
126
|
-
type: :development
|
127
|
-
prerelease: false
|
128
|
-
version_requirements: !ruby/object:Gem::Requirement
|
129
|
-
requirements:
|
130
|
-
- - ">="
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
version: 2.7.2
|
133
49
|
description: 'Automatic tracing and metrics for Ruby applications. Get started at
|
134
50
|
appoptics.com. @AppOptics
|
135
51
|
|
136
|
-
'
|
52
|
+
'
|
137
53
|
email: support@appoptics.com
|
138
54
|
executables:
|
139
55
|
- appoptics_apm_config
|
@@ -156,8 +72,7 @@ files:
|
|
156
72
|
- README.md
|
157
73
|
- appoptics_apm.gemspec
|
158
74
|
- bin/appoptics_apm_config
|
159
|
-
- examples/
|
160
|
-
- examples/carrying_context.rb
|
75
|
+
- examples/sdk_examples.rb
|
161
76
|
- ext/oboe_metal/README.md
|
162
77
|
- ext/oboe_metal/extconf.rb
|
163
78
|
- ext/oboe_metal/lib/.keep
|
@@ -1,68 +0,0 @@
|
|
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
|
-
AppOpticsAPM::API.log_info(AppOpticsAPM.layer, { some: :fancy, hash: :to, send: 1 })
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
# Example 3
|
60
|
-
def do_traced_work
|
61
|
-
AppOpticsAPM::SDK.trace('simple_span_2') do
|
62
|
-
do_work
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
AppOpticsAPM::SDK.start_trace('outer_span_2') do
|
67
|
-
do_traced_work
|
68
|
-
end
|
@@ -1,220 +0,0 @@
|
|
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
|
-
#
|