|
40 | 40 | event = spans[0].events[0] |
41 | 41 | expect(event.name).to eq 'feature_flag' |
42 | 42 | expect(event.attributes['feature_flag.key']).to eq 'boolean' |
43 | | - expect(event.attributes['feature_flag.provider_name']).to eq 'LaunchDarkly' |
44 | | - expect(event.attributes['feature_flag.context.key']).to eq 'org:org-key' |
45 | | - expect(event.attributes['feature_flag.variant']).to be_nil |
| 43 | + expect(event.attributes['feature_flag.provider.name']).to eq 'LaunchDarkly' |
| 44 | + expect(event.attributes['feature_flag.context.id']).to eq 'org:org-key' |
| 45 | + expect(event.attributes['feature_flag.result.value']).to be_nil |
46 | 46 | end |
47 | 47 | end |
48 | 48 |
|
49 | | - context 'with include_variant' do |
50 | | - let(:options) { LaunchDarkly::Otel::TracingHookOptions.new({include_variant: true}) } |
| 49 | + context 'with include_value' do |
| 50 | + let(:options) { LaunchDarkly::Otel::TracingHookOptions.new({include_value: true}) } |
51 | 51 | let(:hook) { LaunchDarkly::Otel::TracingHook.new(options) } |
52 | 52 | let(:config) { LaunchDarkly::Config.new({data_source: td, hooks: [hook]}) } |
53 | 53 | let(:client) { LaunchDarkly::LDClient.new('key', config) } |
|
64 | 64 | event = spans[0].events[0] |
65 | 65 | expect(event.name).to eq 'feature_flag' |
66 | 66 | expect(event.attributes['feature_flag.key']).to eq 'boolean' |
67 | | - expect(event.attributes['feature_flag.provider_name']).to eq 'LaunchDarkly' |
68 | | - expect(event.attributes['feature_flag.context.key']).to eq 'org:org-key' |
69 | | - expect(event.attributes['feature_flag.variant']).to eq 'true' |
| 67 | + expect(event.attributes['feature_flag.provider.name']).to eq 'LaunchDarkly' |
| 68 | + expect(event.attributes['feature_flag.context.id']).to eq 'org:org-key' |
| 69 | + expect(event.attributes['feature_flag.result.value']).to eq 'true' |
| 70 | + end |
| 71 | + end |
| 72 | + |
| 73 | + context 'with include_variant (deprecated)' do |
| 74 | + let(:options) { LaunchDarkly::Otel::TracingHookOptions.new({include_variant: true}) } |
| 75 | + let(:hook) { LaunchDarkly::Otel::TracingHook.new(options) } |
| 76 | + let(:config) { LaunchDarkly::Config.new({data_source: td, hooks: [hook]}) } |
| 77 | + let(:client) { LaunchDarkly::LDClient.new('key', config) } |
| 78 | + |
| 79 | + it 'still works for backward compatibility' do |
| 80 | + flag = LaunchDarkly::Integrations::TestData::FlagBuilder.new('boolean').boolean_flag |
| 81 | + td.update(flag) |
| 82 | + |
| 83 | + tracer.in_span('toplevel') do |span| |
| 84 | + result = client.variation('boolean', {key: 'org-key', kind: 'org'}, false) |
| 85 | + end |
| 86 | + |
| 87 | + spans = exporter.finished_spans |
| 88 | + event = spans[0].events[0] |
| 89 | + expect(event.attributes['feature_flag.result.value']).to eq 'true' |
70 | 90 | end |
71 | 91 | end |
72 | 92 |
|
|
82 | 102 | spans = exporter.finished_spans |
83 | 103 | expect(spans.count).to eq 1 |
84 | 104 |
|
85 | | - expect(spans[0].attributes['feature_flag.context.key']).to eq 'org:org-key' |
| 105 | + expect(spans[0].attributes['feature_flag.context.id']).to eq 'org:org-key' |
86 | 106 | expect(spans[0].attributes['feature_flag.key']).to eq 'boolean' |
87 | 107 | expect(spans[0].events).to be_nil |
88 | 108 | end |
|
101 | 121 | ld_span = spans[0] |
102 | 122 | toplevel = spans[1] |
103 | 123 |
|
104 | | - expect(ld_span.attributes['feature_flag.context.key']).to eq 'org:org-key' |
| 124 | + expect(ld_span.attributes['feature_flag.context.id']).to eq 'org:org-key' |
105 | 125 | expect(ld_span.attributes['feature_flag.key']).to eq 'boolean' |
106 | 126 |
|
107 | 127 | event = toplevel.events[0] |
108 | 128 | expect(event.name).to eq 'feature_flag' |
109 | 129 | expect(event.attributes['feature_flag.key']).to eq 'boolean' |
110 | | - expect(event.attributes['feature_flag.provider_name']).to eq 'LaunchDarkly' |
111 | | - expect(event.attributes['feature_flag.context.key']).to eq 'org:org-key' |
112 | | - expect(event.attributes['feature_flag.variant']).to be_nil |
| 130 | + expect(event.attributes['feature_flag.provider.name']).to eq 'LaunchDarkly' |
| 131 | + expect(event.attributes['feature_flag.context.id']).to eq 'org:org-key' |
| 132 | + expect(event.attributes['feature_flag.result.value']).to be_nil |
113 | 133 | end |
114 | 134 |
|
115 | 135 | it 'hook makes its span active' do |
116 | | - # By adding the same hook twice, we should get 3 spans. |
117 | 136 | client.add_hook(LaunchDarkly::Otel::TracingHook.new(options)) |
118 | 137 |
|
119 | 138 | flag = LaunchDarkly::Integrations::TestData::FlagBuilder.new('boolean').boolean_flag |
|
130 | 149 | middle = spans[1] |
131 | 150 | top = spans[2] |
132 | 151 |
|
133 | | - expect(inner.attributes['feature_flag.context.key']).to eq 'org:org-key' |
| 152 | + expect(inner.attributes['feature_flag.context.id']).to eq 'org:org-key' |
134 | 153 | expect(inner.attributes['feature_flag.key']).to eq 'boolean' |
135 | 154 | expect(inner.events).to be_nil |
136 | 155 |
|
137 | | - expect(middle.attributes['feature_flag.context.key']).to eq 'org:org-key' |
| 156 | + expect(middle.attributes['feature_flag.context.id']).to eq 'org:org-key' |
138 | 157 | expect(middle.attributes['feature_flag.key']).to eq 'boolean' |
139 | 158 | expect(middle.events[0].name).to eq 'feature_flag' |
140 | 159 | expect(middle.events[0].attributes['feature_flag.key']).to eq 'boolean' |
141 | | - expect(middle.events[0].attributes['feature_flag.provider_name']).to eq 'LaunchDarkly' |
142 | | - expect(middle.events[0].attributes['feature_flag.context.key']).to eq 'org:org-key' |
143 | | - expect(middle.events[0].attributes['feature_flag.variant']).to be_nil |
| 160 | + expect(middle.events[0].attributes['feature_flag.provider.name']).to eq 'LaunchDarkly' |
| 161 | + expect(middle.events[0].attributes['feature_flag.context.id']).to eq 'org:org-key' |
| 162 | + expect(middle.events[0].attributes['feature_flag.result.value']).to be_nil |
144 | 163 |
|
145 | 164 | expect(top.events[0].name).to eq 'feature_flag' |
146 | 165 | expect(top.events[0].attributes['feature_flag.key']).to eq 'boolean' |
147 | | - expect(top.events[0].attributes['feature_flag.provider_name']).to eq 'LaunchDarkly' |
148 | | - expect(top.events[0].attributes['feature_flag.context.key']).to eq 'org:org-key' |
149 | | - expect(top.events[0].attributes['feature_flag.variant']).to be_nil |
| 166 | + expect(top.events[0].attributes['feature_flag.provider.name']).to eq 'LaunchDarkly' |
| 167 | + expect(top.events[0].attributes['feature_flag.context.id']).to eq 'org:org-key' |
| 168 | + expect(top.events[0].attributes['feature_flag.result.value']).to be_nil |
150 | 169 | end |
| 170 | + |
| 171 | + context 'with environment_id' do |
| 172 | + let(:options) { LaunchDarkly::Otel::TracingHookOptions.new({environment_id: 'test-env-123'}) } |
| 173 | + let(:hook) { LaunchDarkly::Otel::TracingHook.new(options) } |
| 174 | + let(:config) { LaunchDarkly::Config.new({data_source: td, hooks: [hook]}) } |
| 175 | + let(:client) { LaunchDarkly::LDClient.new('key', config) } |
| 176 | + |
| 177 | + it 'includes environment_id in event' do |
| 178 | + tracer.in_span('toplevel') do |span| |
| 179 | + result = client.variation('boolean', {key: 'org-key', kind: 'org'}, true) |
| 180 | + end |
| 181 | + |
| 182 | + spans = exporter.finished_spans |
| 183 | + event = spans[0].events[0] |
| 184 | + expect(event.attributes['feature_flag.set.id']).to eq 'test-env-123' |
| 185 | + end |
| 186 | + |
| 187 | + it 'does not include environment_id when invalid' do |
| 188 | + invalid_options = LaunchDarkly::Otel::TracingHookOptions.new({environment_id: ''}) |
| 189 | + invalid_hook = LaunchDarkly::Otel::TracingHook.new(invalid_options) |
| 190 | + invalid_config = LaunchDarkly::Config.new({data_source: td, hooks: [invalid_hook]}) |
| 191 | + invalid_client = LaunchDarkly::LDClient.new('key', invalid_config) |
| 192 | + |
| 193 | + tracer.in_span('toplevel') do |span| |
| 194 | + result = invalid_client.variation('boolean', {key: 'org-key', kind: 'org'}, true) |
| 195 | + end |
| 196 | + |
| 197 | + spans = exporter.finished_spans |
| 198 | + event = spans[0].events[0] |
| 199 | + expect(event.attributes['feature_flag.set.id']).to be_nil |
| 200 | + end |
| 201 | + end |
| 202 | + |
| 203 | + context 'with inExperiment and variationIndex' do |
| 204 | + let(:hook) { LaunchDarkly::Otel::TracingHook.new } |
| 205 | + let(:config) { LaunchDarkly::Config.new({data_source: td, hooks: [hook]}) } |
| 206 | + let(:client) { LaunchDarkly::LDClient.new('key', config) } |
| 207 | + |
| 208 | + it 'includes inExperiment when evaluation is part of experiment' do |
| 209 | + flag = LaunchDarkly::Integrations::TestData::FlagBuilder.new('experiment-flag') |
| 210 | + .variations(false, true) |
| 211 | + .fallthrough_variation(1) |
| 212 | + .on(true) |
| 213 | + td.update(flag) |
| 214 | + |
| 215 | + tracer.in_span('toplevel') do |span| |
| 216 | + result = client.variation('experiment-flag', {key: 'user-key', kind: 'user'}, false) |
| 217 | + end |
| 218 | + |
| 219 | + spans = exporter.finished_spans |
| 220 | + event = spans[0].events[0] |
| 221 | + expect(event.attributes.key?('feature_flag.result.reason.inExperiment')).to be false |
| 222 | + end |
| 223 | + |
| 224 | + it 'includes variationIndex when available' do |
| 225 | + flag = LaunchDarkly::Integrations::TestData::FlagBuilder.new('indexed-flag') |
| 226 | + .variations('value-0', 'value-1', 'value-2') |
| 227 | + .fallthrough_variation(1) |
| 228 | + .on(true) |
| 229 | + td.update(flag) |
| 230 | + |
| 231 | + tracer.in_span('toplevel') do |span| |
| 232 | + result = client.variation('indexed-flag', {key: 'user-key', kind: 'user'}, 'default') |
| 233 | + end |
| 234 | + |
| 235 | + spans = exporter.finished_spans |
| 236 | + event = spans[0].events[0] |
| 237 | + expect(event.attributes['feature_flag.result.variationIndex']).to eq 1 |
| 238 | + end |
| 239 | + end |
| 240 | + |
151 | 241 | end |
152 | 242 | end |
0 commit comments