Repository: DataDog/dd-trace-rb
Pull request #4493: feat: baggage otel api
Author: login: ZStriker19
Labels: name: integrations
description: Involves tracing integrations
name: tracing
name: otel
description: OpenTelemetry-related changes
Created: 2025-03-13T19:37:30Z | Merged: 2025-03-20T20:56:14Z

<!--
Check out the
https://github.com/DataDog/dd-trace-rb/blob/master/docs/DevelopmentGuide.md
for guidance on how to set up your development environment,
run the test suite, write new integrations, and more.
-->

**What does this PR do?**
Adds drop in support for otel baggage api essentially adding support for these methods: https://github.com/open-telemetry/opentelemetry-ruby/blob/ffc7349478ed34d007b068a4e3b5a1a39498d395/api/lib/opentelemetry/baggage.rb

Which are outlined in this spec: https://opentelemetry.io/docs/specs/otel/baggage/api/

**Motivation:**
So the Datadog tracer can be used to modify baggage in the same way otel allows.

**Change log entry**
* Tracing: Added support for Baggage otel api

**Additional Notes:**
<!-- Anything else we should know when reviewing? -->

**How to test the change?**
<!--
Describe here how the change can be validated.
You are strongly encouraged to provide automated tests for this PR (unit or integration).
If this change cannot be feasibly tested, please explain why,
unless the change does not modify code (e.g. only modifies docs, comments).
-->

<!-- Unsure? Have a question? Request a review! -->



Diff:
diff --git a/.standard_todo.yml b/.standard_todo.yml
index f62c9bc6f25..f6877e17653 100644
--- a/.standard_todo.yml
+++ b/.standard_todo.yml
@@ -44,6 +44,7 @@ ignore:
 - spec/datadog/core/**/**
 - spec/datadog/di/integration/*_test_class*.rb
 - spec/datadog/kit/**/**
+- spec/datadog/opentelemetry/**/**
 - spec/datadog/tracing/**/**
 - spec/support/**/**
 - tasks/**/**
diff --git a/lib/datadog/opentelemetry.rb b/lib/datadog/opentelemetry.rb
index 51676e419a2..005a04b981e 100644
--- a/lib/datadog/opentelemetry.rb
+++ b/lib/datadog/opentelemetry.rb
@@ -13,6 +13,7 @@
 require_relative 'tracing/contrib'
 
 require_relative 'opentelemetry/api/context'
+require_relative 'opentelemetry/api/baggage'
 
 # DEV: Should this be a Contrib integration, that depends on the `opentelemetry-sdk`
 # DEV: and checks for compatibility?
diff --git a/lib/datadog/opentelemetry/api/baggage.rb b/lib/datadog/opentelemetry/api/baggage.rb
new file mode 100644
index 00000000000..eb7d75b06c4
--- /dev/null
+++ b/lib/datadog/opentelemetry/api/baggage.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require_relative 'trace/span'
+require_relative '../../tracing/trace_operation'
+require_relative '../trace'
+
+module Datadog
+  module OpenTelemetry
+    module API
+      # The Baggage module provides an implementation of the OpenTelemetry Baggage API.
+      #
+      # Baggage is a set of name/value pairs describing user-defined properties that can be
+      # propagated through a distributed trace. This implementation follows the W3C Baggage
+      # specification and the OpenTelemetry Baggage API.
+      #
+      # @see https://www.w3.org/TR/baggage/
+      # @see https://opentelemetry.io/docs/specs/otel/baggage/api/
+      module Baggage
+        def initialize(trace: nil)
+          @trace = trace
+        end
+
+        # Returns a new context with empty baggage
+        #
+        # @param [optional Context] context Context to clear baggage from. Defaults
+        # to ::OpenTelemetry::Context.current
+        # @return [Context]
+        def clear(context: ::OpenTelemetry::Context.current)
+          context.ensure_trace.baggage.clear
+          context
+        end
+
+        # Returns the corresponding value for key
+        #
+        # @param [String] key The lookup key
+        # @param [optional Context] context The context from which to retrieve
+        # the key. Defaults to ::OpenTelemetry::Context.current
+        # @return [String, nil]
+        def value(key, context: ::OpenTelemetry::Context.current)
+          trace = context.ensure_trace
+          return nil if trace.nil?
+
+          trace.baggage && trace.baggage[key]
+        end
+
+        # Returns all baggage values
+        #
+        # @param [optional Context] context The context from which to retrieve
+        # the baggage. Defaults to ::OpenTelemetry::Context.current
+        # @return [Hash<String, String>]
+        def values(context: ::OpenTelemetry::Context.current)
+          trace = context.ensure_trace
+          return {} if trace.nil?
+
+          trace.baggage ? trace.baggage.dup : {}
+        end
+
+        # Returns a new context with new key-value pair
+        #
+        # @param [String] key The key to store this value under
+        # @param [String] value String value to be stored under key
+        # @param [optional String] metadata This is here to store properties
+        # received from other W3C Baggage implementations but is not exposed in
+        # OpenTelemetry. This is considered private API and not for use by
+        # end-users.
+        # @param [optional Context] context The context to update with new
+        # value. Defaults to ::OpenTelemetry::Context.current
+        # @return [Context]
+        def set_value(key, value, metadata: nil, context: ::OpenTelemetry::Context.current)
+          # Delegate to the context to set the value because an active trace is not guaranteed
+          # set_values handles this logic
+          context.set_values({ ::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY) => { key => value } })
+        end
+
+        # Returns a new context with value at key removed
+        #
+        # @param [String] key The key to remove
+        # @param [optional Context] context The context to remove baggage
+        # from. Defaults to ::OpenTelemetry::Context.current
+        # @return [Context]
+        def remove_value(key, context: ::OpenTelemetry::Context.current)
+          # Delegate to the context to remove the value because an active trace is not guaranteed
+          # set_values handles this logic
+          context.set_values({ Context::BAGGAGE_REMOVE_KEY => key })
+        end
+        ::OpenTelemetry::Baggage.singleton_class.prepend(self)
+      end
+    end
+  end
+end
diff --git a/lib/datadog/opentelemetry/api/baggage.rbs b/lib/datadog/opentelemetry/api/baggage.rbs
new file mode 100644
index 00000000000..1725deb8a55
--- /dev/null
+++ b/lib/datadog/opentelemetry/api/baggage.rbs
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Datadog
+  module OpenTelemetry
+    module API
+      module Baggage
+        def initialize: (?trace: Datadog::Tracing::TraceOperation?) -> void
+
+        # Returns a new context with empty baggage
+        def clear: (?context: OpenTelemetry::Context) -> OpenTelemetry::Context
+
+        # Returns the corresponding value for key
+        def value: (String key, ?context: OpenTelemetry::Context) -> String?
+
+        # Returns all baggage values
+        def values: (?context: OpenTelemetry::Context) -> Hash[String, String]
+
+        # Returns a new context with key-value pair
+        def set_value: (String key, String value, ?metadata: String?, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
+
+        # Returns a new context with value at key removed
+        def remove_value: (String key, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
+      end
+    end
+  end
+end 
\ No newline at end of file
diff --git a/lib/datadog/opentelemetry/api/context.rb b/lib/datadog/opentelemetry/api/context.rb
index c16adc1ba13..c304b037bf9 100644
--- a/lib/datadog/opentelemetry/api/context.rb
+++ b/lib/datadog/opentelemetry/api/context.rb
@@ -21,11 +21,13 @@ module API
       module Context
         CURRENT_SPAN_KEY = ::OpenTelemetry::Trace.const_get(:CURRENT_SPAN_KEY)
         private_constant :CURRENT_SPAN_KEY
+        BAGGAGE_REMOVE_KEY = Object.new # sentinel object to indicate the deletion of a value in baggage
 
-        def initialize(entries, trace: nil)
+        def initialize(entries, trace: nil, baggage: nil)
           @trace = trace || ::Datadog::Tracing.send(:tracer).send(:start_trace)
           @trace.otel_values.merge!(entries) if entries
           @trace.otel_context ||= self
+          @trace.baggage = baggage if baggage
         end
 
         # Because Context can be reused, we have to make sure we have
@@ -79,8 +81,20 @@ def set_values(values)
           end
 
           existing_values = @trace && @trace.otel_values || {}
+          existing_baggage = @trace && @trace.baggage || {}
 
-          ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace)
+          # Retrieve the baggage removal sentinel and remove it from the values hash
+          existing_baggage.delete(values[BAGGAGE_REMOVE_KEY]) if values.key?(BAGGAGE_REMOVE_KEY)
+
+          # If the values hash contains a BAGGAGE_KEY, merge its contents with existing baggage
+          # Otherwise, keep the existing baggage unchanged
+          new_baggage = if values.key?(::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY))
+                          existing_baggage.merge(values[::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY)])
+                        else
+                          existing_baggage
+                        end
+
+          ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace, baggage: new_baggage)
         end
 
         # The Datadog {TraceOperation} associated with this {Context}.
diff --git a/sig/datadog/opentelemetry/api/baggage.rbs b/sig/datadog/opentelemetry/api/baggage.rbs
new file mode 100644
index 00000000000..8ca3f78b451
--- /dev/null
+++ b/sig/datadog/opentelemetry/api/baggage.rbs
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Datadog
+  module OpenTelemetry
+    module API
+      module Baggage
+        def initialize: (?trace: Datadog::Tracing::TraceOperation?) -> void
+
+        def clear: (?context: untyped) -> untyped
+
+        def value: (String key, ?context: untyped) -> String?
+
+        def values: (?context: untyped) -> Hash[String, String]
+
+        def set_value: (String key, String value, ?metadata: String?, ?context: untyped) -> untyped
+
+        def remove_value: (String key, ?context: untyped) -> untyped
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/sig/datadog/opentelemetry/api/context.rbs b/sig/datadog/opentelemetry/api/context.rbs
index 8dd7a839800..c1f5275c338 100644
--- a/sig/datadog/opentelemetry/api/context.rbs
+++ b/sig/datadog/opentelemetry/api/context.rbs
@@ -3,6 +3,7 @@ module Datadog
     module API
       module Context
         CURRENT_SPAN_KEY: untyped
+        BAGGAGE_REMOVE_KEY: Symbol
 
         def initialize: (untyped entries, ?trace: untyped?) -> void
         def ensure_trace: () -> (nil | untyped)
@@ -10,7 +11,7 @@ module Datadog
 
         alias [] value
         def set_value: (untyped key, untyped value) -> untyped
-        def set_values: (untyped values) -> untyped
+        def set_values: (Hash[Symbol, Hash[String, String] | String]) -> untyped
         def trace: () -> untyped
         module SingletonClass
           def current: () -> untyped
