Skip to content

feat: batch records and flush them on Close - #33

Merged
samber merged 4 commits into
mainfrom
feat/batch-and-flush
Oct 13, 2026
Merged

samber merged 4 commits into
mainfrom
feat/batch-and-flush

Conversation

@samber

@samber samber commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #32.

Each record was sent in its own goroutine: records logged right before the process exits were lost, and a burst of logs opened one request per record.

  • records go through a bounded queue to a single worker sending batches
  • new options: BatchSize (100), FlushInterval (1s), QueueSize (1000)
  • Close() delivers the records still queued; idempotent; covers handlers derived with With/WithGroup
  • full queue: record dropped and reported through OnError, logging never blocks
  • NewBetterstackHandler returns *BetterstackHandler (still a slog.Handler)
  • README and example call Close

@codecov

codecov Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.19048% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.39%. Comparing base (1c1f4b2) to head (5b3c3f4).

Files with missing lines Patch % Lines
dispatcher.go 96.82% 1 Missing and 1 partial ⚠️
handler.go 95.23% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main      #33       +/-   ##
===========================================
+ Coverage   75.90%   92.39%   +16.49%     
===========================================
  Files           2        3        +1     
  Lines          83      171       +88     
===========================================
+ Hits           63      158       +95     
+ Misses         16        7        -9     
- Partials        4        6        +2     
Flag Coverage Δ
unittests 92.39% <96.19%> (+16.49%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@samber
samber force-pushed the feat/batch-and-flush branch 2 times, most recently from 69a6fda to bd187f8 Compare October 13, 2026 15:55
Base automatically changed from feat/report-delivery-errors to main October 13, 2026 15:57
Each record was sent in its own goroutine, so records logged right
before the process exited were lost and a log burst opened one request
per record.

Records now go through a bounded queue to a single worker that sends
batches (BatchSize, FlushInterval, QueueSize). Close delivers what is
still queued. When the queue is full, records are dropped and reported
through OnError, so logging never blocks the caller.

NewBetterstackHandler now returns *BetterstackHandler, which still
implements slog.Handler.
* feat: retry failed batches with exponential backoff

A batch hit by a network error, a 429 or a 5xx was lost on the first
failure.

Retry those with a doubling delay (MaxRetries, RetryBackoff), capped at
30s per wait. Other 4xx responses and marshaling failures are not
retried: they fail the same way every time. The last error is reported
through OnError once retries are exhausted.

* feat: add jitter to retry backoff

Handlers that failed together, for example during a server outage,
retried at the same instants.

Wait a random duration between 50% and 100% of the backoff.

* feat: make retry jitter additive

Wait a random duration between 100% and 150% of the backoff, so the
configured RetryBackoff stays a lower bound.

* docs: clarify that the backoff cap applies before jitter
Match the file it covers, dispatcher.go.
@samber
samber force-pushed the feat/batch-and-flush branch from bd187f8 to 5b3c3f4 Compare October 13, 2026 15:57
@samber
samber marked this pull request as ready for review October 13, 2026 15:59
@samber
samber merged commit 50c86d3 into main Oct 13, 2026
12 of 14 checks passed
@samber
samber deleted the feat/batch-and-flush branch October 13, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant