solarwinds_apm 5.1.8 → 6.0.0.preV1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +0 -1
  3. data/ext/oboe_metal/extconf.rb +19 -23
  4. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +1 -1
  5. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +1 -1
  6. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +1 -1
  7. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +1 -1
  8. data/ext/oboe_metal/src/VERSION +1 -1
  9. data/ext/oboe_metal/src/oboe_api.cpp +9 -7
  10. data/ext/oboe_metal/src/oboe_api.h +7 -7
  11. data/ext/oboe_metal/src/oboe_debug.h +2 -0
  12. data/ext/oboe_metal/src/oboe_swig_wrap.cc +19 -18
  13. data/lib/oboe_metal.rb +116 -80
  14. data/lib/rails/generators/solarwinds_apm/install_generator.rb +1 -2
  15. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +44 -260
  16. data/lib/solarwinds_apm/api/current_trace_info.rb +148 -0
  17. data/lib/solarwinds_apm/api/tracing.rb +30 -0
  18. data/lib/solarwinds_apm/api/transaction_name.rb +57 -0
  19. data/lib/solarwinds_apm/api.rb +8 -15
  20. data/lib/solarwinds_apm/base.rb +4 -131
  21. data/lib/solarwinds_apm/config.rb +128 -175
  22. data/lib/solarwinds_apm/constants.rb +32 -0
  23. data/lib/solarwinds_apm/logger.rb +1 -1
  24. data/lib/solarwinds_apm/noop/context.rb +2 -5
  25. data/lib/solarwinds_apm/noop/metadata.rb +1 -2
  26. data/lib/solarwinds_apm/noop/profiling.rb +3 -7
  27. data/lib/solarwinds_apm/oboe_init_options.rb +71 -33
  28. data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +204 -0
  29. data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +163 -0
  30. data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +92 -0
  31. data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +72 -0
  32. data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +330 -0
  33. data/lib/solarwinds_apm/opentelemetry.rb +8 -0
  34. data/lib/solarwinds_apm/otel_config.rb +161 -0
  35. data/lib/solarwinds_apm/{inst → support}/logger_formatter.rb +5 -6
  36. data/lib/solarwinds_apm/{inst → support}/logging_log_event.rb +3 -6
  37. data/lib/solarwinds_apm/{inst → support}/lumberjack_formatter.rb +1 -4
  38. data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +27 -0
  39. data/lib/solarwinds_apm/support/swomarginalia/LICENSE +20 -0
  40. data/lib/solarwinds_apm/support/swomarginalia/README.md +41 -0
  41. data/lib/solarwinds_apm/support/swomarginalia/comment.rb +205 -0
  42. data/lib/solarwinds_apm/support/swomarginalia/load_swomarginalia.rb +48 -0
  43. data/lib/solarwinds_apm/support/swomarginalia/railtie.rb +22 -0
  44. data/lib/solarwinds_apm/support/swomarginalia/swomarginalia.rb +86 -0
  45. data/lib/solarwinds_apm/support/transaction_cache.rb +24 -0
  46. data/lib/solarwinds_apm/support/transaction_settings.rb +26 -209
  47. data/lib/solarwinds_apm/support/transformer.rb +56 -0
  48. data/lib/solarwinds_apm/support/txn_name_manager.rb +25 -0
  49. data/lib/solarwinds_apm/support/x_trace_options.rb +42 -26
  50. data/lib/solarwinds_apm/support.rb +33 -10
  51. data/lib/solarwinds_apm/support_report.rb +10 -32
  52. data/lib/solarwinds_apm/thread_local.rb +1 -1
  53. data/lib/solarwinds_apm/version.rb +4 -4
  54. data/lib/solarwinds_apm.rb +31 -26
  55. metadata +76 -121
  56. data/.dockerignore +0 -5
  57. data/.gitignore +0 -58
  58. data/.rubocop.yml +0 -29
  59. data/.whitesource +0 -22
  60. data/.yardopts +0 -7
  61. data/CHANGELOG-appoptics.md +0 -766
  62. data/CHANGELOG.md +0 -72
  63. data/CONFIG.md +0 -31
  64. data/Gemfile +0 -15
  65. data/README.md +0 -385
  66. data/bin/solarwinds_apm_config +0 -15
  67. data/examples/prepend.rb +0 -13
  68. data/examples/sdk_examples.rb +0 -158
  69. data/ext/oboe_metal/README.md +0 -69
  70. data/ext/oboe_metal/extconf_local.rb +0 -75
  71. data/ext/oboe_metal/lib/.keep +0 -0
  72. data/ext/oboe_metal/noop/noop.c +0 -8
  73. data/ext/oboe_metal/src/README.md +0 -6
  74. data/ext/oboe_metal/src/frames.cc +0 -247
  75. data/ext/oboe_metal/src/frames.h +0 -40
  76. data/ext/oboe_metal/src/logging.cc +0 -97
  77. data/ext/oboe_metal/src/logging.h +0 -34
  78. data/ext/oboe_metal/src/profiling.cc +0 -435
  79. data/ext/oboe_metal/src/profiling.h +0 -78
  80. data/ext/oboe_metal/test/CMakeLists.txt +0 -53
  81. data/ext/oboe_metal/test/FindGMock.cmake +0 -43
  82. data/ext/oboe_metal/test/README.md +0 -56
  83. data/ext/oboe_metal/test/frames_test.cc +0 -164
  84. data/ext/oboe_metal/test/profiling_test.cc +0 -93
  85. data/ext/oboe_metal/test/ruby_inc_dir.rb +0 -8
  86. data/ext/oboe_metal/test/ruby_prefix.rb +0 -8
  87. data/ext/oboe_metal/test/ruby_test_helper.rb +0 -67
  88. data/ext/oboe_metal/test/test.h +0 -11
  89. data/ext/oboe_metal/test/test_main.cc +0 -32
  90. data/init.rb +0 -4
  91. data/lib/solarwinds_apm/api/layerinit.rb +0 -41
  92. data/lib/solarwinds_apm/api/logging.rb +0 -356
  93. data/lib/solarwinds_apm/api/memcache.rb +0 -37
  94. data/lib/solarwinds_apm/api/metrics.rb +0 -63
  95. data/lib/solarwinds_apm/api/util.rb +0 -98
  96. data/lib/solarwinds_apm/frameworks/grape.rb +0 -96
  97. data/lib/solarwinds_apm/frameworks/padrino.rb +0 -78
  98. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +0 -100
  99. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +0 -50
  100. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +0 -50
  101. data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +0 -88
  102. data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +0 -26
  103. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +0 -29
  104. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +0 -22
  105. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +0 -103
  106. data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +0 -14
  107. data/lib/solarwinds_apm/frameworks/rails.rb +0 -100
  108. data/lib/solarwinds_apm/frameworks/sinatra.rb +0 -96
  109. data/lib/solarwinds_apm/inst/bunny-client.rb +0 -157
  110. data/lib/solarwinds_apm/inst/bunny-consumer.rb +0 -102
  111. data/lib/solarwinds_apm/inst/curb.rb +0 -289
  112. data/lib/solarwinds_apm/inst/dalli.rb +0 -89
  113. data/lib/solarwinds_apm/inst/delayed_job.rb +0 -100
  114. data/lib/solarwinds_apm/inst/excon.rb +0 -113
  115. data/lib/solarwinds_apm/inst/faraday.rb +0 -96
  116. data/lib/solarwinds_apm/inst/graphql.rb +0 -206
  117. data/lib/solarwinds_apm/inst/grpc_client.rb +0 -147
  118. data/lib/solarwinds_apm/inst/grpc_server.rb +0 -119
  119. data/lib/solarwinds_apm/inst/httpclient.rb +0 -182
  120. data/lib/solarwinds_apm/inst/memcached.rb +0 -86
  121. data/lib/solarwinds_apm/inst/mongo.rb +0 -246
  122. data/lib/solarwinds_apm/inst/mongo2.rb +0 -225
  123. data/lib/solarwinds_apm/inst/moped.rb +0 -466
  124. data/lib/solarwinds_apm/inst/net_http.rb +0 -60
  125. data/lib/solarwinds_apm/inst/rack.rb +0 -223
  126. data/lib/solarwinds_apm/inst/rack_cache.rb +0 -35
  127. data/lib/solarwinds_apm/inst/redis.rb +0 -280
  128. data/lib/solarwinds_apm/inst/redis_v4.rb +0 -273
  129. data/lib/solarwinds_apm/inst/resque.rb +0 -129
  130. data/lib/solarwinds_apm/inst/rest-client.rb +0 -43
  131. data/lib/solarwinds_apm/inst/sequel.rb +0 -241
  132. data/lib/solarwinds_apm/inst/sidekiq-client.rb +0 -63
  133. data/lib/solarwinds_apm/inst/sidekiq-worker.rb +0 -64
  134. data/lib/solarwinds_apm/inst/typhoeus.rb +0 -90
  135. data/lib/solarwinds_apm/instrumentation.rb +0 -22
  136. data/lib/solarwinds_apm/loading.rb +0 -65
  137. data/lib/solarwinds_apm/ruby.rb +0 -35
  138. data/lib/solarwinds_apm/sdk/current_trace_info.rb +0 -123
  139. data/lib/solarwinds_apm/sdk/custom_metrics.rb +0 -94
  140. data/lib/solarwinds_apm/sdk/logging.rb +0 -37
  141. data/lib/solarwinds_apm/sdk/trace_context_headers.rb +0 -69
  142. data/lib/solarwinds_apm/sdk/tracing.rb +0 -432
  143. data/lib/solarwinds_apm/support/profiling.rb +0 -25
  144. data/lib/solarwinds_apm/support/trace_context.rb +0 -53
  145. data/lib/solarwinds_apm/support/trace_state.rb +0 -69
  146. data/lib/solarwinds_apm/support/trace_string.rb +0 -89
  147. data/lib/solarwinds_apm/support/transaction_metrics.rb +0 -67
  148. data/lib/solarwinds_apm/test.rb +0 -165
  149. data/lib/solarwinds_apm/util.rb +0 -426
  150. data/log/.keep +0 -0
  151. data/log/postgresql/.keep +0 -0
  152. data/solarwinds_apm.gemspec +0 -55
  153. data/yardoc_frontpage.md +0 -24
@@ -1,233 +1,50 @@
1
1
  # Copyright (c) 2018 SolarWinds, LLC.
2
2
  # All rights reserved.
3
3
  #
4
-
5
- AO_TRACING_ENABLED = 1
6
- AO_TRACING_DISABLED = 0
7
- AO_TRACING_UNSET = -1
8
-
9
- AO_TRACING_DECISIONS_OK = 0
10
-
11
- OBOE_SETTINGS_UNSET = -1
12
-
13
4
  module SolarWindsAPM
14
5
  ##
15
6
  # This module helps with setting up the transaction filters and applying them
16
7
  #
17
8
  class TransactionSettings
9
+ SWO_TRACING_ENABLED = 1
10
+ SWO_TRACING_DISABLED = 0
18
11
 
19
- attr_accessor :do_sample, :do_metrics
20
- attr_reader :auth_msg, :do_propagate, :status_msg, :type, :source, :rate, :tracestring, :sw_member_value
21
-
22
- def initialize(url = '', headers = {}, options = nil)
23
- @do_metrics = false
24
- @do_sample = false
25
- @do_propagate = true
26
-
27
- SolarWindsAPM.trace_context = SolarWindsAPM::TraceContext.new(headers)
28
- @tracestring = SolarWindsAPM.trace_context.tracestring
29
- @sw_member_value = SolarWindsAPM.trace_context.sw_member_value
30
- tracing_mode = AO_TRACING_ENABLED
31
-
32
- # TODO
33
- # NH-11132 will address this
34
- # incoming tracing info has priority over existing context
35
- # if SolarWindsAPM::Context.isValid && !@sw_member_value
36
- # @do_sample = SolarWindsAPM.tracing?
37
- # return
38
- # end
39
-
40
- if url && asset?(url)
41
- @do_propagate = false
42
- return
43
- end
44
-
45
- if tracing_mode_disabled? && !tracing_enabled?(url) ||
46
- tracing_disabled?(url)
47
-
48
- tracing_mode = AO_TRACING_DISABLED
49
- end
50
-
51
- # args (all optional)
52
- # 0 char const *in_xtrace
53
- # 1 char const *tracestate
54
- # 2 int custom_tracing_mode
55
- # 3 int custom_sample_rate
56
- # 4 int request_type
57
- # 5 int custom_trigger_mode
58
- # 6 char const *header_options
59
- # 7 char const *header_signature
60
- # 8 long header_timestamp
61
- args = [@tracestring, @sw_member_value] #0,1
62
- args << tracing_mode #2
63
- args << (SolarWindsAPM::Config[:sample_rate] || OBOE_SETTINGS_UNSET) #3
64
-
65
- if options && (options.options || options.signature)
66
- args << (options.trigger_trace ? 1 : 0) #4
67
- args << (trigger_tracing_mode_disabled? ? 0 : 1) #5
68
- args << options.options #6
69
- args << options.signature #7
70
- args << options.timestamp #8
71
- end
72
-
73
- metrics, sample, @rate, @source, @bucket_rate, @bucket_cap, @type, @auth, @status_msg, @auth_msg, @status =
74
- SolarWindsAPM::Context.getDecisions(*args)
75
-
76
- if @status > AO_TRACING_DECISIONS_OK
77
- SolarWindsAPM.logger.warn "[solarwinds_apm/sample] Problem getting the sampling decisions: #{@status_msg} code: #{@status}"
78
- end
79
-
80
- @do_metrics = metrics > 0
81
- @do_sample = sample > 0
82
- end
83
-
84
- def to_s
85
- "do_propagate: #{do_propagate}, do_sample: #{do_sample}, do_metrics: #{do_metrics} rate: #{rate}, source: #{source}"
86
- end
87
-
88
- def add_kvs(kvs)
89
- kvs[:SampleRate] = @rate
90
- kvs[:SampleSource] = @source
91
- end
92
-
93
- def triggered_trace?
94
- @type == 1
12
+ def initialize(url: '', name: '', kind: '')
13
+ @url = url
14
+ @name = name
15
+ @kind = kind
95
16
  end
