Skip to content

Expose C_SEGMENT_SIZE_BYTES gauges - #218

Open
lukas8219 wants to merge 11 commits into
rabbitmq:mainfrom
lukas8219:osiris-segmenet-size-gauge
Open

Expose C_SEGMENT_SIZE_BYTES gauges#218
lukas8219 wants to merge 11 commits into
rabbitmq:mainfrom
lukas8219:osiris-segmenet-size-gauge

Conversation

@lukas8219

@lukas8219 lukas8219 commented May 19, 2026

Copy link
Copy Markdown

What

Add both metrics for C_SEGMENT_SIZE_BYTES so we can enable on Management UI and Prometheus.

How

  • 1 new fields
  • Increment on each write
  • Decrement after each retention eval cycle
  • Calculate the initial sizes doing stat at each file at init

Below is AI-generated

Benchmark with Mac Book M3 Max PRO (32GB RAM 10-4 CPU)

Phase Result
Fill (50 GB, 101 segments) ~1.25 GB/s sustained, stable across all segments
Restart (101 segments) 9 ms avg (16 ms cold, 6 ms warm) — sum_log_sizes is 101 × 2 stat calls, negligible
Retention run 1 (51 segments deleted, 25 GB) 406 ms
Retention runs 2–5 (idempotent, 0 deletes) 2–3 ms

The 406 ms on the first retention run is the actual file deletion of 51 segments. Runs 2–5 (index scan only, nothing to delete) are 2–3 ms regardless of how many segments remain — that confirms the O(remaining) scan is cheap at this scale.

At 100 GB you'd expect ~800 ms for a full 50% delete run, and the same 2–4 ms for idempotent evaluations. Nothing alarming.

Closes #161

Comment thread src/osiris_log.erl Outdated
%% local segments
[begin ok = delete_segment_from_index(I) end
|| I <- IdxFiles],
[delete_segment_from_index(I) || I <- IdxFiles],

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Not sure we pattern match from above is really necessary?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah looks like it isn't since delete_segment_from_index/1 already hard matches on ok

Comment thread src/osiris_log.erl Outdated
Comment thread src/osiris_log.erl Outdated

@the-mikedavis the-mikedavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I took a look and I have a few nits but I think this is the right approach. I'm not an authority here so I'd wait for feedback from Arnaud / David / Karl before acting on my opinions (especially the index file part).

Comment thread src/osiris_log.erl Outdated
{segments, ?C_SEGMENTS, counter, "Number of segments"}
{segments, ?C_SEGMENTS, counter, "Number of segments"},
{segment_size_bytes, ?C_SEGMENT_SIZE_BYTES, counter, "Total size of all segment files in bytes"},
{index_size_bytes, ?C_INDEX_SIZE_BYTES, counter, "Total size of all index files in bytes"}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure it's worthwhile to track index data. It would mean an extra fstat for index files during recovery and retention to gather the size data. Since chunk headers are at minimum 48 bytes per chunk, the segment will always be larger (48 > 29 for each index record). If these metrics aim to answer a question of "which stream is taking up all of my data" I think segment size metrics are enough.

I think there's a separate question of "are my chunks so small they're hurting performance" and that could be answered by a bytes-per-chunk metric instead. Tracking index data here would indirectly hint towards that rather than answer it clearly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I am not strong on any claim here as I also believe that for big clusters, with loads of streams, that's not a cheap price to pay.

@lukas8219 lukas8219 Jun 2, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@the-mikedavis
To track or not to track it: I thought maybe, if the overhead is not big, to keep going with both. Easier to catch bugs if users have this level of visibility.
Now that was myself assuming there's a chance the index file could have holes/get bloated somehow - which could have been naive as Streams are running for lots of years and there's not a single complaint about it.

I'll good with removing the index tracking from this PR

Comment thread src/osiris_log.erl Outdated
Comment thread src/osiris_log.erl Outdated
%% local segments
[begin ok = delete_segment_from_index(I) end
|| I <- IdxFiles],
[delete_segment_from_index(I) || I <- IdxFiles],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah looks like it isn't since delete_segment_from_index/1 already hard matches on ok

Comment thread src/osiris_log.erl Outdated
Comment thread src/osiris_log.erl Outdated
{segments, ?C_SEGMENTS, counter, "Number of segments"}
{segments, ?C_SEGMENTS, counter, "Number of segments"},
{segment_size_bytes, ?C_SEGMENT_SIZE_BYTES, counter, "Total size of all segment files in bytes"},
{index_size_bytes, ?C_INDEX_SIZE_BYTES, counter, "Total size of all index files in bytes"}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like all of these are counter currently but I think most of them (maybe all of them?) should be gauge. Maybe it's outside the scope of this change though since the existing ones all use counter

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agree for a future PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds two new size metrics to Osiris logs—total segment bytes and total index bytes—so they can be surfaced in the Management UI and exported to Prometheus. The metrics are initialized on startup via filesystem stat, incremented on writes, and decremented after retention deletes segments.

Changes:

  • Extend osiris_log counters with segment_size_bytes and index_size_bytes, including initialization, write-time increments, and retention-time decrements.
  • Extend retention evaluation to return deleted segment/index byte counts so stream processes can update the new metrics.
  • Add Common Test coverage for fresh logs, writes, restart, and retention effects on the new size counters.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/osiris_log.erl Adds the two new counters, initializes them at init, updates them on write, and decrements them based on retention deletions.
src/osiris_retention.erl Adjusts scheduling pattern match to handle the extended retention evaluation return value.
src/osiris.hrl Increases the base log counter field count to accommodate the two new counters.
test/osiris_log_SUITE.erl Adds tests validating the new counters across init/write/restart/retention flows and adapts retention tests to new return shape.
test/osiris_SUITE.erl Adds an integration test ensuring retention decreases segment_size_bytes at the writer counter level.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/osiris_log.erl Outdated
Comment thread src/osiris_log.erl Outdated
Comment thread test/osiris_log_SUITE.erl Outdated
Comment thread test/osiris_log_SUITE.erl Outdated
Comment thread src/osiris_log.erl Outdated
Comment thread src/osiris_log.erl Outdated
Comment thread test/osiris_log_SUITE.erl Outdated
Comment thread test/osiris_log_SUITE.erl Outdated
@lukas8219
lukas8219 requested a review from the-mikedavis June 1, 2026 14:44

@the-mikedavis the-mikedavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is looking good to me 👍. I only have nitpicks / style comments left.

Before merging though I think we should discuss/decide whether index file bytes are worthy of tracking. I would lean against it but I don't have a strong opinion either way.

Comment thread src/osiris_log.erl Outdated
Comment thread src/osiris_log.erl
- Restored comments about future performance improvements
- Removed Index Tracking
- Moved to Maps instead of Tuple
@lukas8219
lukas8219 requested a review from the-mikedavis June 6, 2026 00:30
@lukas8219 lukas8219 changed the title Expose C_SEGMENT_SIZE_BYTES and C_INDEX_SIZE_BYTES gauges Expose C_SEGMENT_SIZE_BYTES gauges Jun 8, 2026

@the-mikedavis the-mikedavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks great to me 👍

@the-mikedavis
the-mikedavis requested a review from kjnilsson June 8, 2026 15:58
@lukas8219

Copy link
Copy Markdown
Author

Hi @kjnilsson Any estimates for this? Just so I can snooze this notification for a while

@mergify

mergify Bot commented Jul 1, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/osiris_log.erl
counters:put(Cnt, ?C_FIRST_TIMESTAMP, FstTs),
counters:put(Cnt, ?C_SEGMENTS, NumSegLeft);
counters:put(Cnt, ?C_SEGMENTS, NumSegLeft),
counters:sub(Cnt, ?C_SEGMENT_SIZE_BYTES, DelSegBytes);

@kjnilsson kjnilsson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

some performance regressions that could be improved.

Comment thread src/osiris_log.erl Outdated
%% at a valid chunk we can now truncate the segment to size in
%% case there is trailing data
ok = file:truncate(SegFd),
InitSegBytes = sum_log_sizes(Config),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this adds an additional file listing operation (which is O(N)) - at least we should be able to use the same listing for first_and_last_seginfos and this by adding the index_files key to the Config before that (but after maybe_fix_corrupted_files/1 as this may change the files on disk.

Comment thread src/osiris_log.erl Outdated
delete_segment_from_index(Index) ->
File = segment_from_index_file(Index),
?DEBUG("osiris_log: deleting segment ~ts", [File]),
SegSize = file_size_or_zero(File),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this incurs an additional syscall for all calls of this function, even if they don't make use of it. Perhaps we need two different functions or the file size if got independently where needed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've used the Size from previous read. What I am not completely sure is if, there's any chance the segment size would change between the first stat and the delete

@lukas8219
lukas8219 requested a review from kjnilsson July 3, 2026 20:29
lukas8219 and others added 2 commits July 27, 2026 17:45
The fold ignored its element and deleted the first index file N times
while summing its size N times, leaving older segments undeleted and
under-reporting deleted_segment_bytes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Add guage to track total stream size in bytes

4 participants