diff --git a/spec/datadog/opentelemetry/api/baggage_spec.rb b/spec/datadog/opentelemetry/api/baggage_spec.rb
new file mode 100644
index 00000000000..2ef41cdf694
--- /dev/null
+++ b/spec/datadog/opentelemetry/api/baggage_spec.rb
@@ -0,0 +1,137 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'opentelemetry/sdk'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { ::OpenTelemetry::Baggage }
+
+  let(:trace) { Datadog::Tracing::TraceOperation.new }
+  let(:context) { ::OpenTelemetry::Context.current }
+
+  describe '#set_value' do
+    it 'sets a baggage value in the trace' do
+      ctx = baggage.set_value('test_key', 'test_value')
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('test_value')
+    end
+
+    it 'updates an existing baggage value' do
+      ctx = baggage.set_value('test_key', 'initial_value')
+      ctx = baggage.set_value('test_key', 'new_value', context: ctx)
+
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('new_value')
+    end
+
+    it 'preserves existing baggage values when adding new ones' do
+      ctx = baggage.set_value('key1', 'value1')
+      ctx = baggage.set_value('key2', 'value2', context: ctx)
+
+      expect(ctx.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+
+    it 'maintains immutability of the baggage hash' do
+      baggage.set_value('test_key', 'test_value')
+
+      expect(baggage.values).to eq({})
+    end
+  end
+
+  describe '#remove_value' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'removes a baggage value from the trace' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq({ 'key2' => 'value2' })
+    end
+
+    it 'preserves other baggage values when removing one' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result.instance_variable_get(:@trace).baggage).to eq({ 'key2' => 'value2' })
+    end
+
+    it 'handles removing non-existent keys' do
+      result = baggage.remove_value('non_existent_key', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+  end
+
+  describe '#value' do
+    let(:ctx) do
+      baggage.set_value('key1', 'value1')
+    end
+
+    it 'retrieves a baggage value from the trace' do
+      expect(baggage.value('key1', context: ctx)).to eq('value1')
+    end
+
+    it 'returns nil for non-existent keys' do
+      expect(baggage.value('non_existent_key', context: ctx)).to be_nil
+    end
+  end
+
+  describe '#values' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'returns all baggage values from the trace' do
+      expect(baggage.values(context: ctx)).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+
+    it 'returns a new context with the updated baggage' do
+      values = baggage.values(context: ctx)
+      values['key3'] = 'value3'
+
+      expect(baggage.values(context: ctx)).not_to include('key3')
+      expect(ctx.instance_variable_get(:@trace).baggage).not_to include('key3')
+    end
+  end
+
+  describe '#clear' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'removes all baggage values from the trace' do
+      result = baggage.clear(context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to be_empty
+    end
+
+    it 'maintains immutability when clearing' do
+      original_baggage = ctx.instance_variable_get(:@trace).baggage.dup
+      result = baggage.clear(context: ctx)
+
+      expect(result.instance_variable_get(:@trace).baggage).not_to be(original_baggage)
+    end
+  end
+end
diff --git a/spec/datadog/opentelemetry_spec.rb b/spec/datadog/opentelemetry_spec.rb
index 45f82db3781..3d3aab13500 100644
--- a/spec/datadog/opentelemetry_spec.rb
+++ b/spec/datadog/opentelemetry_spec.rb
@@ -954,5 +954,93 @@ def headers
         end
       end
     end
+
+    context 'Baggage API' do
+      let(:otel_baggage) { ::OpenTelemetry::Baggage }
+      let(:writer) { get_test_writer }
+      let(:tracer) { Datadog::Tracing.send(:tracer) }
+
+      before do
+        writer_ = writer
+        Datadog.configure do |c|
+          c.tracing.writer = writer_
+        end
+
+        ::OpenTelemetry::SDK.configure do |c|
+        end
+      end
+
+      after do
+        ::OpenTelemetry.logger = nil
+      end
+
+      describe 'baggage operations' do
+        around do |example|
+          OpenTelemetry::Context.with_current(OpenTelemetry::Context.new({})) do
+            example.run
+          end
+        end
+        it 'sets and gets baggage values' do
+          context = otel_baggage.set_value('test_key', 'test_value')
+          expect(otel_baggage.value('test_key', context: context)).to eq('test_value')
+        end
+
+        it 'returns nil for non-existent keys' do
+          context = ::OpenTelemetry::Context.current
+
+          expect(otel_baggage.value('non_existent_key', context: context)).to be_nil
+        end
+
+        it 'returns all baggage values' do
+          # Set multiple baggage values
+          context = otel_baggage.set_value('key1', 'value1')
+          context = otel_baggage.set_value('key2', 'value2', context: context)
+
+          # Get all values
+          expect(otel_baggage.values(context: context)).to include(
+            'key1' => 'value1',
+            'key2' => 'value2'
+          )
+        end
+
+        it 'removes baggage values' do
+          # Set and then remove a baggage value
+          context = otel_baggage.set_value('key_to_remove', 'value')
+          context = otel_baggage.remove_value('key_to_remove', context: context)
+
+          # Value should be removed
+          expect(otel_baggage.value('key_to_remove', context: context)).to be_nil
+        end
+
+        it 'clears all baggage values' do
+          # Set multiple baggage values
+          context = otel_baggage.set_value('key1', 'value1')
+          context = otel_baggage.set_value('key2', 'value2', context: context)
+
+          # Clear all values
+          context = otel_baggage.clear(context: context)
+
+          # All values should be cleared
+          expect(otel_baggage.values(context: context)).to be_empty
+        end
+
+        # Set Datadog baggage and read from otel
+        it 'shares baggage between Datadog and OpenTelemetry' do
+          # Set baggage using Datadog API
+          Datadog::Tracing.baggage['dd_key'] = 'dd_value'
+
+          # Verify it can be read by OpenTelemetry API
+          expect(otel_baggage.value('dd_key')).to eq('dd_value')
+
+          # Set baggage using OpenTelemetry API
+          context = otel_baggage.set_value('otel_key', 'otel_value')
+
+          ::OpenTelemetry::Context.attach(context)
+
+          # Verify it can be read by Datadog API
+          expect(Datadog::Tracing.baggage['otel_key']).to eq('otel_value')
+        end
+      end
+    end
   end
 end
diff --git a/vendor/rbs/opentelemetry-api/0/opentelemetry-api.rbs b/vendor/rbs/opentelemetry-api/0/opentelemetry-api.rbs
index 2a1554671ef..75f2d270367 100644
--- a/vendor/rbs/opentelemetry-api/0/opentelemetry-api.rbs
+++ b/vendor/rbs/opentelemetry-api/0/opentelemetry-api.rbs
@@ -1,4 +1,13 @@
 module OpenTelemetry
+  class Context
+    def self.current: () -> self
+    def ensure_trace: () -> Datadog::Tracing::TraceOperation?
+    def set_values: (Hash[Symbol, Hash[String, String] | String]) -> self
+  end
+
+  module Baggage
+  end
+
   module Trace
   end
 end


Reviews:
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T19:38:08Z
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T20:46:44Z
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T21:00:10Z
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T19:11:26Z
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T20:04:56Z
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T20:21:54Z
user: login: datadog-datadog-prod-us1[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T20:25:16Z
user: login: marcotc
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-20T20:11:05Z

Review comments:
diff_hunk: @@ -67,4 +68,11 @@
       let(:datadog) { propagation }
     end
   end
+
+  context 'for Baggage' do
+    it_behaves_like 'Baggage distributed format' do
+      before { Datadog.configure { |c| c.tracing.propagation_style = ['baggage'] } }
path: spec/datadog/tracing/contrib/http/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
      before { Datadog.configure { |c| c.tracing.propagation_style = %w[baggage] } }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATO-56GdLgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBdFkzd3NlOE9kQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATO-56GdLgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBdFkzd3NlOE9kQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -19,8 +20,8 @@
     )
   end
 
-  let(:propagation_style_inject) { ['datadog', 'tracecontext'] }
-  let(:propagation_style_extract) { ['datadog', 'tracecontext'] }
+  let(:propagation_style_inject) { ['datadog', 'tracecontext', 'baggage'] }
path: spec/datadog/tracing/contrib/http/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
  let(:propagation_style_inject) { %w[datadog tracecontext baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATO-56Gc9wAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBR25uUy1FaVlZQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATO-56Gc9wAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBR25uUy1FaVlZQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -417,16 +440,18 @@
             expect(trace_digest.span_id).to eq(73456)
             expect(trace_digest.trace_id).to eq(61185)
             expect(trace_digest.trace_sampling_priority).to eq(1)
+            expect(trace_digest.baggage).to eq({ 'key' => 'value' })
path: spec/datadog/tracing/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATO-56GddQAAAAAAAAAYAAAAAEFaV1JBUnRJQUFEaUcxQ05mV0JYQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATO-56GddQAAAAAAAAAYAAAAAEFaV1JBUnRJQUFEaUcxQ05mV0JYQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATO-56GdxgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFEekNLWkJubGNwQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATO-56GdxgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFEekNLWkJubGNwQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,8 +18,8 @@
     )
   end
 
-  let(:propagation_style_inject) { ['datadog', 'tracecontext'] }
-  let(:propagation_style_extract) { ['datadog', 'tracecontext'] }
+  let(:propagation_style_inject) { ['datadog', 'tracecontext', 'baggage'] }
path: spec/datadog/tracing/contrib/grpc/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
  let(:propagation_style_inject) { %w[datadog tracecontext baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATO-56GdtAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCc09jcXdld3N3QUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATO-56GdtAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCc09jcXdld3N3QUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
+        )
+      end
+
+      it do
+        inject!
+        expect(data).to eq(
+          'baggage' => 'key=value',
+        )
+      end
+
+      context 'with multiple key value' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key' => 'value', 'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key=value,key2=value2',
+          )
+        end
+      end
+
+      context 'with special allowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^_`|~' =>
+            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~',
+                       'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^' \
+            '_`|~=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~,key2=value2',
+          )
+        end
+      end
+
+      context 'with special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key with=spacesand%' => 'value with=spaces' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key%20with%3Dspacesand%25=value%20with%3Dspaces',
+          )
+        end
+      end
+
+      context 'with other special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'userId' => 'Amélie' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'userId=Am%C3%A9lie',
+          )
+        end
+      end
+
+      context 'when baggage size exceeds maximum items' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: (1..(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS + 1)).map do |i|
+              ["key#{i}", "value#{i}"]
+            end.to_h
+          )
+        end
+
+        it 'logs a warning and stops injecting excess items' do
+          expect(Datadog.logger).to receive(:warn).with('Baggage item limit exceeded, dropping excess items')
+          inject!
+          expect(data['baggage'].split(',').size).to eq(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS)
+        end
+      end
+
+      context 'when baggage size exceeds maximum bytes' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key1' => 'value1',
+                       'key' => 'a' * (Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_BYTES + 1) }
+          )
+        end
+
+        it 'logs a warning and stops injecting excess items' do
+          expect(Datadog.logger).to receive(:warn).with('Baggage header size exceeded, dropping excess items')
+          inject!
+          expect(data['baggage']).to eq('key1=value1')
+        end
+      end
+    end
+  end
+
+  describe '#extract' do
+    subject(:extract) { propagation.extract(data) }
+    let(:digest) { extract }
+
+    let(:data) { {} }
+
+    context 'with empty data' do
+      it { is_expected.to be nil }
+    end
+
+    context 'single key value' do
+      let(:data) do
+        { prepare_key['baggage'] => 'key=value' }
+      end
+
+      it { expect(digest.baggage).to eq({ 'key' => 'value' }) }
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqEKwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBS3daUkY5OEpkQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqEKwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBS3daUkY5OEpkQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
+        )
+      end
+
+      it do
+        inject!
+        expect(data).to eq(
+          'baggage' => 'key=value',
+        )
+      end
+
+      context 'with multiple key value' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key' => 'value', 'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key=value,key2=value2',
+          )
+        end
+      end
+
+      context 'with special allowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^_`|~' =>
+            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~',
+                       'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^' \
+            '_`|~=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~,key2=value2',
+          )
+        end
+      end
+
+      context 'with special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key with=spacesand%' => 'value with=spaces' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key%20with%3Dspacesand%25=value%20with%3Dspaces',
+          )
+        end
+      end
+
+      context 'with other special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'userId' => 'Amélie' },
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqCOgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCRUpCNGIzTDhGQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqCOgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCRUpCNGIzTDhGQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
+        )
+      end
+
+      it do
+        inject!
+        expect(data).to eq(
+          'baggage' => 'key=value',
+        )
+      end
+
+      context 'with multiple key value' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key' => 'value', 'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key=value,key2=value2',
+          )
+        end
+      end
+
+      context 'with special allowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^_`|~' =>
+            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~',
+                       'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^' \
+            '_`|~=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~,key2=value2',
+          )
+        end
+      end
+
+      context 'with special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key with=spacesand%' => 'value with=spaces' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key%20with%3Dspacesand%25=value%20with%3Dspaces',
+          )
+        end
+      end
+
+      context 'with other special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'userId' => 'Amélie' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'userId=Am%C3%A9lie',
+          )
+        end
+      end
+
+      context 'when baggage size exceeds maximum items' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: (1..(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS + 1)).map do |i|
+              ["key#{i}", "value#{i}"]
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
              %W[key#{i} value#{i}]
```

<details>
  <summary>
    Consider using the %W syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqCCAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCRlNlemJIaXNSQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqCCAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCRlNlemJIaXNSQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -13,21 +13,22 @@
       let(:trace_id) { Datadog::Tracing::Utils::TraceId.next_id }
       let(:span_id) { Datadog::Tracing::Utils.next_id }
       let(:digest) do
-        Datadog::Tracing::TraceDigest.new(trace_id: trace_id, span_id: span_id)
+        Datadog::Tracing::TraceDigest.new(trace_id: trace_id, span_id: span_id, baggage: { 'key' => 'value' })
path: spec/datadog/tracing/contrib/grpc_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqDlgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFERFlMZ1kzZ242QUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqDlgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFERFlMZ1kzZ242QUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
+        )
+      end
+
+      it do
+        inject!
+        expect(data).to eq(
+          'baggage' => 'key=value',
+        )
+      end
+
+      context 'with multiple key value' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key' => 'value', 'key2' => 'value2' },
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqDTgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCcmZGT1l5cjlNQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqDTgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCcmZGT1l5cjlNQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,21 +11,22 @@
       let(:trace_id) { Datadog::Tracing::Utils::TraceId.next_id }
       let(:span_id) { Datadog::Tracing::Utils.next_id }
       let(:digest) do
-        Datadog::Tracing::TraceDigest.new(trace_id: trace_id, span_id: span_id)
+        Datadog::Tracing::TraceDigest.new(trace_id: trace_id, span_id: span_id, baggage: { 'key' => 'value' })
path: spec/datadog/tracing/contrib/http_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqEPAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDQXpqd241Nk5fQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqEPAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDQXpqd241Nk5fQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1059,6 +1059,36 @@
       end
     end
   end
+
+  describe '#baggage_tracing_interactions' do
+    it 'baggage set before active trace creates active trace' do
+      Datadog::Tracing.baggage['key'] = 'value'
+      Datadog::Tracing.trace('operation') do |_span, trace|
+        expect(trace.to_digest.baggage).to eq('key' => 'value')
+      end
+    end
+
+    it 'baggage set after trace finish creates new traceoperation with baggage value' do
+      Datadog::Tracing.trace('operation') do |_span, _trace|
+        expect(Datadog::Tracing.baggage).to be_empty
+      end
+      Datadog::Tracing.baggage['key'] = 'value'
+      expect(Datadog::Tracing.active_trace.to_digest.baggage).to eq('key' => 'value')
+    end
+  end
+
+  it 'baggage value is overridden inside an active trace' do
+    Datadog::Tracing.trace('operation') do |_span, trace|
+      Datadog::Tracing.baggage['key'] = 'value'
+      expect(trace.to_digest.baggage).to eq('key' => 'value')
+    end
+  end
+
+  it 'incoming headers overrides existing baggage' do
+    Datadog::Tracing.baggage['key'] = 'value'
+    Datadog::Tracing.continue_trace!(Datadog::Tracing::TraceDigest.new(baggage: { 'key1' => 'value1' }))
path: spec/datadog/tracing/tracer_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqCHAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCd3k1cktuRVlUQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqCHAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCd3k1cktuRVlUQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
+        )
+      end
+
+      it do
+        inject!
+        expect(data).to eq(
+          'baggage' => 'key=value',
+        )
+      end
+
+      context 'with multiple key value' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key' => 'value', 'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key=value,key2=value2',
+          )
+        end
+      end
+
+      context 'with special allowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^_`|~' =>
+            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~',
+                       'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^' \
+            '_`|~=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~,key2=value2',
+          )
+        end
+      end
+
+      context 'with special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key with=spacesand%' => 'value with=spaces' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key%20with%3Dspacesand%25=value%20with%3Dspaces',
+          )
+        end
+      end
+
+      context 'with other special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'userId' => 'Amélie' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'userId=Am%C3%A9lie',
+          )
+        end
+      end
+
+      context 'when baggage size exceeds maximum items' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: (1..(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS + 1)).map do |i|
+              ["key#{i}", "value#{i}"]
+            end.to_h
+          )
+        end
+
+        it 'logs a warning and stops injecting excess items' do
+          expect(Datadog.logger).to receive(:warn).with('Baggage item limit exceeded, dropping excess items')
+          inject!
+          expect(data['baggage'].split(',').size).to eq(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS)
+        end
+      end
+
+      context 'when baggage size exceeds maximum bytes' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key1' => 'value1',
+                       'key' => 'a' * (Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_BYTES + 1) }
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqE8QAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDemVNeDRXRlJhQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqE8QAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDemVNeDRXRlJhQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -82,4 +83,11 @@
       let(:datadog) { propagation }
     end
   end
