feat: add statistics API and dashboard for asset metrics
All checks were successful
Rust CI / build-test (push) Successful in 1m22s
All checks were successful
Rust CI / build-test (push) Successful in 1m22s
- Implemented `/api/stats` endpoint to return JSON metrics including active assets, total uploads, storage usage, and recent activity. - Created `stats.html` page to display real-time statistics with auto-refresh functionality. - Enhanced asset logging to include uploader IP and detailed event information for uploads and deletions. - Updated asset model to store uploader IP for audit purposes. - Improved logging functionality to ensure log directory exists before writing. - Refactored asset creation and management to support new features and logging.
This commit is contained in:
38
src/logs.rs
38
src/logs.rs
@@ -11,6 +11,12 @@ pub fn log_to_file(req: &HttpRequest, start: Instant) {
|
||||
|
||||
let log_path = LOG_DIR.to_string() + "access.log";
|
||||
|
||||
// Ensure log directory exists
|
||||
if let Err(e) = std::fs::create_dir_all(LOG_DIR) {
|
||||
eprintln!("failed to create log dir: {}", e);
|
||||
return;
|
||||
}
|
||||
|
||||
let Ok(mut file) = OpenOptions::new().create(true).append(true).open(log_path) else {
|
||||
eprintln!("failed to open log file");
|
||||
return;
|
||||
@@ -40,3 +46,35 @@ pub fn log_to_file(req: &HttpRequest, start: Instant) {
|
||||
|
||||
let _ = file.write_all(line.as_bytes());
|
||||
}
|
||||
|
||||
pub fn log_asset_event(
|
||||
action: &str,
|
||||
id: &str,
|
||||
mime: &str,
|
||||
size_bytes: usize,
|
||||
duration_min: u32,
|
||||
created_at_ms: i64,
|
||||
expires_at_ms: i64,
|
||||
uploader_ip: &str,
|
||||
) {
|
||||
// Ensure logging directory exists before writing
|
||||
if let Err(e) = std::fs::create_dir_all(LOG_DIR) {
|
||||
eprintln!("failed to create log dir for asset event: {}", e);
|
||||
return;
|
||||
}
|
||||
|
||||
let log_path = LOG_DIR.to_string() + "access.log";
|
||||
|
||||
let Ok(mut file) = OpenOptions::new().create(true).append(true).open(log_path) else {
|
||||
eprintln!("failed to open log file for asset event");
|
||||
return;
|
||||
};
|
||||
|
||||
let ts = chrono::Local::now().to_rfc3339();
|
||||
|
||||
let line = format!(
|
||||
"{ts} event=asset action={action} id={id} mime={mime} size_bytes={size_bytes} duration_min={duration_min} created_at_ms={created_at_ms} expires_at_ms={expires_at_ms} uploader_ip={uploader_ip}\n"
|
||||
);
|
||||
|
||||
let _ = file.write_all(line.as_bytes());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user