mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-06-15 04:01:58 +08:00
refactor: 删除部分多余的代码和注释
This commit is contained in:
23
src/utils/fs.rs
Normal file
23
src/utils/fs.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
//! Small filesystem helpers.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
/// Read a UTF-8 file and trim surrounding whitespace.
|
||||
pub fn read_trimmed(path: &Path) -> Option<String> {
|
||||
std::fs::read_to_string(path)
|
||||
.ok()
|
||||
.map(|value| value.trim().to_string())
|
||||
}
|
||||
|
||||
/// Sorted list of directory entry names (lossy exclusion on non-UTF8).
|
||||
pub fn list_dir_names(path: &Path) -> Vec<String> {
|
||||
let mut names = std::fs::read_dir(path)
|
||||
.ok()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.flatten()
|
||||
.filter_map(|entry| entry.file_name().into_string().ok())
|
||||
.collect::<Vec<_>>();
|
||||
names.sort();
|
||||
names
|
||||
}
|
||||
15
src/utils/host.rs
Normal file
15
src/utils/host.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
//! Host identity helpers.
|
||||
|
||||
/// Truncated content of `/etc/hostname`. Used where RustDesk peers expect the configured static name.
|
||||
pub fn hostname_from_etc() -> String {
|
||||
std::fs::read_to_string("/etc/hostname")
|
||||
.map(|s| s.trim().to_string())
|
||||
.unwrap_or_else(|_| "One-KVM".to_string())
|
||||
}
|
||||
|
||||
/// Current kernel hostname (`gethostname`). Used for live device info in the UI.
|
||||
pub fn hostname_uname() -> String {
|
||||
nix::unistd::gethostname()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|_| "unknown".to_string())
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
//! Utility modules for One-KVM
|
||||
//!
|
||||
//! This module contains common utilities used across the codebase.
|
||||
//! Shared utilities.
|
||||
|
||||
pub mod fs;
|
||||
pub mod host;
|
||||
pub mod net;
|
||||
pub mod throttle;
|
||||
|
||||
pub use fs::{list_dir_names, read_trimmed};
|
||||
pub use host::{hostname_from_etc, hostname_uname};
|
||||
pub use net::{bind_tcp_listener, bind_udp_socket};
|
||||
pub use throttle::LogThrottler;
|
||||
|
||||
@@ -1,44 +1,15 @@
|
||||
//! Log throttling utility
|
||||
//!
|
||||
//! Provides a mechanism to limit how often the same log message is recorded,
|
||||
//! preventing log flooding when errors occur repeatedly.
|
||||
//! Limits repeated identical log lines (e.g. reconnect failures).
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::RwLock;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// Log throttler that limits how often the same message is logged
|
||||
///
|
||||
/// This is useful for preventing log flooding when errors occur repeatedly,
|
||||
/// such as when a device is disconnected and reconnection attempts fail.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use one_kvm::utils::LogThrottler;
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let throttler = LogThrottler::new(Duration::from_secs(5));
|
||||
///
|
||||
/// // First call returns true
|
||||
/// assert!(throttler.should_log("device_error"));
|
||||
///
|
||||
/// // Subsequent calls within 5 seconds return false
|
||||
/// assert!(!throttler.should_log("device_error"));
|
||||
/// ```
|
||||
pub struct LogThrottler {
|
||||
/// Map of message key to last log time
|
||||
last_logged: RwLock<HashMap<String, Instant>>,
|
||||
/// Throttle interval
|
||||
interval: Duration,
|
||||
}
|
||||
|
||||
impl LogThrottler {
|
||||
/// Create a new log throttler with the specified interval
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `interval` - The minimum time between log messages for the same key
|
||||
pub fn new(interval: Duration) -> Self {
|
||||
Self {
|
||||
last_logged: RwLock::new(HashMap::new()),
|
||||
@@ -46,23 +17,14 @@ impl LogThrottler {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new log throttler with interval specified in seconds
|
||||
pub fn with_secs(secs: u64) -> Self {
|
||||
Self::new(Duration::from_secs(secs))
|
||||
}
|
||||
|
||||
/// Check if a message should be logged (not throttled)
|
||||
///
|
||||
/// Returns `true` if the message should be logged, `false` if it should be throttled.
|
||||
/// If `true` is returned, the internal timestamp is updated.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `key` - A unique identifier for the message type
|
||||
/// Returns whether to emit the log line; updates the timestamp when `true`.
|
||||
pub fn should_log(&self, key: &str) -> bool {
|
||||
let now = Instant::now();
|
||||
|
||||
// First check with read lock (fast path)
|
||||
{
|
||||
let map = self.last_logged.read().unwrap();
|
||||
if let Some(last) = map.get(key) {
|
||||
@@ -72,9 +34,7 @@ impl LogThrottler {
|
||||
}
|
||||
}
|
||||
|
||||
// Update with write lock
|
||||
let mut map = self.last_logged.write().unwrap();
|
||||
// Double-check after acquiring write lock
|
||||
if let Some(last) = map.get(key) {
|
||||
if now.duration_since(*last) < self.interval {
|
||||
return false;
|
||||
@@ -84,32 +44,14 @@ impl LogThrottler {
|
||||
true
|
||||
}
|
||||
|
||||
/// Clear throttle state for a specific key
|
||||
///
|
||||
/// This should be called when an error condition recovers,
|
||||
/// so the next error will be logged immediately.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `key` - The key to clear
|
||||
/// Call when a condition recovers so the next failure logs immediately.
|
||||
pub fn clear(&self, key: &str) {
|
||||
self.last_logged.write().unwrap().remove(key);
|
||||
}
|
||||
|
||||
/// Clear all throttle state
|
||||
pub fn clear_all(&self) {
|
||||
self.last_logged.write().unwrap().clear();
|
||||
}
|
||||
|
||||
/// Get the number of tracked keys
|
||||
pub fn len(&self) -> usize {
|
||||
self.last_logged.read().unwrap().len()
|
||||
}
|
||||
|
||||
/// Check if the throttler is empty
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.last_logged.read().unwrap().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for LogThrottler {
|
||||
@@ -122,23 +64,11 @@ impl Clone for LogThrottler {
|
||||
}
|
||||
|
||||
impl Default for LogThrottler {
|
||||
/// Create a default log throttler with 5 second interval
|
||||
fn default() -> Self {
|
||||
Self::with_secs(5)
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro for throttled warning logging
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use one_kvm::utils::LogThrottler;
|
||||
/// use one_kvm::warn_throttled;
|
||||
///
|
||||
/// let throttler = LogThrottler::default();
|
||||
/// warn_throttled!(throttler, "my_error", "Error occurred: {}", "details");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! warn_throttled {
|
||||
($throttler:expr, $key:expr, $($arg:tt)*) => {
|
||||
@@ -148,7 +78,6 @@ macro_rules! warn_throttled {
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for throttled error logging
|
||||
#[macro_export]
|
||||
macro_rules! error_throttled {
|
||||
($throttler:expr, $key:expr, $($arg:tt)*) => {
|
||||
@@ -158,16 +87,6 @@ macro_rules! error_throttled {
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for throttled info logging
|
||||
#[macro_export]
|
||||
macro_rules! info_throttled {
|
||||
($throttler:expr, $key:expr, $($arg:tt)*) => {
|
||||
if $throttler.should_log($key) {
|
||||
tracing::info!($($arg)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -183,16 +102,11 @@ mod tests {
|
||||
fn test_throttling() {
|
||||
let throttler = LogThrottler::new(Duration::from_millis(100));
|
||||
|
||||
// First call should succeed
|
||||
assert!(throttler.should_log("test_key"));
|
||||
|
||||
// Immediate second call should be throttled
|
||||
assert!(!throttler.should_log("test_key"));
|
||||
|
||||
// Wait for throttle to expire
|
||||
thread::sleep(Duration::from_millis(150));
|
||||
|
||||
// Should succeed again
|
||||
assert!(throttler.should_log("test_key"));
|
||||
}
|
||||
|
||||
@@ -200,7 +114,6 @@ mod tests {
|
||||
fn test_different_keys() {
|
||||
let throttler = LogThrottler::with_secs(10);
|
||||
|
||||
// Different keys should be independent
|
||||
assert!(throttler.should_log("key1"));
|
||||
assert!(throttler.should_log("key2"));
|
||||
assert!(!throttler.should_log("key1"));
|
||||
@@ -214,10 +127,8 @@ mod tests {
|
||||
assert!(throttler.should_log("test_key"));
|
||||
assert!(!throttler.should_log("test_key"));
|
||||
|
||||
// Clear the key
|
||||
throttler.clear("test_key");
|
||||
|
||||
// Should be able to log again
|
||||
assert!(throttler.should_log("test_key"));
|
||||
}
|
||||
|
||||
@@ -239,19 +150,4 @@ mod tests {
|
||||
let throttler = LogThrottler::default();
|
||||
assert!(throttler.should_log("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_len_and_is_empty() {
|
||||
let throttler = LogThrottler::with_secs(10);
|
||||
|
||||
assert!(throttler.is_empty());
|
||||
assert_eq!(throttler.len(), 0);
|
||||
|
||||
throttler.should_log("key1");
|
||||
assert!(!throttler.is_empty());
|
||||
assert_eq!(throttler.len(), 1);
|
||||
|
||||
throttler.should_log("key2");
|
||||
assert_eq!(throttler.len(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user