Module: Labkit::RateLimit::Metrics

Defined in:
lib/labkit/rate_limit/metrics.rb

Constant Summary collapse

FAILURE_LOGGED =

Process-wide once-latch for log_failure; specs reset via make_false.

Concurrent::AtomicBoolean.new(false)

Class Method Summary collapse

Class Method Details

.calls_totalObject

Deprecated: superseded by checks_total and rule_evaluations_total. Emitted unchanged (once per matched rule, rule="unmatched" when none matched) until consumers migrate; will get removed in a follow-up release.



58
59
60
61
62
63
64
# File 'lib/labkit/rate_limit/metrics.rb', line 58

def calls_total
  Labkit::Metrics::Client.counter(
    :gitlab_labkit_rate_limiter_calls_total,
    'Total number of successful rate limit checks',
    { rate_limiter: nil, rule: nil, action: nil }
  )
end

.checks_totalObject

Emitted exactly once per #check call, including calls that fail open; summing by rate_limiter gives the request rate through the limiter.



47
48
49
50
51
52
53
# File 'lib/labkit/rate_limit/metrics.rb', line 47

def checks_total
  Labkit::Metrics::Client.counter(
    :gitlab_labkit_rate_limiter_checks_total,
    'Total number of rate limit checks',
    { rate_limiter: nil, action: nil, matched: nil, error: nil }
  )
end

.errors_totalObject

Deprecated: superseded by checks_totalerror="true". Still emitted because it remains the only error metric for #peek.



78
79
80
81
82
83
84
# File 'lib/labkit/rate_limit/metrics.rb', line 78

def errors_total
  Labkit::Metrics::Client.counter(
    :gitlab_labkit_rate_limiter_errors_total,
    'Total number of rate limit check errors',
    { rate_limiter: nil }
  )
end

.limit_gaugeObject



86
87
88
89
90
91
92
93
# File 'lib/labkit/rate_limit/metrics.rb', line 86

def limit_gauge
  Labkit::Metrics::Client.gauge(
    :gitlab_labkit_rate_limiter_limit,
    'The configured rate limit threshold',
    { rate_limiter: nil, rule: nil },
    :max
  )
end

.log_failure(error, metric, labels, logger) ⇒ Object

make_true returns true only for the flipping caller, so exactly one warn per process. Never raises - a raise here would defeat the callers' rescues.



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/labkit/rate_limit/metrics.rb', line 31

def log_failure(error, metric, labels, logger)
  return unless logger && FAILURE_LOGGED.make_true

  logger.warn(
    name: labels[:rate_limiter],
    metric: metric.to_s,
    Labkit::Fields::ERROR_TYPE => "rate_limit_metrics_error",
    Labkit::Fields::CLASS_NAME => error.class.to_s,
    Labkit::Fields::ERROR_MESSAGE => error.message
  )
rescue StandardError
  nil
end

.period_gaugeObject



95
96
97
98
99
100
101
102
# File 'lib/labkit/rate_limit/metrics.rb', line 95

def period_gauge
  Labkit::Metrics::Client.gauge(
    :gitlab_labkit_rate_limiter_period_seconds,
    'The configured rate limit period in seconds',
    { rate_limiter: nil, rule: nil },
    :max
  )
end

.rule_evaluations_totalObject

Emitted once per evaluated rule. Only matched rules are evaluated: Unmatched traffic is checks_totalmatched="false"



68
69
70
71
72
73
74
# File 'lib/labkit/rate_limit/metrics.rb', line 68

def rule_evaluations_total
  Labkit::Metrics::Client.counter(
    :gitlab_labkit_rate_limiter_rule_evaluations_total,
    'Total number of rate limit rule evaluations',
    { rate_limiter: nil, rule: nil, action: nil, result: nil }
  )
end

.safe_increment(counter, labels, logger: nil) ⇒ Object

Metric emission must never affect the caller's outcome. Resolving the metric by name keeps a raising getter inside the rescue.



15
16
17
18
19
# File 'lib/labkit/rate_limit/metrics.rb', line 15

def safe_increment(counter, labels, logger: nil)
  public_send(counter).increment(**labels) # rubocop:disable GitlabSecurity/PublicSend
rescue StandardError => e
  log_failure(e, counter, labels, logger)
end

.safe_set(gauge, labels, value, logger: nil) ⇒ Object

Gauge counterpart of safe_increment.



22
23
24
25
26
# File 'lib/labkit/rate_limit/metrics.rb', line 22

def safe_set(gauge, labels, value, logger: nil)
  public_send(gauge).set(labels, value) # rubocop:disable GitlabSecurity/PublicSend
rescue StandardError => e
  log_failure(e, gauge, labels, logger)
end