solarwinds_apm 6.1.2 → 7.0.0.prev2

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -3
  3. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +1 -30
  4. data/lib/solarwinds_apm/api/current_trace_info.rb +10 -6
  5. data/lib/solarwinds_apm/api/custom_metrics.rb +8 -25
  6. data/lib/solarwinds_apm/api/tracing.rb +12 -27
  7. data/lib/solarwinds_apm/api/transaction_name.rb +6 -10
  8. data/lib/solarwinds_apm/config.rb +7 -1
  9. data/lib/solarwinds_apm/constants.rb +1 -0
  10. data/lib/solarwinds_apm/noop/api.rb +5 -2
  11. data/lib/solarwinds_apm/noop.rb +0 -24
  12. data/lib/solarwinds_apm/opentelemetry/otlp_processor.rb +116 -66
  13. data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +0 -2
  14. data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +5 -4
  15. data/lib/solarwinds_apm/opentelemetry.rb +5 -7
  16. data/lib/solarwinds_apm/otel_native_config.rb +180 -0
  17. data/lib/solarwinds_apm/patch/README.md +15 -0
  18. data/lib/solarwinds_apm/{noop/metadata.rb → sampling/dice.rb} +19 -17
  19. data/lib/solarwinds_apm/sampling/http_sampler.rb +87 -0
  20. data/lib/solarwinds_apm/sampling/json_sampler.rb +52 -0
  21. data/lib/solarwinds_apm/sampling/metrics.rb +38 -0
  22. data/lib/solarwinds_apm/sampling/oboe_sampler.rb +348 -0
  23. data/lib/solarwinds_apm/sampling/sampler.rb +197 -0
  24. data/lib/solarwinds_apm/sampling/sampling_constants.rb +127 -0
  25. data/lib/solarwinds_apm/sampling/sampling_patch.rb +49 -0
  26. data/lib/solarwinds_apm/sampling/setting_example.txt +1 -0
  27. data/lib/solarwinds_apm/{noop/context.rb → sampling/settings.rb} +14 -25
  28. data/lib/solarwinds_apm/sampling/token_bucket.rb +126 -0
  29. data/lib/solarwinds_apm/sampling/trace_options.rb +100 -0
  30. data/lib/solarwinds_apm/{patch.rb → sampling.rb} +20 -4
  31. data/lib/solarwinds_apm/support/logger_formatter.rb +1 -1
  32. data/lib/solarwinds_apm/support/logging_log_event.rb +1 -1
  33. data/lib/solarwinds_apm/support/lumberjack_formatter.rb +1 -1
  34. data/lib/solarwinds_apm/support/otlp_endpoint.rb +99 -0
  35. data/lib/solarwinds_apm/support/resource_detector.rb +192 -0
  36. data/lib/solarwinds_apm/support/service_key_checker.rb +12 -6
  37. data/lib/solarwinds_apm/support/transaction_settings.rb +6 -0
  38. data/lib/solarwinds_apm/support/txn_name_manager.rb +54 -9
  39. data/lib/solarwinds_apm/support/utils.rb +9 -0
  40. data/lib/solarwinds_apm/support.rb +2 -4
  41. data/lib/solarwinds_apm/version.rb +4 -4
  42. data/lib/solarwinds_apm.rb +27 -73
  43. metadata +107 -40
  44. data/ext/oboe_metal/extconf.rb +0 -168
  45. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +0 -1
  46. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +0 -1
  47. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +0 -1
  48. data/ext/oboe_metal/lib/liboboe-1.0-lambda-aarch64.so.sha256 +0 -1
  49. data/ext/oboe_metal/lib/liboboe-1.0-lambda-x86_64.so.sha256 +0 -1
  50. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +0 -1
  51. data/ext/oboe_metal/src/VERSION +0 -1
  52. data/ext/oboe_metal/src/bson/bson.h +0 -220
  53. data/ext/oboe_metal/src/bson/platform_hacks.h +0 -91
  54. data/ext/oboe_metal/src/init_solarwinds_apm.cc +0 -18
  55. data/ext/oboe_metal/src/oboe.h +0 -930
  56. data/ext/oboe_metal/src/oboe_api.cpp +0 -793
  57. data/ext/oboe_metal/src/oboe_api.h +0 -621
  58. data/ext/oboe_metal/src/oboe_debug.h +0 -17
  59. data/ext/oboe_metal/src/oboe_swig_wrap.cc +0 -11045
  60. data/lib/oboe_metal.rb +0 -187
  61. data/lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt +0 -24
  62. data/lib/solarwinds_apm/noop/span.rb +0 -25
  63. data/lib/solarwinds_apm/oboe_init_options.rb +0 -222
  64. data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +0 -239
  65. data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +0 -174
  66. data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +0 -333
  67. data/lib/solarwinds_apm/otel_config.rb +0 -174
  68. data/lib/solarwinds_apm/otel_lambda_config.rb +0 -56
  69. data/lib/solarwinds_apm/patch/dummy_patch.rb +0 -12
  70. data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +0 -33
  71. data/lib/solarwinds_apm/support/support_report.rb +0 -99
  72. data/lib/solarwinds_apm/support/transaction_cache.rb +0 -57
  73. data/lib/solarwinds_apm/support/x_trace_options.rb +0 -138
