Skip to content

feat: support reporting env vars in heartbeat messages to metasrv#8084

Open
v0y4g3r wants to merge 6 commits intoGreptimeTeam:mainfrom
v0y4g3r:feat/env-in-heartbeat
Open

feat: support reporting env vars in heartbeat messages to metasrv#8084
v0y4g3r wants to merge 6 commits intoGreptimeTeam:mainfrom
v0y4g3r:feat/env-in-heartbeat

Conversation

@v0y4g3r
Copy link
Copy Markdown
Contributor

@v0y4g3r v0y4g3r commented May 8, 2026

Summary

  • Add heartbeat_env_vars config option for datanode and frontend to specify environment variable keys whose values should be reported to metasrv in heartbeat messages
  • Metasrv extracts and stores these values in NodeInfo, enabling routing decisions like AZ-aware region placement
  • Implementation follows the existing GcStat extension pattern using the HeartbeatRequest.extensions map with key __env_vars

Changes

  • Config: Add heartbeat_env_vars: Vec<String> to DatanodeOptions, FrontendOptions, and StandaloneOptions
  • Serialization: Add EnvVars helper in common/meta/src/datanode.rs with from_config/into_extensions/from_extensions
  • Storage: Add env_vars: HashMap<String, String> field to NodeInfo in common/meta/src/cluster.rs with #[serde(default)] for backward compat
  • Datanode heartbeat: Read env vars once at startup, inject into extensions on each heartbeat
  • Frontend heartbeat: Same pattern, extensions are now populated for frontend heartbeats
  • Metasrv handlers: All three CollectXxxClusterInfoHandlers extract env vars from req.extensions and store in NodeInfo

Test plan

  • Unit tests for EnvVars round-trip serialization
  • Unit tests for NodeInfo backward compat (deserialize without env_vars field)
  • Integration test test_config_api updated for new config field
  • Manual test: configure heartbeat_env_vars, verify metasrv stores values in NodeInfo

v0y4g3r added 6 commits May 5, 2026 23:14
Add `heartbeat_env_vars` config option for datanode and frontend. When
configured, the specified environment variable values are read at startup
and sent to metasrv in every heartbeat via the `extensions` map. Metasrv
extracts and stores them in `NodeInfo` for use in routing decisions
(e.g. AZ-aware region placement).

- Add `EnvVars` helper in `common/meta/src/datanode.rs` following the
  existing `GcStat` extension pattern with `into_extensions`/`from_extensions`
- Add `env_vars: HashMap<String, String>` field to `NodeInfo` in
  `common/meta/src/cluster.rs` with `#[serde(default)]` for backward compat
- Add `heartbeat_env_vars: Vec<String>` config field to `DatanodeOptions`,
  `FrontendOptions`, and `StandaloneOptions`
- Inject env vars into heartbeat `extensions` in both datanode and frontend
  heartbeat tasks (`datanode/src/heartbeat.rs`, `frontend/src/heartbeat.rs`)
- Extract env vars from `req.extensions` in all three metasrv
  `CollectXxxClusterInfoHandler`s
- Update `NodeInfo` construction sites in `meta-client`,
  `discovery/lease.rs`, and `standalone/information_extension.rs`
- Update expected TOML output in `tests-integration/tests/http.rs`
- Add unit tests for `EnvVars` round-trip and `NodeInfo` backward compat

Signed-off-by: Lei, HUANG <leih@nvidia.com>
Signed-off-by: Lei, HUANG <mrsatangel@gmail.com>
Signed-off-by: Lei, HUANG <mrsatangel@gmail.com>
Signed-off-by: Lei, HUANG <mrsatangel@gmail.com>
Signed-off-by: Lei, HUANG <mrsatangel@gmail.com>
Signed-off-by: Lei, HUANG <mrsatangel@gmail.com>
Signed-off-by: Lei, HUANG <mrsatangel@gmail.com>
Copilot AI review requested due to automatic review settings May 8, 2026 08:58
@v0y4g3r v0y4g3r requested review from a team, MichaelScofield and WenyXu as code owners May 8, 2026 08:58
@github-actions github-actions Bot added docs-not-required This change does not impact docs. size/S labels May 8, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements a mechanism for nodes to report specific environment variables to the meta service via heartbeat messages. It adds a heartbeat_env_vars configuration to Datanode, Frontend, and Standalone components, updates the NodeInfo structure to include an env_vars field, and modifies heartbeat handlers to propagate this data through request extensions. Feedback highlights an opportunity to refactor duplicated mapping logic in the meta-client and notes that environment variables are currently not populated in standalone mode, which affects the consistency of the information_schema.nodes table.

