Add comprehensive logging with tracing, file rotation, and systemd integration
- Add tracing-appender and tracing-journald for production logging - Add LoggingConfig with trace_sample_rate, json_output, journald options - Expand init_logging() with file rotation, journald, and stderr layers - Add sanitize_path() helper for PII protection in logs - Instrument FUSE operations with #[instrument] and trace decision points - Instrument gRPC handlers (10 methods) with span correlation - Add spawn instrumentation for health monitor, indexer, watcher tasks - Add broadcast lag handling (RecvError::Lagged) in event subscribers - Fix webhook.rs expect() calls with proper error handling - Add logging to patterns.rs, collections.rs, artwork.rs database ops - Add Drop impl logging for PluginManager and WatchHandle - Update systemd service with rate limiting and journal output - Add logrotate config and example config.toml with logging section
This commit is contained in:
@@ -4,7 +4,7 @@ use musicfs_origins::Origin;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
use tracing::{debug, info};
|
||||
use tracing::{debug, info, trace};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ScannedFile {
|
||||
@@ -66,9 +66,13 @@ impl DeltaDetector {
|
||||
cached: &HashMap<FileId, FileMeta>,
|
||||
manifests: &HashMap<FileId, Vec<ManifestChunk>>,
|
||||
) -> Result<ChangeSet, DeltaError> {
|
||||
let origin_id = origin.id().clone();
|
||||
info!(origin_id = %origin_id, "Starting delta detection");
|
||||
|
||||
let mut changes = ChangeSet::default();
|
||||
|
||||
let origin_files = self.scan_origin(origin).await?;
|
||||
trace!(origin_id = %origin_id, scanned_count = origin_files.len(), "Completed origin scan");
|
||||
|
||||
let cached_by_path: HashMap<_, _> = cached
|
||||
.values()
|
||||
@@ -78,7 +82,7 @@ impl DeltaDetector {
|
||||
for scanned in &origin_files {
|
||||
if let Some(cached_file) = cached_by_path.get(&scanned.path) {
|
||||
if self.is_modified_scan(cached_file, scanned) {
|
||||
debug!("File modified: {:?}", scanned.path);
|
||||
debug!(origin_id = %origin_id, path = ?scanned.path, "File modified");
|
||||
|
||||
if let Some(old_chunks) = manifests.get(&cached_file.id) {
|
||||
let new_chunks = self.compute_chunks_for_scan(origin, scanned).await?;
|
||||
@@ -87,7 +91,7 @@ impl DeltaDetector {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug!("File added: {:?}", scanned.path);
|
||||
debug!(origin_id = %origin_id, path = ?scanned.path, "File added");
|
||||
changes.added.push(scanned.clone());
|
||||
}
|
||||
}
|
||||
@@ -96,16 +100,17 @@ impl DeltaDetector {
|
||||
|
||||
for cached_file in cached.values() {
|
||||
if !origin_paths.contains(&cached_file.real_path.path) {
|
||||
debug!("File removed: {:?}", cached_file.real_path.path);
|
||||
debug!(origin_id = %origin_id, path = ?cached_file.real_path.path, "File removed");
|
||||
changes.removed.push(cached_file.id);
|
||||
}
|
||||
}
|
||||
|
||||
info!(
|
||||
"Delta detection complete: {} added, {} removed, {} modified",
|
||||
changes.added.len(),
|
||||
changes.removed.len(),
|
||||
changes.modified.len()
|
||||
origin_id = %origin_id,
|
||||
files_added = changes.added.len(),
|
||||
files_removed = changes.removed.len(),
|
||||
files_modified = changes.modified.len(),
|
||||
"Delta detection complete"
|
||||
);
|
||||
|
||||
Ok(changes)
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, error, info};
|
||||
use tracing::{error, info, info_span, trace, Instrument};
|
||||
|
||||
const DEBOUNCE_MS: u64 = 200;
|
||||
|
||||
@@ -31,11 +31,15 @@ impl OriginWatcher {
|
||||
let root = self.root.clone();
|
||||
let event_bus = self.event_bus.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = Self::watch_loop(&origin_id, &root, &event_bus, &mut stop_rx).await {
|
||||
error!("Watcher error: {}", e);
|
||||
let origin_id_str = origin_id.to_string();
|
||||
tokio::spawn(
|
||||
async move {
|
||||
if let Err(e) = Self::watch_loop(&origin_id, &root, &event_bus, &mut stop_rx).await {
|
||||
error!("Watcher error: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
.instrument(info_span!("file_watcher", origin_id = %origin_id_str)),
|
||||
);
|
||||
|
||||
WatchHandle { stop_tx }
|
||||
}
|
||||
@@ -62,7 +66,7 @@ impl OriginWatcher {
|
||||
.watch(root, RecursiveMode::Recursive)
|
||||
.map_err(|e| WatchError::Watch(e.to_string()))?;
|
||||
|
||||
info!("Watching origin {} at {:?}", origin_id, root);
|
||||
info!(origin_id = %origin_id, path = ?root, "Watcher started");
|
||||
|
||||
let mut debouncer: HashMap<PathBuf, Instant> = HashMap::new();
|
||||
|
||||
@@ -72,7 +76,7 @@ impl OriginWatcher {
|
||||
Self::handle_notify_event(origin_id, root, event_bus, event, &mut debouncer);
|
||||
}
|
||||
_ = stop_rx.recv() => {
|
||||
info!("Stopping watcher for {}", origin_id);
|
||||
info!(origin_id = %origin_id, "Watcher stopped");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -104,7 +108,7 @@ impl OriginWatcher {
|
||||
|
||||
if let Some(last_seen) = debouncer.get(&relative) {
|
||||
if now.duration_since(*last_seen).as_millis() < DEBOUNCE_MS as u128 {
|
||||
debug!("Debouncing event for {:?}", relative);
|
||||
trace!(origin_id = %origin_id, path = ?relative, "Debouncing event");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -114,18 +118,18 @@ impl OriginWatcher {
|
||||
|
||||
match event.kind {
|
||||
EventKind::Create(_) => {
|
||||
debug!("File created: {:?}", relative);
|
||||
trace!(origin_id = %origin_id, path = ?relative, "File created");
|
||||
event_bus.publish(Event::FileAdded {
|
||||
path: vpath,
|
||||
origin_id: origin_id.clone(),
|
||||
});
|
||||
}
|
||||
EventKind::Remove(_) => {
|
||||
debug!("File removed: {:?}", relative);
|
||||
trace!(origin_id = %origin_id, path = ?relative, "File removed");
|
||||
event_bus.publish(Event::FileRemoved { path: vpath, file_id: None });
|
||||
}
|
||||
EventKind::Modify(_) => {
|
||||
debug!("File modified: {:?}", relative);
|
||||
trace!(origin_id = %origin_id, path = ?relative, "File modified");
|
||||
event_bus.publish(Event::FileModified { path: vpath });
|
||||
}
|
||||
_ => {}
|
||||
@@ -156,6 +160,7 @@ impl WatchHandle {
|
||||
|
||||
impl Drop for WatchHandle {
|
||||
fn drop(&mut self) {
|
||||
trace!("WatchHandle dropped");
|
||||
let _ = self.stop_tx.try_send(());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user