96
17
 
97
- def auth_ok?
98
- # @auth is undefined if initialize is called with an existing context
99
- !@auth || @auth < 1
18
+ # calculate trace mode to set either 1 or 0 based on url and name+kind
19
+ # first check if url match, if not match, then match the name+kind
20
+ def calculate_trace_mode
21
+ tracing_mode_enabled? && tracing_enabled? ? SWO_TRACING_ENABLED : SWO_TRACING_DISABLED
100
22
  end
101
23
 
102
24
  private
103
25
 
104
- ##
105
- # check the config setting for :tracing_mode
106
- def tracing_mode_disabled?
107
- SolarWindsAPM::Config[:tracing_mode] &&
108
- [:disabled, :never].include?(SolarWindsAPM::Config[:tracing_mode])
26
+ def tracing_mode_enabled?
27
+ SolarWindsAPM::Config[:tracing_mode] && ![:disabled, :never].include?(SolarWindsAPM::Config[:tracing_mode])
109
28
  end
110
29
 
111
- ##
112
- # tracing_enabled?
113
- #
114
- # Given a path, this method determines whether it matches any of the
115
- # regexps to exclude it from metrics and traces
116
- #
117
- def tracing_enabled?(url)
118
- return false unless SolarWindsAPM::Config[:url_enabled_regexps].is_a? Array
119
- # once we only support Ruby >= 2.4.0 use `match?` instead of `=~`
120
- return SolarWindsAPM::Config[:url_enabled_regexps].any? { |regex| regex =~ url }
121
- rescue => e
122
- SolarWindsAPM.logger.warn "[SolarWindsAPM/filter] Could not apply :enabled filter to path. #{e.inspect}"
123
- true
124
- end
125
-
126
- ##
127
- # tracing_disabled?
128
- #
129
- # Given a path, this method determines whether it matches any of the
130
- # regexps to exclude it from metrics and traces
131
- #
132
- def tracing_disabled?(url)
133
- return false unless SolarWindsAPM::Config[:url_disabled_regexps].is_a? Array
134
- # once we only support Ruby >= 2.4.0 use `match?` instead of `=~`
135
- return SolarWindsAPM::Config[:url_disabled_regexps].any? { |regex| regex =~ url }
136
- rescue => e
137
- SolarWindsAPM.logger.warn "[SolarWindsAPM/filter] Could not apply :disabled filter to path. #{e.inspect}"
138
- false
139
- end
140
-
141
- def trigger_tracing_mode_disabled?
142
- SolarWindsAPM::Config[:trigger_tracing_mode] &&
143
- SolarWindsAPM::Config[:trigger_tracing_mode] == :disabled
144
- end
145
-
146
- ##
147
- # asset?
148
- #
149
- # Given a path, this method determines whether it is a static asset
150
- #
151
- def asset?(path)
152
- return false unless SolarWindsAPM::Config[:dnt_compiled]
153
- # once we only support Ruby >= 2.4.0 use `match?` instead of `=~`
154
- return SolarWindsAPM::Config[:dnt_compiled] =~ path
155
- rescue => e
156
- SolarWindsAPM.logger.warn "[SolarWindsAPM/filter] Could not apply do-not-trace filter to path. #{e.inspect}"
157
- false
158
- end
159
-
160
- public
161
-
162
- class << self
30
+ def tracing_enabled?
31
+ span_layer = "#{@name}:#{@kind}"
163
32
 