+
+  context 'for Baggage' do
+    it_behaves_like 'Baggage distributed format' do
+      before { Datadog.configure { |c| c.tracing.propagation_style = ['baggage'] } }
path: spec/datadog/tracing/contrib/grpc/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
      before { Datadog.configure { |c| c.tracing.propagation_style = %w[baggage] } }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATNfnXqEhgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFERUx5ZzZJTXVLQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATNfnXqEhgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFERUx5ZzZJTXVLQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -19,8 +20,8 @@
     )
   end
 
-  let(:propagation_style_inject) { ['datadog', 'tracecontext'] }
-  let(:propagation_style_extract) { ['datadog', 'tracecontext'] }
+  let(:propagation_style_inject) { ['datadog', 'tracecontext', 'baggage'] }
+  let(:propagation_style_extract) { ['datadog', 'tracecontext', 'baggage'] }
path: spec/datadog/tracing/contrib/http/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
  let(:propagation_style_extract) { %w[datadog tracecontext baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuR1QAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCQUhWZGVfWXl4QUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuR1QAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCQUhWZGVfWXl4QUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,8 +18,8 @@
     )
   end
 
-  let(:propagation_style_inject) { ['datadog', 'tracecontext'] }
-  let(:propagation_style_extract) { ['datadog', 'tracecontext'] }
+  let(:propagation_style_inject) { ['datadog', 'tracecontext', 'baggage'] }
+  let(:propagation_style_extract) { ['datadog', 'tracecontext', 'baggage'] }
path: spec/datadog/tracing/contrib/grpc/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
  let(:propagation_style_extract) { %w[datadog tracecontext baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuOQwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFEYTk3TUU4cGRlQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuOQwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFEYTk3TUU4cGRlQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -464,12 +492,14 @@
         let(:tracecontext_span_id) { 0x1111111 }
 
         let(:tracecontext_trace_flags) { 0x01 }
+        let(:baggage) { { 'key' => 'value' } }
path: spec/datadog/tracing/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuQkQAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBTWtqSENESkRCQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuQkQAAAAAAAAAYAAAAAEFaV1JBUnRJQUFBTWtqSENESkRCQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -43,9 +44,15 @@
       let(:span_id) { 9876543210 }
       let(:sampling_priority) { nil }
       let(:origin) { nil }
+      let(:baggage) { { 'key' => 'value', 'key2' => 'value2' } }
path: spec/datadog/tracing/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuPRgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCNXVoV2c0SVNlQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuPRgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCNXVoV2c0SVNlQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+require 'spec_helper'
+
+require 'datadog/tracing/distributed/datadog'
+require 'datadog/tracing/trace_digest'
+require 'datadog/tracing/utils'
+
+RSpec.shared_examples 'Baggage distributed format' do
+  let(:propagation_style_inject) { %w[baggage] }
+  let(:propagation_style_extract) { %w[baggage] }
+
+  let(:prepare_key) { defined?(super) ? super() : proc { |key| key } }
+
+  describe '#inject!' do
+    subject(:inject!) { propagation.inject!(digest, data) }
+    let(:data) { {} }
+
+    context 'with nil digest' do
+      let(:digest) { nil }
+      it { is_expected.to be nil }
+    end
+
+    context 'with TraceDigest' do
+      let(:digest) do
+        Datadog::Tracing::TraceDigest.new(
+          baggage: { 'key' => 'value' },
+        )
+      end
+
+      it do
+        inject!
+        expect(data).to eq(
+          'baggage' => 'key=value',
+        )
+      end
+
+      context 'with multiple key value' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key' => 'value', 'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key=value,key2=value2',
+          )
+        end
+      end
+
+      context 'with special allowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^_`|~' =>
+            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~',
+                       'key2' => 'value2' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'*+-.^' \
+            '_`|~=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$&\'()*+-./:<>?@[]^_`{|}~,key2=value2',
+          )
+        end
+      end
+
+      context 'with special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key with=spacesand%' => 'value with=spaces' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'key%20with%3Dspacesand%25=value%20with%3Dspaces',
+          )
+        end
+      end
+
+      context 'with other special disallowed characters' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'userId' => 'Amélie' },
+          )
+        end
+
+        it do
+          inject!
+          expect(data).to eq(
+            'baggage' => 'userId=Am%C3%A9lie',
+          )
+        end
+      end
+
+      context 'when baggage size exceeds maximum items' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: (1..(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS + 1)).map do |i|
+              ["key#{i}", "value#{i}"]
+            end.to_h
+          )
+        end
+
+        it 'logs a warning and stops injecting excess items' do
+          expect(Datadog.logger).to receive(:warn).with('Baggage item limit exceeded, dropping excess items')
+          inject!
+          expect(data['baggage'].split(',').size).to eq(Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_ITEMS)
+        end
+      end
+
+      context 'when baggage size exceeds maximum bytes' do
+        let(:digest) do
+          Datadog::Tracing::TraceDigest.new(
+            baggage: { 'key1' => 'value1',
+                       'key' => 'a' * (Datadog::Tracing::Distributed::Baggage::DD_TRACE_BAGGAGE_MAX_BYTES + 1) }
+          )
+        end
+
+        it 'logs a warning and stops injecting excess items' do
+          expect(Datadog.logger).to receive(:warn).with('Baggage header size exceeded, dropping excess items')
+          inject!
+          expect(data['baggage']).to eq('key1=value1')
+        end
+      end
+    end
+  end
+
+  describe '#extract' do
+    subject(:extract) { propagation.extract(data) }
+    let(:digest) { extract }
+
+    let(:data) { {} }
+
+    context 'with empty data' do
+      it { is_expected.to be nil }
+    end
+
+    context 'single key value' do
+      let(:data) do
+        { prepare_key['baggage'] => 'key=value' }
+      end
+
+      it { expect(digest.baggage).to eq({ 'key' => 'value' }) }
+    end
+
+    context 'multiple key value' do
+      let(:data) do
+        { prepare_key['baggage'] => 'key=value,key2=value2' }
+      end
+
+      it { expect(digest.baggage).to eq({ 'key' => 'value', 'key2' => 'value2' }) }
path: spec/datadog/tracing/distributed/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuOWgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDN1FYd1RzZlllQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuOWgAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDN1FYd1RzZlllQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -19,12 +19,13 @@
     {
       'datadog' => Datadog::Tracing::Distributed::Datadog.new(fetcher: fetcher_class),
       'tracecontext' => Datadog::Tracing::Distributed::TraceContext.new(fetcher: fetcher_class),
+      'baggage' => Datadog::Tracing::Distributed::Baggage.new(fetcher: fetcher_class),
     }
   end
   let(:fetcher_class) { Datadog::Tracing::Distributed::Fetcher }
 
