e66008f341
This check in offers alpha support for per process metrics, you can view threads, process CPU usage over time, IO, memory, CPU time, parent process, command, uptime and journal entries. This is unfinished but all major functionality is available and I wanted to make it available to feedback and testing.
184 lines
6.2 KiB
Rust
184 lines
6.2 KiB
Rust
//! WebSocket connector library for socktop agents.
|
|
//!
|
|
//! This library provides a high-level interface for connecting to socktop agents
|
|
//! over WebSocket connections with support for TLS and certificate pinning.
|
|
//!
|
|
//! # Quick Start
|
|
//!
|
|
//! ```no_run
|
|
//! use socktop_connector::{connect_to_socktop_agent, AgentRequest, AgentResponse};
|
|
//!
|
|
//! #[tokio::main]
|
|
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
//! let mut connector = connect_to_socktop_agent("ws://localhost:3000/ws").await?;
|
|
//!
|
|
//! // Get comprehensive system metrics
|
|
//! if let Ok(AgentResponse::Metrics(metrics)) = connector.request(AgentRequest::Metrics).await {
|
|
//! println!("Hostname: {}", metrics.hostname);
|
|
//! println!("CPU Usage: {:.1}%", metrics.cpu_total);
|
|
//!
|
|
//! // CPU temperature if available
|
|
//! if let Some(temp) = metrics.cpu_temp_c {
|
|
//! println!("CPU Temperature: {:.1}°C", temp);
|
|
//! }
|
|
//!
|
|
//! // Memory usage
|
|
//! println!("Memory: {:.1} GB / {:.1} GB",
|
|
//! metrics.mem_used as f64 / 1_000_000_000.0,
|
|
//! metrics.mem_total as f64 / 1_000_000_000.0);
|
|
//!
|
|
//! // Per-core CPU usage
|
|
//! for (i, usage) in metrics.cpu_per_core.iter().enumerate() {
|
|
//! println!("Core {}: {:.1}%", i, usage);
|
|
//! }
|
|
//!
|
|
//! // GPU information
|
|
//! if let Some(gpus) = &metrics.gpus {
|
|
//! for gpu in gpus {
|
|
//! if let Some(name) = &gpu.name {
|
|
//! println!("GPU {}: {:.1}% usage", name, gpu.utilization.unwrap_or(0.0));
|
|
//! if let Some(temp) = gpu.temp {
|
|
//! println!(" Temperature: {:.1}°C", temp);
|
|
//! }
|
|
//! }
|
|
//! }
|
|
//! }
|
|
//! }
|
|
//!
|
|
//! // Get process information
|
|
//! if let Ok(AgentResponse::Processes(processes)) = connector.request(AgentRequest::Processes).await {
|
|
//! println!("Running processes: {}", processes.process_count);
|
|
//! for proc in &processes.top_processes {
|
|
//! println!(" PID {}: {} ({:.1}% CPU, {:.1} MB RAM)",
|
|
//! proc.pid, proc.name, proc.cpu_usage, proc.mem_bytes as f64 / 1_000_000.0);
|
|
//! }
|
|
//! }
|
|
//!
|
|
//! // Get disk information
|
|
//! if let Ok(AgentResponse::Disks(disks)) = connector.request(AgentRequest::Disks).await {
|
|
//! for disk in disks {
|
|
//! let used_gb = (disk.total - disk.available) as f64 / 1_000_000_000.0;
|
|
//! let total_gb = disk.total as f64 / 1_000_000_000.0;
|
|
//! println!("Disk {}: {:.1} GB / {:.1} GB", disk.name, used_gb, total_gb);
|
|
//! }
|
|
//! }
|
|
//!
|
|
//! Ok(())
|
|
//! }
|
|
//! ```
|
|
//!
|
|
//! # TLS Support
|
|
//!
|
|
//! ```no_run
|
|
//! use socktop_connector::connect_to_socktop_agent_with_tls;
|
|
//!
|
|
//! # #[tokio::main]
|
|
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
//! let connector = connect_to_socktop_agent_with_tls(
|
|
//! "wss://secure-host:3000/ws",
|
|
//! "/path/to/ca.pem",
|
|
//! false // Enable hostname verification
|
|
//! ).await?;
|
|
//! # Ok(())
|
|
//! # }
|
|
//! ```
|
|
//!
|
|
//! # Continuous Monitoring
|
|
//!
|
|
//! For real-time system monitoring, you can make requests in a loop. The agent
|
|
//! implements intelligent caching to avoid overwhelming the system:
|
|
//!
|
|
//! ```no_run
|
|
//! use socktop_connector::{connect_to_socktop_agent, AgentRequest, AgentResponse};
|
|
//! use tokio::time::{sleep, Duration};
|
|
//!
|
|
//! #[tokio::main]
|
|
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
//! let mut connector = connect_to_socktop_agent("ws://localhost:3000/ws").await?;
|
|
//!
|
|
//! // Monitor system metrics every 2 seconds
|
|
//! loop {
|
|
//! match connector.request(AgentRequest::Metrics).await {
|
|
//! Ok(AgentResponse::Metrics(metrics)) => {
|
|
//! // Calculate total network activity across all interfaces
|
|
//! let total_rx: u64 = metrics.networks.iter().map(|n| n.received).sum();
|
|
//! let total_tx: u64 = metrics.networks.iter().map(|n| n.transmitted).sum();
|
|
//!
|
|
//! println!("CPU: {:.1}%, Memory: {:.1}%, Network: ↓{} ↑{}",
|
|
//! metrics.cpu_total,
|
|
//! (metrics.mem_used as f64 / metrics.mem_total as f64) * 100.0,
|
|
//! format_bytes(total_rx),
|
|
//! format_bytes(total_tx)
|
|
//! );
|
|
//! }
|
|
//! Err(e) => {
|
|
//! eprintln!("Connection error: {}", e);
|
|
//! break;
|
|
//! }
|
|
//! _ => unreachable!(),
|
|
//! }
|
|
//!
|
|
//! sleep(Duration::from_secs(2)).await;
|
|
//! }
|
|
//!
|
|
//! Ok(())
|
|
//! }
|
|
//!
|
|
//! fn format_bytes(bytes: u64) -> String {
|
|
//! const UNITS: &[&str] = &["B", "KB", "MB", "GB"];
|
|
//! let mut size = bytes as f64;
|
|
//! let mut unit_index = 0;
|
|
//!
|
|
//! while size >= 1024.0 && unit_index < UNITS.len() - 1 {
|
|
//! size /= 1024.0;
|
|
//! unit_index += 1;
|
|
//! }
|
|
//!
|
|
//! format!("{:.1}{}", size, UNITS[unit_index])
|
|
//! }
|
|
//! ```
|
|
|
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
|
|
|
// Core modules
|
|
pub mod config;
|
|
pub mod error;
|
|
pub mod types;
|
|
pub mod utils;
|
|
|
|
// Implementation modules
|
|
#[cfg(feature = "networking")]
|
|
pub mod networking;
|
|
|
|
#[cfg(feature = "wasm")]
|
|
pub mod wasm;
|
|
|
|
// Main connector implementation
|
|
pub mod connector_impl;
|
|
|
|
// Re-export the main types
|
|
pub use config::ConnectorConfig;
|
|
pub use connector_impl::SocktopConnector;
|
|
pub use error::{ConnectorError, Result};
|
|
pub use types::{
|
|
AgentRequest, AgentResponse, DetailedProcessInfo, DiskInfo, GpuInfo, JournalEntry,
|
|
JournalResponse, LogLevel, Metrics, NetworkInfo, ProcessInfo, ProcessMetricsResponse,
|
|
ProcessesPayload,
|
|
};
|
|
|
|
// Re-export convenience functions
|
|
#[cfg(feature = "networking")]
|
|
pub use connector_impl::{connect_to_socktop_agent, connect_to_socktop_agent_with_config};
|
|
|
|
#[cfg(all(feature = "tls", feature = "networking"))]
|
|
pub use connector_impl::connect_to_socktop_agent_with_tls;
|
|
|
|
#[cfg(feature = "networking")]
|
|
pub use networking::WsStream;
|
|
|
|
// Protobuf types for internal use
|
|
#[cfg(any(feature = "networking", feature = "wasm"))]
|
|
pub mod pb {
|
|
include!(concat!(env!("OUT_DIR"), "/socktop.rs"));
|
|
}
|