appoptics_apm 4.11.1 → 4.11.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 +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
|
-
#
|