164
- def asset?(path)
165
- return false unless SolarWindsAPM::Config[:dnt_compiled]
166
- # once we only support Ruby >= 2.4.0 use `match?` instead of `=~`
167
- return SolarWindsAPM::Config[:dnt_compiled] =~ path
168
- rescue => e
169
- SolarWindsAPM.logger.warn "[SolarWindsAPM/filter] Could not apply do-not-trace filter to path. #{e.inspect}"
170
- false
171
- end
33
+ enabled_regexps = SolarWindsAPM::Config[:enabled_regexps]
34
+ disabled_regexps = SolarWindsAPM::Config[:disabled_regexps]
172
35
 
173
- def compile_url_settings(settings)
174
- if !settings.is_a?(Array) || settings.empty?
175
- reset_url_regexps
176
- return
177
- end
36
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] enabled_regexps: #{enabled_regexps&.inspect}"}
37
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] disabled_regexps: #{disabled_regexps&.inspect}"}
178
38
 
179
- # `tracing: disabled` is the default
180
- disabled = settings.select { |v| !v.has_key?(:tracing) || v[:tracing] == :disabled }
181
- enabled = settings.select { |v| v[:tracing] == :enabled }
39
+ return false if disabled_regexps.is_a?(Array) && disabled_regexps.any? { |regex| regex.match?(@url) }
40
+ return true if enabled_regexps.is_a?(Array) && enabled_regexps.any? { |regex| regex.match?(@url) }
41
+ return false if disabled_regexps.is_a?(Array) && disabled_regexps.any? { |regex| regex.match?(span_layer) }
42
+ return true if enabled_regexps.is_a?(Array) && enabled_regexps.any? { |regex| regex.match?(span_layer) }
182
43
 