-  let(:propagation_style_inject) { ['datadog', 'tracecontext'] }
-  let(:propagation_style_extract) { ['datadog', 'tracecontext'] }
+  let(:propagation_style_inject) { ['datadog', 'tracecontext', 'baggage'] }
path: spec/datadog/tracing/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
  let(:propagation_style_inject) { %w[datadog tracecontext baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuRhAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDdEhJQ0NxQlFRQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuRhAAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDdEhJQ0NxQlFRQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -19,12 +19,13 @@
     {
       'datadog' => Datadog::Tracing::Distributed::Datadog.new(fetcher: fetcher_class),
       'tracecontext' => Datadog::Tracing::Distributed::TraceContext.new(fetcher: fetcher_class),
+      'baggage' => Datadog::Tracing::Distributed::Baggage.new(fetcher: fetcher_class),
     }
   end
   let(:fetcher_class) { Datadog::Tracing::Distributed::Fetcher }
 
-  let(:propagation_style_inject) { ['datadog', 'tracecontext'] }
-  let(:propagation_style_extract) { ['datadog', 'tracecontext'] }
+  let(:propagation_style_inject) { ['datadog', 'tracecontext', 'baggage'] }
+  let(:propagation_style_extract) { ['datadog', 'tracecontext', 'baggage'] }
path: spec/datadog/tracing/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
  let(:propagation_style_extract) { %w[datadog tracecontext baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuQDwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCekZ3U1BOUm1QQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuQDwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFCekZ3U1BOUm1QQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -139,6 +148,16 @@
           end
         end
       end
+      it_behaves_like 'trace injection' do
+        context 'with only baggage' do
+          let(:propagation_style_inject) { ['baggage'] }
path: spec/datadog/tracing/distributed/propagation_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/percent-w -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>

```suggestion
          let(:propagation_style_inject) { %w[baggage] }
```

<details>
  <summary>
    Consider using the %w syntax instead <i>(...read more)</i>
  </summary>

<br>

The rule "Prefer `%w` to the literal array syntax" is a Ruby style guideline that encourages the use of `%w` notation instead of the traditional array syntax when defining arrays of strings. This rule is part of the Ruby community's efforts to promote readability and simplicity in Ruby code.

This rule is important because it helps to keep the code concise and easy to read. The `%w` notation allows you to define an array of strings without having to use quotes and commas. This can make the code cleaner and easier to understand, especially when dealing with large arrays.

To follow this rule, replace the traditional array syntax with the `%w` notation. For example, instead of writing `['foo', 'bar', 'baz']`, you should write `%w[foo bar baz]`. This will create the same array, but in a more readable and concise way. By following this rule, you can help to make your Ruby code cleaner and easier to understand.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/2af054b9483aa4ab1adbdfb9bade4aca9c7da0cf/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%222af054b9483aa4ab1adbdfb9bade4aca9c7da0cf%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRATKc4OuREwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDb1NUTm43SGUzQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw&trace=AgAAAZWRATKc4OuREwAAAAAAAAAYAAAAAEFaV1JBUnRJQUFDb1NUTm43SGUzQUFBQQAAACQAAAAAMDE5NTkxMDEtMzNiZS00MjgyLWE5YTktN2QyZTdhMzExYWIw" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/percent-w" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T19:38:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe7g4lGPtgAAAAAAAAAYAAAAAEFaV1JRZFpMQUFDWW8yR3ZnVThYQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe7g4lGPtgAAAAAAAAAYAAAAAEFaV1JRZFpMQUFDWW8yR3ZnVThYQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
+      end
+
+      it 'adds a new key-value pair' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq(
+          {
+            'existing_key' => 'existing_value',
+            'test_key' => 'test_value'
+          }
+        )
+      end
+
+      it 'updates an existing key' do
+        baggage.set_value('existing_key', 'new_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'existing_key' => 'new_value' })
+      end
+
+      it 'maintains immutability by creating a copy' do
+        original_baggage = context.trace.baggage
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        # The original hash object should not be the same as the new one
+        expect(context.trace.baggage).not_to be(original_baggage)
+      end
+    end
+
+    it 'returns the context' do
+      result = baggage.set_value('test_key', 'test_value', context: context)
+
+      expect(result).to be(context)
+    end
+  end
+
+  describe '#remove_value' do
+    context 'when baggage is empty' do
+      it 'returns the context unchanged' do
+        result = baggage.remove_value('test_key', context: context)
+
+        expect(result).to be(context)
+        expect(context.trace.baggage).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'removes an existing key' do
+        baggage.remove_value('test_key', context: context)
+
+        expect(context.trace.baggage).to eq({ 'another_key' => 'another_value' })
+      end
+
+      it 'returns the context unchanged when key does not exist' do
+        original_baggage = context.trace.baggage.dup
+        baggage.remove_value('non_existent_key', context: context)
+
+        expect(context.trace.baggage).to eq(original_baggage)
+      end
+
+      it 'maintains immutability by creating a copy' do
+        original_baggage = context.trace.baggage
+        baggage.remove_value('test_key', context: context)
+
+        # The original hash object should not be the same as the new one
+        expect(context.trace.baggage).not_to be(original_baggage)
+      end
+    end
+
+    it 'returns the context' do
+      context.ensure_trace.baggage = { 'test_key' => 'test_value' }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe54wwcZPgAAAAAAAAAYAAAAAEFaV1JRZFpMQUFENUN4cnZ6em5sQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe54wwcZPgAAAAAAAAAYAAAAAEFaV1JRZFpMQUFENUN4cnZ6em5sQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
+      end
+
+      it 'adds a new key-value pair' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq(
+          {
+            'existing_key' => 'existing_value',
+            'test_key' => 'test_value'
+          }
+        )
+      end
+
+      it 'updates an existing key' do
+        baggage.set_value('existing_key', 'new_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'existing_key' => 'new_value' })
+      end
+
+      it 'maintains immutability by creating a copy' do
+        original_baggage = context.trace.baggage
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        # The original hash object should not be the same as the new one
+        expect(context.trace.baggage).not_to be(original_baggage)
+      end
+    end
+
+    it 'returns the context' do
+      result = baggage.set_value('test_key', 'test_value', context: context)
+
+      expect(result).to be(context)
+    end
+  end
+
+  describe '#remove_value' do
+    context 'when baggage is empty' do
+      it 'returns the context unchanged' do
+        result = baggage.remove_value('test_key', context: context)
+
+        expect(result).to be(context)
+        expect(context.trace.baggage).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe54wwcbkwAAAAAAAAAYAAAAAEFaV1JRZFpMQUFEN1JoeTg0dUtUQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe54wwcbkwAAAAAAAAAYAAAAAEFaV1JRZFpMQUFEN1JoeTg0dUtUQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
+      end
+
+      it 'adds a new key-value pair' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq(
+          {
+            'existing_key' => 'existing_value',
+            'test_key' => 'test_value'
+          }
+        )
+      end
+
+      it 'updates an existing key' do
+        baggage.set_value('existing_key', 'new_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'existing_key' => 'new_value' })
+      end
+
+      it 'maintains immutability by creating a copy' do
+        original_baggage = context.trace.baggage
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        # The original hash object should not be the same as the new one
+        expect(context.trace.baggage).not_to be(original_baggage)
+      end
+    end
+
+    it 'returns the context' do
+      result = baggage.set_value('test_key', 'test_value', context: context)
+
+      expect(result).to be(context)
+    end
+  end
+
+  describe '#remove_value' do
+    context 'when baggage is empty' do
+      it 'returns the context unchanged' do
+        result = baggage.remove_value('test_key', context: context)
+
+        expect(result).to be(context)
+        expect(context.trace.baggage).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'removes an existing key' do
+        baggage.remove_value('test_key', context: context)
+
+        expect(context.trace.baggage).to eq({ 'another_key' => 'another_value' })
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe54wwcb-gAAAAAAAAAYAAAAAEFaV1JRZFpMQUFEU0ZuaFRkcGx5QUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe54wwcb-gAAAAAAAAAYAAAAAEFaV1JRZFpMQUFEU0ZuaFRkcGx5QUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
+      end
+
+      it 'adds a new key-value pair' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq(
+          {
+            'existing_key' => 'existing_value',
+            'test_key' => 'test_value'
+          }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe3wqcqj_gAAAAAAAAAYAAAAAEFaV1JRZFpMQUFBUjVuUnlqeWNGQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe3wqcqj_gAAAAAAAAAYAAAAAEFaV1JRZFpMQUFBUjVuUnlqeWNGQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe3wqcqh_gAAAAAAAAAYAAAAAEFaV1JRZFpMQUFCYjBncndEenRKQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe3wqcqh_gAAAAAAAAAYAAAAAEFaV1JRZFpMQUFCYjBncndEenRKQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
+      end
+
+      it 'adds a new key-value pair' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq(
+          {
+            'existing_key' => 'existing_value',
+            'test_key' => 'test_value'
+          }
+        )
+      end
+
+      it 'updates an existing key' do
+        baggage.set_value('existing_key', 'new_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'existing_key' => 'new_value' })
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe3wqcqhsQAAAAAAAAAYAAAAAEFaV1JRZFpMQUFCVWJhdWJlMmwyQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe3wqcqhsQAAAAAAAAAYAAAAAEFaV1JRZFpMQUFCVWJhdWJlMmwyQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/ef244465e49923df490a99679285e8500924c570/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22ef244465e49923df490a99679285e8500924c570%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRQe3wqcqihwAAAAAAAAAYAAAAAEFaV1JRZFpMQUFEdHVEU3R1MVFsQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh&trace=AgAAAZWRQe3wqcqihwAAAAAAAAAYAAAAAEFaV1JRZFpMQUFEdHVEU3R1MVFsQUFBQQAAACQAAAAAMDE5NTkxNDItMDI0Ny00MzdlLTk5OWMtYWVjZTFkMDk1ZmZh" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T20:46:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'returns the value for an existing key' do
+        expect(baggage.value('test_key', context: context)).to eq('test_value')
+      end
+
+      it 'returns nil for a non-existent key' do
+        expect(baggage.value('non_existent_key', context: context)).to be_nil
+      end
+    end
+  end
+
+  describe '#values' do
+    context 'when baggage is empty' do
+      it 'returns an empty hash' do
+        expect(baggage.values(context: context)).to eq({})
+      end
+    end
+
+    context 'when baggage has values' do
+      let(:baggage_data) { { 'test_key' => 'test_value', 'another_key' => 'another_value' } }
+
+      before do
+        context.ensure_trace.baggage = baggage_data
+      end
+
+      it 'returns all baggage values' do
+        expect(baggage.values(context: context)).to eq(baggage_data)
+      end
+
+      it 'returns a copy of the baggage' do
+        result = baggage.values(context: context)
+        result['new_key'] = 'new_value'
+
+        # Original baggage should remain unchanged
+        expect(context.trace.baggage).to eq(baggage_data)
+      end
+    end
+  end
+
+  describe '#set_value' do
+    context 'when baggage is empty' do
+      it 'initializes baggage and sets the value' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'test_key' => 'test_value' })
+      end
+    end
+
+    context 'when baggage already has values' do
+      before do
+        context.ensure_trace.baggage = { 'existing_key' => 'existing_value' }
+      end
+
+      it 'adds a new key-value pair' do
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        expect(context.trace.baggage).to eq(
+          {
+            'existing_key' => 'existing_value',
+            'test_key' => 'test_value'
+          }
+        )
+      end
+
+      it 'updates an existing key' do
+        baggage.set_value('existing_key', 'new_value', context: context)
+
+        expect(context.trace.baggage).to eq({ 'existing_key' => 'new_value' })
+      end
+
+      it 'maintains immutability by creating a copy' do
+        original_baggage = context.trace.baggage
+        baggage.set_value('test_key', 'test_value', context: context)
+
+        # The original hash object should not be the same as the new one
+        expect(context.trace.baggage).not_to be(original_baggage)
+      end
+    end
+
+    it 'returns the context' do
+      result = baggage.set_value('test_key', 'test_value', context: context)
+
+      expect(result).to be(context)
+    end
+  end
+
+  describe '#remove_value' do
+    context 'when baggage is empty' do
+      it 'returns the context unchanged' do
+        result = baggage.remove_value('test_key', context: context)
+
+        expect(result).to be(context)
+        expect(context.trace.baggage).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
+      end
+
+      it 'removes an existing key' do
+        baggage.remove_value('test_key', context: context)
+
+        expect(context.trace.baggage).to eq({ 'another_key' => 'another_value' })
+      end
+
+      it 'returns the context unchanged when key does not exist' do
+        original_baggage = context.trace.baggage.dup
+        baggage.remove_value('non_existent_key', context: context)
+
+        expect(context.trace.baggage).to eq(original_baggage)
+      end
+
+      it 'maintains immutability by creating a copy' do
+        original_baggage = context.trace.baggage
+        baggage.remove_value('test_key', context: context)
+
+        # The original hash object should not be the same as the new one
+        expect(context.trace.baggage).not_to be(original_baggage)
+      end
+    end
+
+    it 'returns the context' do
+      context.ensure_trace.baggage = { 'test_key' => 'test_value' }
+      result = baggage.remove_value('test_key', context: context)
+
+      expect(result).to be(context)
+    end
+  end
+
+  describe '#clear' do
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/0c3910b714b7e4d418c32310456144ad908be59f/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%220c3910b714b7e4d418c32310456144ad908be59f%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWRTj704umOQQAAAAAAAAAYAAAAAEFaV1JUaXdOQUFDVjkzSU5rWVZ5QUFBQQAAACQAAAAAMDE5NTkxNGUtM2VmNC00ZmIxLWE4OTYtNTNmZjEyM2JhZWMy&trace=AgAAAZWRTj704umOQQAAAAAAAAAYAAAAAEFaV1JUaXdOQUFDVjkzSU5rWVZ5QUFBQQAAACQAAAAAMDE5NTkxNGUtM2VmNC00ZmIxLWE4OTYtNTNmZjEyM2JhZWMy" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-13T21:00:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { described_class.new }
+
+  # Mock Context class for testing
+  let(:context) do
+    Class.new do
+      attr_accessor :trace
+
+      def initialize(trace = nil)
+        @trace = trace
+      end
+
+      def ensure_trace
+        @trace ||= Datadog::Tracing::TraceOperation.new(
+          id: Datadog::Tracing::Utils.next_id,
+          parent_id: Datadog::Tracing::Utils.next_id,
+          sampled: true
+        )
+      end
+    end.new
+  end
+
+  describe '#value' do
+    context 'when baggage is empty' do
+      it 'returns nil for any key' do
+        expect(baggage.value('test_key', context: context)).to be_nil
+      end
+    end
+
+    context 'when baggage has values' do
+      before do
+        context.ensure_trace.baggage = { 'test_key' => 'test_value', 'another_key' => 'another_value' }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/9809c3f807992282d17d904e9eb87bb558020cd8/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%229809c3f807992282d17d904e9eb87bb558020cd8%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWWEQNW4gdKDwAAAAAAAAAYAAAAAEFaV1dFUGlUQUFEVDN1VEMzZDhjQUFBQQAAACQAAAAAMDE5NTk2MTEtMmQ5Ni00M2QwLThiNzktZmZjNDFlNGJiNTYx&trace=AgAAAZWWEQNW4gdKDwAAAAAAAAAYAAAAAEFaV1dFUGlUQUFEVDN1VEMzZDhjQUFBQQAAACQAAAAAMDE5NTk2MTEtMmQ5Ni00M2QwLThiNzktZmZjNDFlNGJiNTYx" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-14T19:11:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'opentelemetry/sdk'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { ::OpenTelemetry::Baggage }
+
+  let(:trace) { Datadog::Tracing::TraceOperation.new }
+  let(:context) { ::OpenTelemetry::Context.current }
+
+  before do
+    # Reset any existing baggage before each test
+    trace.baggage = {}
+  end
+
+  describe '#set_value' do
+    it 'sets a baggage value in the trace' do
+      ctx = baggage.set_value('test_key', 'test_value')
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('test_value')
+    end
+
+    it 'updates an existing baggage value' do
+      ctx = baggage.set_value('test_key', 'initial_value')
+      ctx = baggage.set_value('test_key', 'new_value', context: ctx)
+
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('new_value')
+    end
+
+    it 'preserves existing baggage values when adding new ones' do
+      ctx = baggage.set_value('key1', 'value1')
+      ctx = baggage.set_value('key2', 'value2', context: ctx)
+
+      expect(ctx.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/f723c820d1ee80a47472ee0a62ef2e507a5fd24a/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22f723c820d1ee80a47472ee0a62ef2e507a5fd24a%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWv9f4DixuuqwAAAAAAAAAYAAAAAEFaV3ZzTkZlQUFBd01LZU1KSzdvQUFBQQAAACQAAAAAMDE5NWFmZjctYWQ4Ni00ZmIzLWI5NjYtOTNhMjBlNjljODIz&trace=AgAAAZWv9f4DixuuqwAAAAAAAAAYAAAAAEFaV3ZzTkZlQUFBd01LZU1KSzdvQUFBQQAAACQAAAAAMDE5NWFmZjctYWQ4Ni00ZmIzLWI5NjYtOTNhMjBlNjljODIz" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-19T20:04:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'opentelemetry/sdk'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { ::OpenTelemetry::Baggage }
+
+  let(:trace) { Datadog::Tracing::TraceOperation.new }
+  let(:context) { ::OpenTelemetry::Context.current }
+
+  before do
+    # Reset any existing baggage before each test
+    trace.baggage = {}
+  end
+
+  describe '#set_value' do
+    it 'sets a baggage value in the trace' do
+      ctx = baggage.set_value('test_key', 'test_value')
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('test_value')
+    end
+
+    it 'updates an existing baggage value' do
+      ctx = baggage.set_value('test_key', 'initial_value')
+      ctx = baggage.set_value('test_key', 'new_value', context: ctx)
+
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('new_value')
+    end
+
+    it 'preserves existing baggage values when adding new ones' do
+      ctx = baggage.set_value('key1', 'value1')
+      ctx = baggage.set_value('key2', 'value2', context: ctx)
+
+      expect(ctx.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+
+    it 'maintains immutability of the baggage hash' do
+      original_baggage = trace.baggage.dup
+      baggage.set_value('test_key', 'test_value')
+
+      expect(trace.baggage).not_to be(original_baggage)
+    end
+  end
+
+  describe '#remove_value' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'removes a baggage value from the trace' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq({'key2' => 'value2'})
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/f723c820d1ee80a47472ee0a62ef2e507a5fd24a/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%22f723c820d1ee80a47472ee0a62ef2e507a5fd24a%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWv9fyMqOluiAAAAAAAAAAYAAAAAEFaV3ZzTkZlQUFBb3BxM0ZIZTdEQUFBQQAAACQAAAAAMDE5NWFmZjctYWQ4Ni00ZmIzLWI5NjYtOTNhMjBlNjljODIz&trace=AgAAAZWv9fyMqOluiAAAAAAAAAAYAAAAAEFaV3ZzTkZlQUFBb3BxM0ZIZTdEQUFBQQAAACQAAAAAMDE5NWFmZjctYWQ4Ni00ZmIzLWI5NjYtOTNhMjBlNjljODIz" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-19T20:04:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'opentelemetry/sdk'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { ::OpenTelemetry::Baggage }
+
+  let(:trace) { Datadog::Tracing::TraceOperation.new }
+  let(:context) { ::OpenTelemetry::Context.current }
+
+  before do
+    # Reset any existing baggage before each test
+    trace.baggage = {}
+  end
+
+  describe '#set_value' do
+    it 'sets a baggage value in the trace' do
+      ctx = baggage.set_value('test_key', 'test_value')
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('test_value')
+    end
+
+    it 'updates an existing baggage value' do
+      ctx = baggage.set_value('test_key', 'initial_value')
+      ctx = baggage.set_value('test_key', 'new_value', context: ctx)
+
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('new_value')
+    end
+
+    it 'preserves existing baggage values when adding new ones' do
+      ctx = baggage.set_value('key1', 'value1')
+      ctx = baggage.set_value('key2', 'value2', context: ctx)
+
+      expect(ctx.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+
+    it 'maintains immutability of the baggage hash' do
+      original_baggage = trace.baggage.dup
+      baggage.set_value('test_key', 'test_value')
+
+      expect(trace.baggage).not_to be(original_baggage)
+    end
+  end
+
+  describe '#remove_value' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'removes a baggage value from the trace' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq({ 'key2' => 'value2' })
+    end
+
+    it 'preserves other baggage values when removing one' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result.instance_variable_get(:@trace).baggage).to eq({ 'key2' => 'value2' })
+    end
+
+    it 'handles removing non-existent keys' do
+      result = baggage.remove_value('non_existent_key', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/07852cb2a44d73c540eb8b7d555be8c28170eca4/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%2207852cb2a44d73c540eb8b7d555be8c28170eca4%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWwCz5Ox0ic7wAAAAAAAAAYAAAAAEFaV3ZrRS1JQUFEVnctSzJCYkRvQUFBQQAAACQAAAAAMDE5NWIwMGItNTk5ZC00YjNkLWFjN2MtODFhMzA4ZDhiODY0&trace=AgAAAZWwCz5Ox0ic7wAAAAAAAAAYAAAAAEFaV3ZrRS1JQUFEVnctSzJCYkRvQUFBQQAAACQAAAAAMDE5NWIwMGItNTk5ZC00YjNkLWFjN2MtODFhMzA4ZDhiODY0" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-19T20:21:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'opentelemetry/sdk'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { ::OpenTelemetry::Baggage }
+
+  let(:trace) { Datadog::Tracing::TraceOperation.new }
+  let(:context) { ::OpenTelemetry::Context.current }
+
+  before do
+    # Reset any existing baggage before each test
+    trace.baggage = {}
+  end
+
+  describe '#set_value' do
+    it 'sets a baggage value in the trace' do
+      ctx = baggage.set_value('test_key', 'test_value')
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('test_value')
+    end
+
+    it 'updates an existing baggage value' do
+      ctx = baggage.set_value('test_key', 'initial_value')
+      ctx = baggage.set_value('test_key', 'new_value', context: ctx)
+
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('new_value')
+    end
+
+    it 'preserves existing baggage values when adding new ones' do
+      ctx = baggage.set_value('key1', 'value1')
+      ctx = baggage.set_value('key2', 'value2', context: ctx)
+
+      expect(ctx.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+
+    it 'maintains immutability of the baggage hash' do
+      original_baggage = trace.baggage.dup
+      baggage.set_value('test_key', 'test_value')
+
+      expect(trace.baggage).not_to be(original_baggage)
+    end
+  end
+
+  describe '#remove_value' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'removes a baggage value from the trace' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq({'key2' => 'value2'})
+    end
+
+    it 'preserves other baggage values when removing one' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result.instance_variable_get(:@trace).baggage).to eq({'key2' => 'value2'})
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/8728d96115345e45d7840e28bd3f9f1e7093a132/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%228728d96115345e45d7840e28bd3f9f1e7093a132%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWv_Ohi_VVOkgAAAAAAAAAYAAAAAEFaV3ZxNEFZQUFBZjItRXd0U2N5QUFBQQAAACQAAAAAMDE5NWFmZmQtYTgzYy00M2E4LWE5ODAtZGUxZTVlZDExMTBk&trace=AgAAAZWv_Ohi_VVOkgAAAAAAAAAYAAAAAEFaV3ZxNEFZQUFBZjItRXd0U2N5QUFBQQAAACQAAAAAMDE5NWFmZmQtYTgzYy00M2E4LWE5ODAtZGUxZTVlZDExMTBk" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-19T20:25:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'opentelemetry/sdk'
+require 'datadog/opentelemetry'
+
+RSpec.describe Datadog::OpenTelemetry::API::Baggage do
+  subject(:baggage) { ::OpenTelemetry::Baggage }
+
+  let(:trace) { Datadog::Tracing::TraceOperation.new }
+  let(:context) { ::OpenTelemetry::Context.current }
+
+  before do
+    # Reset any existing baggage before each test
+    trace.baggage = {}
+  end
+
+  describe '#set_value' do
+    it 'sets a baggage value in the trace' do
+      ctx = baggage.set_value('test_key', 'test_value')
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('test_value')
+    end
+
+    it 'updates an existing baggage value' do
+      ctx = baggage.set_value('test_key', 'initial_value')
+      ctx = baggage.set_value('test_key', 'new_value', context: ctx)
+
+      expect(ctx).to be_a(OpenTelemetry::Context)
+      expect(ctx.instance_variable_get(:@trace).baggage['test_key']).to eq('new_value')
+    end
+
+    it 'preserves existing baggage values when adding new ones' do
+      ctx = baggage.set_value('key1', 'value1')
+      ctx = baggage.set_value('key2', 'value2', context: ctx)
+
+      expect(ctx.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+
+    it 'maintains immutability of the baggage hash' do
+      original_baggage = trace.baggage.dup
+      baggage.set_value('test_key', 'test_value')
+
+      expect(trace.baggage).not_to be(original_baggage)
+    end
+  end
+
+  describe '#remove_value' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'removes a baggage value from the trace' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq({'key2' => 'value2'})
+    end
+
+    it 'preserves other baggage values when removing one' do
+      result = baggage.remove_value('key1', context: ctx)
+
+      expect(result.instance_variable_get(:@trace).baggage).to eq({'key2' => 'value2'})
+    end
+
+    it 'handles removing non-existent keys' do
+      result = baggage.remove_value('non_existent_key', context: ctx)
+
+      expect(result).to be_a(OpenTelemetry::Context)
+      expect(result.instance_variable_get(:@trace).baggage).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
+      )
+    end
+  end
+
+  describe '#value' do
+    let(:ctx) do
+      baggage.set_value('key1', 'value1')
+    end
+
+    it 'retrieves a baggage value from the trace' do
+      expect(baggage.value('key1', context: ctx)).to eq('value1')
+    end
+
+    it 'returns nil for non-existent keys' do
+      expect(baggage.value('non_existent_key', context: ctx)).to be_nil
+    end
+  end
+
+  describe '#values' do
+    let(:ctx) do
+      ctx1 = baggage.set_value('key1', 'value1')
+      baggage.set_value('key2', 'value2', context: ctx1)
+    end
+
+    it 'returns all baggage values from the trace' do
+      expect(baggage.values(context: ctx)).to eq(
+        {
+          'key1' => 'value1',
+          'key2' => 'value2'
+        }
path: spec/datadog/opentelemetry/api/baggage_spec.rb
user: login: datadog-datadog-prod-us1[bot]
body: <!-- ruby-best-practices/symbols-as-keys -->

<h3><span title="Notice"> :white_circle: </span>Code Quality Violation</h3>



<details>
  <summary>
    Consider using symbols instead of string hash keys <i>(...read more)</i>
  </summary>

<br>

In Ruby, it is a best practice to use symbols instead of strings as hash keys. This rule emphasizes that it's more efficient and idiomatic to use symbols for this purpose. Symbols are immutable and unique, which makes them ideal for identifying things, whereas strings are mutable and can create multiple objects for the same sequence of characters.

The importance of this rule lies in the performance and memory usage of your Ruby application. Using symbols as hash keys reduces memory usage because they are stored in memory only once during a Ruby process. This can make a significant difference in the efficiency of your application, especially when dealing with large data sets.

To ensure you're following good coding practices, always use symbols for hash keys unless there's a specific reason to use a string. A simple refactoring from `values = { 'foo' => 42, 'bar' => 99, 'baz' => 123 }` to `values = { foo: 42, bar: 99, baz: 123 }` will make your code compliant with this rule. This not only improves your code's performance but also makes it more readable and consistent with Ruby's conventions.
</details>

<p align="right"><a href="https://app.datadoghq.com/ci/code-analysis/github.com%2Fdatadog%2Fdd-trace-rb/zachg%2Fbaggage_otel_api/8728d96115345e45d7840e28bd3f9f1e7093a132/code-quality?index=cicodescan&query=%40git.repository.id%3A%22github.com%2Fdatadog%2Fdd-trace-rb%22+%40git.branch%3A%22zachg%2Fbaggage_otel_api%22+%40git.commit.sha%3A%228728d96115345e45d7840e28bd3f9f1e7093a132%22+-%40static_analysis.result.category%3Asecurity+-%40static_analysis.result.item_type%3Asecret&staticAnalysisId=AgAAAZWv_OgbuO2FBQAAAAAAAAAYAAAAAEFaV3ZxNEFZQUFDajBKMWVSUU1jQUFBQQAAACQAAAAAMDE5NWFmZmQtYTgzYy00M2E4LWE5ODAtZGUxZTVlZDExMTBk&trace=AgAAAZWv_OgbuO2FBQAAAAAAAAAYAAAAAEFaV3ZxNEFZQUFDajBKMWVSUU1jQUFBQQAAACQAAAAAMDE5NWFmZmQtYTgzYy00M2E4LWE5ODAtZGUxZTVlZDExMTBk" title="View in Datadog"><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/datadog_icon.svg" alt="View in Datadog" align="center" /></a>&nbsp;&nbsp;<a href="https://dd.enterprise.slack.com/archives/C03NGS0N3GA" title="Leave us feedback"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/comment_light.svg" alt="Leave us feedback" align="center" /></picture></a>&nbsp;&nbsp;<a href="https://docs.datadoghq.com/static_analysis/rules/ruby-best-practices/symbols-as-keys" title="Documentation"><picture><source media="(prefers-color-scheme: dark)" srcset="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_dark.svg"/><img src="https://app.datadoghq.com/api/ui/asset/images/pr_comments/software_delivery/books_light.svg" alt="Documentation" align="center" /></picture></a></p>

created_at: 2025-03-19T20:25:16Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-13T19:37:47Z
body: <!-- CHANGELOG_HIDDEN_MARKER -->
:wave: Hey @DataDog/ruby-guild, please fill "Change log entry" section in the pull request description.

If changes need to be present in [CHANGELOG.md](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md) you can state it this way

```md
**Change log entry**

Yes. A brief summary to be placed into the CHANGELOG.md
```
_(possible answers Yes/Yep/Yeah)_

Or you can opt out like that

```md
**Change log entry**

None.
```
_(possible answers No/Nope/None)_

<sup>Visited at: 2025-03-19 18:04:42 UTC</sup>
author_association: NONE
user: login: codecov-commenter
created_at: 2025-03-13T19:54:02Z
body: ## [Codecov](https://app.codecov.io/gh/DataDog/dd-trace-rb/pull/4493?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) Report
Attention: Patch coverage is `99.30556%` with `1 line` in your changes missing coverage. Please review.
> Project coverage is 97.76%. Comparing base [(`1c8e284`)](https://app.codecov.io/gh/DataDog/dd-trace-rb/commit/1c8e284250db851b5ae4f18160dfe534e342f65d?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) to head [(`8ef0a67`)](https://app.codecov.io/gh/DataDog/dd-trace-rb/commit/8ef0a678a579335830a683cfc674900e3e320797?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog).
> Report is 653 commits behind head on master.

| [Files with missing lines](https://app.codecov.io/gh/DataDog/dd-trace-rb/pull/4493?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) | Patch % | Lines |
|---|---|---|
| [lib/datadog/opentelemetry/api/baggage.rb](https://app.codecov.io/gh/DataDog/dd-trace-rb/pull/4493?src=pr&el=tree&filepath=lib%2Fdatadog%2Fopentelemetry%2Fapi%2Fbaggage.rb&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog#diff-bGliL2RhdGFkb2cvb3BlbnRlbGVtZXRyeS9hcGkvYmFnZ2FnZS5yYg==) | 96.00% | [1 Missing :warning: ](https://app.codecov.io/gh/DataDog/dd-trace-rb/pull/4493?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog) |

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff            @@
##           master    #4493    +/-   ##
========================================
  Coverage   97.76%   97.76%            
========================================
  Files        1388     1390     +2     
  Lines       84621    84763   +142     
  Branches     4274     4281     +7     
========================================
+ Hits        82727    82867   +140     
- Misses       1894     1896     +2     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/DataDog/dd-trace-rb/pull/4493?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=DataDog).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: datadog-datadog-prod-us1[bot]
created_at: 2025-03-13T19:54:11Z
body: 
## Datadog Report

Branch report: [`zachg/baggage_otel_api`](https://app.datadoghq.com/ci/test-branch/github.com%2FDataDog%2Fdd-trace-rb/dd-trace-rb/zachg%2Fbaggage_otel_api?env=ci&index=citest&_user_click_origin_=github)
Commit report: [`8ef0a67`](https://app.datadoghq.com/ci/test-commit/github.com%2FDataDog%2Fdd-trace-rb/dd-trace-rb/zachg%2Fbaggage_otel_api/8ef0a678a579335830a683cfc674900e3e320797?env=ci&index=citest&_user_click_origin_=github)
Test service: `dd-trace-rb`

:white_check_mark: 0 Failed, 20729 Passed, 1370 Skipped, 3m 19.82s Total Time




author_association: CONTRIBUTOR
user: login: pr-commenter[bot]
created_at: 2025-03-13T19:59:13Z
body: ## Benchmarks

Benchmark execution time: 2025-03-20 20:31:14

Comparing candidate commit 8ef0a678a579335830a683cfc674900e3e320797 in PR branch `zachg/baggage_otel_api` with baseline commit 1c8e284250db851b5ae4f18160dfe534e342f65d in branch `master`.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 31 metrics, 2 unstable metrics.


author_association: NONE