instana 2.7.2 → 2.8.0

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.
@@ -0,0 +1,403 @@
1
+ # frozen_string_literal: true
2
+
3
+ # (c) Copyright IBM Corp. 2026
4
+
5
+ require 'socket'
6
+ require 'opentelemetry/semantic_conventions'
7
+ require_relative '../../util'
8
+
9
+ module Instana
10
+ module Exporter
11
+ module Otlp
12
+ # Resource represents a resource, which captures identifying information about the entities
13
+ # for which telemetry (metrics or traces) is reported.
14
+ # This follows OpenTelemetry semantic conventions for resource attributes
15
+ class Resource
16
+ PROC_SELF_CGROUP = '/proc/self/cgroup'
17
+ DOCKER_ENV_FILE = '/.dockerenv'
18
+ PODMAN_CONTAINERENV = '/run/.containerenv'
19
+ # Linux-only stable machine-id paths (systemd and D-Bus fallback).
20
+ # These files do not exist on macOS or Windows; host_id returns nil there.
21
+ MACHINE_ID_PATHS = %w[/etc/machine-id /var/lib/dbus/machine-id].freeze
22
+ # cloud.resource_id is not yet in the installed semconv gem version
23
+ CLOUD_RESOURCE_ID = 'cloud.resource_id'
24
+
25
+ class << self
26
+ private :new
27
+
28
+ # Returns a newly created {Resource} with the specified attributes
29
+ #
30
+ # @param [Hash{String => String, Numeric, Boolean}] attributes Hash of key-value pairs to be used
31
+ # as attributes for this resource
32
+ # @return [Resource]
33
+ def create(attributes = {})
34
+ frozen_attributes = attributes.each_with_object({}) do |(k, v), memo|
35
+ memo[k.freeze] = v.freeze
36
+ end.freeze
37
+
38
+ new(frozen_attributes)
39
+ end
40
+
41
+ # Returns the default resource with standard attributes
42
+ #
43
+ # @return [Resource]
44
+ def default
45
+ @default ||= create(OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => 'ruby-service')
46
+ .merge(process)
47
+ .merge(telemetry_sdk)
48
+ .merge(service_name_from_env)
49
+ .merge(optional_attributes)
50
+ .merge(container_attributes)
51
+ .merge(faas_attributes)
52
+ end
53
+
54
+ # Get the global resource instance (singleton pattern)
55
+ # This method provides backward compatibility with the previous API
56
+ #
57
+ # @return [Hash] Resource attributes as a hash
58
+ def instance
59
+ @instance ||= default.attributes
60
+ end
61
+
62
+ # Reset the resource instance (useful for testing)
63
+ # This method provides backward compatibility with the previous API
64
+ def reset!
65
+ @instance = nil
66
+ @default = nil
67
+ end
68
+
69
+ # Returns telemetry SDK resource attributes
70
+ #
71
+ # @return [Resource]
72
+ def telemetry_sdk
73
+ create(
74
+ OpenTelemetry::SemanticConventions::Resource::TELEMETRY_SDK_NAME => 'instana',
75
+ OpenTelemetry::SemanticConventions::Resource::TELEMETRY_SDK_LANGUAGE => 'ruby',
76
+ OpenTelemetry::SemanticConventions::Resource::TELEMETRY_SDK_VERSION => ::Instana::VERSION
77
+ )
78
+ end
79
+
80
+ # Returns process resource attributes
81
+ #
82
+ # @return [Resource]
83
+ def process
84
+ create(
85
+ OpenTelemetry::SemanticConventions::Resource::PROCESS_PID => Process.pid,
86
+ OpenTelemetry::SemanticConventions::Resource::PROCESS_COMMAND => $PROGRAM_NAME,
87
+ OpenTelemetry::SemanticConventions::Resource::PROCESS_EXECUTABLE_NAME => File.basename($PROGRAM_NAME),
88
+ OpenTelemetry::SemanticConventions::Resource::PROCESS_RUNTIME_NAME => RUBY_ENGINE,
89
+ OpenTelemetry::SemanticConventions::Resource::PROCESS_RUNTIME_VERSION => RUBY_VERSION,
90
+ OpenTelemetry::SemanticConventions::Resource::PROCESS_RUNTIME_DESCRIPTION => RUBY_DESCRIPTION
91
+ )
92
+ end
93
+
94
+ private
95
+
96
+ # Returns service name from environment variables
97
+ #
98
+ # @return [Resource]
99
+ def service_name_from_env
100
+ service_name = ENV.fetch('OTEL_SERVICE_NAME', nil) ||
101
+ ENV.fetch('INSTANA_SERVICE_NAME', nil) ||
102
+ ::Instana::Util.get_app_name
103
+
104
+ return create({}) unless service_name
105
+
106
+ create(OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => service_name)
107
+ end
108
+
109
+ # Returns optional resource attributes:
110
+ # os.type, host.name, host.arch, host.id, service.version, service.instance.id
111
+ #
112
+ # service.instance.id priority (v2 spec §General Resource Attributes):
113
+ # container.id → k8s.pod.uid → host.id → hostname:pid
114
+ #
115
+ # @return [Resource]
116
+ def optional_attributes
117
+ attrs = {}
118
+
119
+ # os.type — Required per v2 spec
120
+ attrs[OpenTelemetry::SemanticConventions::Resource::OS_TYPE] = detect_os_type
121
+
122
+ host = hostname
123
+
124
+ # host.name — Recommended (Conditional) per v2 spec
125
+ attrs[OpenTelemetry::SemanticConventions::Resource::HOST_NAME] = host if host && host != 'unknown'
126
+
127
+ # host.arch
128
+ arch = host_architecture
129
+ attrs[OpenTelemetry::SemanticConventions::Resource::HOST_ARCH] = arch if arch
130
+
131
+ # host.id — Recommended per v2 spec; stable machine identifier
132
+ hid = host_id
133
+ attrs[OpenTelemetry::SemanticConventions::Resource::HOST_ID] = hid if hid
134
+
135
+ # service.version
136
+ version = ENV.fetch('OTEL_SERVICE_VERSION', nil) ||
137
+ ENV.fetch('INSTANA_SERVICE_VERSION', nil) ||
138
+ detect_app_version
139
+ attrs[OpenTelemetry::SemanticConventions::Resource::SERVICE_VERSION] = version if version
140
+
141
+ # service.instance.id — priority: container.id > k8s.pod.uid > host.id > hostname:pid
142
+ instance_id = extract_container_id ||
143
+ ENV.fetch('MY_POD_UID', nil) ||
144
+ hid ||
145
+ "#{host}:#{Process.pid}"
146
+ attrs[OpenTelemetry::SemanticConventions::Resource::SERVICE_INSTANCE_ID] = instance_id
147
+
148
+ create(attrs)
149
+ end
150
+
151
+ # Returns container and cloud platform resource attributes.
152
+ # AWS Lambda is intentionally excluded here — it is a FaaS platform,
153
+ # not a container runtime. See faas_attributes for Lambda/Cloud Run.
154
+ #
155
+ # @return [Resource]
156
+ def container_attributes
157
+ attrs = {}
158
+
159
+ add_docker_or_podman_attributes(attrs)
160
+ add_kubernetes_attributes(attrs)
161
+ add_aws_ecs_attributes(attrs)
162
+
163
+ create(attrs)
164
+ end
165
+
166
+ # Returns FaaS (Function-as-a-Service) platform resource attributes.
167
+ # Kept separate from container_attributes because Lambda and Cloud Run
168
+ # are serverless runtimes, not container runtimes.
169
+ #
170
+ # @return [Resource]
171
+ def faas_attributes
172
+ attrs = {}
173
+
174
+ add_aws_lambda_attributes(attrs)
175
+ add_cloud_run_attributes(attrs)
176
+
177
+ create(attrs)
178
+ end
179
+
180
+ # Sets container.runtime and container.id attributes when a container
181
+ # engine is detected. Only runs on Linux since all sentinel paths are
182
+ # Linux-specific.
183
+ def add_docker_or_podman_attributes(attrs)
184
+ return unless linux?
185
+
186
+ engine = extract_container_engine
187
+ attrs[OpenTelemetry::SemanticConventions::Resource::CONTAINER_RUNTIME] = engine if engine
188
+
189
+ container_id = extract_container_id
190
+ attrs[OpenTelemetry::SemanticConventions::Resource::CONTAINER_ID] = container_id if container_id
191
+ end
192
+
193
+ # Detects the container engine by inspecting Linux sentinel files.
194
+ # Returns 'podman', 'docker', or nil if no container environment is found.
195
+ #
196
+ # @return [String, nil]
197
+ def extract_container_engine
198
+ if File.exist?(PODMAN_CONTAINERENV)
199
+ 'podman'
200
+ elsif File.exist?(DOCKER_ENV_FILE) || File.exist?(PROC_SELF_CGROUP)
201
+ 'docker'
202
+ end
203
+ end
204
+
205
+ def add_kubernetes_attributes(attrs)
206
+ return unless ENV.fetch('KUBERNETES_SERVICE_HOST', nil)
207
+
208
+ attrs[OpenTelemetry::SemanticConventions::Resource::K8S_POD_NAME] = ENV.fetch('HOSTNAME', nil)
209
+
210
+ pod_uid = ENV.fetch('MY_POD_UID', nil)
211
+ attrs[OpenTelemetry::SemanticConventions::Resource::K8S_POD_UID] = pod_uid if pod_uid
212
+
213
+ ns = ENV.fetch('KUBERNETES_NAMESPACE', nil)
214
+ attrs[OpenTelemetry::SemanticConventions::Resource::K8S_NAMESPACE_NAME] = ns if ns
215
+ end
216
+
217
+ def add_aws_ecs_attributes(attrs)
218
+ return unless ENV.fetch('ECS_CONTAINER_METADATA_URI', nil) || ENV.fetch('ECS_CONTAINER_METADATA_URI_V4', nil)
219
+
220
+ attrs[OpenTelemetry::SemanticConventions::Resource::CLOUD_PROVIDER] = 'aws'
221
+ attrs[OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM] = 'aws_ecs'
222
+ end
223
+
224
+ def add_aws_lambda_attributes(attrs)
225
+ lambda_name = ENV.fetch('AWS_LAMBDA_FUNCTION_NAME', nil)
226
+ return unless lambda_name
227
+
228
+ attrs[OpenTelemetry::SemanticConventions::Resource::CLOUD_PROVIDER] = 'aws'
229
+ attrs[OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM] = 'aws_lambda'
230
+ attrs[OpenTelemetry::SemanticConventions::Resource::FAAS_NAME] = lambda_name
231
+
232
+ version = ENV.fetch('AWS_LAMBDA_FUNCTION_VERSION', nil)
233
+ attrs[OpenTelemetry::SemanticConventions::Resource::FAAS_VERSION] = version if version
234
+
235
+ arn = ENV.fetch('AWS_LAMBDA_FUNCTION_ARN', nil)
236
+ attrs.merge!(parse_lambda_arn(arn)) if arn
237
+ end
238
+
239
+ def add_cloud_run_attributes(attrs)
240
+ service = ENV.fetch('K_SERVICE', nil)
241
+ return unless service
242
+
243
+ attrs[OpenTelemetry::SemanticConventions::Resource::CLOUD_PROVIDER] = 'gcp'
244
+ attrs[OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM] = 'gcp_cloud_run'
245
+ attrs[OpenTelemetry::SemanticConventions::Resource::FAAS_NAME] = service
246
+
247
+ revision = ENV.fetch('K_REVISION', nil)
248
+ attrs[OpenTelemetry::SemanticConventions::Resource::FAAS_VERSION] = revision if revision
249
+ end
250
+
251
+ # Returns true when the current OS is Linux.
252
+ #
253
+ # @return [Boolean]
254
+ def linux?
255
+ detect_os_type == 'linux'
256
+ end
257
+
258
+ # Detect the OS type string per OTel semconv os.type values.
259
+ # Returns one of: "linux", "darwin", "windows", or the raw RbConfig string.
260
+ #
261
+ # @return [String]
262
+ def detect_os_type
263
+ raw = RbConfig::CONFIG['host_os'].to_s.downcase
264
+ case raw
265
+ when /linux/ then 'linux'
266
+ when /darwin/ then 'darwin'
267
+ when /mingw|mswin|cygwin/ then 'windows'
268
+ else raw
269
+ end
270
+ end
271
+
272
+ # Returns a stable machine-level identifier.
273
+ # Reads /etc/machine-id (Linux systemd standard) or
274
+ # /var/lib/dbus/machine-id as fallback. Returns nil on macOS/Windows.
275
+ #
276
+ # @return [String, nil]
277
+ def host_id
278
+ path = MACHINE_ID_PATHS.find { |machine_id_path| File.exist?(machine_id_path) }
279
+ return nil unless path
280
+
281
+ id = File.read(path).strip
282
+ return id unless id.empty?
283
+
284
+ nil
285
+ rescue StandardError
286
+ nil
287
+ end
288
+
289
+ # Parses a Lambda ARN and returns a hash of cloud.* resource attributes.
290
+ #
291
+ # @param arn [String] e.g. "arn:aws:lambda:us-east-1:123456789012:function:my-fn"
292
+ # @return [Hash]
293
+ def parse_lambda_arn(arn)
294
+ return {} if arn.nil? || arn.empty?
295
+
296
+ parts = arn.split(':')
297
+ result = {}
298
+ result[OpenTelemetry::SemanticConventions::Resource::CLOUD_REGION] = parts[3] if parts[3] && !parts[3].empty?
299
+ result[OpenTelemetry::SemanticConventions::Resource::CLOUD_ACCOUNT_ID] = parts[4] if parts[4] && !parts[4].empty?
300
+ result[CLOUD_RESOURCE_ID] = arn
301
+ result
302
+ rescue StandardError
303
+ {}
304
+ end
305
+
306
+ # Get hostname
307
+ #
308
+ # @return [String] Hostname
309
+ def hostname
310
+ Socket.gethostname
311
+ rescue StandardError
312
+ 'unknown'
313
+ end
314
+
315
+ # Get host architecture
316
+ #
317
+ # @return [String] Host architecture
318
+ def host_architecture
319
+ RbConfig::CONFIG['host_cpu']
320
+ end
321
+
322
+ # Extract container ID from cgroup file
323
+ #
324
+ # @return [String, nil] Container ID
325
+ def extract_container_id
326
+ return nil unless File.exist?(PROC_SELF_CGROUP)
327
+
328
+ line = File.readlines(PROC_SELF_CGROUP).find do |l|
329
+ l.match?(%r{/docker/([a-f0-9]{64})})
330
+ end
331
+
332
+ return nil unless line
333
+
334
+ match = line.match(%r{/docker/([a-f0-9]{64})})
335
+ match[1]
336
+ rescue StandardError
337
+ nil
338
+ end
339
+
340
+ # Detect application version from various sources
341
+ #
342
+ # @return [String, nil] Application version
343
+ def detect_app_version
344
+ # Try to get version from Rails
345
+ if defined?(::Rails) && ::Rails.respond_to?(:application) && ::Rails.application
346
+ app_class = ::Rails.application.class
347
+ return app_class::VERSION if app_class.const_defined?(:VERSION)
348
+ end
349
+
350
+ # Try to get version from Gemfile.lock
351
+ if File.exist?('Gemfile.lock')
352
+ lockfile = File.read('Gemfile.lock')
353
+ # Look for the main gem version (first gem in the file)
354
+ match = lockfile.match(/^\s{4}(\S+)\s+\(([^)]+)\)/)
355
+ return match[2] if match
356
+ end
357
+
358
+ nil
359
+ rescue StandardError
360
+ nil
361
+ end
362
+ end
363
+
364
+ # @api private
365
+ # The constructor is private and only for use internally by the class.
366
+ # Users should use the {create} factory method to obtain a {Resource}
367
+ # instance.
368
+ #
369
+ # @param [Hash<String, String>] frozen_attributes Frozen-hash of frozen-string
370
+ # key-value pairs to be used as attributes for this resource
371
+ # @return [Resource]
372
+ def initialize(frozen_attributes)
373
+ @attributes = frozen_attributes
374
+ end
375
+
376
+ # Returns an enumerator for attributes of this {Resource}
377
+ #
378
+ # @return [Enumerator]
379
+ def attribute_enumerator
380
+ @attribute_enumerator ||= attributes.to_enum
381
+ end
382
+
383
+ # Returns a new, merged {Resource} by merging the current {Resource} with
384
+ # the other {Resource}. In case of a collision, the other {Resource}
385
+ # takes precedence
386
+ #
387
+ # @param [Resource] other The other resource to merge
388
+ # @return [Resource] A new resource formed by merging the current resource
389
+ # with other
390
+ def merge(other)
391
+ return self unless other.is_a?(Resource)
392
+
393
+ self.class.send(:new, attributes.merge(other.send(:attributes)).freeze)
394
+ end
395
+
396
+ # Returns the attributes hash for this resource
397
+ #
398
+ # @return [Hash] The frozen attributes hash
399
+ attr_reader :attributes
400
+ end
401
+ end
402
+ end
403
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ # (c) Copyright IBM Corp. 2026
4
+
5
+ require_relative 'base_converter'
6
+ require 'opentelemetry/semconv/incubating/rpc'
7
+ require 'opentelemetry/semconv/incubating/code'
8
+ require 'opentelemetry/semconv/server'
9
+
10
+ module Instana
11
+ module Exporter
12
+ module Otlp
13
+ # Converter for RPC spans (gRPC, ActionCable) to OTLP format
14
+ class RpcConverter < BaseConverter
15
+ # Build OTel-compliant span name for RPC spans
16
+ #
17
+ # Formulas per SPAN_NAME_PATTERNS.txt Section 4:
18
+ # gRPC → "{package.Service/Method}" (leading "/" stripped per OTel spec)
19
+ # ActionCable → "{ChannelClass#action}" (call string used as-is)
20
+ #
21
+ # @return [String] The span name
22
+ def span_name
23
+ rpc_data = span[:data]&.[](:rpc) || {}
24
+
25
+ if rpc_data[:flavor] == :actioncable
26
+ rpc_data[:call].to_s
27
+ else
28
+ # Strip the mandatory leading slash per gRPC/OTel spec
29
+ rpc_data[:call].to_s.delete_prefix('/')
30
+ end.then { |n| n.empty? ? super : n }
31
+ end
32
+
33
+ def convert_attributes
34
+ attributes = {}
35
+
36
+ rpc_data = span[:data]&.[](:rpc)
37
+ return attributes unless rpc_data
38
+
39
+ # Check if this is an ActionCable span
40
+ if rpc_data[:flavor] == :actioncable
41
+ convert_action_cable_attributes(attributes, rpc_data)
42
+ else
43
+ convert_grpc_attributes(attributes, rpc_data)
44
+ end
45
+
46
+ attributes
47
+ end
48
+
49
+ private
50
+
51
+ # Convert gRPC span attributes
52
+ def convert_grpc_attributes(attributes, rpc_data)
53
+ # RPC system
54
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::RPC::RPC_SYSTEM, 'grpc')
55
+
56
+ # RPC service and method
57
+ if rpc_data[:call]
58
+ service, method = parse_grpc_call(rpc_data[:call])
59
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::RPC::RPC_SERVICE, service)
60
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::RPC::RPC_METHOD, method)
61
+ end
62
+
63
+ # Network peer
64
+ add_attribute(attributes, OpenTelemetry::SemConv::SERVER::SERVER_ADDRESS, rpc_data[:host])
65
+ add_attribute(attributes, OpenTelemetry::SemConv::SERVER::SERVER_ADDRESS, rpc_data.dig(:peer, :address))
66
+
67
+ # gRPC-specific attributes
68
+ add_attribute(attributes, 'rpc.grpc.call_type', rpc_data[:call_type])
69
+ end
70
+
71
+ # Convert ActionCable span attributes
72
+ def convert_action_cable_attributes(attributes, rpc_data)
73
+ # RPC system
74
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::RPC::RPC_SYSTEM, 'actioncable')
75
+
76
+ # ActionCable-specific attributes
77
+ add_attribute(attributes, 'rails.actioncable.channel', rpc_data[:call])
78
+ add_attribute(attributes, 'rails.actioncable.call_type', rpc_data[:call_type])
79
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::RPC::RPC_SERVICE, span[:data]&.[](:service) || span[:service])
80
+
81
+ # Extract channel class and action from the call attribute
82
+ # Format can be either "ChannelClass" (for transmit) or "ChannelClass#action" (for action dispatch)
83
+ if rpc_data[:call]
84
+ call_parts = rpc_data[:call].to_s.split('#')
85
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::CODE::CODE_NAMESPACE, call_parts[0])
86
+ add_attribute(attributes, OpenTelemetry::SemConv::Incubating::CODE::CODE_FUNCTION, call_parts[1]) if call_parts[1]
87
+ end
88
+
89
+ # Network peer
90
+ add_attribute(attributes, OpenTelemetry::SemConv::SERVER::SERVER_ADDRESS, rpc_data[:host])
91
+ end
92
+
93
+ def parse_grpc_call(call)
94
+ parts = call.to_s.split('/')
95
+ return [nil, nil] if parts.size < 3
96
+
97
+ [parts[1], parts[2]]
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -2,6 +2,6 @@
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
4
  module Instana
5
- VERSION = "2.7.2"
5
+ VERSION = "2.8.0"
6
6
  VERSION_FULL = "instana-#{VERSION}"
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instana
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.2
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Giacomo Lombardo
@@ -205,6 +205,34 @@ dependencies:
205
205
  - - ">="
206
206
  - !ruby/object:Gem::Version
207
207
  version: '0'
208
+ - !ruby/object:Gem::Dependency
209
+ name: opentelemetry-semantic_conventions
210
+ requirement: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ type: :runtime
216
+ prerelease: false
217
+ version_requirements: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ - !ruby/object:Gem::Dependency
223
+ name: opentelemetry-exporter-otlp
224
+ requirement: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ type: :runtime
230
+ prerelease: false
231
+ version_requirements: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
208
236
  - !ruby/object:Gem::Dependency
209
237
  name: cgi
210
238
  requirement: !ruby/object:Gem::Requirement
@@ -291,6 +319,18 @@ files:
291
319
  - lib/instana/backend/serverless_agent.rb
292
320
  - lib/instana/base.rb
293
321
  - lib/instana/config.rb
322
+ - lib/instana/exporter/otlp/aws_converter.rb
323
+ - lib/instana/exporter/otlp/background_job_converter.rb
324
+ - lib/instana/exporter/otlp/base_converter.rb
325
+ - lib/instana/exporter/otlp/converter_factory.rb
326
+ - lib/instana/exporter/otlp/custom_converter.rb
327
+ - lib/instana/exporter/otlp/database_converter.rb
328
+ - lib/instana/exporter/otlp/graphql_converter.rb
329
+ - lib/instana/exporter/otlp/http_converter.rb
330
+ - lib/instana/exporter/otlp/messaging_converter.rb
331
+ - lib/instana/exporter/otlp/rails_converter.rb
332
+ - lib/instana/exporter/otlp/resource.rb
333
+ - lib/instana/exporter/otlp/rpc_converter.rb
294
334
  - lib/instana/frameworks/cuba.rb
295
335
  - lib/instana/frameworks/rails.rb
296
336
  - lib/instana/frameworks/roda.rb
@@ -376,7 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
376
416
  - !ruby/object:Gem::Version
377
417
  version: '0'
378
418
  requirements: []
379
- rubygems_version: 4.0.16
419
+ rubygems_version: 4.0.18
380
420
  specification_version: 4
381
421
  summary: Ruby Distributed Tracing & Metrics Sensor for Instana
382
422
  test_files: []