183
- SolarWindsAPM::Config[:url_enabled_regexps] = compile_regexp(enabled)
184
- SolarWindsAPM::Config[:url_disabled_regexps] = compile_regexp(disabled)
185
- end
186
-
187
- def compile_regexp(settings)
188
- regexp_regexp = compile_url_settings_regexp(settings)
189
- extensions_regexp = compile_url_settings_extensions(settings)
190
-
191
- regexps = [regexp_regexp, extensions_regexp].flatten.compact
192
-
193
- regexps.empty? ? nil : regexps
194
- end
195
-
196
- def compile_url_settings_regexp(value)
197
- regexps = value.select do |v|
198
- v.key?(:regexp) &&
199
- !(v[:regexp].is_a?(String) && v[:regexp].empty?) &&
200
- !(v[:regexp].is_a?(Regexp) && v[:regexp].inspect == '//')
201
- end
202
-
203
- regexps.map! do |v|
204
- begin
205
- v[:regexp].is_a?(String) ? Regexp.new(v[:regexp], v[:opts]) : Regexp.new(v[:regexp])
206
- rescue
207
- SolarWindsAPM.logger.warn "[solarwinds_apm/config] Problem compiling transaction_settings item #{v}, will ignore."
208
- nil
209
- end
210
- end
211
- regexps.keep_if { |v| !v.nil? }
212
- regexps.empty? ? nil : regexps
213
- end
214
-
215
- def compile_url_settings_extensions(value)
216
- extensions = value.select do |v|
217
- v.key?(:extensions) &&
218
- v[:extensions].is_a?(Array) &&
219
- !v[:extensions].empty?
220
- end
221
- extensions = extensions.map { |v| v[:extensions] }.flatten
222
- extensions.keep_if { |v| v.is_a?(String) }
223
-
224
- extensions.empty? ? nil : Regexp.new("(#{Regexp.union(extensions).source})(\\?.+){0,1}$")
225
- end
226
-
227
- def reset_url_regexps
228
- SolarWindsAPM::Config[:url_enabled_regexps] = nil
229
- SolarWindsAPM::Config[:url_disabled_regexps] = nil
230
- end
44
+ true
45
+ rescue StandardError => e
46
+ SolarWindsAPM.logger.warn {"[#{self.class}/#{__method__}] Could not determine tracing status for #{kind}. #{e.inspect}. transaction_settings regexps/extensions igonred/unfiltered."}
47
+ true
231
48
  end
232
49
  end
233
50
  end
@@ -0,0 +1,56 @@
1
+ module SolarWindsAPM
2
+ module OpenTelemetry
3
+ # Transformer
4
+ class Transformer
5
+ VERSION = '00'.freeze
6
+
7
+ def self.sw_from_context(span_context)
8
+ flag = span_context.trace_flags.sampled?? 1 : 0
9
+ "#{span_context.hex_span_id}-0#{flag}"
10
+ end
11
+
12
+ def self.trace_state_header(trace_state)
13
+ arr = []
14
+ trace_state.to_h.each do |key, value|
15
+ arr << "#{key}=#{value}"
16
+ end
17
+ arr.join(",")
18
+ end
19
+
20
+ # Generates a liboboe W3C compatible trace_context from provided OTel span context.
21
+ def self.traceparent_from_context(span_context)
22
+ flag = span_context.trace_flags.sampled?? 1 : 0
23
+ xtr = "#{VERSION}-#{span_context.hex_trace_id}-#{span_context.hex_span_id}-0#{flag}"
24
+ SolarWindsAPM.logger.debug("Generated traceparent #{xtr} from #{span_context.inspect}")
25
+ xtr
26
+ end
27
+
28
+ # Formats tracestate sw value from span_id and liboboe decision as 16-byte span_id with 8-bit trace_flags
29
+ # e.g. 1a2b3c4d5e6f7g8h-01
30
+ def self.sw_from_span_and_decision(span_id, decision)
31
+ [span_id, decision].join("-")
32
+ end
33
+
34
+ # trace_flags [Integer]
35
+ def self.trace_flags_from_int(trace_flags)
36
+ "0#{trace_flags}"
37
+ end
38
+
39
+ def self.trace_flags_from_boolean(trace_flags)
40
+ trace_flags == true ? "01" : "00"
41
+ end
42
+
43
+ def self.sampled?(decision)
44
+ decision == ::OpenTelemetry::SDK::Trace::Samplers::Decision::RECORD_AND_SAMPLE
45
+ end
46
+
47
+ def self.span_id_from_sw(sw_value)
48
+ sw_value.split("-")[0]
49
+ end
50
+
51
+ def self.create_key(name_)
52
+ ::OpenTelemetry::Context.create_key(name_)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,25 @@
1
+ module SolarWindsAPM
2
+ module OpenTelemetry
3
+ # SolarWindsTxnNameManager
4
+ class TxnNameManager
5
+ def initialize
6
+ @cache = {}
7
+ end
8
+
9
+ def get(key)
10
+ @cache[key]
11
+ end
12
+
13
+ def del(key)
14
+ @cache.delete(key)
15
+ end
16
+
17
+ def set(key, value)
18
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] current cache #{@cache.inspect}"}
19
+ @cache[key] = value
20
+ end
21
+
22
+ alias []= set
23
+ end
24
+ end
25
+ end
@@ -2,10 +2,10 @@
2
2
  # All rights reserved.
3
3
 
4
4
  module SolarWindsAPM
5
+ # XTraceOptions
5
6
  class XTraceOptions
