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.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
  4. data/.github/workflows/build_and_release_gem.yml +103 -0
  5. data/.github/workflows/build_for_packagecloud.yml +70 -0
  6. data/.github/workflows/docker-images.yml +47 -0
  7. data/.github/workflows/run_cpluplus_tests.yml +73 -0
  8. data/.github/workflows/run_tests.yml +168 -0
  9. data/.github/workflows/scripts/test_install.rb +23 -0
  10. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  11. data/.github/workflows/test_on_4_linux.yml +159 -0
  12. data/.gitignore +36 -0
  13. data/.rubocop.yml +29 -0
  14. data/.travis.yml +130 -0
  15. data/.yardopts +6 -0
  16. data/CHANGELOG.md +769 -0
  17. data/CONFIG.md +33 -0
  18. data/Gemfile +14 -0
  19. data/LICENSE +202 -0
  20. data/README.md +393 -0
  21. data/appoptics_apm.gemspec +70 -0
  22. data/bin/appoptics_apm_config +15 -0
  23. data/examples/prepend.rb +13 -0
  24. data/examples/sdk_examples.rb +158 -0
  25. data/ext/oboe_metal/README.md +69 -0
  26. data/ext/oboe_metal/extconf.rb +151 -0
  27. data/ext/oboe_metal/lib/.keep +0 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  30. data/ext/oboe_metal/noop/noop.c +8 -0
  31. data/ext/oboe_metal/src/README.md +6 -0
  32. data/ext/oboe_metal/src/VERSION +2 -0
  33. data/ext/oboe_metal/src/bson/bson.h +220 -0
  34. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  35. data/ext/oboe_metal/src/frames.cc +246 -0
  36. data/ext/oboe_metal/src/frames.h +40 -0
  37. data/ext/oboe_metal/src/init_appoptics_apm.cc +21 -0
  38. data/ext/oboe_metal/src/logging.cc +95 -0
  39. data/ext/oboe_metal/src/logging.h +35 -0
  40. data/ext/oboe_metal/src/oboe.h +1156 -0
  41. data/ext/oboe_metal/src/oboe_api.cpp +652 -0
  42. data/ext/oboe_metal/src/oboe_api.hpp +431 -0
  43. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  44. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7329 -0
  45. data/ext/oboe_metal/src/profiling.cc +435 -0
  46. data/ext/oboe_metal/src/profiling.h +78 -0
  47. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  48. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  49. data/ext/oboe_metal/test/README.md +56 -0
  50. data/ext/oboe_metal/test/frames_test.cc +164 -0
  51. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  52. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  54. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  55. data/ext/oboe_metal/test/test.h +11 -0
  56. data/ext/oboe_metal/test/test_main.cc +32 -0
  57. data/init.rb +4 -0
  58. data/lib/appoptics_apm/api/layerinit.rb +41 -0
  59. data/lib/appoptics_apm/api/logging.rb +381 -0
  60. data/lib/appoptics_apm/api/memcache.rb +37 -0
  61. data/lib/appoptics_apm/api/metrics.rb +63 -0
  62. data/lib/appoptics_apm/api/tracing.rb +57 -0
  63. data/lib/appoptics_apm/api/util.rb +120 -0
  64. data/lib/appoptics_apm/api.rb +21 -0
  65. data/lib/appoptics_apm/base.rb +231 -0
  66. data/lib/appoptics_apm/config.rb +299 -0
  67. data/lib/appoptics_apm/frameworks/grape.rb +98 -0
  68. data/lib/appoptics_apm/frameworks/padrino.rb +78 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_controller6.rb +50 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +88 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +114 -0
  81. data/lib/appoptics_apm/frameworks/rails/inst/logger_formatters.rb +27 -0
  82. data/lib/appoptics_apm/frameworks/rails.rb +100 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +96 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
  86. data/lib/appoptics_apm/inst/curb.rb +332 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
  90. data/lib/appoptics_apm/inst/excon.rb +125 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +106 -0
  92. data/lib/appoptics_apm/inst/graphql.rb +240 -0
  93. data/lib/appoptics_apm/inst/grpc_client.rb +159 -0
  94. data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
  95. data/lib/appoptics_apm/inst/http.rb +81 -0
  96. data/lib/appoptics_apm/inst/httpclient.rb +174 -0
  97. data/lib/appoptics_apm/inst/logger_formatter.rb +50 -0
  98. data/lib/appoptics_apm/inst/logging_log_event.rb +28 -0
  99. data/lib/appoptics_apm/inst/lumberjack_formatter.rb +13 -0
  100. data/lib/appoptics_apm/inst/memcached.rb +86 -0
  101. data/lib/appoptics_apm/inst/mongo.rb +246 -0
  102. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  103. data/lib/appoptics_apm/inst/moped.rb +466 -0
  104. data/lib/appoptics_apm/inst/rack.rb +182 -0
  105. data/lib/appoptics_apm/inst/rack_cache.rb +35 -0
  106. data/lib/appoptics_apm/inst/redis.rb +274 -0
  107. data/lib/appoptics_apm/inst/resque.rb +151 -0
  108. data/lib/appoptics_apm/inst/rest-client.rb +48 -0
  109. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  110. data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
  111. data/lib/appoptics_apm/inst/sidekiq-worker.rb +66 -0
  112. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  113. data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
  114. data/lib/appoptics_apm/instrumentation.rb +22 -0
  115. data/lib/appoptics_apm/loading.rb +65 -0
  116. data/lib/appoptics_apm/logger.rb +14 -0
  117. data/lib/appoptics_apm/noop/README.md +9 -0
  118. data/lib/appoptics_apm/noop/context.rb +27 -0
  119. data/lib/appoptics_apm/noop/metadata.rb +25 -0
  120. data/lib/appoptics_apm/noop/profiling.rb +21 -0
  121. data/lib/appoptics_apm/oboe_init_options.rb +211 -0
  122. data/lib/appoptics_apm/ruby.rb +35 -0
  123. data/lib/appoptics_apm/sdk/current_trace.rb +77 -0
  124. data/lib/appoptics_apm/sdk/custom_metrics.rb +94 -0
  125. data/lib/appoptics_apm/sdk/logging.rb +37 -0
  126. data/lib/appoptics_apm/sdk/tracing.rb +434 -0
  127. data/lib/appoptics_apm/support/profiling.rb +18 -0
  128. data/lib/appoptics_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/appoptics_apm/support/transaction_settings.rb +219 -0
  130. data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
  131. data/lib/appoptics_apm/support_report.rb +119 -0
  132. data/lib/appoptics_apm/test.rb +95 -0
  133. data/lib/appoptics_apm/thread_local.rb +26 -0
  134. data/lib/appoptics_apm/util.rb +326 -0
  135. data/lib/appoptics_apm/version.rb +16 -0
  136. data/lib/appoptics_apm/xtrace.rb +115 -0
  137. data/lib/appoptics_apm.rb +77 -0
  138. data/lib/joboe_metal.rb +212 -0
  139. data/lib/oboe.rb +7 -0
  140. data/lib/oboe_metal.rb +172 -0
  141. data/lib/rails/generators/appoptics_apm/install_generator.rb +47 -0
  142. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +425 -0
  143. data/log/.keep +0 -0
  144. data/yardoc_frontpage.md +26 -0
  145. 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