@@ -6,14 +6,12 @@
6
6
  #
7
7
  # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
8
 
9
- require 'opentelemetry/sdk'
10
- require 'opentelemetry/instrumentation/all'
11
-
12
- # TODO: in future, it should add opentelemetry-metrics-sdk and require it here
9
+ require 'opentelemetry-sdk'
10
+ require 'opentelemetry-metrics-sdk'
11
+ require 'opentelemetry-exporter-otlp'
12
+ require 'opentelemetry-exporter-otlp-metrics'
13
+ require 'opentelemetry-instrumentation-all'
13
14
 
14
15
  require_relative 'opentelemetry/solarwinds_propagator'
15
- require_relative 'opentelemetry/solarwinds_processor'
16
- require_relative 'opentelemetry/solarwinds_sampler'
17
- require_relative 'opentelemetry/solarwinds_exporter'
18
16
  require_relative 'opentelemetry/solarwinds_response_propagator'
19
17
  require_relative 'opentelemetry/otlp_processor'
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ # © 2023 SolarWinds Worldwide, LLC. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+
9
+ require_relative 'api'
10
+ require_relative 'support'
11
+ require_relative 'opentelemetry'
12
+ require_relative 'sampling'
13
+
14
+ module SolarWindsAPM
15
+ # OTelNativeConfig module
16
+ module OTelNativeConfig
17
+ @@config = {}
18
+ @@config_map = {}
19
+ @@agent_enabled = false
20
+
21
+ RESOURCE_ATTRIBUTES = 'RESOURCE_ATTRIBUTES'
22
+
23
+ def self.initialize
24
+ return unless defined?(::OpenTelemetry::SDK::Configurator)
25
+
26
+ is_lambda = SolarWindsAPM::Utils.determine_lambda
27
+
28
+ ENV['OTEL_TRACES_EXPORTER'] = ENV['OTEL_TRACES_EXPORTER'].to_s.split(',').tap { |e| e << 'otlp' unless e.include?('otlp') }.join(',')
29
+
30
+ # add response propagator to rack instrumentation
31
+ resolve_response_propagator
32
+
33
+ # dbo: traceparent injection as sql comments
34
+ require_relative 'patch/tag_sql_patch' if SolarWindsAPM::Config[:tag_sql]
35
+
36
+ # endpoint and service_key for non-lambda
37
+ otlp_endpoint = nil
38
+ unless is_lambda
39
+ otlp_endpoint = SolarWindsAPM::OTLPEndPoint.new
40
+ otlp_endpoint.config_otlp_token_and_endpoint
41
+ return if otlp_endpoint.token.nil?
42
+ end
43
+
44
+ ENV['OTEL_RESOURCE_ATTRIBUTES'] = "sw.apm.version=#{SolarWindsAPM::Version::STRING},sw.data.module=apm,service.name=#{ENV.fetch('OTEL_SERVICE_NAME', nil)}," + ENV['OTEL_RESOURCE_ATTRIBUTES'].to_s
45
+
46
+ # resource attributes
47
+ mandatory_resource = SolarWindsAPM::ResourceDetector.detect
48
+ additional_attributes = @@config_map[RESOURCE_ATTRIBUTES]
49
+ if additional_attributes
50
+ if additional_attributes.instance_of?(::OpenTelemetry::SDK::Resources::Resource)
51
+ final_attributes = mandatory_resource.merge(additional_attributes)
52
+ elsif additional_attributes.instance_of?(Hash)
53
+ final_attributes = mandatory_resource.merge(::OpenTelemetry::SDK::Resources::Resource.create(additional_attributes))
54
+ end
55
+ @@config_map.delete(RESOURCE_ATTRIBUTES)
56
+ else
57
+ final_attributes = mandatory_resource.merge({})
58
+ end
59
+
60
+ # set gzip compression
61
+ %w[TRACES METRICS LOGS].each do |signal|
62
+ ENV["OTEL_EXPORTER_OTLP_#{signal}_COMPRESSION"] = 'gzip' if ENV["OTEL_EXPORTER_OTLP_#{signal}_COMPRESSION"].to_s.empty? && ENV['OTEL_EXPORTER_OTLP_COMPRESSION'].to_s.empty?
63
+ end
64
+
65
+ # set http stable semconv
66
+ ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http' if ENV['OTEL_SEMCONV_STABILITY_OPT_IN'].to_s.empty?
67
+
68
+ # set delta temporality
69
+ ENV['OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE'] = 'delta' if ENV['OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE'].to_s.empty?
70
+
71
+ # log level
72
+ if ENV['OTEL_LOG_LEVEL'].to_s.empty?
73
+ log_level = (ENV['SW_APM_DEBUG_LEVEL'] || SolarWindsAPM::Config[:debug_level] || 3).to_i
74
+ ENV['OTEL_LOG_LEVEL'] = SolarWindsAPM::Config::SW_LOG_LEVEL_MAPPING.dig(log_level, :otel)
75
+ end
76
+
77
+ ::OpenTelemetry::SDK.configure do |c|
78
+ c.resource = final_attributes
79
+ c.use_all(@@config_map)
80
+ end
81
+
82
+ # append our propagators
83
+ ::OpenTelemetry.propagation.instance_variable_get(:@propagators).append(SolarWindsAPM::OpenTelemetry::SolarWindsPropagator::TextMapPropagator.new)
84
+
85
+ # add sw metrics processors (only record respone_time)
86
+ txn_manager = TxnNameManager.new
87
+ otlp_processor = SolarWindsAPM::OpenTelemetry::OTLPProcessor.new(txn_manager)
88
+
89
+ @@config[:metrics_processor] = otlp_processor
90
+ ::OpenTelemetry.tracer_provider.add_span_processor(otlp_processor)
91
+
92
+ # collector, service and headers are used for http sampler get settings
93
+ sampler_config = {
94
+ tracing_mode: SolarWindsAPM::Config[:tracing_mode],
95
+ trigger_trace_enabled: SolarWindsAPM::Config[:trigger_tracing_mode],
96
+ transaction_settings: SolarWindsAPM::Config[:transaction_settings]
97
+ }
98
+
99
+ unless otlp_endpoint.nil?
100
+ sampler_config.merge!({
101
+ collector: "https://#{ENV.fetch('SW_APM_COLLECTOR', 'apm.collector.cloud.solarwinds.com:443')}",
102
+ service: otlp_endpoint.service_name,
103
+ headers: "Bearer #{otlp_endpoint.token}"
104
+ })
105
+ end
106
+
107
+ sampler = is_lambda ? JsonSampler.new(sampler_config) : HttpSampler.new(sampler_config)
108
+
109
+ ::OpenTelemetry.tracer_provider.sampler = ::OpenTelemetry::SDK::Trace::Samplers.parent_based(
110
+ root: sampler,
111
+ remote_parent_sampled: sampler,
112
+ remote_parent_not_sampled: sampler
113
+ )
114
+
115
+ @@agent_enabled = true
116
+
117
+ nil
118
+ end
119
+
120
+ def self.[](key)
121
+ @@config[key.to_sym]
122
+ end
123
+
124
+ def self.agent_enabled
125
+ @@agent_enabled
126
+ end
127
+
128
+ def self.resolve_response_propagator
129
+ response_propagator = SolarWindsAPM::OpenTelemetry::SolarWindsResponsePropagator::TextMapPropagator.new
130
+ rack_setting = @@config_map['OpenTelemetry::Instrumentation::Rack']
131
+
132
+ if rack_setting
133
+ if rack_setting[:response_propagators].instance_of?(Array)
134
+ rack_setting[:response_propagators].append(response_propagator)
135
+ elsif rack_setting[:response_propagators].nil?
136
+ rack_setting[:response_propagators] = [response_propagator]
137
+ else
138
+ SolarWindsAPM.logger.warn do
139
+ "[#{name}/#{__method__}] Rack response propagator resolve failed. Provided type #{rack_setting[:response_propagators].class}, please provide Array e.g. [#{rack_setting[:response_propagators]}]"
140
+ end
141
+ end
142
+ else
143
+ @@config_map['OpenTelemetry::Instrumentation::Rack'] = { response_propagators: [response_propagator] }
144
+ end
145
+ end
146
+
147
+ #
148
+ # Allow initialize after set new value to SolarWindsAPM::Config[:key]=value
149
+ #
150
+ # Usage:
151
+ #
152
+ # Default using the use_all to load all instrumentation
153
+ # But with specific instrumentation disabled, use {:enabled: false} in config
154
+ # SolarWindsAPM::OTelNativeConfig.initialize_with_config do |config|
155
+ # config["OpenTelemetry::Instrumentation::Rack"] = {"a" => "b"}
156
+ # config["OpenTelemetry::Instrumentation::Dalli"] = {:enabled: false}
157
+ # config["RESOURCE_ATTRIBUTES"] = ::OpenTelemetry::Resource::Detector::GoogleCloudPlatform.detect
158
+ # end
159
+ #
160
+ def self.initialize_with_config
161
+ unless block_given?
162
+ SolarWindsAPM.logger.warn do
163
+ "[#{name}/#{__method__}] Block not given while doing in-code configuration. Agent disabled."
164
+ end
165
+ return
166
+ end
167
+
168
+ yield @@config_map
169
+
170
+ if @@config_map.empty?
171
+ SolarWindsAPM.logger.warn do
172
+ "[#{name}/#{__method__}] No configuration given for in-code configuration. Agent disabled."
173
+ end
174
+ return
175
+ end
176
+
177
+ initialize
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,15 @@
1
+ # Patch
2
+
3
+ ## Patch upstream code
4
+
5
+ This folder is for storing patch files that apply to upstream code.
6
+
7
+ For example, to patch otel ruby sdk `Registry`, and assume you have dummy_patch file that have module `SolarWindsAPM::Patch::DummyPatch`,
8
+
9
+ ```ruby
10
+ require_relative './patch/dummy_patch'
11
+
12
+ if defined? OpenTelemetry::Instrumentation::Registry && OpenTelemetry::Instrumentation::Registry::VERSION <= '0.3.0'
13
+ OpenTelemetry::Instrumentation::Registry.prepend(SolarWindsAPM::Patch::DummyPatch)
14
+ end
15
+ ```
@@ -6,27 +6,29 @@
6
6
  #
