Don't produce *_lag_seconds when all metric's values are hardcoded to 0.#93
Merged
Conversation
Standardize it across all (`Dockerfile.dev` used a different one from the rest)
I used ``` cargo clippy -- -W clippy::pedantic -W clippy::nursery -W clippy::unwrap_used -A clippy::cast_precision_loss -A clippy::cast_possible_truncation -A clippy::too_many_lines -A clippy::missing_fields_in_debug ``` to reduce the amount of warnings from 201 to 24, and clippy suggestions from 151 to 1. I did this to re-familiarize myself with this code-base, I want to give it another try, our kafka clusters are on the orders of magnitude: - 5+ partitions for biggest topics - 1.5k topics - ~1-3k consumergroups (I am not sure if I'm counting double the ACLs or not, since I know we keep some for rotation purposes per consumer) Thus, when I last tried in february, even after a lot of work on the Rust base (code @ https://github.com/nais/klag-exporter/tree/deploy_our_own_helmchart), we could NOT manage to get `klag-exporter` to scrape lag metrics for an entire cluster reliably within ~20-40 seconds without memory leak. Looking at the code now, I suspect you may have dealt with the librdkafka memory leak I struggled with back then.
Contributor
Author
|
Based on #89, expecting to rebase this one when that one lands. |
04e1cf4 to
ee1fad2
Compare
…lly hardcoded to `0` When the config toml's `exporter.timestamp_sampling.enabled` is false, all `*_lag_seconds` metrics are hardcodet to produce `0`. This causes a lot of confusion, and cannot be expected/intended behaviour ref existing documentation. So whenever `exporter.timestamp_sampling.enabled` is false, all `*_lag_seconds` metrics should be omitted from `/metrics` endpoint.
ee1fad2 to
f00b57c
Compare
Contributor
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
This PR updates the exporter to omit *_lag_seconds metric families when time-lag sampling is disabled (rather than emitting misleading hardcoded 0), alongside a Rust/tooling bump and various refactors/cleanups across the metrics, Kafka, and collector code.
Changes:
- Add a
time_lag_enabledswitch to lag calculation solag_seconds/max_lag_secondsbecomeNonewhen timestamp sampling is disabled (preventing emission of*_lag_seconds). - Refactor Prometheus rendering and various internal helpers (more
const fn, formatting/locking cleanups, minor clippy-driven simplifications). - Add Nix flake tooling and bump Rust toolchain references in CI/Docker.
Reviewed changes
Copilot reviewed 23 out of 25 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| src/metrics/types.rs | Makes small const/refactor changes to metric value/type helpers; updates OTEL datapoint timestamp type. |
| src/metrics/registry.rs | Adjusts registry update signatures to borrow metrics; refactors Prometheus output formatting; updates OTEL timestamp acquisition. |
| src/main.rs | Minor spawn/shutdown control-flow simplifications and signature adjustment for ClusterManager::new. |
| src/leadership/noop.rs | Marks NoopLeader::new as const fn. |
| src/leadership/mod.rs | Marks LeadershipState::is_leader as const fn and simplifies matching. |
| src/kafka/consumer.rs | Refactors pooling and polling logic; minor lock poison handling cleanup. |
| src/kafka/client.rs | Refactors lock poison handling; adjusts RSS reclaimed computation; minor doc/comment tweaks. |
| src/kafka/admin.rs | Replaces wildcard bindings import with explicit list; minor FFI pointer handling refactors; widens some helper visibilities. |
| src/http/server.rs | Simplifies address formatting/parsing. |
| src/export/prometheus.rs | Marks exporter constructor const fn and updates tests for borrowed update API. |
| src/config.rs | Refactors defaults into const fn and tweaks error formatting; (also introduces invalid Duration::from_mins/from_hours calls). |
| src/collector/timestamp_sampler.rs | Minor option-handling simplifications and doc formatting tweaks. |
| src/collector/rate_sampler.rs | Refactors mutex poison handling and some iterator/style details. |
| src/collector/offset_collector.rs | Mutex poison handling cleanup; improves compacted-topics cache logging; minor formatting tweaks. |
| src/collector/lag_calculator.rs | Core change: add time_lag_enabled and ensure lag-seconds are omitted when disabled; adds a targeted test. |
| src/cluster/manager.rs | Propagates time_lag_enabled based on sampler presence; borrows config; (also introduces invalid Duration::from_mins calls). |
| flake.nix | Adds Nix flake dev shell/build; currently pins Rust toolchain to 1.93.0 (inconsistent with CI/Docker). |
| flake.lock | Locks Nix inputs for the new flake. |
| Dockerfile.dev | Bumps Rust image version used for dev builds. |
| Cargo.toml | Excludes flake files and .envrc from packaging. |
| .gitignore | Ignores direnv outputs and .env.* files. |
| .github/workflows/release.yml | Bumps Rust toolchain action version. |
| .github/workflows/release-plz-pr.yml | Bumps Rust toolchain action version. |
| .github/workflows/post-release.yml | Bumps Rust toolchain action version. |
Files excluded by content exclusion policy (1)
- .envrc
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+16
to
+17
| /// Default timeout for a single collection cycle (should be less than `poll_interval`) | ||
| const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_mins(1); |
Comment on lines
103
to
105
| poll_interval: exporter_config.poll_interval, | ||
| max_backoff: Duration::from_secs(300), | ||
| max_backoff: Duration::from_mins(5), | ||
| granularity: exporter_config.granularity, |
Comment on lines
+251
to
253
| const fn default_cache_ttl() -> Duration { | ||
| Duration::from_mins(1) | ||
| } |
Comment on lines
+267
to
269
| const fn default_rate_history_max_age() -> Duration { | ||
| Duration::from_mins(10) | ||
| } |
Comment on lines
+299
to
301
| const fn default_compacted_topics_cache_ttl() -> Duration { | ||
| Duration::from_hours(1) | ||
| } |
Comment on lines
+303
to
305
| const fn default_metadata_cache_ttl() -> Duration { | ||
| Duration::from_mins(5) | ||
| } |
Comment on lines
+307
to
309
| const fn default_consumer_groups_cache_ttl() -> Duration { | ||
| Duration::from_mins(1) | ||
| } |
Comment on lines
+315
to
317
| const fn default_export_interval() -> Duration { | ||
| Duration::from_mins(1) | ||
| } |
Comment on lines
177
to
182
| info!( | ||
| cluster = %self.config.name, | ||
| rss_before_kb = rss_before, | ||
| rss_after_kb = rss_after, | ||
| rss_reclaimed_kb = rss_before as i64 - rss_after as i64, | ||
| rss_reclaimed_kb = rss_before.cast_signed() - rss_after.cast_signed(), | ||
| "Recycled Kafka clients" |
| inherit (pkgs) lib; | ||
| cargoToml = lib.fromTOML (lib.readFile ./Cargo.toml); | ||
|
|
||
| rustToolchain = pkgs.rust-bin.stable."1.93.0".default.override { |
Contributor
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 23 out of 25 changed files in this pull request and generated 7 comments.
Files excluded by content exclusion policy (1)
- .envrc
Comment on lines
+251
to
253
| const fn default_cache_ttl() -> Duration { | ||
| Duration::from_mins(1) | ||
| } |
Comment on lines
+267
to
269
| const fn default_rate_history_max_age() -> Duration { | ||
| Duration::from_mins(10) | ||
| } |
Comment on lines
+299
to
+304
| const fn default_compacted_topics_cache_ttl() -> Duration { | ||
| Duration::from_hours(1) | ||
| } | ||
|
|
||
| fn default_metadata_cache_ttl() -> Duration { | ||
| Duration::from_secs(300) | ||
| const fn default_metadata_cache_ttl() -> Duration { | ||
| Duration::from_mins(5) |
Comment on lines
+16
to
18
| /// Default timeout for a single collection cycle (should be less than `poll_interval`) | ||
| const DEFAULT_COLLECTION_TIMEOUT: Duration = Duration::from_mins(1); | ||
|
|
Comment on lines
103
to
105
| poll_interval: exporter_config.poll_interval, | ||
| max_backoff: Duration::from_secs(300), | ||
| max_backoff: Duration::from_mins(5), | ||
| granularity: exporter_config.granularity, |
Comment on lines
177
to
182
| info!( | ||
| cluster = %self.config.name, | ||
| rss_before_kb = rss_before, | ||
| rss_after_kb = rss_after, | ||
| rss_reclaimed_kb = rss_before as i64 - rss_after as i64, | ||
| rss_reclaimed_kb = rss_before.cast_signed() - rss_after.cast_signed(), | ||
| "Recycled Kafka clients" |
| inherit (pkgs) lib; | ||
| cargoToml = lib.fromTOML (lib.readFile ./Cargo.toml); | ||
|
|
||
| rustToolchain = pkgs.rust-bin.stable."1.93.0".default.override { |
This was referenced Jul 9, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
*_lag_secondsmetrics when they are unconditionally hardcoded to0