//! Simple test for job logging functionality use sd_core::{ config::{AppConfig, JobLoggingConfig}, infra::{db::entities, event::Event}, location::{create_location, IndexMode, LocationCreateArgs}, Core, }; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter}; use std::path::PathBuf; use tokio::time::{sleep, Duration}; #[tokio::main] async fn main() -> Result<(), Box> { // Initialize logging tracing_subscriber::fmt() .with_env_filter("sd_core=debug") .init(); println!("Job Logging Test\n"); // 1. Initialize Core with job logging println!("1. Setting up with job logging enabled..."); let data_dir = PathBuf::from("./data/job-logging-test"); // Configure with job logging { let mut config = AppConfig::load_from(&data_dir) .unwrap_or_else(|_| AppConfig::default_with_dir(data_dir.clone())); config.job_logging = JobLoggingConfig { enabled: true, log_directory: "job_logs".to_string(), max_file_size: 10 * 1024 * 1024, include_debug: true, }; config.save()?; println!(" Job logging enabled"); } let core = Core::new(data_dir.clone()).await?; let job_logs_dir = data_dir.join("job_logs"); println!(" Job logs directory: {:?}", job_logs_dir); // 2. Create library println!("\n2. Creating library..."); let library = if core.libraries.list().await.is_empty() { core.libraries .create_library("Test Library", None, core.context.clone()) .await? } else { core.libraries.list().await.into_iter().next().unwrap() }; println!(" Library ready"); // 3. Create a small test location println!("\n3. Creating test location..."); let test_path = PathBuf::from("./test-data"); // Register device let db = library.db(); let device = core.device.to_device()?; let device_record = match entities::device::Entity::find() .filter(entities::device::Column::Uuid.eq(device.id)) .one(db.conn()) .await? { Some(existing) => existing, None => { let device_model: entities::device::ActiveModel = device.into(); device_model.insert(db.conn()).await? } }; // Create location let location_args = LocationCreateArgs { path: test_path.clone(), name: Some("Test Data".to_string()), index_mode: IndexMode::Deep, }; let _location_db_id = create_location( library.clone(), &core.events, location_args, device_record.id, ) .await?; println!(" Location created, job dispatched"); // 4. Monitor for a short time println!("\n4. Monitoring job progress..."); let mut event_rx = core.events.subscribe(); let start = std::time::Instant::now(); let timeout = Duration::from_secs(10); while start.elapsed() < timeout { tokio::select! { Ok(event) = event_rx.recv() => { match event { Event::JobProgress { job_id, message, .. } => { if let Some(msg) = message { println!(" Job {}: {}", job_id, msg); } } Event::IndexingCompleted { .. } => { println!(" Indexing completed!"); break; } _ => {} } } _ = sleep(Duration::from_millis(100)) => {} } } // 5. Check job logs println!("\n5. Checking job logs..."); if let Ok(mut entries) = tokio::fs::read_dir(&job_logs_dir).await { let mut count = 0; while let Ok(Some(entry)) = entries.next_entry().await { if let Some(name) = entry.file_name().to_str() { if name.ends_with(".log") { count += 1; let log_path = job_logs_dir.join(name); if let Ok(contents) = tokio::fs::read_to_string(&log_path).await { println!("\n Log file: {}", name); println!(" Size: {} bytes", contents.len()); println!(" Lines: {}", contents.lines().count()); // Show first few lines println!("\n First 10 lines:"); for (i, line) in contents.lines().take(10).enumerate() { println!(" {}: {}", i + 1, line); } if contents.lines().count() > 10 { println!(" ... {} more lines", contents.lines().count() - 10); } } } } } if count == 0 { println!(" No job logs found"); } else { println!("\n Found {} job log file(s)", count); } } // 6. Shutdown println!("\n6. Shutting down..."); core.shutdown().await?; println!("\nTest complete!"); println!("Data: {:?}", data_dir); println!("Logs: {:?}", job_logs_dir); Ok(()) }