From bc9c2df920c6eef3da87e6fb45794118600e1899 Mon Sep 17 00:00:00 2001 From: swananan Date: Mon, 6 Oct 2025 15:33:14 +0800 Subject: [PATCH] feat: add ebpf_max_messages configuration --- config.toml | 11 +++++++++ docs/configuration.md | 16 +++++++++++- docs/zh/configuration.md | 16 +++++++++++- ghostscope-ui/src/lib.rs | 1 + ghostscope-ui/src/model/app_state.rs | 2 +- ghostscope-ui/src/model/panel_state.rs | 6 ++++- ghostscope-ui/src/model/ui_state.rs | 2 ++ ghostscope/src/config/merged.rs | 3 +++ ghostscope/src/config/settings.rs | 34 ++++++++++++++++++++++++++ ghostscope/src/runtime/coordinator.rs | 1 + 10 files changed, 88 insertions(+), 4 deletions(-) diff --git a/config.toml b/config.toml index 13ae58dc..5cb36a90 100644 --- a/config.toml +++ b/config.toml @@ -104,6 +104,17 @@ default_focus = "InteractiveCommand" # Default: [4, 3, 3] panel_ratios = [3, 3, 3] +# Maximum number of eBPF trace messages to keep in the output panel +# Older messages are automatically discarded when this limit is reached +# Recommended values: +# - Low-frequency tracing: 1000-2000 +# - Medium-frequency tracing: 2000-5000 (default: 2000) +# - High-frequency tracing: 5000-10000 +# Minimum value: 100 +# Note: Larger values consume more memory +# Default: 2000 +ebpf_max_messages = 2000 + # Command history configuration [ui.history] # Enable/disable command history file functionality diff --git a/docs/configuration.md b/docs/configuration.md index 52083056..7ddec48b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -241,6 +241,16 @@ default_focus = "InteractiveCommand" # Must be 3 positive (non-zero) integers panel_ratios = [4, 3, 3] +# Maximum number of eBPF trace messages to keep in the output panel +# Older messages are automatically discarded when this limit is reached +# Minimum value: 100 +# Recommended values: +# - Low-frequency tracing: 1000-2000 +# - Medium-frequency tracing: 2000-5000 (default: 2000) +# - High-frequency tracing: 5000-10000 +# Note: Larger values consume more memory +ebpf_max_messages = 2000 + [ui.history] # Enable command history enabled = true @@ -422,6 +432,7 @@ export LLVM_SYS_170_PREFIX=/usr/lib/llvm-17 - **Layout**: Horizontal (panels side by side) - **Panel Ratios**: 4:3:3 (Source:EbpfInfo:Command) - **Default Focus**: InteractiveCommand panel +- **eBPF Max Messages**: 2000 messages - **History**: Enabled with 5000 entry limit ## File Output Naming @@ -450,7 +461,9 @@ GhostScope validates configuration at startup: 4. **Panel Ratios**: Ensures all 3 values are positive (non-zero) integers 5. **Log Level**: Validates against allowed values (error, warn, info, debug, trace) 6. **Layout Mode**: Validates against allowed values (Horizontal, Vertical - capitalized) -7. **eBPF Configuration**: +7. **UI Configuration**: + - **ebpf_max_messages**: Must be at least 100 +8. **eBPF Configuration**: - **ringbuf_size**: Must be power of 2, range 4096-16777216 bytes - **perf_page_count**: Must be power of 2, range 8-1024 pages - **proc_module_offsets_max_entries**: Must be in range 64-65536 @@ -468,6 +481,7 @@ Invalid configuration will produce clear error messages with suggestions for fix - **"perf_page_count must be a power of 2"**: Use values like 32, 64, 128, 256, etc. - **"perf_page_count X is out of reasonable range"**: Must be between 8 and 1024 pages. - **"proc_module_offsets_max_entries X is out of reasonable range"**: Must be between 64 and 65536. +- **"ebpf_max_messages X is too small"**: Must be at least 100. Increase the value in your config file. ## Best Practices diff --git a/docs/zh/configuration.md b/docs/zh/configuration.md index c1e77d56..5e8eee87 100644 --- a/docs/zh/configuration.md +++ b/docs/zh/configuration.md @@ -240,6 +240,16 @@ default_focus = "InteractiveCommand" # 必须是 3 个正整数 panel_ratios = [4, 3, 3] +# eBPF 输出面板保留的最大跟踪消息数量 +# 超过限制时,旧消息会自动丢弃 +# 最小值:100 +# 推荐值: +# - 低频跟踪:1000-2000 +# - 中频跟踪:2000-5000(默认:2000) +# - 高频跟踪:5000-10000 +# 注意:较大的值会消耗更多内存 +ebpf_max_messages = 2000 + [ui.history] # 启用命令历史 enabled = true @@ -421,6 +431,7 @@ export LLVM_SYS_170_PREFIX=/usr/lib/llvm-17 - **布局**:Horizontal(面板横向排列) - **面板比例**:4:3:3(Source:EbpfInfo:Command) - **默认焦点**:InteractiveCommand 面板 +- **eBPF 最大消息数**:2000 条消息 - **历史记录**:启用,5000 条条目限制 ## 文件输出命名 @@ -449,7 +460,9 @@ GhostScope 在启动时验证配置: 4. **面板比例**:确保所有 3 个值都是正(非零)整数 5. **日志级别**:验证是否为允许的值(error, warn, info, debug, trace) 6. **布局模式**:验证是否为允许的值(Horizontal, Vertical - 首字母大写) -7. **eBPF 配置**: +7. **UI 配置**: + - **ebpf_max_messages**:必须至少为 100 +8. **eBPF 配置**: - **ringbuf_size**:必须是 2 的幂,范围 4096-16777216 字节 - **proc_module_offsets_max_entries**:必须在 64-65536 范围内 @@ -464,6 +477,7 @@ GhostScope 在启动时验证配置: - **"ringbuf_size must be a power of 2"**:使用 2 的幂值,如 131072、262144、524288 等。 - **"ringbuf_size X is out of reasonable range"**:必须在 4KB 到 16MB 之间。 - **"proc_module_offsets_max_entries X is out of reasonable range"**:必须在 64 到 65536 之间。 +- **"ebpf_max_messages X is too small"**:必须至少为 100。在配置文件中增加该值。 ## 最佳实践 diff --git a/ghostscope-ui/src/lib.rs b/ghostscope-ui/src/lib.rs index b9b629b2..a40068a2 100644 --- a/ghostscope-ui/src/lib.rs +++ b/ghostscope-ui/src/lib.rs @@ -21,6 +21,7 @@ pub async fn run_tui_mode(event_registry: EventRegistry, layout_mode: LayoutMode panel_ratios: [4, 3, 3], // Default ratios for backward compatibility default_focus: crate::action::PanelType::InteractiveCommand, history: HistoryConfig::default(), + ebpf_max_messages: 2000, // Default }; run_tui_mode_with_config(event_registry, ui_config).await } diff --git a/ghostscope-ui/src/model/app_state.rs b/ghostscope-ui/src/model/app_state.rs index 3e68e92d..162a6149 100644 --- a/ghostscope-ui/src/model/app_state.rs +++ b/ghostscope-ui/src/model/app_state.rs @@ -203,7 +203,7 @@ impl AppState { loading_state: LoadingState::Initializing, // Start with loading, wait for runtime response loading_ui: LoadingUI::new(), source_panel: SourcePanelState::new(), - ebpf_panel: EbpfPanelState::new(), + ebpf_panel: EbpfPanelState::new_with_max_messages(ui_config.ebpf_max_messages), command_panel: CommandPanelState::new_with_config(&ui_config.history), command_renderer: OptimizedRenderer::new(), command_input_handler: OptimizedInputHandler::new(), diff --git a/ghostscope-ui/src/model/panel_state.rs b/ghostscope-ui/src/model/panel_state.rs index 9c0ffe78..2ce28859 100644 --- a/ghostscope-ui/src/model/panel_state.rs +++ b/ghostscope-ui/src/model/panel_state.rs @@ -130,10 +130,14 @@ pub enum DisplayMode { impl EbpfPanelState { pub fn new() -> Self { + Self::new_with_max_messages(2000) + } + + pub fn new_with_max_messages(max_messages: usize) -> Self { Self { trace_events: VecDeque::new(), scroll_offset: 0, - max_messages: 2000, // TODO: Make this configurable in the future + max_messages, auto_scroll: true, cursor_trace_index: 0, show_cursor: false, diff --git a/ghostscope-ui/src/model/ui_state.rs b/ghostscope-ui/src/model/ui_state.rs index ae62f04d..ca0a0824 100644 --- a/ghostscope-ui/src/model/ui_state.rs +++ b/ghostscope-ui/src/model/ui_state.rs @@ -31,6 +31,7 @@ pub struct UiConfig { pub panel_ratios: [u16; 3], // [Source, EbpfInfo, InteractiveCommand] pub default_focus: crate::action::PanelType, pub history: HistoryConfig, + pub ebpf_max_messages: usize, } /// UI-specific state management @@ -57,6 +58,7 @@ impl UIState { panel_ratios: [4, 3, 3], // Default ratios default_focus: crate::action::PanelType::InteractiveCommand, history: HistoryConfig::default(), + ebpf_max_messages: 2000, // Default value }) } } diff --git a/ghostscope/src/config/merged.rs b/ghostscope/src/config/merged.rs index 286832af..cd8c876a 100644 --- a/ghostscope/src/config/merged.rs +++ b/ghostscope/src/config/merged.rs @@ -31,6 +31,7 @@ pub struct MergedConfig { pub panel_ratios: [u16; 3], pub history_enabled: bool, pub history_max_entries: usize, + pub ebpf_max_messages: usize, // DWARF configuration #[allow(dead_code)] @@ -157,6 +158,7 @@ impl MergedConfig { panel_ratios: config.ui.panel_ratios, // UI config from file history_enabled: config.ui.history.enabled, history_max_entries: config.ui.history.max_entries, + ebpf_max_messages: config.ui.ebpf_max_messages, dwarf_search_paths: config.dwarf.search_paths, ebpf_config: { // Command line --force-perf-event-array overrides config file @@ -216,6 +218,7 @@ impl MergedConfig { enabled: self.history_enabled, max_entries: self.history_max_entries, }, + ebpf_max_messages: self.ebpf_max_messages, } } diff --git a/ghostscope/src/config/settings.rs b/ghostscope/src/config/settings.rs index 417a6ac5..cd261649 100644 --- a/ghostscope/src/config/settings.rs +++ b/ghostscope/src/config/settings.rs @@ -195,6 +195,9 @@ pub struct UiConfigToml { /// Command history configuration #[serde(default)] pub history: HistoryConfigToml, + /// Maximum number of eBPF trace messages to keep in the output panel + #[serde(default = "default_ebpf_max_messages")] + pub ebpf_max_messages: usize, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -288,6 +291,10 @@ fn default_history_max_entries() -> usize { 5000 } +fn default_ebpf_max_messages() -> usize { + 2000 +} + // Default implementations for each config section impl Default for GeneralConfig { fn default() -> Self { @@ -414,7 +421,31 @@ impl Default for UiConfigToml { default_focus: PanelType::default(), panel_ratios: default_panel_ratios(), history: HistoryConfigToml::default(), + ebpf_max_messages: default_ebpf_max_messages(), + } + } +} + +impl UiConfigToml { + /// Validate UI configuration values + pub fn validate(&self, file_path: &str) -> Result<()> { + // Validate ebpf_max_messages is reasonable (at least 100) + if self.ebpf_max_messages < 100 { + return Err(anyhow::anyhow!( + "❌ Invalid UI configuration in '{}':\n\n\ + ebpf_max_messages {} is too small\n\n\ + 💡 Minimum value: 100\n\ + Recommended values:\n\ + - Low-frequency tracing: 1000-2000\n\ + - Medium-frequency tracing: 2000-5000 (default: 2000)\n\ + - High-frequency tracing: 5000-10000\n\ + Note: Larger values consume more memory", + file_path, + self.ebpf_max_messages + )); } + + Ok(()) } } @@ -477,6 +508,9 @@ impl Config { // Validate eBPF configuration config.ebpf.validate(&path.display().to_string())?; + // Validate UI configuration + config.ui.validate(&path.display().to_string())?; + Ok(config) } diff --git a/ghostscope/src/runtime/coordinator.rs b/ghostscope/src/runtime/coordinator.rs index 583fa122..890cca31 100644 --- a/ghostscope/src/runtime/coordinator.rs +++ b/ghostscope/src/runtime/coordinator.rs @@ -56,6 +56,7 @@ pub async fn run_tui_coordinator(parsed_args: ParsedArgs) -> Result<()> { default_focus: ghostscope_ui::PanelType::InteractiveCommand, // Default panel_ratios: [4, 3, 3], // Default history: ghostscope_ui::HistoryConfig::default(), + ebpf_max_messages: 2000, // Default }; // Create a default MergedConfig from ParsedArgs for compatibility