Comment on lines 460 to +463
cpu_usage_millicores: node_info.cpu_usage_millicores,
memory_usage_bytes: node_info.memory_usage_bytes,
hostname: node_info.hostname,
env_vars: Default::default(),
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.

medium

The mapping logic from the Protobuf NodeInfo to the internal NodeInfo struct is duplicated multiple times in this file (e.g., lines 460-463, 476-480, 494-498, 510-514). This violates the general rule of refactoring duplicated logic into shared helper functions to improve maintainability. Consider creating a helper method to handle this conversion, which would also make it easier to propagate env_vars if they are added to the Protobuf definition in the future.

References
  1. Refactor duplicated logic (like environment variable extraction) into shared helper functions to improve maintainability and reduce code duplication.

.unwrap_or_default()
.to_string_lossy()
.to_string(),
env_vars: Default::default(),
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.

medium

In standalone mode, the env_vars field is hardcoded to Default::default(). This means that environment variables configured via heartbeat_env_vars will not be visible in the information_schema.nodes table when running in standalone mode. To ensure consistency across deployment modes and provide a complete view of node metadata, this extension should be updated to populate env_vars from the process environment based on the configured keys.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a configurable mechanism for datanode/frontend (and standalone via option propagation) to report selected environment variable values to metasrv via heartbeat extensions, and persists them into NodeInfo for later routing/placement decisions (e.g., AZ-aware logic).

Changes:

  • Introduces heartbeat_env_vars: Vec<String> in datanode/frontend/standalone options and wires it into env-based config loading.
  • Implements EnvVars (serialize into / deserialize from heartbeat extensions under __env_vars) and stores extracted values in common_meta::cluster::NodeInfo.
  • Updates heartbeat senders (datanode/frontend) and metasrv heartbeat handlers to populate/extract the env-var extension; expands tests for config loading and serialization/backward-compat.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests-integration/tests/http.rs Updates /config expected output to include heartbeat_env_vars = [].
src/standalone/src/options.rs Adds heartbeat_env_vars to standalone config and propagates into frontend/datanode options.
src/standalone/src/information_extension.rs Updates standalone NodeInfo construction for the new env_vars field.
src/meta-srv/src/handler/collect_cluster_info_handler.rs Extracts __env_vars from heartbeat extensions and stores into NodeInfo.
src/meta-srv/src/discovery/lease.rs Updates metasrv discovery tests to populate NodeInfo.env_vars.
src/meta-client/src/client/util.rs Updates meta-client test helpers for the new NodeInfo.env_vars field.
src/meta-client/src/client.rs Ensures metasrv node info construction populates env_vars (default).
src/frontend/src/heartbeat.rs Reads configured env vars once at startup and injects into heartbeat extensions.
src/frontend/src/frontend.rs Adds heartbeat_env_vars to frontend options and env list parsing keys.
src/datanode/src/heartbeat.rs Reads configured env vars once at startup and injects into heartbeat extensions (alongside existing GC stat extension).
src/datanode/src/config.rs Adds heartbeat_env_vars to datanode options and env list parsing keys.
src/common/meta/src/datanode.rs Adds EnvVars helper + unit tests for extension round-trip behavior.
src/common/meta/src/cluster.rs Adds NodeInfo.env_vars with serde default + tests for backward compatibility and round-trip.
src/cmd/tests/load_config_test.rs Adds env-based config loading test for heartbeat_env_vars across components.

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

pub memory: MemoryOptions,
/// The event recorder options.
pub event_recorder: EventRecorderOptions,
/// Environment variable keys to read and report in heartbeat messages.
pub slow_query: SlowQueryOptions,
pub query: QueryOptions,
pub memory: MemoryOptions,
/// Environment variable keys to read and report in heartbeat messages.
let env_vars = EnvVars::from_extensions(&request.extensions)
.inspect_err(|e| {
warn!(e;
"Failed to deserialize __env_vars from heartbeat extensions, peer: {}", peer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-not-required This change does not impact docs. size/S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants