diff --git a/launchdarkly-openfeature-server-sdk.gemspec b/launchdarkly-openfeature-server-sdk.gemspec index d329cf8..074c7e9 100644 --- a/launchdarkly-openfeature-server-sdk.gemspec +++ b/launchdarkly-openfeature-server-sdk.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_runtime_dependency "launchdarkly-server-sdk", "~> 8.4" - spec.add_runtime_dependency "openfeature-sdk", "~> 0.6.0" + spec.add_runtime_dependency "openfeature-sdk", ">= 0.6.1", "< 0.7.0" # For more information and examples about making a new gem, check out our # guide at: https://bundler.io/guides/creating_gem.html diff --git a/lib/ldclient-openfeature/provider.rb b/lib/ldclient-openfeature/provider.rb index f339d43..f6fdbd9 100644 --- a/lib/ldclient-openfeature/provider.rb +++ b/lib/ldclient-openfeature/provider.rb @@ -33,6 +33,7 @@ class Provider def initialize(sdk_key, config = LaunchDarkly::Config.default, wait_for_seconds = 5) @client = LaunchDarkly::LDClient.new(sdk_key, config, wait_for_seconds) + @logger = config.logger @context_converter = Impl::EvaluationContextConverter.new(config.logger) @details_converter = Impl::ResolutionDetailsConverter.new @@ -63,6 +64,32 @@ def fetch_object_value(flag_key:, default_value:, evaluation_context: nil) resolve_value(:object, flag_key, default_value, evaluation_context) end + # + # Track a custom event, which can be used as a metric for an experiment. + # + # @param tracking_event_name [String] + # @param evaluation_context [::OpenFeature::SDK::EvaluationContext, nil] + # @param tracking_event_details [::OpenFeature::SDK::TrackingEventDetails, nil] + # + # @return [void] + # + def track(tracking_event_name, evaluation_context: nil, tracking_event_details: nil) + if evaluation_context.nil? + @logger.warn( + "The track method was called without an evaluation context. No event will be sent to LaunchDarkly, " \ + "because a context is required to associate the event with." + ) + return + end + + ld_context = @context_converter.to_ld_context(evaluation_context) + + data = tracking_event_details&.fields + data = nil if data.nil? || data.empty? + + @client.track(tracking_event_name, ld_context, data, tracking_event_details&.value) + end + # # @param flag_type [Symbol] # @param flag_key [String] diff --git a/spec/provider_spec.rb b/spec/provider_spec.rb index e704e0b..f0c5c7b 100644 --- a/spec/provider_spec.rb +++ b/spec/provider_spec.rb @@ -18,6 +18,31 @@ expect(provider.client).to be_a LaunchDarkly::LDClient end + it "track sends a custom event for the provided context" do + allow(provider.client).to receive(:track) + + provider.track("event-name", evaluation_context: evaluation_context) + + expect(provider.client).to have_received(:track).with("event-name", instance_of(LaunchDarkly::LDContext), nil, nil) + end + + it "track includes event details" do + details = OpenFeature::SDK::TrackingEventDetails.new(value: 3.14, category: "shopping") + allow(provider.client).to receive(:track) + + provider.track("event-name", evaluation_context: evaluation_context, tracking_event_details: details) + + expect(provider.client).to have_received(:track).with("event-name", instance_of(LaunchDarkly::LDContext), { "category" => "shopping" }, 3.14) + end + + it "track without a context does not send an event" do + allow(provider.client).to receive(:track) + + provider.track("event-name") + + expect(provider.client).not_to have_received(:track) + end + it "not providing context returns error" do resolution_details = provider.fetch_boolean_value(flag_key: "flag-key", default_value: true)