Sha256: cf4c0292dceaf200a9c0ec255293e672e7ae72012a44590690b2d5c588b42707

Contents?: true

Size: 1.17 KB

Versions: 4

Compression:

Stored size: 1.17 KB

Contents

# frozen_string_literal: true

require_relative '../core/rate_limiter'

module Datadog
  module AppSec
    # Per-thread rate limiter based on token bucket rate limiter.
    #
    # Since AppSec marks sampling to keep on a security event, this limits
    # the flood of egress traces involving AppSec
    class RateLimiter
      THREAD_KEY = :datadog_security_appsec_rate_limiter

      class << self
        def thread_local
          rate_limiter = Thread.current.thread_variable_get(THREAD_KEY)
          return rate_limiter unless rate_limiter.nil?

          Thread.current.thread_variable_set(THREAD_KEY, new(trace_rate_limit))
        end

        # reset a rate limiter: used for testing
        def reset!
          Thread.current.thread_variable_set(THREAD_KEY, nil)
        end

        private

        def trace_rate_limit
          Datadog.configuration.appsec.trace_rate_limit
        end
      end

      def initialize(rate)
        @rate_limiter = Core::TokenBucket.new(rate)
      end

      def limit
        return yield if @rate_limiter.allow?

        Datadog.logger.debug { "Rate limit hit: #{@rate_limiter.current_window_rate} AppSec traces/second" }
      end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
datadog-2.7.0 lib/datadog/appsec/rate_limiter.rb
datadog-2.6.0 lib/datadog/appsec/rate_limiter.rb
datadog-2.5.0 lib/datadog/appsec/rate_limiter.rb
datadog-2.4.0 lib/datadog/appsec/rate_limiter.rb