Skip to content

Commit e015112

Browse files
committed
graph,node: Add log store configuration system
Adds a configuration layer for selecting and configuring log backends: - LogStoreConfig enum with variants: Disabled, File, Elasticsearch, Loki - LogConfigProvider for loading config from environment variables and CLI args - Unified GRAPH_LOG_STORE_* environment variable naming - CLI arguments with --log-store-backend and backend-specific options - Configuration precedence: CLI args > env vars > defaults - Deprecation warnings for old config variables Supported configuration: - Backend selection (disabled, file, elasticsearch, loki) - File: directory, max size, retention days - Elasticsearch: endpoint, credentials, index, timeout - Loki: endpoint, tenant ID
1 parent 8046900 commit e015112

4 files changed

Lines changed: 526 additions & 3 deletions

File tree

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
use slog::{warn, Logger};
2+
use std::env;
3+
4+
/// Read environment variable with fallback to deprecated key
5+
///
6+
/// This helper function implements backward compatibility for environment variables.
7+
/// It first tries the new key, then falls back to the old (deprecated) key with a warning.
8+
///
9+
/// # Arguments
10+
/// * `logger` - Logger for emitting deprecation warnings
11+
/// * `new_key` - The new environment variable name
12+
/// * `old_key` - The deprecated environment variable name
13+
///
14+
/// # Returns
15+
/// The value of the environment variable if found, or None if neither key is set
16+
pub fn read_env_with_fallback(logger: &Logger, new_key: &str, old_key: &str) -> Option<String> {
17+
// Try new key first
18+
if let Ok(value) = env::var(new_key) {
19+
return Some(value);
20+
}
21+
22+
// Fall back to old key with deprecation warning
23+
if let Ok(value) = env::var(old_key) {
24+
warn!(
25+
logger,
26+
"Using deprecated environment variable '{}', please use '{}' instead", old_key, new_key
27+
);
28+
return Some(value);
29+
}
30+
31+
None
32+
}
33+
34+
/// Read environment variable with default value and fallback
35+
///
36+
/// Similar to `read_env_with_fallback`, but returns a default value if neither key is set.
37+
///
38+
/// # Arguments
39+
/// * `logger` - Logger for emitting deprecation warnings
40+
/// * `new_key` - The new environment variable name
41+
/// * `old_key` - The deprecated environment variable name
42+
/// * `default` - Default value to return if neither key is set
43+
///
44+
/// # Returns
45+
/// The value of the environment variable, or the default if neither key is set
46+
pub fn read_env_with_default(
47+
logger: &Logger,
48+
new_key: &str,
49+
old_key: &str,
50+
default: &str,
51+
) -> String {
52+
read_env_with_fallback(logger, new_key, old_key).unwrap_or_else(|| default.to_string())
53+
}
54+
55+
/// Parse u64 from environment variable with fallback
56+
///
57+
/// Reads an environment variable with fallback support and parses it as a u64.
58+
/// Returns the default value if the variable is not set or cannot be parsed.
59+
///
60+
/// # Arguments
61+
/// * `logger` - Logger for emitting deprecation warnings
62+
/// * `new_key` - The new environment variable name
63+
/// * `old_key` - The deprecated environment variable name
64+
/// * `default` - Default value to return if parsing fails or neither key is set
65+
///
66+
/// # Returns
67+
/// The parsed u64 value, or the default if parsing fails or neither key is set
68+
pub fn read_u64_with_fallback(logger: &Logger, new_key: &str, old_key: &str, default: u64) -> u64 {
69+
read_env_with_fallback(logger, new_key, old_key)
70+
.and_then(|s| s.parse().ok())
71+
.unwrap_or(default)
72+
}
73+
74+
/// Parse u32 from environment variable with fallback
75+
///
76+
/// Reads an environment variable with fallback support and parses it as a u32.
77+
/// Returns the default value if the variable is not set or cannot be parsed.
78+
///
79+
/// # Arguments
80+
/// * `logger` - Logger for emitting deprecation warnings
81+
/// * `new_key` - The new environment variable name
82+
/// * `old_key` - The deprecated environment variable name
83+
/// * `default` - Default value to return if parsing fails or neither key is set
84+
///
85+
/// # Returns
86+
/// The parsed u32 value, or the default if parsing fails or neither key is set
87+
pub fn read_u32_with_fallback(logger: &Logger, new_key: &str, old_key: &str, default: u32) -> u32 {
88+
read_env_with_fallback(logger, new_key, old_key)
89+
.and_then(|s| s.parse().ok())
90+
.unwrap_or(default)
91+
}
92+
93+
#[cfg(test)]
94+
mod tests {
95+
use super::*;
96+
97+
#[test]
98+
fn test_read_new_key_takes_precedence() {
99+
let logger = crate::log::logger(true);
100+
std::env::set_var("NEW_KEY_PRECEDENCE", "new_value");
101+
std::env::set_var("OLD_KEY_PRECEDENCE", "old_value");
102+
103+
let result = read_env_with_fallback(&logger, "NEW_KEY_PRECEDENCE", "OLD_KEY_PRECEDENCE");
104+
assert_eq!(result, Some("new_value".to_string()));
105+
106+
std::env::remove_var("NEW_KEY_PRECEDENCE");
107+
std::env::remove_var("OLD_KEY_PRECEDENCE");
108+
}
109+
110+
#[test]
111+
fn test_read_old_key_when_new_not_present() {
112+
let logger = crate::log::logger(true);
113+
std::env::remove_var("NEW_KEY_FALLBACK");
114+
std::env::set_var("OLD_KEY_FALLBACK", "old_value");
115+
116+
let result = read_env_with_fallback(&logger, "NEW_KEY_FALLBACK", "OLD_KEY_FALLBACK");
117+
assert_eq!(result, Some("old_value".to_string()));
118+
119+
std::env::remove_var("OLD_KEY_FALLBACK");
120+
}
121+
122+
#[test]
123+
fn test_read_returns_none_when_neither_present() {
124+
let logger = crate::log::logger(true);
125+
std::env::remove_var("NEW_KEY_NONE");
126+
std::env::remove_var("OLD_KEY_NONE");
127+
128+
let result = read_env_with_fallback(&logger, "NEW_KEY_NONE", "OLD_KEY_NONE");
129+
assert_eq!(result, None);
130+
}
131+
132+
#[test]
133+
fn test_read_with_default() {
134+
let logger = crate::log::logger(true);
135+
std::env::remove_var("NEW_KEY_DEFAULT");
136+
std::env::remove_var("OLD_KEY_DEFAULT");
137+
138+
let result = read_env_with_default(
139+
&logger,
140+
"NEW_KEY_DEFAULT",
141+
"OLD_KEY_DEFAULT",
142+
"default_value",
143+
);
144+
assert_eq!(result, "default_value");
145+
146+
std::env::remove_var("NEW_KEY_DEFAULT");
147+
std::env::remove_var("OLD_KEY_DEFAULT");
148+
}
149+
150+
#[test]
151+
fn test_read_u64_with_fallback() {
152+
let logger = crate::log::logger(true);
153+
std::env::set_var("NEW_KEY_U64", "12345");
154+
155+
let result = read_u64_with_fallback(&logger, "NEW_KEY_U64", "OLD_KEY_U64", 999);
156+
assert_eq!(result, 12345);
157+
158+
std::env::remove_var("NEW_KEY_U64");
159+
160+
// Test with old key
161+
std::env::set_var("OLD_KEY_U64", "67890");
162+
let result = read_u64_with_fallback(&logger, "NEW_KEY_U64", "OLD_KEY_U64", 999);
163+
assert_eq!(result, 67890);
164+
165+
std::env::remove_var("OLD_KEY_U64");
166+
167+
// Test with default
168+
let result = read_u64_with_fallback(&logger, "NEW_KEY_U64", "OLD_KEY_U64", 999);
169+
assert_eq!(result, 999);
170+
}
171+
172+
#[test]
173+
fn test_read_u32_with_fallback() {
174+
let logger = crate::log::logger(true);
175+
std::env::set_var("NEW_KEY_U32", "123");
176+
177+
let result = read_u32_with_fallback(&logger, "NEW_KEY_U32", "OLD_KEY_U32", 999);
178+
assert_eq!(result, 123);
179+
180+
std::env::remove_var("NEW_KEY_U32");
181+
182+
// Test with old key
183+
std::env::set_var("OLD_KEY_U32", "456");
184+
let result = read_u32_with_fallback(&logger, "NEW_KEY_U32", "OLD_KEY_U32", 999);
185+
assert_eq!(result, 456);
186+
187+
std::env::remove_var("OLD_KEY_U32");
188+
189+
// Test with default
190+
let result = read_u32_with_fallback(&logger, "NEW_KEY_U32", "OLD_KEY_U32", 999);
191+
assert_eq!(result, 999);
192+
}
193+
194+
#[test]
195+
fn test_invalid_u64_uses_default() {
196+
let logger = crate::log::logger(true);
197+
std::env::set_var("NEW_KEY_INVALID", "not_a_number");
198+
199+
let result = read_u64_with_fallback(&logger, "NEW_KEY_INVALID", "OLD_KEY_INVALID", 999);
200+
assert_eq!(result, 999);
201+
202+
std::env::remove_var("NEW_KEY_INVALID");
203+
}
204+
205+
#[test]
206+
fn test_invalid_u32_uses_default() {
207+
let logger = crate::log::logger(true);
208+
std::env::set_var("NEW_KEY_INVALID_U32", "not_a_number");
209+
210+
let result =
211+
read_u32_with_fallback(&logger, "NEW_KEY_INVALID_U32", "OLD_KEY_INVALID_U32", 999);
212+
assert_eq!(result, 999);
213+
214+
std::env::remove_var("NEW_KEY_INVALID_U32");
215+
}
216+
}

node/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod chain;
99
pub mod config;
1010
mod helpers;
1111
pub mod launcher;
12+
pub mod log_config_provider;
1213
pub mod manager;
1314
pub mod network_setup;
1415
pub mod opt;

0 commit comments

Comments
 (0)