Андела спонсировала этот пост.
Инструменты мониторинга системы есть повсюду, но большинство из них представляют собой либо тяжелые приложения с графическим интерфейсом, либо базовые утилиты командной строки, которые сбрасывают статическую информацию. Что, если бы вы могли построить что-то среднее; живую интерактивную панель терминала, одновременно легкую и мощную?
Это именно то, что я намеревался создать с помощью Monitor-rs. После работы над различными системными инструментами я хотел изучить, как уникальные функции Rust могут решить классические задачи мониторинга в реальном времени: управлять одновременным сбором данных, корректно обрабатывать ошибки и четко представлять информацию, не потребляя чрезмерных ресурсов.
Monitor-rs отслеживает использование ЦП, потребление памяти, дисковый ввод-вывод и сетевую активность в режиме реального времени, и все это в чистом интерфейсе терминала. Это практическое исследование того, что делает Rust особенно подходящим для системного программирования.
Давайте углубимся в важные детали реализации:
- Абстракции с нулевой стоимостью: Посмотрите, как код высокого уровня компилируется в высокоэффективные машинные инструкции.
- Собственность и заимствование: Поймите, как уникальное управление памятью Rust обеспечивает безопасность потоков без сборщика мусора.
- Бесстрашный параллелизм: Узнайте, как каналы и потоки используются для безопасного управления сложными потоками данных в реальном времени.
- Надежная обработка ошибок: убедитесь в эффективности Result при создании отказоустойчивых приложений.
- Мощная экосистема и ящики: узнайте, как такие библиотеки, как sysinfo и ratatui, легко расширяют возможности Rust.
- Модульная конструкция: Оцените, как система модулей Rust облегчает четкое разделение задач по удобству сопровождения.
Предварительные условия
Прежде чем углубиться в код, вам понадобится несколько вещей:
- Базовые знания Rust: знание таких понятий, как структуры, модули и потоки, будет полезным.
- Система Linux или macOS: Monitor-rs в основном тестировался на Ubuntu 22.04.
- Знакомство с терминалом: поскольку это приложение на основе терминала, удобство использования интерфейсов командной строки будет полезно.
- Установлены Rust и Cargo: Если у вас не установлен Rust, вы можете сделать это с помощью следующей команды:
локон —proto ‘=https’ —tlsv1.2 -sSf [ | sh
What Is monitor-rs?
Monitor-rs is a real-time terminal dashboard designed to display critical system performance metrics. IT provides insights into:
- CPU usage: See your processor’s utilization at a glance.
- Memory (RAM) utilization: Track how much of your system’s memory is in use.
- Disk read/write throughput: Monitor your storage device’s activity.
- Network traffic: Keep an eye on incoming and outgoing network data.
- Alerting system: Get notified when customizable performance thresholds are exceeded.
IT achieves this robust functionality with key Rust libraries:
- sysinfo: For efficient and cross-platform system statistics collection.
- Ratatui: For rendering the dynamic and interactive TUI dashboard.
- Modular Rust design: Ensuring an easily extensible and maintainable codebase.
The monitor-rs Project Structure: A Modular Deep Dive
One of the strengths of monitor-rs is its clean, modular architecture. This design principle ensures that different functionalities are well-separated, making the codebase easier to understand, maintain and extend. Here’s a look at the project’s directory layout:
monitor-rs/
├── src/
│ ├── main.rs # App entry point
│ ├── metrics/ # System collectors and data snapshot
│ │ ├── cpu.rs
│ │ ├── disk.rs
│ │ ├── memory.rs
│ │ ├── network.rs
│ │ └── snapshot.rs
│ ├── alerting/ # Alerting rules and evaluation logic
│ │ ├── handler.rs
│ │ └── rules.rs
│ └── ui/ # Terminal UI components
│ ├── dashboard.rs
│ ├── cpu_widget.rs
│ ├── memory_widget.rs
│ ├── disk_widget.rs
│ ├── net_widget.rs
│ └── theme.rs
├── Cargo.toml # Dependencies and package config
└── alerts.log # File where triggered alerts are logged
This structure clearly delineates responsibilities: metrics handles data gathering, alerting manages threshold checks, and ui is solely concerned with presentation. This separation is key to monitor-rs’s extensibility.
Setup and Running the Project
Getting monitor-rs up and running on your system is straightforward. Follow these steps:
Get the Code and Build
First, clone the monitor-rs repository from GitHub to your local machine. Open your terminal and run:
git clone
cd monitor-rs
12
git clone cd monitor-rs
Once inside the project directory, compile the application. We recommend building in release mode for optimal performance, as this applies Rust’s full suite of optimizations.
cargo build —release
This command will compile monitor-rs and its dependencies. The resulting executable will be placed in the target/release/ directory.
Run the Monitor
After the compilation is complete, start monitor-rs.
To run the optimized release build:
./target/release/monitor-rs
Alternatively, if you’re in the project root and haven’t changed the code since the last build, you can use cargo run —release, which will recompile if necessary and then execute the optimized binary:
cargo run —release
You’ll instantly see a dynamic, real-time system dashboard appear in your terminal. To quit the application, simply press the q key.
The Metrics Engine (CPU, Memory, Disk, Network)
The core of monitor-rs lies in its independent metrics collectors, residing in the src/metrics/directory. Each collector is responsible for refreshing specific system values, typically on a one-second interval, ensuring real-time accuracy.
CPU Usage
The CPU usage is collected efficiently using the sysinfo library, specifically within src/metrics/cpu.rs.
// src/metrics/cpu.rs
pub fn collect(&mut self) -> f32 {
self.sys.refresh_cpu_all();
self.sys.global_cpu_usage()
}
12345
// src/metrics/cpu.rspub fn collect(&mut self) -> f32 { self.sys.refresh_cpu_all(); self.sys.global_cpu_usage()}
This snippet first refreshes all CPU information systemwide, then retrieves the overall global CPU usage as a percentage.
Memory Usage
Memory metrics capture both total and used RAM, allowing for a precise utilization calculation, handled in src/metrics/memory.rs.
// src/metrics/memory.rs
pub fn collect_total(&mut self) -> u64 {
self.sys.refresh_memory();
self.sys.total_memory()
}
pub fn collect_used(&mut self) -> u64 {
self.sys.refresh_memory();
self.sys.used_memory()
}
12345678910
// src/metrics/memory.rspub fn collect_total(&mut self) -> u64 { self.sys.refresh_memory(); self.sys.total_memory()} pub fn collect_used(&mut self) -> u64 { self.sys.refresh_memory(); self.sys.used_memory()}
IT captures the total available memory and the currently used memory, then calculates the ratio to display as a percentage in the UI.
Disk Read/Write
Disk I/O is aggregated from process-level information, and throughput is calculated by comparing current values to previously recorded ones, all within src/metrics/disk.rs.
// src/metrics/disk.rs (simplified example of delta calculation)
// In a real scenario, this involves iterating through disk information
// and calculating the change since the last collection.
let delta = read.saturating_sub(self.prev_read);
self.prev_read = read;
// … (rest of the disk I/O collection logic)
123456
// src/metrics/disk.rs (simplified example of delta calculation)// In a real scenario, this involves iterating through disk information// and calculating the change since the last collection.let delta = read.saturating_sub(self.prev_read);self.prev_read = read;// … (rest of the disk I/O collection logic)
This ensures IT’s displaying actual read/write speeds (in bytes per second ) rather than just cumulative totals. The saturating_sub prevents underflow if the current value somehow drops below the previous one (though unlikely for cumulative metrics).
Network Traffic
Network traffic is measured by tracking received (Rx) and transmitted (Tx) bytes. Similar to disk I/O, deltas are computed each second in src/metrics/network.rs.
// src/metrics/network.rs
pub fn collect_rx(&mut self) -> u64 {
self.networks.refresh(true); // Refresh network interfaces
let (rx, _) = Self::aggregate(&self.networks); // Aggregate total received bytes
let delta = rx.saturating_sub(self.prev_rx); // Calculate bytes received since last check
self.prev_rx = rx; // Store current total for next calculation
delta // Return the delta
}
// Similar logic for collect_tx
123456789
// src/metrics/network.rspub fn collect_rx(&mut self) -> u64 { self.networks.refresh(true); // Refresh network interfaces let (rx, _) = Self::aggregate(&self.networks); // Aggregate total received bytes let delta = rx.saturating_sub(self.prev_rx); // Calculate bytes received since last check self.prev_rx = rx; // Store current total for next calculation delta // Return the delta}// Similar logic for collect_tx
This function collects the total received bytes across all network interfaces, calculates the difference from the previous second, and returns this delta, representing the current received throughput.
Explaining the Alerting and UI System
Terminal Dashboard (ratatui)
The user interface of monitor-rs is meticulously crafted using the ratatui library, providing a clean and informative dashboard. The core UI orchestration happens in src/ui/dashboard.rs. IT’s organized into four primary panels, each managed by its own widget (cpu_widget.rs, memory_widget.rs, etc.):
- CPU: A vivid green gauge indicating current CPU utilization.
- Memory: A clear blue gauge displaying RAM usage.
- Disk I/O: Shows real-time read and write speeds in bytes per second.
- Network I/O: Presents current received (Rx) and transmitted (Tx) network traffic in bytes per second.
Here’s a look at the monitor-rs dashboard in action:
Figure 1: The real-time system dashboard of monitor-rs, displaying CPU, memory, disk and network metrics.
The layout is defined and rendered efficiently:
// src/ui/dashboard.rs
let layout = Layout::default()
.direction(Direction::Vertical)
.margin(1)
.constraints([
Constraint::Length(3), // CPU Gauge height
Constraint::Length(3), // Memory Gauge height
Constraint::Length(3), // Disk I/O Block height
Constraint::Length(3), // Network I/O Block height
Constraint::Min(0), // Remaining space for alerts/other
]) .split(f.area()); 123456789101112 // src/ui/dashboard.rslet макет = Layout::default() .direction(Direction::Vertical) .margin(1) .constraints([ Constraint::Length(3), // CPU Gauge height Constraint::Length(3), // Memory Gauge height Constraint::Length(3), // Disk I/O Block height Constraint::Length(3), // Network I/O Block height Constraint::Min(0), // Remaining space for alerts/other ]) .split(f.area());
Затем каждый виджет пользовательского интерфейса получает последний снимок MetricSnapshot и соответствующим образом отображает текущие значения, гарантируя, что отображение всегда будет актуальным. Стилизация и цвета управляются централизованно в src/ui/theme.rs.
Система оповещения
Надежная система оповещений является важной функцией, позволяющей пользователям определять собственные пороговые значения для различных показателей. Эти правила определены в src/alerting/rules.rs:
pub fn default_rules() -> Vec
AlertRule {
name: «High CPU Usage»,
threshold: 70.0,
check: |snap| snap.cpu_usage > 70.0,
},
AlertRule {
name: «High Memory Usage»,
threshold: 70.0,
check: |snap| {
if snap.total_memory == 0 {
false
} else {
(snap.used_memory as f64 / snap.total_memory as f64) * 100.0 > 70.0
}
},
},
// … more rules can be added here
]
} 123456789101112131415161718192021 pub fn default_rules() -> Vec
Модуль src/alerting/handler.rs отвечает за получение MetricSnapshot и его оценку на соответствие этим правилам. Если условие определенного правила выполняется, срабатывает оповещение, которое записывается в файл alerts.log в корне проекта. Это обеспечивает постоянную запись событий производительности для последующего просмотра или интеграции с другими инструментами мониторинга.
Пример записи оповещения в alerts.log:
[ALERT] Высокая загрузка ЦП возникла 25 мая 2025 г., 20:26:49. Порог: 5
[ALERT] Высокое использование памяти активировано 25 мая 2025 г., 20:26:49. Порог: 70
[ALERT] Высокая загрузка ЦП возникла 25 мая 2025 г., 20:26:50. Порог: 5
[ALERT] Высокое использование памяти активировано 25 мая 2025 г., 20:26:50. Порог: 70
[ALERT] Высокая загрузка ЦП возникла 25 мая 2025 г., 20:26:51. Порог: 5
[ALERT] Высокое использование памяти активировано 25 мая 2025 г., 20:26:51. Порог: 70
[ALERT] Высокая загрузка ЦП возникла 25 мая 2025 г., 20:26:53. Порог: 5
[ALERT] Высокое использование памяти активировано 25 мая 2025 г., 20:26:53. Порог: 70
[ALERT] Высокая загрузка ЦП возникла 25 мая 2025 г., 20:26:54. Порог: 5
[ALERT] Высокое использование памяти активировано 25 мая 2025 г., 20:26:54. Порог: 70
[ALERT] Высокая загрузка ЦП возникла 25 мая 2025 г., 20:26:55. Порог: 5
7. Ключевые выводы
Monitor-rs демонстрирует несколько мощных возможностей и лучших практик разработки на Rust:
- Мониторинг ресурсов в реальном времени с минимальной нагрузкой на процессор, что делает его эффективным для непрерывного использования.
- Полностью расширяемый дизайн, позволяющий легко добавлять новые показатели, создавать собственные виджеты или определять более сложные правила оповещений.
- Использует мощные и надежные библиотеки Rust: sysinfo для системных данных, ratatui для рендеринга текстового пользовательского интерфейса (TUI), Chronic для обработки времени и Crossterm для управления терминалом.
- Оповещения сохраняются в файле (alerts.log), который может иметь неоценимое значение для ведения журнала, упреждающего мониторинга или даже для проверки производительности системы с течением времени.
- Высокая портативность, разработанная для бесперебойной работы в любой системе Linux или macOS.
8. Заключение
Создаете ли вы внутренние инструменты, изучаете системное программирование или совершенствуете свои знания Rust, Monitor-rs демонстрирует, как можно создавать мощные терминальные приложения с удивительно небольшим количеством кода.
Этот проект, состоящий всего из 700 строк идиоматического языка Rust, обеспечивает мониторинг в реальном времени, модульную архитектуру и усовершенствованный интерфейс терминала, который может конкурировать с альтернативами с графическим пользовательским интерфейсом. Сочетание sysinfo для системных показателей и ratatui для интерфейса создает основу, одновременно производительную и расширяемую.
Модульная конструкция позволяет легко добавлять новые метрики, настраивать отображение или интегрировать дополнительные источники данных с готовым к использованию кодом, который демонстрирует сильные стороны Rust в системном программировании.
- Изучите код и внесите свой вклад в репозиторий GitHub..
- Узнайте больше о контейнере sysinfo для системной информации: документация sysinfo.
- Откройте для себя возможности ratatui для создания потрясающих TUI: документация Ratatui
Погрузитесь глубже в Rust и Docker с помощью руководства Анделы «Создание докеризованного приложения Todo с помощью React, Chakra UI и Rust».
Andela предоставляет крупнейшую в мире частную рыночную площадку для талантов удаленных технологий, управляемую платформой на базе искусственного интеллекта для управления полным жизненным циклом найма по контракту. Andela помогает компаниям масштабировать команды и быстрее реализовывать проекты в специализированных областях: разработка приложений, искусственный интеллект, облако, данные и аналитика. Узнайте больше Последние новости от Анделы ТЕНДЕНЦИОННЫЕ ИСТОРИИ YOUTUBE.COM/THENEWSTACK Технологии развиваются быстро, не пропустите ни одной серии. Подпишитесь на наш канал YouTube, чтобы смотреть все наши подкасты, интервью, демонстрации и многое другое. ПОДПИСАТЬСЯ Группа, созданная в Sketch. Тинега — старший инженер DevOps и технолог в Andela, частной глобальной торговой площадке для технических талантов. Тинега начал свою карьеру в сфере технологий в 2018 году после получения стипендии Google Africa Developer Scholarship — программы обучения Анделы в партнерстве с Google. Тинега… Читать далее от Тинега Ончари