launchdarkly-observability 0.2.2 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +53 -7
- data/lib/launchdarkly-observability.rb +9 -0
- data/lib/launchdarkly_observability/instrumentation_log_filter.rb +85 -0
- data/lib/launchdarkly_observability/instrumentations.rb +47 -0
- data/lib/launchdarkly_observability/opentelemetry_config.rb +105 -5
- data/lib/launchdarkly_observability/rails.rb +29 -1
- data/lib/launchdarkly_observability/version.rb +1 -1
- data/lib/launchdarkly_observability.rb +72 -2
- metadata +271 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cd8ffbd0f163139ada7ca0908969dbdc7f5b4b011c76e297bcf6c5c7c50cf438
|
|
4
|
+
data.tar.gz: 72ea24f86f9e22a0af99ee8ea84d175f29d9c8a9dc87451daaa31e770d5d111d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42fe80077d434efa30061e01608781323ab215a36b49d1852326158025837ca04541605534c6d1ed52c707598795ba66889194bf3dac6f2f1aa8d8cc475ae1af
|
|
7
|
+
data.tar.gz: af53b3d86a7ad13b0f47b67a96ef14ae85706f7575c4b15fafe61524c0b1ec00b7ee9d9a8b986ee6ebd0790d50fe33c00cad07d49a1f21b98d06de7c52503708
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.0](https://github.com/launchdarkly/observability-sdk/compare/launchdarkly-observability-ruby/0.2.2...launchdarkly-observability-ruby/0.3.0) (2026-06-29)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **ruby:** boot-time OTel auto-instrumentation; keep it working on Rails 7.0 ([#643](https://github.com/launchdarkly/observability-sdk/issues/643)) ([350d549](https://github.com/launchdarkly/observability-sdk/commit/350d54994ff3745aba3d8f9a4c8602ce18dc6807))
|
|
14
|
+
|
|
8
15
|
## [0.2.2](https://github.com/launchdarkly/observability-sdk/compare/launchdarkly-observability-ruby/0.2.1...launchdarkly-observability-ruby/0.2.2) (2026-06-22)
|
|
9
16
|
|
|
10
17
|
|
data/README.md
CHANGED
|
@@ -38,13 +38,43 @@ The gem includes everything needed for traces and logs out of the box:
|
|
|
38
38
|
- `launchdarkly-server-sdk` >= 8.11.0 (plugin support was added in 8.11.0)
|
|
39
39
|
- `opentelemetry-sdk` ~> 1.4
|
|
40
40
|
- `opentelemetry-exporter-otlp` ~> 0.28
|
|
41
|
-
- `opentelemetry-instrumentation-all` ~> 0.62
|
|
42
41
|
- `opentelemetry-logs-sdk` ~> 0.1
|
|
43
42
|
- `opentelemetry-exporter-otlp-logs` ~> 0.1
|
|
43
|
+
- A curated set of individual `opentelemetry-instrumentation-*` gems (see [Ruby & Rails compatibility](#ruby--rails-compatibility))
|
|
44
44
|
|
|
45
45
|
For metrics support (optional):
|
|
46
46
|
- `opentelemetry-metrics-sdk` ~> 0.1
|
|
47
47
|
|
|
48
|
+
### Ruby & Rails compatibility
|
|
49
|
+
|
|
50
|
+
| Component | Supported |
|
|
51
|
+
|-----------|-----------|
|
|
52
|
+
| Ruby | >= 3.0 |
|
|
53
|
+
| Rails | >= 7.0 (auto-instrumentation); Rack / Sinatra / other Rack apps are unaffected by Rails version |
|
|
54
|
+
|
|
55
|
+
The plugin depends on **individual** `opentelemetry-instrumentation-*` gems rather
|
|
56
|
+
than the `opentelemetry-instrumentation-all` meta-gem. The meta-gem couples every
|
|
57
|
+
instrumentation to a single version, so when the Rails-family instrumentations
|
|
58
|
+
raised their minimum to Rails 7.1, Rails 7.0 apps silently lost *all*
|
|
59
|
+
auto-instrumentation. Listing gems individually keeps the Rails family
|
|
60
|
+
(`opentelemetry-instrumentation-rails`, `-action_pack`, `-active_record`,
|
|
61
|
+
`-active_support`, `-action_view`, `-active_job`, `-action_mailer`,
|
|
62
|
+
`-active_storage`) pinned below the releases that require Rails 7.1, while every
|
|
63
|
+
other instrumentation tracks the latest version. Those pinned releases are still
|
|
64
|
+
compatible with Rails 7.1+, so modern apps are unaffected.
|
|
65
|
+
|
|
66
|
+
If an instrumentation cannot attach on your framework version, the plugin emits a
|
|
67
|
+
**single actionable warning** (instead of a flurry of "failed to install" lines)
|
|
68
|
+
and keeps everything else working — flag-eval spans, manual instrumentation, logs,
|
|
69
|
+
and error capture are unaffected. You can add any other
|
|
70
|
+
`opentelemetry-instrumentation-*` gem to your own Gemfile and it is picked up
|
|
71
|
+
automatically (the plugin activates every instrumentation that is loaded), or pin
|
|
72
|
+
one to a framework-compatible release, e.g.:
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
gem 'opentelemetry-instrumentation-rails', '~> 0.41'
|
|
76
|
+
```
|
|
77
|
+
|
|
48
78
|
## Quick Start
|
|
49
79
|
|
|
50
80
|
### Basic Usage (Non-Rails)
|
|
@@ -92,6 +122,15 @@ Rails.configuration.ld_client = LaunchDarkly::LDClient.new(
|
|
|
92
122
|
at_exit { Rails.configuration.ld_client.close }
|
|
93
123
|
```
|
|
94
124
|
|
|
125
|
+
> **Lazy client initialization:** Creating the LaunchDarkly client during boot
|
|
126
|
+
> (as above) is recommended. If your app instead creates the client lazily —
|
|
127
|
+
> e.g. from a model on first request, after Rails has finished booting — the gem
|
|
128
|
+
> still installs the Rails auto-instrumentation during boot via its Railtie, as
|
|
129
|
+
> long as `LAUNCHDARKLY_SDK_KEY` is set in the environment before Rails boots. If
|
|
130
|
+
> it isn't, the OpenTelemetry Rails instrumentations can't attach (their load
|
|
131
|
+
> hooks have already fired) and the plugin logs a single warning explaining how
|
|
132
|
+
> to fix it.
|
|
133
|
+
|
|
95
134
|
Use in controllers:
|
|
96
135
|
|
|
97
136
|
```ruby
|
|
@@ -145,10 +184,12 @@ LaunchDarklyObservability::Plugin.new(
|
|
|
145
184
|
enable_logs: true, # default: true
|
|
146
185
|
enable_metrics: true, # default: true
|
|
147
186
|
|
|
148
|
-
# Optional: Custom instrumentation configuration
|
|
187
|
+
# Optional: Custom instrumentation configuration. Keys are instrumentation
|
|
188
|
+
# class names; values are that instrumentation's own options (only pass
|
|
189
|
+
# options the installed instrumentation version supports).
|
|
149
190
|
instrumentations: {
|
|
150
|
-
'OpenTelemetry::Instrumentation::
|
|
151
|
-
'OpenTelemetry::Instrumentation::
|
|
191
|
+
'OpenTelemetry::Instrumentation::Rack' => { untraced_endpoints: ['/health'] },
|
|
192
|
+
'OpenTelemetry::Instrumentation::Net::HTTP' => { untraced_hosts: ['internal.example.com'] }
|
|
152
193
|
}
|
|
153
194
|
)
|
|
154
195
|
```
|
|
@@ -308,12 +349,17 @@ This generates:
|
|
|
308
349
|
|
|
309
350
|
By default, the plugin enables OpenTelemetry auto-instrumentation for common Ruby libraries:
|
|
310
351
|
|
|
311
|
-
- **Rails
|
|
312
|
-
- **
|
|
313
|
-
- **Net::HTTP**: Outbound HTTP request tracing
|
|
352
|
+
- **Rails** (and the Action/Active family): Request tracing, route recognition, DB queries, view rendering, jobs
|
|
353
|
+
- **Net::HTTP**, **HTTP**, **Faraday**: Outbound HTTP request tracing
|
|
314
354
|
- **Rack**: Request/response tracing
|
|
355
|
+
- **PG**, **MySQL2**: Database query tracing
|
|
315
356
|
- **Redis**: Cache operation tracing
|
|
316
357
|
- **Sidekiq**: Background job tracing
|
|
358
|
+
- **GraphQL**: Query/field tracing
|
|
359
|
+
- **Sinatra**: Request tracing
|
|
360
|
+
|
|
361
|
+
Need another library instrumented? Add its `opentelemetry-instrumentation-*` gem
|
|
362
|
+
to your Gemfile — the plugin activates every loaded instrumentation automatically.
|
|
317
363
|
|
|
318
364
|
### Customizing Instrumentations
|
|
319
365
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Entry point matching the gem name (`launchdarkly-observability`) so that
|
|
4
|
+
# Bundler.require auto-loads the gem during application boot. Without this,
|
|
5
|
+
# Bundler's default `require 'launchdarkly-observability'` fails (the real entry
|
|
6
|
+
# point is the underscore file) and users must require the gem manually — often
|
|
7
|
+
# in an initializer, which is too late for the Rails Railtie to install
|
|
8
|
+
# auto-instrumentation during boot.
|
|
9
|
+
require_relative 'launchdarkly_observability'
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LaunchDarklyObservability
|
|
4
|
+
# Wraps the OpenTelemetry logger to suppress the per-instrumentation install
|
|
5
|
+
# chatter ("... was successfully installed" / "... failed to install") and
|
|
6
|
+
# record the names of instrumentations that failed to install. Everything else
|
|
7
|
+
# (including level / level=) is delegated to the real logger.
|
|
8
|
+
#
|
|
9
|
+
# OpenTelemetryConfig uses this to replace the SDK's flurry of
|
|
10
|
+
# per-instrumentation warnings with a single actionable summary.
|
|
11
|
+
class InstrumentationLogFilter
|
|
12
|
+
FAILED_PATTERN = /Instrumentation: (\S+) failed to install/
|
|
13
|
+
|
|
14
|
+
# Run the block with OpenTelemetry.logger swapped for a filter that
|
|
15
|
+
# suppresses per-instrumentation install chatter, returning the names of any
|
|
16
|
+
# instrumentations that reported "failed to install". The SDK installs
|
|
17
|
+
# instrumentations after a configure block returns, so wrap the whole
|
|
18
|
+
# OpenTelemetry::SDK.configure call — not just use_all.
|
|
19
|
+
def self.capture_failures
|
|
20
|
+
original = OpenTelemetry.logger
|
|
21
|
+
failed = []
|
|
22
|
+
OpenTelemetry.logger = new(original, failed)
|
|
23
|
+
yield
|
|
24
|
+
failed
|
|
25
|
+
ensure
|
|
26
|
+
OpenTelemetry.logger = original
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Build ONE actionable warning naming the instrumentations that could not
|
|
30
|
+
# attach and how to resolve it. Telemetry that does not depend on those
|
|
31
|
+
# instrumentations (flag-eval spans, manual instrumentation, logs, errors)
|
|
32
|
+
# keeps working regardless.
|
|
33
|
+
def self.failure_warning(failed)
|
|
34
|
+
names = failed.map { |n| n.sub('OpenTelemetry::Instrumentation::', '') }.uniq
|
|
35
|
+
rails = defined?(::Rails) && ::Rails.respond_to?(:version) ? " on Rails #{::Rails.version}" : ''
|
|
36
|
+
"[LaunchDarklyObservability] #{names.size} OpenTelemetry instrumentation(s) could not attach" \
|
|
37
|
+
"#{rails} (Ruby #{RUBY_VERSION}): #{names.join(', ')}. Those libraries will not be " \
|
|
38
|
+
'auto-instrumented; flag-eval spans, manual instrumentation, logs and error capture are ' \
|
|
39
|
+
'unaffected. This usually means an instrumentation gem dropped support for your framework ' \
|
|
40
|
+
'version — upgrade the framework, or pin the instrumentation gem to a compatible release ' \
|
|
41
|
+
'(e.g. gem "opentelemetry-instrumentation-rails", "~> 0.41").'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def initialize(delegate, failed)
|
|
45
|
+
@delegate = delegate
|
|
46
|
+
@failed = failed
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# OTel logs installs via OpenTelemetry.logger.info / .warn, so intercept the
|
|
50
|
+
# level methods (not just #add) — otherwise the calls fall through to
|
|
51
|
+
# method_missing and bypass the filter.
|
|
52
|
+
%i[debug info warn error fatal unknown].each do |level|
|
|
53
|
+
define_method(level) do |message = nil, &block|
|
|
54
|
+
forward?(message || block&.call) ? @delegate.public_send(level, message, &block) : true
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def add(severity, message = nil, progname = nil, &block)
|
|
59
|
+
forward?(message || progname || block&.call) ? @delegate.add(severity, message, progname, &block) : true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def method_missing(name, ...)
|
|
63
|
+
@delegate.send(name, ...)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def respond_to_missing?(name, include_private = false)
|
|
67
|
+
@delegate.respond_to?(name, include_private) || super
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Returns false when the message is install chatter that should be suppressed
|
|
73
|
+
# (recording failed-instrumentation names as a side effect), true when it
|
|
74
|
+
# should be forwarded to the real logger.
|
|
75
|
+
def forward?(message)
|
|
76
|
+
text = message.to_s
|
|
77
|
+
if (match = text.match(FAILED_PATTERN))
|
|
78
|
+
@failed << match[1]
|
|
79
|
+
return false
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
!text.include?('was successfully installed')
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Loads the OpenTelemetry auto-instrumentations the plugin enables by default.
|
|
4
|
+
#
|
|
5
|
+
# We require INDIVIDUAL instrumentation gems instead of
|
|
6
|
+
# `opentelemetry/instrumentation/all` on purpose. The meta-gem couples every
|
|
7
|
+
# instrumentation to a single version, so when the Rails-family instrumentations
|
|
8
|
+
# raised their minimum to Rails 7.1 (opentelemetry-instrumentation-rails 0.42.0),
|
|
9
|
+
# the whole bundle moved with them and Rails 7.0 apps silently lost ALL
|
|
10
|
+
# auto-instrumentation. Requiring gems individually lets the Rails family stay on
|
|
11
|
+
# a Rails-7.0-compatible release (pinned in the gemspec) while everything else
|
|
12
|
+
# tracks the latest.
|
|
13
|
+
#
|
|
14
|
+
# `OpenTelemetry::SDK#use_all` activates every instrumentation that has been
|
|
15
|
+
# loaded, so any additional `opentelemetry-instrumentation-*` gem a consumer adds
|
|
16
|
+
# to their own Gemfile is picked up automatically alongside these defaults.
|
|
17
|
+
|
|
18
|
+
# Rails family. Requiring this pulls every Rails-family instrumentation —
|
|
19
|
+
# action_mailer, action_pack, action_view, active_job, active_record,
|
|
20
|
+
# active_storage and active_support — which is why each is capped in the gemspec
|
|
21
|
+
# (the Rails 7.0 floor has to hold on all of them, not just the rails meta-gem).
|
|
22
|
+
# It also pulls concurrent_ruby, which tracks latest and is required explicitly
|
|
23
|
+
# below.
|
|
24
|
+
require 'opentelemetry/instrumentation/rails'
|
|
25
|
+
|
|
26
|
+
# Common non-Rails instrumentations (latest; see gemspec for version policy).
|
|
27
|
+
# Note the require paths differ from gem names in places, e.g. the
|
|
28
|
+
# opentelemetry-instrumentation-net_http gem is required as 'net/http'.
|
|
29
|
+
%w[
|
|
30
|
+
concurrent_ruby
|
|
31
|
+
faraday
|
|
32
|
+
graphql
|
|
33
|
+
http
|
|
34
|
+
mysql2
|
|
35
|
+
net/http
|
|
36
|
+
pg
|
|
37
|
+
rack
|
|
38
|
+
redis
|
|
39
|
+
sidekiq
|
|
40
|
+
sinatra
|
|
41
|
+
].each do |path|
|
|
42
|
+
require "opentelemetry/instrumentation/#{path}"
|
|
43
|
+
rescue LoadError => e
|
|
44
|
+
# A default instrumentation gem is unexpectedly absent. Don't abort the whole
|
|
45
|
+
# plugin over one missing instrumentation; the rest still load.
|
|
46
|
+
warn "[LaunchDarklyObservability] optional instrumentation '#{path}' not loaded: #{e.message}"
|
|
47
|
+
end
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
require 'opentelemetry/sdk'
|
|
4
4
|
require 'opentelemetry/exporter/otlp'
|
|
5
|
-
require 'opentelemetry/instrumentation/all'
|
|
6
5
|
require 'opentelemetry/semantic_conventions'
|
|
6
|
+
require_relative 'instrumentations'
|
|
7
|
+
require_relative 'instrumentation_log_filter'
|
|
7
8
|
|
|
8
9
|
module LaunchDarklyObservability
|
|
9
10
|
# Configures OpenTelemetry SDK with appropriate providers and exporters
|
|
@@ -61,6 +62,8 @@ module LaunchDarklyObservability
|
|
|
61
62
|
def configure
|
|
62
63
|
return if @configured
|
|
63
64
|
|
|
65
|
+
warn_ignored_boot_options if LaunchDarklyObservability.instrumentation_installed_at_boot?
|
|
66
|
+
|
|
64
67
|
configure_traces if @options.fetch(:enable_traces, true)
|
|
65
68
|
configure_logs if @options.fetch(:enable_logs, true)
|
|
66
69
|
configure_metrics if @options.fetch(:enable_metrics, true)
|
|
@@ -70,6 +73,20 @@ module LaunchDarklyObservability
|
|
|
70
73
|
@configured = true
|
|
71
74
|
end
|
|
72
75
|
|
|
76
|
+
# Install the SDK tracer provider and auto-instrumentation WITHOUT exporters.
|
|
77
|
+
#
|
|
78
|
+
# Called from the Rails Railtie during boot so the Rails-family
|
|
79
|
+
# instrumentations (which patch via ActiveSupport.on_load hooks that fire
|
|
80
|
+
# during boot) attach even when the LaunchDarkly client — and therefore
|
|
81
|
+
# #register / #configure — is created lazily afterward. Exporters are added
|
|
82
|
+
# later by #configure_traces when the client registers the plugin.
|
|
83
|
+
def install_instrumentation_only
|
|
84
|
+
configure_sdk_capturing_failures do |c|
|
|
85
|
+
c.resource = create_resource
|
|
86
|
+
configure_instrumentations(c)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
73
90
|
# Flush all pending telemetry data
|
|
74
91
|
def flush
|
|
75
92
|
OpenTelemetry.tracer_provider&.force_flush
|
|
@@ -90,24 +107,93 @@ module LaunchDarklyObservability
|
|
|
90
107
|
|
|
91
108
|
private
|
|
92
109
|
|
|
93
|
-
# Configure OpenTelemetry traces with OTLP exporter
|
|
110
|
+
# Configure OpenTelemetry traces with OTLP exporter.
|
|
111
|
+
#
|
|
112
|
+
# If auto-instrumentation was already installed during Rails boot (see
|
|
113
|
+
# LaunchDarklyObservability.install_rails_instrumentation), the SDK tracer
|
|
114
|
+
# provider already exists with instrumentation attached — so we add the OTLP
|
|
115
|
+
# span exporter and refresh its resource, rather than re-running
|
|
116
|
+
# OpenTelemetry::SDK.configure (which would replace the provider and, in the
|
|
117
|
+
# lazy-init case, drop the Rails-family instrumentation that can only attach
|
|
118
|
+
# during boot).
|
|
94
119
|
def configure_traces
|
|
95
|
-
|
|
120
|
+
if LaunchDarklyObservability.instrumentation_installed_at_boot?
|
|
121
|
+
provider = OpenTelemetry.tracer_provider
|
|
122
|
+
provider.add_span_processor(create_batch_span_processor)
|
|
123
|
+
|
|
124
|
+
# The boot-time install built the provider's resource before this plugin
|
|
125
|
+
# (and its service_name/service_version options) existed, so it carries
|
|
126
|
+
# the inferred service name. configure_logs/configure_metrics below build
|
|
127
|
+
# a fresh resource from those options; without updating the trace
|
|
128
|
+
# resource too, spans would report a different service identity than logs
|
|
129
|
+
# and metrics. OTel exposes no resource setter, but the provider reads
|
|
130
|
+
# @resource live when creating each span — so update it in place.
|
|
131
|
+
provider.instance_variable_set(:@resource, create_resource)
|
|
132
|
+
return
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
configure_sdk_capturing_failures do |c|
|
|
96
136
|
c.resource = create_resource
|
|
97
137
|
c.add_span_processor(create_batch_span_processor)
|
|
98
138
|
|
|
99
139
|
# Enable auto-instrumentation
|
|
100
140
|
configure_instrumentations(c)
|
|
101
141
|
end
|
|
142
|
+
|
|
143
|
+
warn_if_rails_instrumentation_missed
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Emit a single actionable warning when the plugin is registered after Rails
|
|
147
|
+
# has finished booting and boot-time instrumentation install did not run
|
|
148
|
+
# (e.g. LAUNCHDARKLY_SDK_KEY was not set in the environment at boot). In that
|
|
149
|
+
# case the OTel Rails-family instrumentations log a flurry of
|
|
150
|
+
# "failed to install" warnings because their load hooks have already fired.
|
|
151
|
+
def warn_if_rails_instrumentation_missed
|
|
152
|
+
return unless defined?(::Rails) && ::Rails.respond_to?(:application)
|
|
153
|
+
return unless ::Rails.application.respond_to?(:initialized?) && ::Rails.application.initialized?
|
|
154
|
+
|
|
155
|
+
warn '[LaunchDarklyObservability] The LaunchDarkly client was created after Rails finished ' \
|
|
156
|
+
'booting, so the Rails auto-instrumentation (ActionPack, ActiveRecord, ...) could not be ' \
|
|
157
|
+
'installed. To enable it, set LAUNCHDARKLY_SDK_KEY in the environment before Rails boots, ' \
|
|
158
|
+
'or create the LaunchDarkly client from a config/initializer.'
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Emit a single actionable warning when the client is created lazily (so
|
|
162
|
+
# instrumentation was installed at boot, before this plugin existed) but was
|
|
163
|
+
# given options that can only take effect at install time. Custom
|
|
164
|
+
# `instrumentations` config and `enable_traces: false` cannot be applied
|
|
165
|
+
# retroactively: an OTel instrumentation patches its library during boot via
|
|
166
|
+
# ActiveSupport.on_load hooks and cannot be reconfigured or detached
|
|
167
|
+
# afterward. (service_name/service_version are the exception — the trace
|
|
168
|
+
# resource is refreshed in #configure_traces because it is read live per
|
|
169
|
+
# span.) To honor these options, create the client from a config/initializer
|
|
170
|
+
# so #configure runs during boot with them.
|
|
171
|
+
def warn_ignored_boot_options
|
|
172
|
+
ignored = []
|
|
173
|
+
ignored << 'instrumentations' unless @options.fetch(:instrumentations, {}).empty?
|
|
174
|
+
ignored << 'enable_traces: false' unless @options.fetch(:enable_traces, true)
|
|
175
|
+
return if ignored.empty?
|
|
176
|
+
|
|
177
|
+
warn '[LaunchDarklyObservability] Rails auto-instrumentation was installed at boot, so these ' \
|
|
178
|
+
"plugin option(s) cannot be applied and will be ignored: #{ignored.join(', ')}. Instrumentations " \
|
|
179
|
+
'attach during boot, before the client exists, and cannot be reconfigured or detached afterward. ' \
|
|
180
|
+
'To apply these options, create the LaunchDarkly client from a config/initializer instead of lazily.'
|
|
102
181
|
end
|
|
103
182
|
|
|
104
183
|
# Configure auto-instrumentations with sensible defaults.
|
|
105
184
|
# User-provided instrumentation config is merged on top of defaults,
|
|
106
185
|
# so users only need to specify the instrumentations they want to override.
|
|
107
186
|
def configure_instrumentations(config)
|
|
187
|
+
# Only pass options that the instrumentations actually accept. Unknown
|
|
188
|
+
# options are not fatal but emit a warning on every boot ("ignored the
|
|
189
|
+
# following unknown configuration options [...]"):
|
|
190
|
+
# - `enable_recognize_route` is not an option on the Rails, Rack, or
|
|
191
|
+
# ActionPack instrumentations; route-based span naming (http.route) is
|
|
192
|
+
# handled automatically by the ActionPack instrumentation.
|
|
193
|
+
# - ActiveRecord has no `db_statement` option; SQL capture comes from the
|
|
194
|
+
# database adapter instrumentations (Mysql2, PG, ...) which default to
|
|
195
|
+
# obfuscating statements.
|
|
108
196
|
defaults = {
|
|
109
|
-
'OpenTelemetry::Instrumentation::Rails' => { enable_recognize_route: true },
|
|
110
|
-
'OpenTelemetry::Instrumentation::ActiveRecord' => { db_statement: :include },
|
|
111
197
|
'OpenTelemetry::Instrumentation::Net::HTTP' => { untraced_hosts: [] },
|
|
112
198
|
'OpenTelemetry::Instrumentation::Rack' => { untraced_endpoints: ['/health', '/healthz', '/ready'] }
|
|
113
199
|
}
|
|
@@ -118,6 +204,20 @@ module LaunchDarklyObservability
|
|
|
118
204
|
warn "[LaunchDarklyObservability] Error configuring instrumentations: #{e.message}"
|
|
119
205
|
end
|
|
120
206
|
|
|
207
|
+
# Run an OpenTelemetry::SDK.configure block, replacing the SDK's
|
|
208
|
+
# per-instrumentation install logging (a flurry of "Instrumentation: <X>
|
|
209
|
+
# failed to install" WARN lines when instrumentations are incompatible with
|
|
210
|
+
# the framework version — e.g. the Rails family below its Rails floor) with a
|
|
211
|
+
# single actionable summary. The SDK installs the instrumentations AFTER the
|
|
212
|
+
# configure block returns (use_all only queues them), so the filter wraps the
|
|
213
|
+
# whole call, not just use_all.
|
|
214
|
+
def configure_sdk_capturing_failures(&block)
|
|
215
|
+
failed = InstrumentationLogFilter.capture_failures do
|
|
216
|
+
OpenTelemetry::SDK.configure(&block)
|
|
217
|
+
end
|
|
218
|
+
warn InstrumentationLogFilter.failure_warning(failed) unless failed.empty?
|
|
219
|
+
end
|
|
220
|
+
|
|
121
221
|
# Configure OpenTelemetry logs with OTLP exporter.
|
|
122
222
|
# The log gems are runtime dependencies, so require should always succeed.
|
|
123
223
|
# If anything goes wrong, we warn once and leave traces unaffected.
|
|
@@ -127,8 +127,22 @@ module LaunchDarklyObservability
|
|
|
127
127
|
warn "[LaunchDarklyObservability] Could not attach log bridge to Rails.logger: #{e.message}"
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
+
# The availability check is inlined here rather than delegating to
|
|
131
|
+
# LaunchDarklyObservability.otel_logger_provider_available? on purpose.
|
|
132
|
+
# rails.rb is required from launchdarkly_observability.rb *before* that
|
|
133
|
+
# file's `class << self` block (which defines the module method) has run.
|
|
134
|
+
# When the gem is lazily required after Rails has booted, the
|
|
135
|
+
# `config.after_initialize` hook above executes synchronously while this
|
|
136
|
+
# file is still loading, so the module method does not exist yet and the
|
|
137
|
+
# delegation raised "undefined method `otel_logger_provider_available?'".
|
|
130
138
|
def otel_logger_provider_available?
|
|
131
|
-
|
|
139
|
+
# `defined?` returns nil (not false) when the constant is absent, so
|
|
140
|
+
# guard first and return an explicit boolean — callers (and the
|
|
141
|
+
# railtie test) expect true/false, never nil.
|
|
142
|
+
return false unless defined?(OpenTelemetry::SDK::Logs::LoggerProvider)
|
|
143
|
+
|
|
144
|
+
OpenTelemetry.respond_to?(:logger_provider) &&
|
|
145
|
+
OpenTelemetry.logger_provider.is_a?(OpenTelemetry::SDK::Logs::LoggerProvider)
|
|
132
146
|
end
|
|
133
147
|
end
|
|
134
148
|
|
|
@@ -136,6 +150,20 @@ module LaunchDarklyObservability
|
|
|
136
150
|
app.middleware.insert_before(0, LaunchDarklyObservability::Middleware)
|
|
137
151
|
end
|
|
138
152
|
|
|
153
|
+
# Install OpenTelemetry auto-instrumentation during boot so the Rails-family
|
|
154
|
+
# instrumentations attach even when the LaunchDarkly client is created
|
|
155
|
+
# lazily (after boot) rather than in an initializer.
|
|
156
|
+
#
|
|
157
|
+
# Runs `after: :load_config_initializers` on purpose: if the client was
|
|
158
|
+
# created in a config/initializer during boot, it has already configured
|
|
159
|
+
# OpenTelemetry (with the user's options), so `install_rails_instrumentation`
|
|
160
|
+
# detects the existing provider and no-ops. Otherwise it installs the
|
|
161
|
+
# default instrumentation now — still during boot, before eager loading and
|
|
162
|
+
# the ActiveSupport.on_load hooks that the instrumentations depend on.
|
|
163
|
+
initializer 'launchdarkly_observability.install_instrumentation', after: :load_config_initializers do
|
|
164
|
+
LaunchDarklyObservability.install_rails_instrumentation
|
|
165
|
+
end
|
|
166
|
+
|
|
139
167
|
config.after_initialize do
|
|
140
168
|
if defined?(ActionController::Base)
|
|
141
169
|
ActionController::Base.include(LaunchDarklyObservability::ControllerHelpers)
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
require 'opentelemetry/sdk'
|
|
4
4
|
require 'opentelemetry/exporter/otlp'
|
|
5
|
-
require 'opentelemetry/instrumentation/all'
|
|
6
5
|
require 'opentelemetry/semantic_conventions'
|
|
7
6
|
|
|
7
|
+
# Loads the individual OpenTelemetry instrumentation gems (not the
|
|
8
|
+
# opentelemetry-instrumentation-all meta-gem) so the Rails family can be pinned
|
|
9
|
+
# for old-Rails compatibility independently of everything else.
|
|
10
|
+
require_relative 'launchdarkly_observability/instrumentations'
|
|
11
|
+
|
|
8
12
|
require_relative 'launchdarkly_observability/version'
|
|
9
13
|
require_relative 'launchdarkly_observability/hook'
|
|
10
14
|
require_relative 'launchdarkly_observability/opentelemetry_config'
|
|
@@ -13,7 +17,13 @@ require_relative 'launchdarkly_observability/source_context'
|
|
|
13
17
|
|
|
14
18
|
require_relative 'launchdarkly_observability/middleware'
|
|
15
19
|
require_relative 'launchdarkly_observability/otel_log_bridge'
|
|
16
|
-
|
|
20
|
+
|
|
21
|
+
# NOTE: rails.rb is required at the *bottom* of this file, after the
|
|
22
|
+
# LaunchDarklyObservability module body has been fully defined. Its Railtie
|
|
23
|
+
# registers a `config.after_initialize` hook that runs synchronously when the
|
|
24
|
+
# gem is required lazily after Rails has booted. That hook references module
|
|
25
|
+
# constants and `class << self` methods, so they must already exist when the
|
|
26
|
+
# require runs. See the require at the end of this file.
|
|
17
27
|
|
|
18
28
|
module LaunchDarklyObservability
|
|
19
29
|
# Default OTLP endpoint for LaunchDarkly Observability
|
|
@@ -170,6 +180,60 @@ module LaunchDarklyObservability
|
|
|
170
180
|
@instance = nil
|
|
171
181
|
end
|
|
172
182
|
|
|
183
|
+
# @return [Boolean] whether auto-instrumentation was installed during Rails
|
|
184
|
+
# boot by {.install_rails_instrumentation}. When true, the plugin attaches
|
|
185
|
+
# exporters to the existing tracer provider at register time instead of
|
|
186
|
+
# reconfiguring it.
|
|
187
|
+
def instrumentation_installed_at_boot?
|
|
188
|
+
@instrumentation_installed_at_boot == true
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Install OpenTelemetry auto-instrumentation during Rails boot.
|
|
192
|
+
#
|
|
193
|
+
# The OTel Rails-family instrumentations (ActionPack, ActiveRecord, ...) patch
|
|
194
|
+
# via ActiveSupport.on_load hooks that fire while Rails is booting. If the
|
|
195
|
+
# LaunchDarkly client is created lazily (e.g. from a model on first request),
|
|
196
|
+
# the plugin's #register runs after those hooks have fired and the
|
|
197
|
+
# instrumentations report "failed to install". The Rails Railtie calls this
|
|
198
|
+
# during boot so instrumentation attaches regardless of when the client is
|
|
199
|
+
# created. Exporters are still configured later, when the client registers
|
|
200
|
+
# the plugin.
|
|
201
|
+
#
|
|
202
|
+
# The project_id needed for the resource is resolved from the
|
|
203
|
+
# LAUNCHDARKLY_SDK_KEY environment variable, which is present at boot in the
|
|
204
|
+
# common case even when the client object is created lazily. If it cannot be
|
|
205
|
+
# resolved, instrumentation is left to #register (which warns if it then runs
|
|
206
|
+
# after boot).
|
|
207
|
+
#
|
|
208
|
+
# @param project_id [String, nil] explicit project id; falls back to ENV
|
|
209
|
+
# @param otlp_endpoint [String] OTLP endpoint (only relevant for exporters)
|
|
210
|
+
# @param options [Hash] additional OpenTelemetryConfig options
|
|
211
|
+
# @return [Boolean] whether instrumentation was installed
|
|
212
|
+
def install_rails_instrumentation(project_id: nil, otlp_endpoint: DEFAULT_ENDPOINT, **options)
|
|
213
|
+
return false if @instrumentation_installed_at_boot
|
|
214
|
+
|
|
215
|
+
project_id ||= ENV.fetch('LAUNCHDARKLY_SDK_KEY', nil)
|
|
216
|
+
return false if project_id.nil? || project_id.empty?
|
|
217
|
+
|
|
218
|
+
# If something already configured an SDK tracer provider (e.g. the client
|
|
219
|
+
# was created in a config/initializer during boot), don't reconfigure —
|
|
220
|
+
# that would replace the provider and drop its exporters.
|
|
221
|
+
return false if OpenTelemetry.tracer_provider.is_a?(OpenTelemetry::SDK::Trace::TracerProvider)
|
|
222
|
+
|
|
223
|
+
OpenTelemetryConfig.new(project_id: project_id, otlp_endpoint: otlp_endpoint, **options)
|
|
224
|
+
.install_instrumentation_only
|
|
225
|
+
@instrumentation_installed_at_boot = true
|
|
226
|
+
rescue StandardError => e
|
|
227
|
+
warn "[LaunchDarklyObservability] Could not install Rails auto-instrumentation at boot: #{e.message}"
|
|
228
|
+
false
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Reset boot-instrumentation state. Intended for tests only.
|
|
232
|
+
# @api private
|
|
233
|
+
def reset_instrumentation_state!
|
|
234
|
+
@instrumentation_installed_at_boot = false
|
|
235
|
+
end
|
|
236
|
+
|
|
173
237
|
private
|
|
174
238
|
|
|
175
239
|
def otel_logger_provider_available?
|
|
@@ -179,3 +243,9 @@ module LaunchDarklyObservability
|
|
|
179
243
|
end
|
|
180
244
|
end
|
|
181
245
|
end
|
|
246
|
+
|
|
247
|
+
# Required last, on purpose: the Rails Railtie's `config.after_initialize` hook
|
|
248
|
+
# can run synchronously during this require (lazy require after Rails has
|
|
249
|
+
# booted), and it depends on the fully-defined LaunchDarklyObservability module
|
|
250
|
+
# above. See the note next to the other require_relative calls at the top.
|
|
251
|
+
require_relative 'launchdarkly_observability/rails'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: launchdarkly-observability
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LaunchDarkly
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: launchdarkly-server-sdk
|
|
@@ -39,33 +39,291 @@ dependencies:
|
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0.28'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: opentelemetry-
|
|
42
|
+
name: opentelemetry-sdk
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '1.4'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '1.4'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: opentelemetry-
|
|
56
|
+
name: opentelemetry-instrumentation-action_mailer
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - "<"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '0.8'
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - "<"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
68
|
+
version: '0.8'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: opentelemetry-instrumentation-action_pack
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "<"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.18'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "<"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.18'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: opentelemetry-instrumentation-action_view
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "<"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.13'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "<"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.13'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: opentelemetry-instrumentation-active_job
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "<"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0.12'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "<"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0.12'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: opentelemetry-instrumentation-active_record
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "<"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0.13'
|
|
118
|
+
type: :runtime
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "<"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0.13'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: opentelemetry-instrumentation-active_storage
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "<"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.5'
|
|
132
|
+
type: :runtime
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "<"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.5'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: opentelemetry-instrumentation-active_support
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "<"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.12'
|
|
146
|
+
type: :runtime
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "<"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0.12'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: opentelemetry-instrumentation-rails
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0.34'
|
|
160
|
+
- - "<"
|
|
161
|
+
- !ruby/object:Gem::Version
|
|
162
|
+
version: '0.42'
|
|
163
|
+
type: :runtime
|
|
164
|
+
prerelease: false
|
|
165
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
166
|
+
requirements:
|
|
167
|
+
- - ">="
|
|
168
|
+
- !ruby/object:Gem::Version
|
|
169
|
+
version: '0.34'
|
|
170
|
+
- - "<"
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: '0.42'
|
|
173
|
+
- !ruby/object:Gem::Dependency
|
|
174
|
+
name: opentelemetry-instrumentation-concurrent_ruby
|
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0.21'
|
|
180
|
+
type: :runtime
|
|
181
|
+
prerelease: false
|
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '0.21'
|
|
187
|
+
- !ruby/object:Gem::Dependency
|
|
188
|
+
name: opentelemetry-instrumentation-faraday
|
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - ">="
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '0.24'
|
|
194
|
+
type: :runtime
|
|
195
|
+
prerelease: false
|
|
196
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
197
|
+
requirements:
|
|
198
|
+
- - ">="
|
|
199
|
+
- !ruby/object:Gem::Version
|
|
200
|
+
version: '0.24'
|
|
201
|
+
- !ruby/object:Gem::Dependency
|
|
202
|
+
name: opentelemetry-instrumentation-graphql
|
|
203
|
+
requirement: !ruby/object:Gem::Requirement
|
|
204
|
+
requirements:
|
|
205
|
+
- - ">="
|
|
206
|
+
- !ruby/object:Gem::Version
|
|
207
|
+
version: '0.28'
|
|
208
|
+
type: :runtime
|
|
209
|
+
prerelease: false
|
|
210
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '0.28'
|
|
215
|
+
- !ruby/object:Gem::Dependency
|
|
216
|
+
name: opentelemetry-instrumentation-http
|
|
217
|
+
requirement: !ruby/object:Gem::Requirement
|
|
218
|
+
requirements:
|
|
219
|
+
- - ">="
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0.23'
|
|
222
|
+
type: :runtime
|
|
223
|
+
prerelease: false
|
|
224
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
225
|
+
requirements:
|
|
226
|
+
- - ">="
|
|
227
|
+
- !ruby/object:Gem::Version
|
|
228
|
+
version: '0.23'
|
|
229
|
+
- !ruby/object:Gem::Dependency
|
|
230
|
+
name: opentelemetry-instrumentation-mysql2
|
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
|
232
|
+
requirements:
|
|
233
|
+
- - ">="
|
|
234
|
+
- !ruby/object:Gem::Version
|
|
235
|
+
version: '0.28'
|
|
236
|
+
type: :runtime
|
|
237
|
+
prerelease: false
|
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
239
|
+
requirements:
|
|
240
|
+
- - ">="
|
|
241
|
+
- !ruby/object:Gem::Version
|
|
242
|
+
version: '0.28'
|
|
243
|
+
- !ruby/object:Gem::Dependency
|
|
244
|
+
name: opentelemetry-instrumentation-net_http
|
|
245
|
+
requirement: !ruby/object:Gem::Requirement
|
|
246
|
+
requirements:
|
|
247
|
+
- - ">="
|
|
248
|
+
- !ruby/object:Gem::Version
|
|
249
|
+
version: '0.22'
|
|
250
|
+
type: :runtime
|
|
251
|
+
prerelease: false
|
|
252
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
253
|
+
requirements:
|
|
254
|
+
- - ">="
|
|
255
|
+
- !ruby/object:Gem::Version
|
|
256
|
+
version: '0.22'
|
|
257
|
+
- !ruby/object:Gem::Dependency
|
|
258
|
+
name: opentelemetry-instrumentation-pg
|
|
259
|
+
requirement: !ruby/object:Gem::Requirement
|
|
260
|
+
requirements:
|
|
261
|
+
- - ">="
|
|
262
|
+
- !ruby/object:Gem::Version
|
|
263
|
+
version: '0.29'
|
|
264
|
+
type: :runtime
|
|
265
|
+
prerelease: false
|
|
266
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
267
|
+
requirements:
|
|
268
|
+
- - ">="
|
|
269
|
+
- !ruby/object:Gem::Version
|
|
270
|
+
version: '0.29'
|
|
271
|
+
- !ruby/object:Gem::Dependency
|
|
272
|
+
name: opentelemetry-instrumentation-rack
|
|
273
|
+
requirement: !ruby/object:Gem::Requirement
|
|
274
|
+
requirements:
|
|
275
|
+
- - ">="
|
|
276
|
+
- !ruby/object:Gem::Version
|
|
277
|
+
version: '0.24'
|
|
278
|
+
type: :runtime
|
|
279
|
+
prerelease: false
|
|
280
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
281
|
+
requirements:
|
|
282
|
+
- - ">="
|
|
283
|
+
- !ruby/object:Gem::Version
|
|
284
|
+
version: '0.24'
|
|
285
|
+
- !ruby/object:Gem::Dependency
|
|
286
|
+
name: opentelemetry-instrumentation-redis
|
|
287
|
+
requirement: !ruby/object:Gem::Requirement
|
|
288
|
+
requirements:
|
|
289
|
+
- - ">="
|
|
290
|
+
- !ruby/object:Gem::Version
|
|
291
|
+
version: '0.25'
|
|
292
|
+
type: :runtime
|
|
293
|
+
prerelease: false
|
|
294
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
295
|
+
requirements:
|
|
296
|
+
- - ">="
|
|
297
|
+
- !ruby/object:Gem::Version
|
|
298
|
+
version: '0.25'
|
|
299
|
+
- !ruby/object:Gem::Dependency
|
|
300
|
+
name: opentelemetry-instrumentation-sidekiq
|
|
301
|
+
requirement: !ruby/object:Gem::Requirement
|
|
302
|
+
requirements:
|
|
303
|
+
- - ">="
|
|
304
|
+
- !ruby/object:Gem::Version
|
|
305
|
+
version: '0.25'
|
|
306
|
+
type: :runtime
|
|
307
|
+
prerelease: false
|
|
308
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
309
|
+
requirements:
|
|
310
|
+
- - ">="
|
|
311
|
+
- !ruby/object:Gem::Version
|
|
312
|
+
version: '0.25'
|
|
313
|
+
- !ruby/object:Gem::Dependency
|
|
314
|
+
name: opentelemetry-instrumentation-sinatra
|
|
315
|
+
requirement: !ruby/object:Gem::Requirement
|
|
316
|
+
requirements:
|
|
317
|
+
- - ">="
|
|
318
|
+
- !ruby/object:Gem::Version
|
|
319
|
+
version: '0.24'
|
|
320
|
+
type: :runtime
|
|
321
|
+
prerelease: false
|
|
322
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
323
|
+
requirements:
|
|
324
|
+
- - ">="
|
|
325
|
+
- !ruby/object:Gem::Version
|
|
326
|
+
version: '0.24'
|
|
69
327
|
- !ruby/object:Gem::Dependency
|
|
70
328
|
name: opentelemetry-semantic_conventions
|
|
71
329
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -161,8 +419,11 @@ files:
|
|
|
161
419
|
- CHANGELOG.md
|
|
162
420
|
- LICENSE.txt
|
|
163
421
|
- README.md
|
|
422
|
+
- lib/launchdarkly-observability.rb
|
|
164
423
|
- lib/launchdarkly_observability.rb
|
|
165
424
|
- lib/launchdarkly_observability/hook.rb
|
|
425
|
+
- lib/launchdarkly_observability/instrumentation_log_filter.rb
|
|
426
|
+
- lib/launchdarkly_observability/instrumentations.rb
|
|
166
427
|
- lib/launchdarkly_observability/middleware.rb
|
|
167
428
|
- lib/launchdarkly_observability/opentelemetry_config.rb
|
|
168
429
|
- lib/launchdarkly_observability/otel_log_bridge.rb
|