6
-
7
- attr_reader :options, :signature, :trigger_trace, :timestamp
8
- attr_reader :sw_keys, :custom_kvs, :ignored # used in tests
7
+ attr_reader :options, :signature, :trigger_trace, :timestamp,
8
+ :sw_keys, :custom_kvs, :ignored
9
9
 
10
10
  ##
11
11
  # use by Trigger Tracing
@@ -33,16 +33,20 @@ module SolarWindsAPM
33
33
  # - ts (unix timestamp)
34
34
  # - other keys will be reported in the response options as ignored
35
35
 
36
- def initialize(options, signature = nil)
37
- @options = options.dup
38
- @signature = signature.dup
36
+ SW_XTRACEOPTIONS_RESPONSE_KEY = 'xtrace_options_response'.freeze
37
+
38
+ def initialize(context)
39
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] x_trace_options context: #{context.inspect}"}
40
+ @context = context.dup
39
41
  @trigger_trace = false
40
42
  @custom_kvs = {}
41
43
  @sw_keys = nil
42
44
  @ignored = []
43
45
  @timestamp = 0
46
+ @options = options_header
47
+ @signature = obtain_signature
44
48
 
45
- options&.split(/;+/)&.each do |val|
49
+ @options&.split(/;+/)&.each do |val|
46
50
  k = val.split('=', 2)
47
51
 
48
52
  next unless k[0] # it can be nil, eg when the header starts with ';'
@@ -57,19 +61,19 @@ module SolarWindsAPM
57
61
  end
58
62
  when 'sw-keys'
59
63
  if @sw_keys
60
- SolarWindsAPM.logger.info "[solarwinds_apm/x-trace-options] Duplicate key: #{k[0]}"
64
+ SolarWindsAPM.logger.info {"[#{self.class}/#{__method__}] Duplicate key: #{k[0]}"}
61
65
  else
62
66
  @sw_keys = k[1].strip
63
67
  end
64
68
  when /^custom-[^\s]*$/
65
69
  if @custom_kvs[k[0]]
66
- SolarWindsAPM.logger.info "[solarwinds_apm/x-trace-options] Duplicate key: #{k[0]}"
70
+ SolarWindsAPM.logger.info {"[#{self.class}/#{__method__}] Duplicate key: #{k[0]}"}
67
71
  else
68
72
  @custom_kvs[k[0]] = k[1].strip
69
73
  end
70
74
  when 'ts'
71
75
  if @timestamp > 0
72
- SolarWindsAPM.logger.info "[solarwinds_apm/x-trace-options] Duplicate key: #{k[0]}"
76
+ SolarWindsAPM.logger.info {"[#{self.class}/#{__method__}] Duplicate key: #{k[0]}"}
73
77
  else
74
78
  @timestamp = k[1].to_i
75
79
  end
@@ -77,10 +81,7 @@ module SolarWindsAPM
77
81
  @ignored << k[0]
78
82
  end
79
83
  end
80
- unless @ignored.empty?
81
- msg = "[solarwinds_apm/x-trace-options] Some keys were ignored: #{@ignored.join(',')}"
82
- SolarWindsAPM.logger.info(msg)
83
- end
84
+ SolarWindsAPM.logger.info("[#{self.class}/#{__method__}] Some keys were ignored: #{@ignored.join(',')}") unless @ignored.empty?
84
85
  end
85
86
 
86
87
  def add_kvs(kvs, settings)
@@ -91,23 +92,38 @@ module SolarWindsAPM
91
92
  kvs['TriggeredTrace'] = true if settings.triggered_trace?
92
93
  end
93
94
 
94
- def add_response_header(headers, settings)
95
- return unless options
95
+ def obtain_signature
96
+ # INTL_SWO_SIGNATURE_KEY = sw_signature
97
+ signature = obtain_sw_value(SolarWindsAPM::Constants::INTL_SWO_SIGNATURE_KEY)
98
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] x_trace_options option_signature: #{signature}"}
99
+ signature
100
+ end
96
101
 
97
- response = []
98
- response << "auth=#{settings.auth_msg}" if @signature
99
- if settings.auth_ok?
100
- if @trigger_trace
101
- trigger_msg = settings.tracestring && settings.type == 0 ? 'ignored' : settings.status_msg
102
- else
103
- trigger_msg = 'not-requested'
102
+ def options_header
103
+ # INTL_SWO_X_OPTIONS_KEY = sw_xtraceoptions
104
+ header = obtain_sw_value(SolarWindsAPM::Constants::INTL_SWO_X_OPTIONS_KEY)
105
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] x_trace_options option_header: #{header}"}
106
+ header
107
+ end
108
+
109
+ def obtain_sw_value(type)
110
+ sw_value = nil
111
+ instance_variable = @context&.instance_variable_get("@entries")
112
+ instance_variable&.each do |key, value|
113
+ if key.instance_of?(::String)
114
+ sw_value = value if key == type
115
+ SolarWindsAPM.logger.debug {"[#{self.class}/#{__method__}] obtained sw value: #{type} #{key}: #{value.inspect}"}
104
116
  end
105
- response << "trigger-trace=#{trigger_msg}"
106
- response << "ignored=#{@ignored.join(',')}" unless @ignored.empty?
107
117
  end
118
+ sw_value
119
+ end
108
120
 
109
- headers['X-Trace-Options-Response'] = response.join(';')
121
+ def intify_trigger_trace
122
+ @trigger_trace ? 1 : 0
110
123
  end
111
124
 
125
+ def self.sw_xtraceoptions_response_key
126
+ SW_XTRACEOPTIONS_RESPONSE_KEY
127
+ end
112
128
  end
113
129
  end
@@ -1,13 +1,36 @@
1
- # Copyright (c) SolarWinds, LLC.
2
- # All rights reserved
1
+ # Copyright (c) 2023 SolarWinds, LLC.
2
+ # All rights reserved.
3
+ #
4
+ # This file is for loading support library
5
+ #
3
6
 
4
- pattern = File.join(File.dirname(__FILE__), 'support', '*.rb')
5
- Dir.glob(pattern) do |f|
6
- next if f =~ /profiling/ unless defined?(SolarWindsAPM::CProfiler) # ignore defining SolarWindsAPM::Profiling if Init_profiling disabled
7
- begin
8
- require f
9
- rescue => e
10
- SolarWindsAPM.logger.error "[solarwinds_apm/loading] Error loading support file '#{f}' : #{e}"
11
- SolarWindsAPM.logger.debug "[solarwinds_apm/loading] #{e.backtrace.first}"
7
+ require_relative './support/logger_formatter'
8
+ require_relative './support/logging_log_event'
9
+ require_relative './support/lumberjack_formatter'
10
+ require_relative './support/transaction_cache'
11
+ require_relative './support/transaction_settings'
12
+ require_relative './support/oboe_tracing_mode'
13
+ require_relative './support/txn_name_manager'
14
+ require_relative './support/transformer'
15
+ require_relative './support/x_trace_options'
16
+
17
+ if SolarWindsAPM::Config[:tag_sql]
18
+ if defined?(::Rails)
19
+ if ::Rails.version < '7'
20
+ require_relative './support/swomarginalia/railtie'
21
+ elsif ::Rails.version >= '7'
22
+ # User has to define in their config/environments:
23
+ # config.active_record.query_log_tags = [
24
+ # {
25
+ # tracecontext: -> {
26
+ # SolarWindsAPM::SWOMarginalia::Comment.traceparent
27
+ # }
28
+ # }
29
+ # ]
30
+ require_relative './support/swomarginalia/comment'
31
+ end
32
+ else
33
+ require_relative './support/swomarginalia/load_swomarginalia'
34
+ SolarWindsAPM::SWOMarginalia::LoadSWOMarginalia.insert
12
35
  end
13
36
  end
@@ -14,33 +14,23 @@ module SolarWindsAPM
14
14
  # yesno
15
15
  #
16
16
  # Utility method to translate value/nil to "yes"/"no" strings
17
- def self.yesno(x)
18
- x ? 'yes' : 'no'
17
+ def self.yesno(condition)
18
+ condition ? 'yes' : 'no'
19
19
  end
20
20
 
21
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
22
21
  def self.support_report
23
22
  @logger_level = SolarWindsAPM.logger.level
24
23
  SolarWindsAPM.logger.level = ::Logger::DEBUG
25
24
 
26
25
  SolarWindsAPM.logger.warn '********************************************************'
27
26
  SolarWindsAPM.logger.warn '* BEGIN SolarWindsAPM Support Report'
28
- SolarWindsAPM.logger.warn '* Please email the output of this report to technicalsupport@solarwinds.com'
27
+ SolarWindsAPM.logger.warn '* Please email the output of this report to SWO-support@solarwinds.com'
29
28
  SolarWindsAPM.logger.warn '********************************************************'
30
29
  SolarWindsAPM.logger.warn "Ruby: #{RUBY_DESCRIPTION}"
31
- SolarWindsAPM.logger.warn "$0: #{$0}"
32
- SolarWindsAPM.logger.warn "$1: #{$1}" unless $1.nil?
33
- SolarWindsAPM.logger.warn "$2: #{$2}" unless $2.nil?
34
- SolarWindsAPM.logger.warn "$3: #{$3}" unless $3.nil?
35
- SolarWindsAPM.logger.warn "$4: #{$4}" unless $4.nil?
30
+ SolarWindsAPM.logger.warn "PROGRAM_NAME: #{$PROGRAM_NAME}" # replace $0 to get executing script
31
+ SolarWindsAPM.logger.warn "ARGV: #{ARGV.inspect}"
36
32
  SolarWindsAPM.logger.warn "SolarWindsAPM.loaded == #{SolarWindsAPM.loaded}"
37
33
 
38
- on_heroku = SolarWindsAPM.heroku?
39
- SolarWindsAPM.logger.warn "On Heroku?: #{yesno(on_heroku)}"
40
- if on_heroku
41
- SolarWindsAPM.logger.warn "SW_APM_URL: #{ENV['SW_APM_URL']}"
42
- end
43
-
44
34
  SolarWindsAPM.logger.warn "SolarWindsAPM::Ruby defined?: #{yesno(defined?(SolarWindsAPM::Ruby))}"
45
35
  SolarWindsAPM.logger.warn "SolarWindsAPM.reporter: #{SolarWindsAPM.reporter}"
46
36
 
@@ -52,9 +42,7 @@ module SolarWindsAPM
52
42
  SolarWindsAPM.logger.warn "Using Rails?: #{yesno(using_rails)}"
53
43
  if using_rails
54
44
  SolarWindsAPM.logger.warn "SolarWindsAPM::Rails loaded?: #{yesno(defined?(SolarWindsAPM::Rails))}"
55
- if defined?(SolarWindsAPM::Rack)
56
- SolarWindsAPM.logger.warn "SolarWindsAPM::Rack middleware loaded?: #{yesno(::Rails.configuration.middleware.include? SolarWindsAPM::Rack)}"
57
- end
45
+ SolarWindsAPM.logger.warn "SolarWindsAPM::Rack middleware loaded?: #{yesno(::Rails.configuration.middleware.include?(SolarWindsAPM::Rack))}" if defined?(SolarWindsAPM::Rack)
58
46
  end
59
47
 
60
48
  using_sinatra = defined?(::Sinatra)
@@ -80,34 +68,24 @@ module SolarWindsAPM
80
68
  SolarWindsAPM.logger.warn '********************************************************'
81
69
  SolarWindsAPM.logger.warn '* SolarWindsAPM::Config Values'
82
70
  SolarWindsAPM.logger.warn '********************************************************'
83
- SolarWindsAPM::Config.print_config
84
71
 
85
72
  SolarWindsAPM.logger.warn '********************************************************'
86
73
  SolarWindsAPM.logger.warn '* OS, Platform + Env'
87
74
  SolarWindsAPM.logger.warn '********************************************************'
88
- SolarWindsAPM.logger.warn "host_os: " + RbConfig::CONFIG['host_os']
89
- SolarWindsAPM.logger.warn "sitearch: " + RbConfig::CONFIG['sitearch']
90
- SolarWindsAPM.logger.warn "arch: " + RbConfig::CONFIG['arch']
75
+ SolarWindsAPM.logger.warn "host_os: #{RbConfig::CONFIG['host_os']}"
76
+ SolarWindsAPM.logger.warn "sitearch: #{RbConfig::CONFIG['sitearch']}"
77
+ SolarWindsAPM.logger.warn "arch: #{RbConfig::CONFIG['arch']}"
91
78
  SolarWindsAPM.logger.warn RUBY_PLATFORM
92
79
  SolarWindsAPM.logger.warn "RACK_ENV: #{ENV['RACK_ENV']}"
93
80
  SolarWindsAPM.logger.warn "RAILS_ENV: #{ENV['RAILS_ENV']}" if using_rails
94
81
 
95
- SolarWindsAPM.logger.warn '********************************************************'
96
- SolarWindsAPM.logger.warn '* Raw __Init KVs'
97
- SolarWindsAPM.logger.warn '********************************************************'
98
- platform_info = SolarWindsAPM::Util.build_init_report
99
- platform_info.each { |k,v|
100
- SolarWindsAPM.logger.warn "#{k}: #{v}"
101
- }
102
-
103
82
  SolarWindsAPM.logger.warn '********************************************************'
104
83
  SolarWindsAPM.logger.warn '* END SolarWindsAPM Support Report'
105
84
  SolarWindsAPM.logger.warn '* Support Email: technicalsupport@solarwinds.com'
106
- SolarWindsAPM.logger.warn '* Github: https://github.com/librato/ruby-solarwinds'
85
+ SolarWindsAPM.logger.warn '* Github: https://github.com/solarwindscloud/swotel-ruby'
107
86
  SolarWindsAPM.logger.warn '********************************************************'
108
87
 
109
88
  SolarWindsAPM.logger.level = @logger_level
110
89
  nil
111
90
  end
112
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
113
91
  end
@@ -18,7 +18,7 @@ module SolarWindsAPM
18
18
  Thread.current[key]
19
19
  end
20
20
 
21
- define_method(name.to_s + '=') do |value|
21
+ define_method("#{name}=") do |value|
22
22
  Thread.current[key] = value
23
23
  end
24
24
  end
@@ -6,10 +6,10 @@ module SolarWindsAPM
6
6
  # The current version of the gem. Used mainly by
7
7
  # solarwinds_apm.gemspec during gem build process
8
8
  module Version
9
- MAJOR = 5 # breaking,
10
- MINOR = 1 # feature,
11
- PATCH = 8 # fix => BFF
12
- PRE = nil # for pre-releases into packagecloud, set to nil for production releases into rubygems
9
+ MAJOR = 6 # breaking,
10
+ MINOR = 0 # feature,
11
+ PATCH = 0 # fix => BFF
12
+ PRE = 'preV1' # for pre-releases into packagecloud, set to nil for production releases into rubygems
13
13
 
14
14
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
15
15
  end