7
7
  # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
8
 
9
- ####
10
- # noop version of SolarWindsAPM::Metadata
11
- #
12
- module Oboe_metal # rubocop:disable Naming/ClassAndModuleCamelCase
13
- # Metadata
14
- class Metadata
15
- ##
16
- # noop version of :makeRandom
17
- #
18
- # needs to return an object that responds to :isValid
19
- #
20
- def self.makeRandom
21
- Metadata.new
9
+ # Dice is used in oboe_sampler diceRollAlgo
10
+ module SolarWindsAPM
11
+ class Dice
12
+ attr_reader :rate, :scale
13
+
14
+ def initialize(settings)
15
+ @scale = settings[:scale]
16
+ @rate = settings[:rate] || 0
17
+ end
18
+
19
+ def update(settings)
20
+ @scale = settings[:scale] if settings[:scale]
21
+ @rate = settings[:rate] if settings[:rate]
22
22
  end
23
23
 
24
- def self.fromString(*)
25
- Metadata.new
24
+ # return Boolean
25
+ def roll
26
+ (rand * @scale) < @rate
26
27
  end
27
28
 
28
- def isValid
29
- false
29
+ def rate=(rate)
30
+ # Math.max(0, Math.min(this.#scale, n))
31
+ @rate = rate.clamp(0, @scale)
30
32
  end
31
33
  end
32
34
  end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # © 2023 SolarWinds Worldwide, LLC. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+
9
+ module SolarWindsAPM
10
+ class HttpSampler < Sampler
11
+ REQUEST_TIMEOUT = 10 # 10s
12
+ GET_SETTING_DURAION = 60 # 60s
13
+
14
+ # we don't need hostname as it's for separating browser and local env
15
+ def initialize(config)
16
+ super(config, SolarWindsAPM.logger)
17
+
18
+ @url = config[:collector]
19
+ @service = URI.encode_www_form_component(config[:service]) # service name "Hello world" -> "Hello%20world"
20
+ @headers = config[:headers]
21
+
22
+ @hostname = hostname
23
+ @setting_url = URI.join(@url, "./v1/settings/#{@service}/#{@hostname}")
24
+
25
+ Thread.new { settings_request }
26
+ end
27
+
28
+ private
29
+
30
+ # Node.js equivalent: Retrieve system hostname
31
+ # e.g. docker -> docker.swo.ubuntu.development; macos -> NHSDFWSSD
32
+ def hostname
33
+ host = Socket.gethostname
34
+ URI.encode_www_form_component(host)
35
+ end
36
+
37
+ def fetch_with_timeout(url, timeout_seconds = nil)
38
+ uri = url
39
+ response = nil
40
+
41
+ thread = Thread.new do
42
+ ::OpenTelemetry::Common::Utilities.untraced do
43
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
44
+ request = Net::HTTP::Get.new(uri)
45
+ request['Authorization'] = @headers
46
+
47
+ response = http.request(request)
48
+ end
49
+ end
50
+ rescue StandardError => e
51
+ @logger.debug { "Error during request: #{e.message}" }
52
+ end
53
+
54
+ thread_join = thread.join(timeout_seconds || REQUEST_TIMEOUT)
55
+ if thread_join.nil?
56
+ @logger.debug { "Request timed out after #{timeout_seconds} seconds" }
57
+ thread.kill
58
+ end
59
+
60
+ response
61
+ end
62
+
63
+ # a endless loop within a thread (non-blocking)
64
+ def settings_request
65
+ loop do
66
+ @logger.debug { "Retrieving sampling settings from #{@setting_url}" }
67
+
68
+ response = fetch_with_timeout(@setting_url)
69
+ parsed = response.nil? ? nil : JSON.parse(response.body)
70
+
71
+ @logger.debug { "parsed settings in json: #{parsed.inspect}" }
72
+
73
+ if update_settings(parsed)
74
+ # update the settings before the previous ones expire with some time to spare
75
+ expiry = (parsed['timestamp'].to_i + parsed['ttl'].to_i)
76
+ expiry_timeout = expiry - REQUEST_TIMEOUT - Time.now.to_i
77
+ sleep([0, expiry_timeout].max)
78
+ else
79
+ @logger.warn { 'Retrieved sampling settings are invalid. Ensure proper configuration.' }
80
+ sleep(GET_SETTING_DURAION)
81
+ end
82
+ rescue StandardError => e
83
+ @logger.warn { "Failed to retrieve sampling settings (#{e.message}), tracing will be disabled until valid ones are available." }
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # © 2023 SolarWinds Worldwide, LLC. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+
9
+ module SolarWindsAPM
10
+ class JsonSampler < Sampler
11
+ DEFAULT_PATH = File.join(Dir.tmpdir, 'solarwinds-apm-settings.json')
12
+
13
+ def initialize(config, path = nil)
14
+ super(config, SolarWindsAPM.logger)
15
+
16
+ @path = path || DEFAULT_PATH
17
+ @expiry = Time.now.to_i
18
+ loop_check
19
+ end
20
+
21
+ # only json sampler will need to check if the settings.json file
22
+ # updated or not from collector extention
23
+ def should_sample?(params)
24
+ loop_check
25
+ super
26
+ end
27
+
28
+ private
29
+
30
+ def loop_check
31
+ # Update if we're within 10s of expiry
32
+ return if Time.now.to_i + 10 < @expiry
33
+
34
+ begin
35
+ contents = File.read(@path)
36
+ unparsed = JSON.parse(contents)
37
+ rescue StandardError => e
38
+ @logger.debug { "missing or invalid settings file; Error: #{e.message}" }
39
+ return
40
+ end
41
+
42
+ unless unparsed.is_a?(Array) && unparsed.length == 1
43
+ @logger.debug { "invalid settings file : #{unparsed}" }
44
+ return
45
+ end
46
+
47
+ parsed = update_settings(unparsed.first)
48
+ @logger.debug { "update_settings: #{parsed}" }
49
+ @expiry = parsed[:timestamp].to_i + parsed[:ttl].to_i if parsed
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # © 2023 SolarWinds Worldwide, LLC. All rights reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8
+
9
+ module SolarWindsAPM
10
+ module Metrics
11
+ class Counter
12
+ # counter = Counter.new
13
+ # counter[:request_count].update(1)
14
+ def initialize
15
+ @meter = ::OpenTelemetry.meter_provider.meter('sw.apm.sampling.metrics')
16
+
17
+ @counter = {
18
+ request_count:
19
+ @meter.create_counter('trace.service.request_count', unit: '{request}', description: 'Count of all requests.'),
20
+ sample_count:
21
+ @meter.create_counter('trace.service.samplecount', unit: '{request}', description: 'Count of requests that went through sampling, which excludes those with a valid upstream decision or trigger traced.'),
22
+ trace_count:
23
+ @meter.create_counter('trace.service.tracecount', unit: '{trace}', description: 'Count of all traces.'),
24
+ through_trace_count:
25
+ @meter.create_counter('trace.service.through_trace_count', unit: '{request}', description: 'Count of requests with a valid upstream decision, thus passed through sampling.'),
26
+ triggered_trace_count:
27
+ @meter.create_counter('trace.service.triggered_trace_count', unit: '{trace}', description: 'Count of triggered traces.'),
28
+ token_bucket_exhaustion_count:
29
+ @meter.create_counter('trace.service.tokenbucket_exhaustion_count', unit: '{request}', description: 'Count of requests that were not traced due to token bucket rate limiting.')
30
+ }
31
+ end
32
+
33
+ def [](key)
34
+ @counter[key]
35
+ end
36
+ end
37
+ end
38
+ end