process.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. use std::sync::Arc;
  2. #[cfg(feature = "system-metrics")]
  3. use prometheus::{Gauge, IntGauge, Registry};
  4. #[cfg(feature = "system-metrics")]
  5. use sysinfo::{Pid, System};
  6. /// System metrics collector that provides CPU, memory, disk, network, and process metrics
  7. #[cfg(feature = "system-metrics")]
  8. #[derive(Clone, Debug)]
  9. pub struct SystemMetrics {
  10. registry: Arc<Registry>,
  11. system: Arc<std::sync::Mutex<System>>,
  12. // Process metrics (for the CDK process)
  13. process_cpu_usage_percent: Gauge,
  14. process_memory_bytes: IntGauge,
  15. process_memory_percent: Gauge,
  16. }
  17. #[cfg(feature = "system-metrics")]
  18. impl SystemMetrics {
  19. /// Create a new `SystemMetrics` instance
  20. ///
  21. /// # Errors
  22. /// Returns an error if any of the metrics cannot be created or registered
  23. pub fn new() -> crate::Result<Self> {
  24. let registry = Arc::new(Registry::new());
  25. // Process metrics
  26. let process_cpu_usage_percent = Gauge::new(
  27. "process_cpu_usage_percent",
  28. "CPU usage percentage of the CDK process (0-100)",
  29. )?;
  30. registry.register(Box::new(process_cpu_usage_percent.clone()))?;
  31. let process_memory_bytes = IntGauge::new(
  32. "process_memory_bytes",
  33. "Memory usage of the CDK process in bytes",
  34. )?;
  35. registry.register(Box::new(process_memory_bytes.clone()))?;
  36. let process_memory_percent = Gauge::new(
  37. "process_memory_percent",
  38. "Memory usage percentage of the CDK process (0-100)",
  39. )?;
  40. registry.register(Box::new(process_memory_percent.clone()))?;
  41. // Initialize system with all needed refresh kinds
  42. let system = Arc::new(std::sync::Mutex::new(System::new()));
  43. let result = Self {
  44. registry,
  45. system,
  46. process_cpu_usage_percent,
  47. process_memory_bytes,
  48. process_memory_percent,
  49. };
  50. Ok(result)
  51. }
  52. /// Get the metrics registry
  53. #[must_use]
  54. pub fn registry(&self) -> Arc<Registry> {
  55. Arc::<Registry>::clone(&self.registry)
  56. }
  57. /// Update all system metrics
  58. ///
  59. /// # Errors
  60. /// Returns an error if the system mutex cannot be locked
  61. pub fn update_metrics(&self) -> crate::Result<()> {
  62. let mut system = self.system.lock().map_err(|e| {
  63. crate::error::PrometheusError::SystemMetrics(format!("Failed to lock system: {e}"))
  64. })?;
  65. // Refresh system information
  66. system.refresh_all();
  67. // Update memory metrics
  68. let total_memory = i64::try_from(system.total_memory()).unwrap_or(i64::MAX);
  69. // Update process metrics for the current process
  70. // This is a simplified approach that may not work perfectly in all cases
  71. if let Some(process) = system.process(Pid::from(std::process::id() as usize)) {
  72. // Get CPU usage if available
  73. let process_cpu = process.cpu_usage();
  74. self.process_cpu_usage_percent.set(f64::from(process_cpu));
  75. // Get memory usage if available
  76. let process_memory = i64::try_from(process.memory()).unwrap_or(i64::MAX);
  77. self.process_memory_bytes.set(process_memory);
  78. // Calculate memory percentage
  79. if total_memory > 0 {
  80. // Precision loss is acceptable for percentage calculation
  81. #[allow(clippy::cast_precision_loss)]
  82. let process_memory_percent = (process_memory as f64 / total_memory as f64) * 100.0;
  83. self.process_memory_percent.set(process_memory_percent);
  84. }
  85. }
  86. // Drop the system lock early to avoid resource contention
  87. drop(system);
  88. Ok(())
  89. }
  90. }