Skip to content

FDN-4523: Add time-based throttling to RollbarLogger via atMostEvery#379

Merged
gheine merged 2 commits intomainfrom
FDN-4523
Feb 23, 2026
Merged

FDN-4523: Add time-based throttling to RollbarLogger via atMostEvery#379
gheine merged 2 commits intomainfrom
FDN-4523

Conversation

@gheine
Copy link
Contributor

@gheine gheine commented Feb 22, 2026

Summary

  • Add atMostEvery(d: FiniteDuration) to RollbarLogger for time-based log throttling (e.g. logger.atMostEvery(1.minute).warn("msg"))
  • Uses a shared AtomicLong timestamp with CAS for thread-safe throttling that survives .copy() / builder chains
  • Add Guice binding for the new field so DI continues to work
  • Add RollbarLoggerSpec with tests for throttle behavior, state sharing across copies, and combination with withFrequency
  • Add CLAUDE.md for Claude Code guidance

Test plan

  • All 17 tests pass (sbt test)
  • New RollbarLoggerSpec covers: default no-throttle, first call allowed, suppression within interval, allow after interval, shared state across builder calls, combination with withFrequency
  • Existing RollbarModuleSpec Guice injection test passes with new field
  • Code formatted with sbt scalafmtAll

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added time-based throttling via atMostEvery(duration) so specific log messages can be limited by interval; works alongside existing frequency controls.
  • Tests

    • Added tests covering interval throttling, first-call/ suppression behavior, shared throttle state, and interaction with frequency settings.
  • Documentation

    • Added comprehensive library guidance and usage documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

📝 Walkthrough

Walkthrough

Adds interval-based throttling to RollbarLogger, a new atMostEvery builder, a new Guice binding for Option[(FiniteDuration, AtomicLong)], updated shouldLog logic to combine frequency and time-based throttling, tests validating the new behavior, and a new CLAUDE.md guidance document.

Changes

Cohort / File(s) Summary
Documentation
CLAUDE.md
Adds a new guidance document for the lib-log Play 2.9 Scala logging library covering purpose, build, coverage, style, architecture, components, testing, CI/CD, and publishing.
Dependency Injection
src/main/scala/io/flow/log/Rollbar.scala
Adds imports AtomicLong and FiniteDuration and a new Guice binding for Option[(FiniteDuration, AtomicLong)] (bound to None), exposing an optional shared interval state for injection; no runtime logic changes to Rollbar initialization.
Core Logger
src/main/scala/io/flow/log/RollbarLogger.scala
Introduces interval-based throttling: new constructor parameter interval: Option[(FiniteDuration, AtomicLong)] = None, new public builder atMostEvery(d: FiniteDuration): RollbarLogger, and updated private[log] def shouldLog combining frequency sampling with optional atomic time-based throttle. Added relevant imports.
Tests
src/test/scala/io/flow/log/RollbarLoggerSpec.scala
Adds ScalaTest spec covering atMostEvery behavior: default interval state, first-call allowance, suppression within interval, resumption after interval, shared throttle state across builder chains, and interplay with withFrequency.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding time-based throttling to RollbarLogger via a new atMostEvery method, which aligns with the core functionality introduced across modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@flow-tech
Copy link
Contributor

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/scala/io/flow/log/RollbarLogger.scala`:
- Around line 179-189: The current shouldLog lets timeThrottleCheck run even
when frequencyCheck is false, causing lastLoggedAt to advance on skipped
samples; change shouldLog so frequencyCheck is evaluated first and the interval
check (the match on interval/lastLoggedAt and the compareAndSet call) only runs
when frequencyCheck is true, e.g. compute frequencyCheck then if false return
false else execute the interval/time throttle logic (using lastLoggedAt only
when emitting) so lastLoggedAt is updated only for actually emitted logs in
shouldLog.

jackl
jackl previously approved these changes Feb 23, 2026
Prevents skipped frequency samples from advancing the lastLoggedAt
timestamp, which would suppress later logs more than intended.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@flow-tech
Copy link
Contributor

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/main/scala/io/flow/log/RollbarLogger.scala (1)

179-189: The fix correctly addresses the previous review concern.

The pattern-match on (interval, frequencyCheck) ensures the CAS operation only executes when frequencyCheck is true, preventing skipped frequency samples from advancing lastLoggedAt. The implementation now properly gates the time check behind the frequency check.
,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/scala/io/flow/log/RollbarLogger.scala` around lines 179 - 189, The
shouldLog method previously allowed the interval CAS
(lastLoggedAt.compareAndSet) to run even when frequency sampling was skipped;
update shouldLog (function shouldLog) so that frequencyCheck is evaluated first
and the time throttle CAS only runs when frequencyCheck is true—accomplish this
as shown by computing frequencyCheck, then pattern-matching (interval,
frequencyCheck) to run the CAS inside the case that matches (Some((minInterval,
lastLoggedAt)), true), using now/last and compareAndSet on lastLoggedAt to
update the timestamp; keep the final return as frequencyCheck &&
timeThrottleCheck.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/main/scala/io/flow/log/RollbarLogger.scala`:
- Around line 179-189: The shouldLog method previously allowed the interval CAS
(lastLoggedAt.compareAndSet) to run even when frequency sampling was skipped;
update shouldLog (function shouldLog) so that frequencyCheck is evaluated first
and the time throttle CAS only runs when frequencyCheck is true—accomplish this
as shown by computing frequencyCheck, then pattern-matching (interval,
frequencyCheck) to run the CAS inside the case that matches (Some((minInterval,
lastLoggedAt)), true), using now/last and compareAndSet on lastLoggedAt to
update the timestamp; keep the final return as frequencyCheck &&
timeThrottleCheck.
ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3676e99 and 78f65fc.

📒 Files selected for processing (1)
  • src/main/scala/io/flow/log/RollbarLogger.scala

@gheine gheine merged commit 21506e4 into main Feb 23, 2026
7 checks passed
@gheine gheine deleted the FDN-4523 branch February 23, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants