-
Notifications
You must be signed in to change notification settings - Fork 3
fix: enhance OpenTelemetry configuration with vendor support and refactor tracing settings #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ use clap::{Args, ValueEnum}; | |
| use module_parser::ConfigModuleMetadata; | ||
| use serde::{Deserialize, Serialize}; | ||
| use serde_json::{Map, Value, json}; | ||
| use std::collections::BTreeMap; | ||
| use std::collections::{BTreeMap, HashMap}; | ||
| use std::path::PathBuf; | ||
| use std::time::Duration; | ||
|
|
||
|
|
@@ -18,15 +18,19 @@ pub struct AppConfig { | |
| /// Logging configuration. | ||
| #[serde(default = "default_logging_config")] | ||
| pub logging: LoggingConfig, | ||
| /// Tracing configuration. | ||
| /// OpenTelemetry configuration (resource, tracing, metrics). | ||
| #[serde(default)] | ||
| pub tracing: TracingConfig, | ||
| pub opentelemetry: OpenTelemetryConfig, | ||
| /// Directory containing per-module YAML files (optional). | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub modules_dir: Option<String>, | ||
| /// Per-module configuration bag: `module_name` -> module config. | ||
| #[serde(default)] | ||
| pub modules: BTreeMap<String, ModuleConfig>, | ||
| /// Per-vendor configuration bag: `vendor_name` → arbitrary JSON/YAML value. | ||
| /// Allows vendors to add their own typed configuration sections. | ||
| #[serde(default)] | ||
| pub vendor: VendorConfig, | ||
| } | ||
|
|
||
| impl Default for AppConfig { | ||
|
|
@@ -35,9 +39,10 @@ impl Default for AppConfig { | |
| server: ServerConfig::default(), | ||
| database: None, | ||
| logging: default_logging_config(), | ||
| tracing: TracingConfig::default(), | ||
| opentelemetry: OpenTelemetryConfig::default(), | ||
| modules_dir: None, | ||
| modules: BTreeMap::new(), | ||
| vendor: VendorConfig::default(), | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -361,27 +366,68 @@ fn parse_duration_secs(raw: &str) -> Result<Duration, String> { | |
| .map_err(|_| format!("invalid duration seconds '{raw}'")) | ||
| } | ||
|
|
||
| /// Per-vendor configuration bag: vendor name → arbitrary JSON/YAML value. | ||
| /// Each vendor's section can be deserialized into a typed struct via | ||
| /// [`AppConfig::vendor_config`] or [`AppConfig::vendor_config_or_default`]. | ||
| pub type VendorConfig = HashMap<String, serde_json::Value>; | ||
|
|
||
| /// Top-level OpenTelemetry configuration grouping resource identity, | ||
| /// a shared default exporter, tracing settings and metrics settings. | ||
| #[derive(Clone, Deserialize, Serialize, Default)] | ||
| #[serde(deny_unknown_fields)] | ||
| pub struct OpenTelemetryConfig { | ||
| #[serde(default)] | ||
| pub resource: OpenTelemetryResource, | ||
| /// Default exporter shared by tracing and metrics. Per-signal `exporter` | ||
| /// fields override this when present. | ||
| pub exporter: Option<Exporter>, | ||
| #[serde(default)] | ||
| pub tracing: TracingConfig, | ||
| #[serde(default)] | ||
| pub metrics: MetricsConfig, | ||
|
Comment on lines
+374
to
+387
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n crates/cli/src/config/app_config.rs | sed -n '360,410p'Repository: cyberfabric/cf-cli Length of output: 2211 🏁 Script executed: # Find MetricsConfig definition
rg "struct MetricsConfig" -A 20Repository: cyberfabric/cf-cli Length of output: 1331 🏁 Script executed: # Find TracingConfig definition to see if it has the same pattern
rg "struct TracingConfig" -A 20Repository: cyberfabric/cf-cli Length of output: 1610 🏁 Script executed: # Check for any existing fallback/inheritance logic related to exporter
rg "exporter" crates/cli/src/config/app_config.rs -B 2 -A 2Repository: cyberfabric/cf-cli Length of output: 962 🏁 Script executed: # Look for any implementation code that handles exporter fallback
rg "OpenTelemetryConfig" -A 5 -B 5 | head -100Repository: cyberfabric/cf-cli Length of output: 2579 🏁 Script executed: # Search for tests related to OpenTelemetry config
fd "test" --type f | xargs rg -l "OpenTelemetryConfig|MetricsConfig" 2>/dev/null | head -5Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Check if there are any impl blocks for OpenTelemetryConfig
ast-grep --pattern $'impl OpenTelemetryConfig {
$$$
}'Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Look for where these configs are actually used/instantiated
rg "metrics\.exporter|tracing\.exporter" -B 2 -A 2Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Look for all test files
find . -name "*test*" -type f | grep -E "\.(rs|toml)$" | head -20Repository: cyberfabric/cf-cli Length of output: 102 🏁 Script executed: # Search for test modules in the config crate
rg "#\[cfg\(test\)\]|#\[test\]" crates/cli/src/config/ -A 3Repository: cyberfabric/cf-cli Length of output: 1871 🏁 Script executed: # Look for where OpenTelemetry setup happens (likely in a separate init/setup file)
fd -e rs | xargs rg -l "TracingConfig|MetricsConfig" | grep -v app_configRepository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Check the actual usage of these configs - look for where metrics exporter is extracted/used
rg "\.metrics" crates/cli/src/ -B 2 -A 2 | head -60Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Search for where telemetry is actually initialized or used
rg "otel|telemetry|instrumentation" crates/cli/src/ -l | head -10Repository: cyberfabric/cf-cli Length of output: 207 🏁 Script executed: # Look for any mention of metrics or tracing initialization
rg "metrics_config|tracing_config|otel_config" crates/cli/src/ -B 2 -A 2 | head -80Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Check if there's a separate module for telemetry setup
find crates/cli/src -name "*.rs" | xargs grep -l "metrics\|tracing" | grep -v ".git"Repository: cyberfabric/cf-cli Length of output: 122 🏁 Script executed: # Search more broadly for where the config fields are accessed
rg "\.exporter" crates/cli/src/ -B 3 -A 3Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Look at run_loop.rs to see how telemetry config is used
cat -n crates/cli/src/run/run_loop.rs | head -150Repository: cyberfabric/cf-cli Length of output: 7688 🏁 Script executed: # Check for any exporter resolution or fallback logic
rg "opentelemetry.exporter|otel.*exporter" crates/ -iRepository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Look at how metrics config is actually used in run_loop
rg "metrics" crates/cli/src/run/run_loop.rs -B 3 -A 3Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Search for any function that might handle the exporter inheritance
rg "fn.*exporter|exporter.*fn" crates/cli/src/ -i -B 1 -A 5Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Check common.rs for telemetry/config setup
cat -n crates/cli/src/common.rs | head -200Repository: cyberfabric/cf-cli Length of output: 7135 🏁 Script executed: # Search for where metrics exporter is actually instantiated or used
rg "MetricsConfig" crates/cli/src/ -B 5 -A 5Repository: cyberfabric/cf-cli Length of output: 1544 🏁 Script executed: # Look for any builder or post-processing after deserialization
rg "from_config|with_exporter|exporter.*=|metrics.*=" crates/cli/src/ -iRepository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Look for modkit usage - this is where the config is actually applied
rg "run_server|AppConfig" crates/cli/src/ -B 2 -A 5Repository: cyberfabric/cf-cli Length of output: 7888 🏁 Script executed: # Check if there's a specific handler for exporter in metrics setup
rg "impl.*MetricsConfig|fn.*metrics" crates/cli/src/ -B 2 -A 8Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Look for where Exporter::default is used or referenced
rg "Exporter::default|Default for.*Exporter" crates/cli/src/Repository: cyberfabric/cf-cli Length of output: 44 🏁 Script executed: # Check the Exporter struct more carefully
rg "struct Exporter" -A 15 crates/cli/src/config/Repository: cyberfabric/cf-cli Length of output: 1172 Change
This differs from Shape change pub struct MetricsConfig {
#[serde(default)]
pub enabled: bool,
- #[serde(default)]
- pub exporter: Exporter,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub exporter: Option<Exporter>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cardinality_limit: Option<usize>,
}Resolve the effective exporter after deserialization by falling back to 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| /// OpenTelemetry resource identity — attached to all traces and metrics. | ||
| #[derive(Clone, Deserialize, Serialize)] | ||
| #[serde(deny_unknown_fields)] | ||
| pub struct OpenTelemetryResource { | ||
| /// Logical service name. | ||
| #[serde(default = "default_service_name")] | ||
| pub service_name: String, | ||
| /// Extra resource attributes added to every span and metric data point. | ||
| #[serde(default)] | ||
| pub attributes: BTreeMap<String, String>, | ||
| } | ||
|
|
||
| /// Return the default OpenTelemetry service name used when none is configured. | ||
| fn default_service_name() -> String { | ||
| "cyberfabric".to_owned() | ||
| } | ||
|
|
||
| impl Default for OpenTelemetryResource { | ||
| fn default() -> Self { | ||
| Self { | ||
| service_name: default_service_name(), | ||
| attributes: BTreeMap::default(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Tracing configuration for OpenTelemetry distributed tracing. | ||
| #[derive(Clone, Deserialize, Serialize, Default)] | ||
| pub struct TracingConfig { | ||
| #[serde(default)] | ||
| pub enabled: bool, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub service_name: Option<String>, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub exporter: Option<Exporter>, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub sampler: Option<Sampler>, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub propagation: Option<Propagation>, | ||
| #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] | ||
| pub resource: BTreeMap<String, String>, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub http: Option<HttpOpts>, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub logs_correlation: Option<LogsCorrelation>, | ||
| #[serde(default)] | ||
| pub metrics: MetricsConfig, | ||
| } | ||
|
|
||
| /// Metrics configuration for OpenTelemetry metrics collection. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.