openfeature-otel-hook 0.1.3
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +4 -0
- data/.rubocop.yml +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +56 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +118 -0
- data/README.md +66 -0
- data/Rakefile +9 -0
- data/lib/openfeature/otel/hook/metrics_hook.rb +80 -0
- data/lib/openfeature/otel/hook/traces_hook.rb +33 -0
- data/lib/openfeature/otel/hook/version.rb +9 -0
- data/lib/openfeature/otel/hook.rb +5 -0
- data/openfeature-otel-hook.gemspec +40 -0
- metadata +200 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 15068afb1cca6261319c3d07accc017b99e301b58faf7d45acf3d22fbb88e9f0
|
|
4
|
+
data.tar.gz: 58358d038c392cd2c4db6e7b6512b2e137279b54bf39de6ea076f1d33c9a0a72
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bc3bb5645d891f8f698ac0a9f6c0fcab6d0aaa92ce41ef0f70ac3546193032c84273d18d39b4bfb8c6ee1eba9f5385520f15788b9cf58b473ccc7551b56720ee
|
|
7
|
+
data.tar.gz: 11e77c8f5f426dc349d923a1c807ad867754005db4d88151f931eaa8aae79a2da0e58e93425353e9492a8bbc4834e107b073d9d29fad76db42a3d0c38f2979b3
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
inherit_from: ../../shared_config/.rubocop.yml
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.0.9
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.3](https://github.com/open-feature/ruby-sdk-contrib/compare/openfeature-otel-hook/v0.1.2...openfeature-otel-hook/v0.1.3) (2026-11-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### 🐛 Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **flagd-provider:** update fractional targeting test expectations for flagd v0.15.4 ([#166](https://github.com/open-feature/ruby-sdk-contrib/issues/166)) ([f3ea5cb](https://github.com/open-feature/ruby-sdk-contrib/commit/f3ea5cbd372b11942109c1ed1577d8bb2f577711))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### 🧹 Chore
|
|
12
|
+
|
|
13
|
+
* **deps:** lock file maintenance ([#234](https://github.com/open-feature/ruby-sdk-contrib/issues/234)) ([402c691](https://github.com/open-feature/ruby-sdk-contrib/commit/402c6913534128605eb2bd4cad870c31cff2d7c0))
|
|
14
|
+
* **deps:** lock file maintenance ([#242](https://github.com/open-feature/ruby-sdk-contrib/issues/242)) ([788b51c](https://github.com/open-feature/ruby-sdk-contrib/commit/788b51c34300d0654fa837bfd15a86d56a7ac142))
|
|
15
|
+
* **deps:** lock file maintenance ([#248](https://github.com/open-feature/ruby-sdk-contrib/issues/248)) ([24d69f1](https://github.com/open-feature/ruby-sdk-contrib/commit/24d69f1ce10a461a9e86971ffa3d579394894145))
|
|
16
|
+
* **deps:** lock file maintenance ([#251](https://github.com/open-feature/ruby-sdk-contrib/issues/251)) ([a351265](https://github.com/open-feature/ruby-sdk-contrib/commit/a3512650043f83c8be7e224d9797c639ddc3a4f0))
|
|
17
|
+
* **deps:** lock file maintenance ([#259](https://github.com/open-feature/ruby-sdk-contrib/issues/259)) ([ffe7663](https://github.com/open-feature/ruby-sdk-contrib/commit/ffe7663ffef575202abe21b94f196076a49b3ad1))
|
|
18
|
+
* **deps:** lock file maintenance ([#277](https://github.com/open-feature/ruby-sdk-contrib/issues/277)) ([857f47f](https://github.com/open-feature/ruby-sdk-contrib/commit/857f47f679bfa29454dd899ef40040c08a69dd13))
|
|
19
|
+
* **deps:** lock file maintenance ([#284](https://github.com/open-feature/ruby-sdk-contrib/issues/284)) ([73f1ac8](https://github.com/open-feature/ruby-sdk-contrib/commit/73f1ac8372d698d0c913383b4c923b41620bc3be))
|
|
20
|
+
* **deps:** update dependency ruby to v4 ([#124](https://github.com/open-feature/ruby-sdk-contrib/issues/124)) ([f6fdaf6](https://github.com/open-feature/ruby-sdk-contrib/commit/f6fdaf6c304f730960e379ec7042657916a7ae44))
|
|
21
|
+
* **deps:** update dependency ruby to v4.0.3 ([#161](https://github.com/open-feature/ruby-sdk-contrib/issues/161)) ([538486e](https://github.com/open-feature/ruby-sdk-contrib/commit/538486e8b6a42979c35a251f12e94292f412f8a0))
|
|
22
|
+
* **deps:** update dependency ruby to v4.0.4 ([#170](https://github.com/open-feature/ruby-sdk-contrib/issues/170)) ([0bde1a8](https://github.com/open-feature/ruby-sdk-contrib/commit/0bde1a85b475764deb22b56d34e1e333a809ec37))
|
|
23
|
+
* **deps:** update dependency ruby to v4.0.5 ([#173](https://github.com/open-feature/ruby-sdk-contrib/issues/173)) ([d410cee](https://github.com/open-feature/ruby-sdk-contrib/commit/d410ceeed7c77ea2626d009c052ed53d2621e511))
|
|
24
|
+
* **deps:** update dependency ruby to v4.0.6 ([#194](https://github.com/open-feature/ruby-sdk-contrib/issues/194)) ([c786a79](https://github.com/open-feature/ruby-sdk-contrib/commit/c786a7972924b7feee9321fd20062bb17ca2caea))
|
|
25
|
+
* **deps:** update dependency ruby to v4.0.7 ([#219](https://github.com/open-feature/ruby-sdk-contrib/issues/219)) ([74e1acb](https://github.com/open-feature/ruby-sdk-contrib/commit/74e1acb0bab6d20d74107da95a6472daff0c0da4))
|
|
26
|
+
* **deps:** update dependency ruby to v4.0.8 ([#272](https://github.com/open-feature/ruby-sdk-contrib/issues/272)) ([003d193](https://github.com/open-feature/ruby-sdk-contrib/commit/003d193e84e4c27639405d2cfe83680f0aa0c21b))
|
|
27
|
+
* **deps:** update dependency ruby to v4.0.9 ([#276](https://github.com/open-feature/ruby-sdk-contrib/issues/276)) ([feaca24](https://github.com/open-feature/ruby-sdk-contrib/commit/feaca24ef5f68442132750137c73a49780eabc3a))
|
|
28
|
+
* resolve open dependabot security alerts ([#180](https://github.com/open-feature/ruby-sdk-contrib/issues/180)) ([b96958f](https://github.com/open-feature/ruby-sdk-contrib/commit/b96958ffd4603caf8b64dcf432a729a44289afc0))
|
|
29
|
+
* resolve open dependabot security alerts ([#203](https://github.com/open-feature/ruby-sdk-contrib/issues/203)) ([a1ab3a3](https://github.com/open-feature/ruby-sdk-contrib/commit/a1ab3a38f8221ea822792f098c5213a071c01d68))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### 🛠️ Build
|
|
33
|
+
|
|
34
|
+
* **deps-dev:** bump mcp from 0.8.0 to 0.9.2 in /hooks/openfeature-otel-hook ([#142](https://github.com/open-feature/ruby-sdk-contrib/issues/142)) ([6ff9fcb](https://github.com/open-feature/ruby-sdk-contrib/commit/6ff9fcbbe83d5903333e9e201eb3402898d898a9))
|
|
35
|
+
* **deps-dev:** bump mcp from 0.9.2 to 0.23.0 in /hooks/openfeature-otel-hook ([#199](https://github.com/open-feature/ruby-sdk-contrib/issues/199)) ([0327de0](https://github.com/open-feature/ruby-sdk-contrib/commit/0327de0fb0075a0060f78c2a068a51d1a5f2989e))
|
|
36
|
+
|
|
37
|
+
## [0.1.2](https://github.com/open-feature/ruby-sdk-contrib/compare/openfeature-otel-hook/v0.1.1...openfeature-otel-hook/v0.1.2) (2026-03-18)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
### 🧹 Chore
|
|
41
|
+
|
|
42
|
+
* **deps:** update dependency ruby to v3.4.9 ([#107](https://github.com/open-feature/ruby-sdk-contrib/issues/107)) ([e0d4314](https://github.com/open-feature/ruby-sdk-contrib/commit/e0d4314f1183cc80e84ba04980fe2d01584bec9c))
|
|
43
|
+
|
|
44
|
+
## [0.1.1](https://github.com/open-feature/ruby-sdk-contrib/compare/openfeature-otel-hook-v0.1.0...openfeature-otel-hook/v0.1.1) (2026-03-09)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### ✨ New Features
|
|
48
|
+
|
|
49
|
+
* add OpenTelemetry traces and metrics hooks ([#89](https://github.com/open-feature/ruby-sdk-contrib/issues/89)) ([efaa252](https://github.com/open-feature/ruby-sdk-contrib/commit/efaa25201372bffb72047b71f17891c06ed605f4))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### 🧹 Chore
|
|
53
|
+
|
|
54
|
+
* improve repository maturity and contributor experience ([#91](https://github.com/open-feature/ruby-sdk-contrib/issues/91)) ([7e28025](https://github.com/open-feature/ruby-sdk-contrib/commit/7e280257e6f543bc46537f43aeac302be003b47b))
|
|
55
|
+
|
|
56
|
+
## Changelog
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
openfeature-otel-hook (0.1.3)
|
|
5
|
+
logger
|
|
6
|
+
openfeature-sdk (~> 0.6)
|
|
7
|
+
opentelemetry-api (~> 1.0)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
ast (2.4.3)
|
|
13
|
+
diff-lcs (1.6.2)
|
|
14
|
+
docile (1.4.1)
|
|
15
|
+
json (3.1.0)
|
|
16
|
+
language_server-protocol (3.17.0.6)
|
|
17
|
+
lint_roller (1.1.0)
|
|
18
|
+
logger (1.7.0)
|
|
19
|
+
openfeature-sdk (0.8.1)
|
|
20
|
+
opentelemetry-api (1.11.1)
|
|
21
|
+
logger
|
|
22
|
+
opentelemetry-common (0.25.2)
|
|
23
|
+
opentelemetry-api (~> 1.0)
|
|
24
|
+
opentelemetry-metrics-api (0.10.0)
|
|
25
|
+
opentelemetry-api (~> 1.0)
|
|
26
|
+
opentelemetry-metrics-sdk (0.22.0)
|
|
27
|
+
opentelemetry-api (~> 1.1)
|
|
28
|
+
opentelemetry-metrics-api (~> 0.10.0)
|
|
29
|
+
opentelemetry-sdk (~> 1.13.0)
|
|
30
|
+
opentelemetry-registry (0.6.3)
|
|
31
|
+
opentelemetry-api (~> 1.1)
|
|
32
|
+
opentelemetry-sdk (1.13.1)
|
|
33
|
+
logger
|
|
34
|
+
opentelemetry-api (~> 1.1)
|
|
35
|
+
opentelemetry-common (~> 0.20)
|
|
36
|
+
opentelemetry-registry (~> 0.2)
|
|
37
|
+
opentelemetry-semantic_conventions
|
|
38
|
+
opentelemetry-semantic_conventions (1.44.0)
|
|
39
|
+
opentelemetry-api (~> 1.0)
|
|
40
|
+
parallel (2.3.0)
|
|
41
|
+
parser (3.3.13.0)
|
|
42
|
+
ast (~> 2.4.1)
|
|
43
|
+
racc
|
|
44
|
+
prism (1.9.0)
|
|
45
|
+
racc (1.8.1)
|
|
46
|
+
rainbow (3.1.1)
|
|
47
|
+
rake (13.4.2)
|
|
48
|
+
regexp_parser (2.13.1)
|
|
49
|
+
rspec (3.13.2)
|
|
50
|
+
rspec-core (~> 3.13.0)
|
|
51
|
+
rspec-expectations (~> 3.13.0)
|
|
52
|
+
rspec-mocks (~> 3.13.0)
|
|
53
|
+
rspec-core (3.13.6)
|
|
54
|
+
rspec-support (~> 3.13.0)
|
|
55
|
+
rspec-expectations (3.13.5)
|
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
57
|
+
rspec-support (~> 3.13.0)
|
|
58
|
+
rspec-mocks (3.13.8)
|
|
59
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
60
|
+
rspec-support (~> 3.13.0)
|
|
61
|
+
rspec-support (3.13.7)
|
|
62
|
+
rubocop (1.92.2)
|
|
63
|
+
json (>= 2.3)
|
|
64
|
+
language_server-protocol (~> 3.17.0.2)
|
|
65
|
+
lint_roller (~> 1.1.0)
|
|
66
|
+
parallel (>= 1.10)
|
|
67
|
+
parser (>= 3.3.0.2)
|
|
68
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
69
|
+
regexp_parser (>= 2.11.3, < 3.0)
|
|
70
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
71
|
+
ruby-progressbar (~> 1.7)
|
|
72
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
73
|
+
rubocop-ast (1.50.0)
|
|
74
|
+
parser (>= 3.3.7.2)
|
|
75
|
+
prism (~> 1.7)
|
|
76
|
+
rubocop-performance (1.26.1)
|
|
77
|
+
lint_roller (~> 1.1)
|
|
78
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
79
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
|
80
|
+
ruby-progressbar (1.13.0)
|
|
81
|
+
simplecov (0.22.0)
|
|
82
|
+
docile (~> 1.1)
|
|
83
|
+
simplecov-html (~> 0.11)
|
|
84
|
+
simplecov_json_formatter (~> 0.1)
|
|
85
|
+
simplecov-html (0.13.2)
|
|
86
|
+
simplecov_json_formatter (0.1.4)
|
|
87
|
+
standard (1.35.0.1)
|
|
88
|
+
language_server-protocol (~> 3.17.0.2)
|
|
89
|
+
lint_roller (~> 1.0)
|
|
90
|
+
rubocop (~> 1.62)
|
|
91
|
+
standard-custom (~> 1.0.0)
|
|
92
|
+
standard-performance (~> 1.3)
|
|
93
|
+
standard-custom (1.0.2)
|
|
94
|
+
lint_roller (~> 1.0)
|
|
95
|
+
rubocop (~> 1.50)
|
|
96
|
+
standard-performance (1.9.0)
|
|
97
|
+
lint_roller (~> 1.1)
|
|
98
|
+
rubocop-performance (~> 1.26.0)
|
|
99
|
+
unicode-display_width (3.3.0)
|
|
100
|
+
unicode-emoji (~> 4.3)
|
|
101
|
+
unicode-emoji (4.3.0)
|
|
102
|
+
|
|
103
|
+
PLATFORMS
|
|
104
|
+
arm64-darwin-24
|
|
105
|
+
ruby
|
|
106
|
+
|
|
107
|
+
DEPENDENCIES
|
|
108
|
+
openfeature-otel-hook!
|
|
109
|
+
opentelemetry-metrics-sdk
|
|
110
|
+
opentelemetry-sdk (~> 1.0)
|
|
111
|
+
rake (~> 13.0)
|
|
112
|
+
rspec (~> 3.12)
|
|
113
|
+
rubocop (~> 1.0)
|
|
114
|
+
simplecov (~> 0.22)
|
|
115
|
+
standard (~> 1.0)
|
|
116
|
+
|
|
117
|
+
BUNDLED WITH
|
|
118
|
+
4.0.12
|
data/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# OpenFeature OTel Hook
|
|
2
|
+
|
|
3
|
+
OpenTelemetry hooks for the [OpenFeature Ruby SDK](https://github.com/open-feature/ruby-sdk). Provides `TracesHook` and `MetricsHook` for emitting OTel signals during feature flag evaluations.
|
|
4
|
+
|
|
5
|
+
Complies with:
|
|
6
|
+
- [OTel Semantic Conventions for Feature Flag Events](https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-events/)
|
|
7
|
+
- [OpenFeature Spec Appendix D (Observability)](https://openfeature.dev/specification/appendix-d/)
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem "openfeature-otel-hook", "~> 0.1.0"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### TracesHook
|
|
18
|
+
|
|
19
|
+
Adds `feature_flag.evaluation` span events to the current active span.
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
require "openfeature/otel/hook"
|
|
23
|
+
|
|
24
|
+
# Register globally
|
|
25
|
+
OpenFeature::SDK.configure do |config|
|
|
26
|
+
config.hooks << OpenFeature::OTel::Hook::TracesHook.new
|
|
27
|
+
end
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### MetricsHook
|
|
31
|
+
|
|
32
|
+
Tracks evaluation counters: requests, successes, errors, and active evaluations.
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
require "openfeature/otel/hook"
|
|
36
|
+
|
|
37
|
+
# Register globally (uses global MeterProvider)
|
|
38
|
+
OpenFeature::SDK.configure do |config|
|
|
39
|
+
config.hooks << OpenFeature::OTel::Hook::MetricsHook.new
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Or with a custom MeterProvider
|
|
43
|
+
metrics_hook = OpenFeature::OTel::Hook::MetricsHook.new(
|
|
44
|
+
meter_provider: my_meter_provider
|
|
45
|
+
)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Metrics Emitted
|
|
49
|
+
|
|
50
|
+
| Metric | Type | Description |
|
|
51
|
+
|--------|------|-------------|
|
|
52
|
+
| `feature_flag.evaluation_active_count` | UpDownCounter | Evaluations currently in progress |
|
|
53
|
+
| `feature_flag.evaluation_requests_total` | Counter | Total evaluation requests |
|
|
54
|
+
| `feature_flag.evaluation_success_total` | Counter | Total successful evaluations |
|
|
55
|
+
| `feature_flag.evaluation_error_total` | Counter | Total errored evaluations |
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- Ruby >= 3.4
|
|
60
|
+
- `openfeature-sdk` ~> 0.6
|
|
61
|
+
- `opentelemetry-api` ~> 1.0
|
|
62
|
+
- Your application must configure an OpenTelemetry SDK with appropriate exporters
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
Apache-2.0
|
data/Rakefile
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "opentelemetry"
|
|
4
|
+
require "open_feature/sdk"
|
|
5
|
+
|
|
6
|
+
module OpenFeature
|
|
7
|
+
module OTel
|
|
8
|
+
module Hook
|
|
9
|
+
class MetricsHook
|
|
10
|
+
def initialize(meter_provider: ::OpenTelemetry.meter_provider)
|
|
11
|
+
meter = meter_provider.meter("openfeature-otel-hook")
|
|
12
|
+
|
|
13
|
+
@active_count = meter.create_up_down_counter(
|
|
14
|
+
"feature_flag.evaluation_active_count",
|
|
15
|
+
description: "Number of feature flag evaluations currently in progress"
|
|
16
|
+
)
|
|
17
|
+
@request_counter = meter.create_counter(
|
|
18
|
+
"feature_flag.evaluation_requests_total",
|
|
19
|
+
description: "Total number of feature flag evaluation requests"
|
|
20
|
+
)
|
|
21
|
+
@success_counter = meter.create_counter(
|
|
22
|
+
"feature_flag.evaluation_success_total",
|
|
23
|
+
description: "Total number of successful feature flag evaluations"
|
|
24
|
+
)
|
|
25
|
+
@error_counter = meter.create_counter(
|
|
26
|
+
"feature_flag.evaluation_error_total",
|
|
27
|
+
description: "Total number of errored feature flag evaluations"
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def before(hook_context:, hints:)
|
|
32
|
+
attrs = base_attributes(hook_context)
|
|
33
|
+
@active_count.add(1, attributes: attrs)
|
|
34
|
+
@request_counter.add(1, attributes: attrs)
|
|
35
|
+
nil
|
|
36
|
+
rescue # rubocop:disable Lint/SuppressedException
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def after(hook_context:, evaluation_details:, hints:)
|
|
40
|
+
attrs = evaluation_attributes(hook_context, evaluation_details)
|
|
41
|
+
@success_counter.add(1, attributes: attrs)
|
|
42
|
+
rescue # rubocop:disable Lint/SuppressedException
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def error(hook_context:, exception:, hints:)
|
|
46
|
+
attrs = base_attributes(hook_context).merge(
|
|
47
|
+
"error.type" => exception.class.name.downcase
|
|
48
|
+
)
|
|
49
|
+
@error_counter.add(1, attributes: attrs)
|
|
50
|
+
rescue # rubocop:disable Lint/SuppressedException
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def finally(hook_context:, evaluation_details:, hints:)
|
|
54
|
+
attrs = base_attributes(hook_context)
|
|
55
|
+
@active_count.add(-1, attributes: attrs)
|
|
56
|
+
rescue # rubocop:disable Lint/SuppressedException
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def base_attributes(hook_context)
|
|
62
|
+
attrs = {"feature_flag.key" => hook_context.flag_key}
|
|
63
|
+
provider_name = hook_context.provider_metadata&.name
|
|
64
|
+
attrs["feature_flag.provider.name"] = provider_name if provider_name
|
|
65
|
+
attrs
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def evaluation_attributes(hook_context, evaluation_details)
|
|
69
|
+
event = ::OpenFeature::SDK::Telemetry.create_evaluation_event(
|
|
70
|
+
hook_context: hook_context,
|
|
71
|
+
evaluation_details: evaluation_details
|
|
72
|
+
)
|
|
73
|
+
event.attributes.transform_keys do |key|
|
|
74
|
+
(key == "error.message") ? "feature_flag.error.message" : key
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "opentelemetry"
|
|
4
|
+
require "open_feature/sdk"
|
|
5
|
+
|
|
6
|
+
module OpenFeature
|
|
7
|
+
module OTel
|
|
8
|
+
module Hook
|
|
9
|
+
class TracesHook
|
|
10
|
+
def finally(hook_context:, evaluation_details:, hints:)
|
|
11
|
+
span = ::OpenTelemetry::Trace.current_span
|
|
12
|
+
return unless span.recording?
|
|
13
|
+
|
|
14
|
+
event = ::OpenFeature::SDK::Telemetry.create_evaluation_event(
|
|
15
|
+
hook_context: hook_context,
|
|
16
|
+
evaluation_details: evaluation_details
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
span.add_event(event.name, attributes: remap_attributes(event.attributes))
|
|
20
|
+
rescue # rubocop:disable Lint/SuppressedException
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def remap_attributes(attributes)
|
|
26
|
+
attributes.transform_keys do |key|
|
|
27
|
+
(key == "error.message") ? "feature_flag.error.message" : key
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/openfeature/otel/hook/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "openfeature-otel-hook"
|
|
7
|
+
spec.version = OpenFeature::OTel::Hook::VERSION
|
|
8
|
+
spec.authors = ["OpenFeature Contributors"]
|
|
9
|
+
spec.email = ["cncf-openfeature-contributors@lists.cncf.io"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "OpenTelemetry hooks for the OpenFeature Ruby SDK"
|
|
12
|
+
spec.description = "Traces and metrics hooks that emit OpenTelemetry signals for OpenFeature flag evaluations"
|
|
13
|
+
spec.homepage = "https://github.com/open-feature/ruby-sdk-contrib/tree/main/hooks/openfeature-otel-hook"
|
|
14
|
+
spec.license = "Apache-2.0"
|
|
15
|
+
spec.required_ruby_version = ">= 3.4"
|
|
16
|
+
|
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
19
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
20
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/open-feature/ruby-sdk-contrib/issues"
|
|
21
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
22
|
+
|
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
spec.require_paths = ["lib"]
|
|
28
|
+
|
|
29
|
+
spec.add_runtime_dependency "logger"
|
|
30
|
+
spec.add_runtime_dependency "openfeature-sdk", "~> 0.6"
|
|
31
|
+
spec.add_runtime_dependency "opentelemetry-api", "~> 1.0"
|
|
32
|
+
|
|
33
|
+
spec.add_development_dependency "opentelemetry-sdk", "~> 1.0"
|
|
34
|
+
spec.add_development_dependency "opentelemetry-metrics-sdk"
|
|
35
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
36
|
+
spec.add_development_dependency "rspec", "~> 3.12"
|
|
37
|
+
spec.add_development_dependency "simplecov", "~> 0.22"
|
|
38
|
+
spec.add_development_dependency "standard", "~> 1.0"
|
|
39
|
+
spec.add_development_dependency "rubocop", "~> 1.0"
|
|
40
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: openfeature-otel-hook
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- OpenFeature Contributors
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: logger
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: openfeature-sdk
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.6'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.6'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: opentelemetry-api
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: opentelemetry-sdk
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '1.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: opentelemetry-metrics-sdk
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rake
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '13.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '13.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rspec
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.12'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '3.12'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: simplecov
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0.22'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0.22'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: standard
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - "~>"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '1.0'
|
|
131
|
+
type: :development
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - "~>"
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '1.0'
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: rubocop
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - "~>"
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '1.0'
|
|
145
|
+
type: :development
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - "~>"
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '1.0'
|
|
152
|
+
description: Traces and metrics hooks that emit OpenTelemetry signals for OpenFeature
|
|
153
|
+
flag evaluations
|
|
154
|
+
email:
|
|
155
|
+
- cncf-openfeature-contributors@lists.cncf.io
|
|
156
|
+
executables: []
|
|
157
|
+
extensions: []
|
|
158
|
+
extra_rdoc_files: []
|
|
159
|
+
files:
|
|
160
|
+
- ".gitignore"
|
|
161
|
+
- ".rspec"
|
|
162
|
+
- ".rubocop.yml"
|
|
163
|
+
- ".ruby-version"
|
|
164
|
+
- CHANGELOG.md
|
|
165
|
+
- Gemfile
|
|
166
|
+
- Gemfile.lock
|
|
167
|
+
- README.md
|
|
168
|
+
- Rakefile
|
|
169
|
+
- lib/openfeature/otel/hook.rb
|
|
170
|
+
- lib/openfeature/otel/hook/metrics_hook.rb
|
|
171
|
+
- lib/openfeature/otel/hook/traces_hook.rb
|
|
172
|
+
- lib/openfeature/otel/hook/version.rb
|
|
173
|
+
- openfeature-otel-hook.gemspec
|
|
174
|
+
homepage: https://github.com/open-feature/ruby-sdk-contrib/tree/main/hooks/openfeature-otel-hook
|
|
175
|
+
licenses:
|
|
176
|
+
- Apache-2.0
|
|
177
|
+
metadata:
|
|
178
|
+
homepage_uri: https://github.com/open-feature/ruby-sdk-contrib/tree/main/hooks/openfeature-otel-hook
|
|
179
|
+
source_code_uri: https://github.com/open-feature/ruby-sdk-contrib/tree/main/hooks/openfeature-otel-hook
|
|
180
|
+
changelog_uri: https://github.com/open-feature/ruby-sdk-contrib/tree/main/hooks/openfeature-otel-hook/blob/main/CHANGELOG.md
|
|
181
|
+
bug_tracker_uri: https://github.com/open-feature/ruby-sdk-contrib/issues
|
|
182
|
+
rubygems_mfa_required: 'true'
|
|
183
|
+
rdoc_options: []
|
|
184
|
+
require_paths:
|
|
185
|
+
- lib
|
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
187
|
+
requirements:
|
|
188
|
+
- - ">="
|
|
189
|
+
- !ruby/object:Gem::Version
|
|
190
|
+
version: '3.4'
|
|
191
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
192
|
+
requirements:
|
|
193
|
+
- - ">="
|
|
194
|
+
- !ruby/object:Gem::Version
|
|
195
|
+
version: '0'
|
|
196
|
+
requirements: []
|
|
197
|
+
rubygems_version: 4.0.20
|
|
198
|
+
specification_version: 4
|
|
199
|
+
summary: OpenTelemetry hooks for the OpenFeature Ruby SDK
|
|
200
|
+
test_files: []
|