appoptics_apm-zearn 4.13.1
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/.github/workflows/build_and_release_gem.yml +103 -0
- data/.github/workflows/build_for_packagecloud.yml +70 -0
- data/.github/workflows/docker-images.yml +47 -0
- data/.github/workflows/run_cpluplus_tests.yml +73 -0
- data/.github/workflows/run_tests.yml +168 -0
- data/.github/workflows/scripts/test_install.rb +23 -0
- data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
- data/.github/workflows/test_on_4_linux.yml +159 -0
- data/.gitignore +36 -0
- data/.rubocop.yml +29 -0
- data/.travis.yml +130 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Gemfile +14 -0
- data/LICENSE +202 -0
- data/README.md +393 -0
- data/appoptics_apm.gemspec +70 -0
- data/bin/appoptics_apm_config +15 -0
- data/examples/prepend.rb +13 -0
- data/examples/sdk_examples.rb +158 -0
- data/ext/oboe_metal/README.md +69 -0
- data/ext/oboe_metal/extconf.rb +151 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
- data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
- data/ext/oboe_metal/noop/noop.c +8 -0
- data/ext/oboe_metal/src/README.md +6 -0
- data/ext/oboe_metal/src/VERSION +2 -0
- data/ext/oboe_metal/src/bson/bson.h +220 -0
- data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
- data/ext/oboe_metal/src/frames.cc +246 -0
- data/ext/oboe_metal/src/frames.h +40 -0
- data/ext/oboe_metal/src/init_appoptics_apm.cc +21 -0
- data/ext/oboe_metal/src/logging.cc +95 -0
- data/ext/oboe_metal/src/logging.h +35 -0
- data/ext/oboe_metal/src/oboe.h +1156 -0
- data/ext/oboe_metal/src/oboe_api.cpp +652 -0
- data/ext/oboe_metal/src/oboe_api.hpp +431 -0
- data/ext/oboe_metal/src/oboe_debug.h +59 -0
- data/ext/oboe_metal/src/oboe_swig_wrap.cc +7329 -0
- data/ext/oboe_metal/src/profiling.cc +435 -0
- data/ext/oboe_metal/src/profiling.h +78 -0
- data/ext/oboe_metal/test/CMakeLists.txt +53 -0
- data/ext/oboe_metal/test/FindGMock.cmake +43 -0
- data/ext/oboe_metal/test/README.md +56 -0
- data/ext/oboe_metal/test/frames_test.cc +164 -0
- data/ext/oboe_metal/test/profiling_test.cc +93 -0
- data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
- data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
- data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
- data/ext/oboe_metal/test/test.h +11 -0
- data/ext/oboe_metal/test/test_main.cc +32 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm/api/layerinit.rb +41 -0
- data/lib/appoptics_apm/api/logging.rb +381 -0
- data/lib/appoptics_apm/api/memcache.rb +37 -0
- data/lib/appoptics_apm/api/metrics.rb +63 -0
- data/lib/appoptics_apm/api/tracing.rb +57 -0
- data/lib/appoptics_apm/api/util.rb +120 -0
- data/lib/appoptics_apm/api.rb +21 -0
- data/lib/appoptics_apm/base.rb +231 -0
- data/lib/appoptics_apm/config.rb +299 -0
- data/lib/appoptics_apm/frameworks/grape.rb +98 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +78 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -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_controller6.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 +88 -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 +114 -0
- data/lib/appoptics_apm/frameworks/rails/inst/logger_formatters.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails.rb +100 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +96 -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 +332 -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 +106 -0
- data/lib/appoptics_apm/inst/graphql.rb +240 -0
- data/lib/appoptics_apm/inst/grpc_client.rb +159 -0
- data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
- data/lib/appoptics_apm/inst/http.rb +81 -0
- data/lib/appoptics_apm/inst/httpclient.rb +174 -0
- data/lib/appoptics_apm/inst/logger_formatter.rb +50 -0
- data/lib/appoptics_apm/inst/logging_log_event.rb +28 -0
- data/lib/appoptics_apm/inst/lumberjack_formatter.rb +13 -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 +182 -0
- data/lib/appoptics_apm/inst/rack_cache.rb +35 -0
- data/lib/appoptics_apm/inst/redis.rb +274 -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 +66 -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/loading.rb +65 -0
- data/lib/appoptics_apm/logger.rb +14 -0
- data/lib/appoptics_apm/noop/README.md +9 -0
- data/lib/appoptics_apm/noop/context.rb +27 -0
- data/lib/appoptics_apm/noop/metadata.rb +25 -0
- data/lib/appoptics_apm/noop/profiling.rb +21 -0
- data/lib/appoptics_apm/oboe_init_options.rb +211 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/sdk/current_trace.rb +77 -0
- data/lib/appoptics_apm/sdk/custom_metrics.rb +94 -0
- data/lib/appoptics_apm/sdk/logging.rb +37 -0
- data/lib/appoptics_apm/sdk/tracing.rb +434 -0
- data/lib/appoptics_apm/support/profiling.rb +18 -0
- data/lib/appoptics_apm/support/transaction_metrics.rb +67 -0
- data/lib/appoptics_apm/support/transaction_settings.rb +219 -0
- data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
- data/lib/appoptics_apm/support_report.rb +119 -0
- data/lib/appoptics_apm/test.rb +95 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +326 -0
- data/lib/appoptics_apm/version.rb +16 -0
- data/lib/appoptics_apm/xtrace.rb +115 -0
- data/lib/appoptics_apm.rb +77 -0
- data/lib/joboe_metal.rb +212 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe_metal.rb +172 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +47 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +425 -0
- data/log/.keep +0 -0
- data/yardoc_frontpage.md +26 -0
- metadata +231 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module AppOpticsAPM
|
2
|
+
|
3
|
+
# override the Ruby method, so that no code related to profiling gets executed
|
4
|
+
class Profiling
|
5
|
+
|
6
|
+
def self.run
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# these put the c-functions into "noop"
|
12
|
+
module CProfiler
|
13
|
+
def self.set_interval(_)
|
14
|
+
# do nothing
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get_tid
|
18
|
+
return 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# Copyright (c) 2019 SolarWinds, LLC.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
module AppOpticsAPM
|
7
|
+
|
8
|
+
class OboeInitOptions
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
attr_reader :reporter, :host, :service_name, :ec2_md_timeout, :grpc_proxy # exposing these mainly for testing
|
12
|
+
|
13
|
+
# TODO decide if these globals are useful when testing
|
14
|
+
# OBOE_HOSTNAME_ALIAS = 0
|
15
|
+
# OBOE_DEBUG_LEVEL = 1
|
16
|
+
# OBOE_LOGFILE = 2
|
17
|
+
#
|
18
|
+
# OBOE_MAX_TRANSACTIONS = 3
|
19
|
+
# OBOE_FLUSH_MAX_WAIT_TIME = 4
|
20
|
+
# OBOE_EVENTS_FLUSH_INTERVAL = 5
|
21
|
+
# OBOE_EVENTS_FLUSH_BATCH_SIZE = 6
|
22
|
+
#
|
23
|
+
# OBOE_REPORTER = 7
|
24
|
+
# OBOE_COLLECTOR = 8
|
25
|
+
# OBOE_SERVICE_KEY = 9
|
26
|
+
# OBOE_TRUSTEDPATH = 10
|
27
|
+
#
|
28
|
+
# OBOE_BUFSIZE = 11
|
29
|
+
# OBOE_TRACE_METRICS = 12
|
30
|
+
# OBOE_HISTOGRAM_PRECISION = 13
|
31
|
+
# OBOE_TOKEN_BUCKET_CAPACITY = 14
|
32
|
+
# OBOE_TOKEN_BUCKET_RATE = 15
|
33
|
+
# OBOE_FILE_SINGLE = 16
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
# optional hostname alias
|
37
|
+
@hostname_alias = ENV['APPOPTICS_HOSTNAME_ALIAS'] || AppOpticsAPM::Config[:hostname_alias] || ''
|
38
|
+
# level at which log messages will be written to log file (0-6)
|
39
|
+
@debug_level = (ENV['APPOPTICS_DEBUG_LEVEL'] || AppOpticsAPM::Config[:debug_level] || 3).to_i
|
40
|
+
# file name including path for log file
|
41
|
+
# TODO eventually find better way to combine ruby and oboe logs
|
42
|
+
@log_file_path = ENV['APPOPTICS_LOGFILE'] || ''
|
43
|
+
# maximum number of transaction names to track
|
44
|
+
@max_transactions = (ENV['APPOPTICS_MAX_TRANSACTIONS'] || -1).to_i
|
45
|
+
# maximum wait time for flushing data before terminating in milli seconds
|
46
|
+
@max_flush_wait_time = (ENV['APPOPTICS_FLUSH_MAX_WAIT_TIME'] || -1).to_i
|
47
|
+
# events flush timeout in seconds (threshold for batching messages before sending off)
|
48
|
+
@events_flush_interval = (ENV['APPOPTICS_EVENTS_FLUSH_INTERVAL'] || -1).to_i
|
49
|
+
# events flush batch size in KB (threshold for batching messages before sending off)
|
50
|
+
@event_flush_batch_size = (ENV['APPOPTICS_EVENTS_FLUSH_BATCH_SIZE'] || -1).to_i
|
51
|
+
|
52
|
+
# the reporter to be used (ssl, upd, file, null)
|
53
|
+
# collector endpoint (reporter=ssl), udp address (reporter=udp), or file path (reporter=file)
|
54
|
+
@reporter, @host = reporter_and_host
|
55
|
+
|
56
|
+
# the service key
|
57
|
+
@service_key = read_and_validate_service_key
|
58
|
+
# path to the SSL certificate (only for ssl)
|
59
|
+
@trusted_path = ENV['APPOPTICS_TRUSTEDPATH'] || ''
|
60
|
+
# size of the message buffer
|
61
|
+
@buffer_size = (ENV['APPOPTICS_BUFSIZE'] || -1).to_i
|
62
|
+
# flag indicating if trace metrics reporting should be enabled (default) or disabled
|
63
|
+
@trace_metrics = (ENV['APPOPTICS_TRACE_METRICS'] || -1).to_i
|
64
|
+
# the histogram precision (only for ssl)
|
65
|
+
@histogram_precision = (ENV['APPOPTICS_HISTOGRAM_PRECISION'] || -1).to_i
|
66
|
+
# custom token bucket capacity
|
67
|
+
@token_bucket_capacity = (ENV['APPOPTICS_TOKEN_BUCKET_CAPACITY'] || -1).to_i
|
68
|
+
# custom token bucket rate
|
69
|
+
@token_bucket_rate = (ENV['APPOPTICS_TOKEN_BUCKET_RATE'] || -1).to_i
|
70
|
+
# use single files in file reporter for each event
|
71
|
+
@file_single = (ENV['APPOPTICS_REPORTER_FILE_SINGLE'].to_s.downcase == 'true') ? 1 : 0
|
72
|
+
# timeout for ec2 metadata
|
73
|
+
@ec2_md_timeout = read_and_validate_ec2_md_timeout
|
74
|
+
@grpc_proxy = read_and_validate_proxy
|
75
|
+
# hardcoded arg for lambda (lambda not supported yet)
|
76
|
+
# hardcoded arg for grpc hack
|
77
|
+
end
|
78
|
+
|
79
|
+
def re_init # for testing with changed ENV vars
|
80
|
+
initialize
|
81
|
+
end
|
82
|
+
|
83
|
+
def array_for_oboe
|
84
|
+
[
|
85
|
+
@hostname_alias, # 0
|
86
|
+
@debug_level, # 1
|
87
|
+
@log_file_path, # 2
|
88
|
+
@max_transactions, # 3
|
89
|
+
@max_flush_wait_time, # 4
|
90
|
+
@events_flush_interval, # 5
|
91
|
+
@event_flush_batch_size, # 6
|
92
|
+
|
93
|
+
@reporter, # 7
|
94
|
+
@host, # 8
|
95
|
+
@service_key, # 9
|
96
|
+
@trusted_path, #10
|
97
|
+
@buffer_size, #11
|
98
|
+
@trace_metrics, #12
|
99
|
+
@histogram_precision, #13
|
100
|
+
@token_bucket_capacity, #14
|
101
|
+
@token_bucket_rate, #15
|
102
|
+
@file_single, #16
|
103
|
+
@ec2_md_timeout, #17
|
104
|
+
@grpc_proxy, #18
|
105
|
+
0, # arg for lambda
|
106
|
+
1 # arg for grpc hack, hardcoded to include hack
|
107
|
+
]
|
108
|
+
end
|
109
|
+
|
110
|
+
def service_key_ok?
|
111
|
+
return !@service_key.empty? || @reporter != 'ssl'
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def reporter_and_host
|
117
|
+
|
118
|
+
reporter = ENV['APPOPTICS_REPORTER'] || 'ssl'
|
119
|
+
# override with 'file', e.g. when running tests
|
120
|
+
# changed my mind => set the right reporter in the env when running tests !!!
|
121
|
+
# reporter = 'file' if ENV.key?('APPOPTICS_GEM_TEST')
|
122
|
+
|
123
|
+
host = ''
|
124
|
+
case reporter
|
125
|
+
when 'ssl', 'file'
|
126
|
+
host = ENV['APPOPTICS_COLLECTOR'] || ''
|
127
|
+
when 'udp'
|
128
|
+
host = ENV['APPOPTICS_COLLECTOR'] ||
|
129
|
+
"#{AppOpticsAPM::Config[:reporter_host]}:#{AppOpticsAPM::Config[:reporter_port]}"
|
130
|
+
# TODO decide what to do
|
131
|
+
# ____ AppOpticsAPM::Config[:reporter_host] and
|
132
|
+
# ____ AppOpticsAPM::Config[:reporter_port] were moved here from
|
133
|
+
# ____ oboe_metal.rb and are not documented anywhere
|
134
|
+
# ____ udp is for internal use only
|
135
|
+
when 'null'
|
136
|
+
host = ''
|
137
|
+
end
|
138
|
+
|
139
|
+
[reporter, host]
|
140
|
+
end
|
141
|
+
|
142
|
+
def read_and_validate_service_key
|
143
|
+
return '' unless @reporter == 'ssl'
|
144
|
+
|
145
|
+
service_key = ENV['APPOPTICS_SERVICE_KEY'] || AppOpticsAPM::Config[:service_key]
|
146
|
+
unless service_key
|
147
|
+
AppOpticsAPM.logger.error "[appoptics_apm/oboe_options] APPOPTICS_SERVICE_KEY not configured."
|
148
|
+
return ''
|
149
|
+
end
|
150
|
+
|
151
|
+
match = service_key.match( /([^:]+)(:{0,1})(.*)/ )
|
152
|
+
token = match[1]
|
153
|
+
service_name = match[3]
|
154
|
+
|
155
|
+
return '' unless validate_token(token)
|
156
|
+
return '' unless validate_transform_service_name(service_name)
|
157
|
+
|
158
|
+
return "#{token}:#{service_name}"
|
159
|
+
end
|
160
|
+
|
161
|
+
def validate_token(token)
|
162
|
+
if (token !~ /^[0-9a-fA-F]{64}|[0-9a-zA-Z_-]{71}$/) && ENV['APPOPTICS_COLLECTOR'] !~ /java-collector:1222/
|
163
|
+
masked = "#{token[0..3]}...#{token[-4..-1]}"
|
164
|
+
AppOpticsAPM.logger.error "[appoptics_apm/oboe_options] APPOPTICS_SERVICE_KEY problem. API Token in wrong format. Masked token: #{masked}"
|
165
|
+
return false
|
166
|
+
end
|
167
|
+
|
168
|
+
true
|
169
|
+
end
|
170
|
+
|
171
|
+
def validate_transform_service_name(service_name)
|
172
|
+
service_name = 'test_ssl_collector' if ENV['APPOPTICS_COLLECTOR'] =~ /java-collector:1222/
|
173
|
+
if service_name.empty?
|
174
|
+
AppOpticsAPM.logger.error "[appoptics_apm/oboe_options] APPOPTICS_SERVICE_KEY problem. Service Name is missing"
|
175
|
+
return false
|
176
|
+
end
|
177
|
+
|
178
|
+
name = service_name.dup
|
179
|
+
name.downcase!
|
180
|
+
name.gsub!(/[^a-z0-9.:_-]/, '')
|
181
|
+
name = name[0..254]
|
182
|
+
|
183
|
+
if name != service_name
|
184
|
+
AppOpticsAPM.logger.warn "[appoptics_apm/oboe_options] APPOPTICS_SERVICE_KEY problem. Service Name transformed from #{service_name} to #{name}"
|
185
|
+
service_name = name
|
186
|
+
end
|
187
|
+
@service_name = service_name # instance variable used in testing
|
188
|
+
true
|
189
|
+
end
|
190
|
+
|
191
|
+
def read_and_validate_ec2_md_timeout
|
192
|
+
timeout = ENV['APPOPTICS_EC2_METADATA_TIMEOUT'] || AppOpticsAPM::Config[:ec2_metadata_timeout]
|
193
|
+
return 1000 unless timeout.is_a?(Integer) || timeout =~ /^\d+$/
|
194
|
+
timeout = timeout.to_i
|
195
|
+
return timeout.between?(0, 3000) ? timeout : 1000
|
196
|
+
end
|
197
|
+
|
198
|
+
def read_and_validate_proxy
|
199
|
+
proxy = ENV['APPOPTICS_PROXY'] || AppOpticsAPM::Config[:http_proxy] || ''
|
200
|
+
return proxy if proxy == ''
|
201
|
+
|
202
|
+
unless proxy =~ /http:\/\/.*:\d+$/
|
203
|
+
AppOpticsAPM.logger.error "[appoptics_apm/oboe_options] APPOPTICS_PROXY/http_proxy doesn't start with 'http://', #{proxy}"
|
204
|
+
return '' # try without proxy, it may work, shouldn't crash but may not report
|
205
|
+
end
|
206
|
+
|
207
|
+
proxy
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
module AppOpticsAPM
|
5
|
+
##
|
6
|
+
# This module provides a method to manually initialize the
|
7
|
+
# Ruby instrumentation. Normally this is done by detecting
|
8
|
+
# frameworks at load time and inserting initialization hooks.
|
9
|
+
module Ruby
|
10
|
+
class << self
|
11
|
+
def initialize
|
12
|
+
load
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# The core method to load Ruby instrumentation. Call this
|
17
|
+
# from raw Ruby scripts or in Ruby applications where a
|
18
|
+
# supported framework isn't being used. Supported frameworks
|
19
|
+
# will instead be detected at load time and initialization is
|
20
|
+
# automatic.
|
21
|
+
def load
|
22
|
+
# In case some apps call this manually, make sure
|
23
|
+
# that the gem is fully loaded and not in no-op
|
24
|
+
# mode (e.g. on unsupported platforms etc.)
|
25
|
+
if AppOpticsAPM.loaded
|
26
|
+
AppOpticsAPM::Inst.load_instrumentation
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if AppOpticsAPM.loaded && !AppOpticsAPM.framework?
|
34
|
+
AppOpticsAPM::Ruby.load
|
35
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2019 SolarWinds, LLC.
|
3
|
+
# All rights reserved.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module AppOpticsAPM
|
7
|
+
module SDK
|
8
|
+
|
9
|
+
module CurrentTrace
|
10
|
+
|
11
|
+
# Creates an instance of {TraceId} with instance methods {TraceId#id}, {TraceId#for_log}
|
12
|
+
# and {TraceId#hash_for_log}.
|
13
|
+
#
|
14
|
+
# === Example:
|
15
|
+
#
|
16
|
+
# trace = AppOpticsAPM::SDK.current_trace
|
17
|
+
# trace.id # '7435A9FE510AE4533414D425DADF4E180D2B4E36-0'
|
18
|
+
# trace.for_log # 'ao.traceId=7435A9FE510AE4533414D425DADF4E180D2B4E36-0' or '' depends on Config
|
19
|
+
# trace.hash_for_log # { ao: { traceId: '7435A9FE510AE4533414D425DADF4E180D2B4E36-0 } } or {} depends on Config
|
20
|
+
#
|
21
|
+
# Configure traceId injection with lograge:
|
22
|
+
#
|
23
|
+
# Lograge.custom_options = lambda do |event|
|
24
|
+
# AppOpticsAPM::SDK.current_trace.hash_for_log
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
def current_trace
|
28
|
+
TraceId.new
|
29
|
+
end
|
30
|
+
|
31
|
+
# @attr id the current traceId, it looks like: '7435A9FE510AE4533414D425DADF4E180D2B4E36-0'
|
32
|
+
# and ends in '-1' if the request is sampled and '-0' otherwise.
|
33
|
+
# Results in '0000000000000000000000000000000000000000-0'
|
34
|
+
# if the CurrentTrace instance was created outside of the context
|
35
|
+
# of a request.
|
36
|
+
class TraceId
|
37
|
+
attr_reader :id
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@xtrace = AppOpticsAPM::Context.toString
|
41
|
+
task_id = AppOpticsAPM::XTrace.task_id(@xtrace)
|
42
|
+
sampled = AppOpticsAPM::XTrace.sampled?(@xtrace)
|
43
|
+
@id = "#{task_id}-#{sampled ? 1 : 0}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# for_log returns a string in the format 'traceId=<current_trace.id>' or ''.
|
47
|
+
# An empty string is returned depending on the setting for
|
48
|
+
# <tt>AppOpticsAPM::Config[:log_traceId]</tt>, which can be :never,
|
49
|
+
# :sampled, :traced, or :always.
|
50
|
+
#
|
51
|
+
def for_log
|
52
|
+
@for_log ||= log? ? "ao.traceId=#{@id}" : ''
|
53
|
+
end
|
54
|
+
|
55
|
+
def hash_for_log
|
56
|
+
@hash_for_log ||= log? ? { ao: { traceId: @id } } : {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def log? # should the traceId be added to the log?
|
60
|
+
case AppOpticsAPM::Config[:log_traceId]
|
61
|
+
when :never, nil
|
62
|
+
false
|
63
|
+
when :always
|
64
|
+
AppOpticsAPM::XTrace.ok?(@xtrace)
|
65
|
+
when :traced
|
66
|
+
AppOpticsAPM::XTrace.valid?(@xtrace)
|
67
|
+
when :sampled
|
68
|
+
AppOpticsAPM::XTrace.sampled?(@xtrace)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
extend CurrentTrace
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
3
|
+
# All rights reserved.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module AppOpticsAPM
|
7
|
+
module SDK
|
8
|
+
|
9
|
+
module CustomMetrics
|
10
|
+
|
11
|
+
# Send counts
|
12
|
+
#
|
13
|
+
# Use this method to report the number of times an action occurs. The metric counts reported are summed and flushed every 60 seconds.
|
14
|
+
#
|
15
|
+
# === Arguments:
|
16
|
+
#
|
17
|
+
# * +name+ (String) Name to be used for the metric. Must be 255 or fewer characters and consist only of A-Za-z0-9.:-*
|
18
|
+
# * +count+ (Integer, optional, default = 1): Count of actions being reported
|
19
|
+
# * +with_hostname+ (Boolean, optional, default = false): Indicates if the host name should be included as a tag for the metric
|
20
|
+
# * +tags_kvs+ (Hash, optional): List of key/value pairs to describe the metric. The key must be <= 64 characters, the value must be <= 255 characters, allowed characters: A-Za-z0-9.:-_
|
21
|
+
#
|
22
|
+
# === Example:
|
23
|
+
#
|
24
|
+
# class WorkTracker
|
25
|
+
# def counting(name, tags = {})
|
26
|
+
# yield # yield to where work is done
|
27
|
+
# AppOpticsAPM::SDK.increment_metric(name, 1, false, tags)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# === Returns:
|
32
|
+
# * 0 on success, error code on failure
|
33
|
+
#
|
34
|
+
def increment_metric(name, count = 1, with_hostname = false, tags_kvs = {})
|
35
|
+
return true unless AppOpticsAPM.loaded
|
36
|
+
with_hostname = with_hostname ? 1 : 0
|
37
|
+
tags, tags_count = make_tags(tags_kvs)
|
38
|
+
AppOpticsAPM::CustomMetrics.increment(name.to_s, count, with_hostname, nil, tags, tags_count) == 1
|
39
|
+
end
|
40
|
+
|
41
|
+
# Send values with counts
|
42
|
+
#
|
43
|
+
# Use this method to report a value for each or multiple counts. The metric values reported are aggregated and flushed every 60 seconds. The dashboard displays the average value per count.
|
44
|
+
#
|
45
|
+
# === Arguments:
|
46
|
+
#
|
47
|
+
# * +name+ (String) Name to be used for the metric. Must be 255 or fewer characters and consist only of A-Za-z0-9.:-*
|
48
|
+
# * +value+ (Numeric) Value to be added to the current sum
|
49
|
+
# * +count+ (Integer, optional, default = 1): Count of actions being reported
|
50
|
+
# * +with_hostname+ (Boolean, optional, default = false): Indicates if the host name should be included as a tag for the metric
|
51
|
+
# * +tags_kvs+ (Hash, optional): List of key/value pairs to describe the metric. The key must be <= 64 characters, the value must be <= 255 characters, allowed characters: A-Za-z0-9.:-_
|
52
|
+
#
|
53
|
+
# === Example:
|
54
|
+
#
|
55
|
+
# class WorkTracker
|
56
|
+
# def timing(name, tags = {})
|
57
|
+
# start = Time.now
|
58
|
+
# yield # yield to where work is done
|
59
|
+
# duration = Time.now - start
|
60
|
+
# AppOpticsAPM::SDK.summary_metric(name, duration, 1, false, tags)
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# === Returns:
|
65
|
+
# * 0 on success, error code on failure
|
66
|
+
#
|
67
|
+
def summary_metric(name, value, count = 1, with_hostname = false, tags_kvs = {})
|
68
|
+
return true unless AppOpticsAPM.loaded
|
69
|
+
with_hostname = with_hostname ? 1 : 0
|
70
|
+
tags, tags_count = make_tags(tags_kvs)
|
71
|
+
AppOpticsAPM::CustomMetrics.summary(name.to_s, value, count, with_hostname, nil, tags, tags_count) == 1
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def make_tags(tags_kvs)
|
77
|
+
unless tags_kvs.is_a?(Hash)
|
78
|
+
AppOpticsAPM.logger.warn("[appoptics_apm/metrics] CustomMetrics received tags_kvs that are not a Hash (found #{tags_kvs.class}), setting tags_kvs = {}")
|
79
|
+
tags_kvs = {}
|
80
|
+
end
|
81
|
+
count = tags_kvs.size
|
82
|
+
tags = AppOpticsAPM::MetricTags.new(count)
|
83
|
+
|
84
|
+
tags_kvs.each_with_index do |(k, v), i|
|
85
|
+
tags.add(i, k.to_s, v.to_s)
|
86
|
+
end
|
87
|
+
|
88
|
+
[tags, count]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
extend CustomMetrics
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright (c) 2019 SolarWinds, LLC.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
module AppOpticsAPM
|
6
|
+
module SDK
|
7
|
+
module Logging
|
8
|
+
|
9
|
+
# Log an information event in the current span
|
10
|
+
#
|
11
|
+
# a possible use-case is to collect extra information during the execution of a request
|
12
|
+
#
|
13
|
+
# === Arguments:
|
14
|
+
# * +opts+ - (optional) hash containing key/value pairs that will be reported with this span.
|
15
|
+
#
|
16
|
+
def log_info(opts)
|
17
|
+
AppOpticsAPM::API.log_info(AppOpticsAPM.layer, opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Log an exception/error event in the current span
|
21
|
+
#
|
22
|
+
# this may be helpful to track problems when an exception is rescued
|
23
|
+
#
|
24
|
+
# === Arguments:
|
25
|
+
# * +exception+ - an exception, must respond to :message and :backtrace
|
26
|
+
# * +opts+ - (optional) hash containing key/value pairs that will be reported with this span.
|
27
|
+
#
|
28
|
+
def log_exception(exception, opts = {})
|
29
|
+
AppOpticsAPM::API.log_exception(AppOpticsAPM.layer, exception, opts)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
extend Logging
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|