From e30d974a5aa17428a3cb56a4714dcc45f6c2417d Mon Sep 17 00:00:00 2001 From: Mike Goldsmth Date: Tue, 21 May 2024 11:32:52 +0100 Subject: [PATCH] add regex example and test --- processor/baggage/README.md | 21 ++++++++++--- .../baggage/baggage_span_processor.rb | 28 +++++++---------- .../baggage/baggage_span_processor_test.rb | 31 +++++++++++++++---- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/processor/baggage/README.md b/processor/baggage/README.md index 379f5c2590..bff352f437 100644 --- a/processor/baggage/README.md +++ b/processor/baggage/README.md @@ -31,7 +31,7 @@ To install the instrumentation, add the gem to your Gemfile: gem 'opentelemetry-processor-baggage' ``` -Then add the processor to an SDK's configuration: +Then configure the span processor to copy all baggage entries: ```ruby require 'rubygems' @@ -40,8 +40,11 @@ require 'bundler/setup' Bundler.require OpenTelemetry::SDK.configure do |c| - # Add the BaggageSpanProcessor to the collection of span processors - c.add_span_processor(OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new) + # Add the BaggageSpanProcessor to the collection of span processors and + # copy all baggage entries + c.add_span_processor(OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( + OpenTelemetry::Processor::Baggage::ALLOW_ALL_BAGGAGE_KEYS + )) # Because the span processor list is no longer empty, the SDK will not use the # values in OTEL_TRACES_EXPORTER to instantiate exporters. @@ -57,13 +60,21 @@ OpenTelemetry::SDK.configure do |c| end ``` -A predicate proc that determines what baggage entries are copied can be provided as a constructor parameter. +Alternatively, you can provide a custom baggage key predicate to select which baggage keys you want to copy. For example, to only copy baggage entries that start with `my-key`: ```ruby OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( - keyfilter: ->(key) { key.start_with?('my-key') } + ->(baggage_key) { baggage_key.start_with?('my-key') } +) +``` + +For example, to only copy baggage entries that match the regex `^key.+`: + +```ruby +OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( + ->(baggage_key) { baggage_key.match?('^key.+') } ) ``` diff --git a/processor/baggage/lib/opentelemetry/processor/baggage/baggage_span_processor.rb b/processor/baggage/lib/opentelemetry/processor/baggage/baggage_span_processor.rb index e78e759136..1bf961dbf2 100644 --- a/processor/baggage/lib/opentelemetry/processor/baggage/baggage_span_processor.rb +++ b/processor/baggage/lib/opentelemetry/processor/baggage/baggage_span_processor.rb @@ -10,8 +10,8 @@ module OpenTelemetry module Processor module Baggage - # A regex that matches all Baggage keys. - ALLOW_ALL = '*' + # A baggage key predicate that allows all keys to be added to the span as attributes. + ALLOW_ALL_BAGGAGE_KEYS = ->(_) { true } # The BaggageSpanProcessor reads key/values stored in Baggage in the # starting span's parent context and adds them as attributes to the span. @@ -31,7 +31,7 @@ module Baggage # OpenTelemetry::SDK.configure do |c| # # Add the BaggageSpanProcessor to the collection of span processors # c.add_span_processor(OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( - # OpenTelemetry::Processor::Baggage::ALLOW_ALL) + # OpenTelemetry::Processor::Baggage::ALLOW_ALL_BAGGAGE_KEYS) # ) # # # Because the span processor list is no longer empty, the SDK will not use the @@ -50,10 +50,10 @@ class BaggageSpanProcessor < OpenTelemetry::SDK::Trace::SpanProcessor # Create a new BaggageSpanProcessor that reads Baggage keys and values from the parent context # and adds them as attributes to the span. # - # @param [Regexp] baggage_key_regex A regular expression that matches Baggage keys to be added as span attributes. - # If the regex is '*', all Baggage keys will be added as attributes. - def initialize(baggage_key_regex) - @baggage_key_regex = baggage_key_regex + # @param [lambda] baggage_key_predicate A lambda that takes a baggage key and returns true if + # the key should be added to the span as an attribute, false otherwise. + def initialize(baggage_key_predicate) + @baggage_key_predicate = baggage_key_predicate super() end @@ -66,15 +66,11 @@ def initialize(baggage_key_regex) def on_start(span, parent_context) return unless span.respond_to?(:add_attributes) && parent_context.is_a?(::OpenTelemetry::Context) - if @baggage_key_regex == ALLOW_ALL - span.add_attributes(::OpenTelemetry::Baggage.values(context: parent_context)) - else - span.add_attributes( - ::OpenTelemetry::Baggage - .values(context: parent_context) - .select { |k, _v| @baggage_key_regex.match(k) } - ) - end + span.add_attributes( + ::OpenTelemetry::Baggage + .values(context: parent_context) + .select { |k, _v| @baggage_key_predicate.call(k) } + ) end # Called when a Span is ended, does nothing. diff --git a/processor/baggage/test/opentelemetry/processor/baggage/baggage_span_processor_test.rb b/processor/baggage/test/opentelemetry/processor/baggage/baggage_span_processor_test.rb index f144bf1532..5dde2b40b7 100644 --- a/processor/baggage/test/opentelemetry/processor/baggage/baggage_span_processor_test.rb +++ b/processor/baggage/test/opentelemetry/processor/baggage/baggage_span_processor_test.rb @@ -13,7 +13,7 @@ OpenTelemetry::SDK.configure do |c| # the baggage processor getting wired in for integration testing c.add_span_processor OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( - OpenTelemetry::Processor::Baggage::ALLOW_ALL + OpenTelemetry::Processor::Baggage::ALLOW_ALL_BAGGAGE_KEYS ) # use a simple processor and in-memory export for testing sent spans @@ -28,10 +28,19 @@ describe OpenTelemetry::Processor::Baggage::BaggageSpanProcessor do let(:processor) do OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( - OpenTelemetry::Processor::Baggage::ALLOW_ALL + OpenTelemetry::Processor::Baggage::ALLOW_ALL_BAGGAGE_KEYS + ) + end + let(:starts_with_processor) do + OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( + ->(baggage_key) { baggage_key.start_with?('a') } + ) + end + let(:regex_processor) do + OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new( + ->(baggage_key) { baggage_key.match?(/^b_ke.+/) } ) end - let(:filtered_processor) { OpenTelemetry::Processor::Baggage::BaggageSpanProcessor.new('^a.key') } let(:span) { Minitest::Mock.new } let(:context_with_baggage) do OpenTelemetry::Baggage.build(context: OpenTelemetry::Context.empty) do |baggage| @@ -105,11 +114,21 @@ end end - describe 'with a keyfilter' do + describe 'with a starts_with key predicate' do it 'only adds attributes that pass the keyfilter' do - span.expect(:add_attributes, span, [{ 'a_key' => 'a_value', 'b_key' => 'b_value' }]) + span.expect(:add_attributes, span, [{ 'a_key' => 'a_value' }]) - processor.on_start(span, context_with_baggage) + starts_with_processor.on_start(span, context_with_baggage) + + span.verify + end + end + + describe 'with a regex key predicate' do + it 'only adds attributes that pass the keyfilter' do + span.expect(:add_attributes, span, [{ 'b_key' => 'b_value' }]) + + regex_processor.on_start(span, context_with_baggage) span.verify end