pub struct Logger {
pub verbose: bool,
pub quiet: bool,
pub start_time: Option<Instant>,
}
Expand description
Logger responsible for all user-visible output
Fields§
§verbose: bool
§quiet: bool
§start_time: Option<Instant>
Implementations§
Source§impl Logger
impl Logger
Sourcepub fn new(verbose: bool) -> Self
pub fn new(verbose: bool) -> Self
Examples found in repository?
examples/basic_usage_demo.rs (line 36)
29async fn main() -> Result<()> {
30 println!("🚀 Docker Image Pusher - Basic Usage Demo");
31 println!("==========================================");
32 println!("This demo corresponds to README Quick Start examples");
33 println!();
34
35 // Initialize logger for verbose output
36 let logger = Logger::new(true);
37
38 // Configuration from environment
39 let registry_username = env::var("REGISTRY_USERNAME").unwrap_or_else(|_| {
40 println!("⚠️ REGISTRY_USERNAME not set, using demo credentials");
41 "demo_user".to_string()
42 });
43
44 let registry_password = env::var("REGISTRY_PASSWORD").unwrap_or_else(|_| {
45 println!("⚠️ REGISTRY_PASSWORD not set, using demo credentials");
46 "demo_pass".to_string()
47 });
48
49 let target_registry = env::var("TARGET_REGISTRY").unwrap_or_else(|_| {
50 "registry.example.com".to_string()
51 });
52
53 let cache_dir = ".cache_basic_demo";
54
55 // Clean up previous demo
56 let _ = std::fs::remove_dir_all(cache_dir);
57
58 logger.section("Demo 1: Basic Extract and Push Workflow");
59 println!("📝 Scenario: Extract tar file → Cache → Push to registry");
60 println!("📄 Command equivalent:");
61 println!(" docker-image-pusher extract --file image.tar --verbose");
62 println!(" docker-image-pusher push --source image:tag --target {}/app:v1.0", target_registry);
63 println!();
64
65 // Demo the basic workflow
66 demo_extract_and_push(&logger, cache_dir, &target_registry, ®istry_username, ®istry_password).await?;
67
68 logger.section("Demo 2: Pull and Cache Workflow");
69 println!("📝 Scenario: Pull from registry → Cache locally");
70 println!("📄 Command equivalent:");
71 println!(" docker-image-pusher pull --image nginx:latest --verbose");
72 println!();
73
74 demo_pull_and_cache(&logger, cache_dir, ®istry_username, ®istry_password).await?;
75
76 logger.section("Demo 3: Complete Pull-to-Push Migration");
77 println!("📝 Scenario: Pull from source → Cache → Push to target");
78 println!("📄 Command equivalent:");
79 println!(" docker-image-pusher pull --image alpine:latest");
80 println!(" docker-image-pusher push --source alpine:latest --target {}/alpine:migrated", target_registry);
81 println!();
82
83 demo_complete_migration(&logger, cache_dir, &target_registry, ®istry_username, ®istry_password).await?;
84
85 println!("✅ Basic usage demo completed successfully!");
86 println!("📚 These examples correspond to the README Quick Start section");
87
88 Ok(())
89}
More examples
examples/concurrency_monitoring_demo.rs (line 15)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 println!("🚀 Docker Image Pusher - Concurrency Monitoring Demo");
13 println!("====================================================");
14
15 let logger = Logger::new(false); // false for non-verbose mode
16
17 // Create blob handler with different concurrency configurations
18 println!("\n📊 Testing different concurrency configurations:");
19
20 // Test 1: Default configuration (should be 3 concurrent tasks now)
21 let default_config = PipelineConfig::default();
22 let _blob_handler_default = BlobHandler::with_config(logger.clone(), default_config.clone());
23
24 println!("✅ Default Configuration:");
25 println!(" - Max concurrent tasks: {}", default_config.max_concurrent);
26 println!(" - Retry attempts: {}", default_config.retry_attempts);
27 println!(" - Timeout: {}s", default_config.timeout_seconds);
28
29 // Test 2: Conservative configuration (1 concurrent task)
30 let conservative_config = PipelineConfig {
31 max_concurrent: 1,
32 ..PipelineConfig::default()
33 };
34 let _blob_handler_conservative = BlobHandler::with_config(logger.clone(), conservative_config.clone());
35
36 println!("\n🔒 Conservative Configuration:");
37 println!(" - Max concurrent tasks: {}", conservative_config.max_concurrent);
38 println!(" - This prevents memory exhaustion for very large images");
39
40 // Test 3: Aggressive configuration (5 concurrent tasks)
41 let aggressive_config = PipelineConfig {
42 max_concurrent: 5,
43 ..PipelineConfig::default()
44 };
45 let _blob_handler_aggressive = BlobHandler::with_config(logger.clone(), aggressive_config.clone());
46
47 println!("\n⚡ Aggressive Configuration:");
48 println!(" - Max concurrent tasks: {}", aggressive_config.max_concurrent);
49 println!(" - Use with caution - may cause SIGKILL for large blobs");
50
51 println!("\n🎯 Key Features of Concurrency Monitoring:");
52 println!(" • Real-time active task count in upload logs");
53 println!(" • Adaptive concurrency based on blob sizes:");
54 println!(" - Blobs > 1GB: Max 1 concurrent task");
55 println!(" - Blobs > 500MB: Max 2 concurrent tasks");
56 println!(" - Memory-based scaling for smaller blobs");
57 println!(" • Peak concurrent tasks summary");
58 println!(" • Periodic progress updates every 5 seconds");
59
60 println!("\n📈 Sample Upload Logs with Concurrency Info:");
61 println!(" Upload task 1: Processing layer blob abcd1234... (150.2 MB) [Active tasks: 1]");
62 println!(" Upload task 2: Processing layer blob efgh5678... (75.8 MB) [Active tasks: 2]");
63 println!(" ✅ Blob abcd1234 uploaded in 15.3s (9.8 MB/s) [Active tasks: 1]");
64 println!(" 📊 Upload progress: 2 active tasks, 1 remaining");
65 println!(" ✅ Unified Pipeline completed successfully (avg speed: 12.5 MB/s) [Peak concurrent tasks: 3]");
66
67 println!("\n🛡️ Memory Protection Benefits:");
68 println!(" • Prevents SIGKILL termination from excessive memory usage");
69 println!(" • 2GB memory limit with intelligent blob size detection");
70 println!(" • Conservative handling of large total image sizes (>10GB)");
71 println!(" • 10MB overhead estimation per concurrent blob");
72
73 println!("\n✨ Enhanced Error Handling:");
74 println!(" • Individual task failure tracking");
75 println!(" • Active task count shown in error messages");
76 println!(" • Graceful degradation under memory pressure");
77
78 logger.success("Demo completed successfully! Your blob uploads now have full visibility into concurrent task execution.");
79
80 Ok(())
81}
pub fn new_quiet() -> Self
Sourcepub fn section(&self, title: &str)
pub fn section(&self, title: &str)
Main section heading
Examples found in repository?
examples/basic_usage_demo.rs (line 58)
29async fn main() -> Result<()> {
30 println!("🚀 Docker Image Pusher - Basic Usage Demo");
31 println!("==========================================");
32 println!("This demo corresponds to README Quick Start examples");
33 println!();
34
35 // Initialize logger for verbose output
36 let logger = Logger::new(true);
37
38 // Configuration from environment
39 let registry_username = env::var("REGISTRY_USERNAME").unwrap_or_else(|_| {
40 println!("⚠️ REGISTRY_USERNAME not set, using demo credentials");
41 "demo_user".to_string()
42 });
43
44 let registry_password = env::var("REGISTRY_PASSWORD").unwrap_or_else(|_| {
45 println!("⚠️ REGISTRY_PASSWORD not set, using demo credentials");
46 "demo_pass".to_string()
47 });
48
49 let target_registry = env::var("TARGET_REGISTRY").unwrap_or_else(|_| {
50 "registry.example.com".to_string()
51 });
52
53 let cache_dir = ".cache_basic_demo";
54
55 // Clean up previous demo
56 let _ = std::fs::remove_dir_all(cache_dir);
57
58 logger.section("Demo 1: Basic Extract and Push Workflow");
59 println!("📝 Scenario: Extract tar file → Cache → Push to registry");
60 println!("📄 Command equivalent:");
61 println!(" docker-image-pusher extract --file image.tar --verbose");
62 println!(" docker-image-pusher push --source image:tag --target {}/app:v1.0", target_registry);
63 println!();
64
65 // Demo the basic workflow
66 demo_extract_and_push(&logger, cache_dir, &target_registry, ®istry_username, ®istry_password).await?;
67
68 logger.section("Demo 2: Pull and Cache Workflow");
69 println!("📝 Scenario: Pull from registry → Cache locally");
70 println!("📄 Command equivalent:");
71 println!(" docker-image-pusher pull --image nginx:latest --verbose");
72 println!();
73
74 demo_pull_and_cache(&logger, cache_dir, ®istry_username, ®istry_password).await?;
75
76 logger.section("Demo 3: Complete Pull-to-Push Migration");
77 println!("📝 Scenario: Pull from source → Cache → Push to target");
78 println!("📄 Command equivalent:");
79 println!(" docker-image-pusher pull --image alpine:latest");
80 println!(" docker-image-pusher push --source alpine:latest --target {}/alpine:migrated", target_registry);
81 println!();
82
83 demo_complete_migration(&logger, cache_dir, &target_registry, ®istry_username, ®istry_password).await?;
84
85 println!("✅ Basic usage demo completed successfully!");
86 println!("📚 These examples correspond to the README Quick Start section");
87
88 Ok(())
89}
Sourcepub fn subsection(&self, title: &str)
pub fn subsection(&self, title: &str)
Sub-section heading
pub fn trace(&self, message: &str)
pub fn debug(&self, message: &str)
pub fn verbose(&self, message: &str)
Sourcepub fn info(&self, message: &str)
pub fn info(&self, message: &str)
Information message
Examples found in repository?
examples/basic_usage_demo.rs (line 98)
91async fn demo_extract_and_push(
92 logger: &Logger,
93 _cache_dir: &str,
94 target_registry: &str,
95 username: &str,
96 _password: &str,
97) -> Result<()> {
98 logger.info("Creating demo tar file (simulated)...");
99
100 // In a real scenario, you would have an actual tar file
101 // For demo purposes, we'll simulate the operation
102 println!("📦 Would extract tar file and cache locally");
103 println!("🚀 Would push cached image to: {}/project/app:v1.0", target_registry);
104
105 // Create registry client for demonstration
106 let registry_url = format!("https://{}", target_registry);
107 let _client = RegistryClientBuilder::new(registry_url)
108 .with_verbose(true)
109 .build()?;
110
111 logger.info(&format!("Registry client created for: {}", target_registry));
112 logger.info(&format!("Would authenticate with username: {}", username));
113
114 // Note: In production, you would:
115 // 1. Use ExtractAndCache operation mode with actual tar file
116 // 2. Use PushFromCacheUsingManifest operation mode
117
118 Ok(())
119}
120
121async fn demo_pull_and_cache(
122 logger: &Logger,
123 cache_dir: &str,
124 _username: &str,
125 _password: &str,
126) -> Result<()> {
127 logger.info("Demonstrating pull and cache workflow...");
128
129 // Create image manager
130 let mut _image_manager = ImageManager::new(Some(cache_dir), true)?;
131
132 println!("🔽 Would pull nginx:latest from Docker Hub");
133 println!("💾 Would cache image locally in: {}", cache_dir);
134
135 // In production, you would use:
136 // let operation = OperationMode::PullAndCache {
137 // registry_url: "https://registry-1.docker.io".to_string(),
138 // repository: "library/nginx".to_string(),
139 // reference: "latest".to_string(),
140 // cache_dir: cache_dir.to_string(),
141 // auth_config: Some(auth_config),
142 // };
143
144 logger.info("Pull and cache operation configured (demo mode)");
145
146 Ok(())
147}
148
149async fn demo_complete_migration(
150 logger: &Logger,
151 _cache_dir: &str,
152 target_registry: &str,
153 _username: &str,
154 _password: &str,
155) -> Result<()> {
156 logger.info("Demonstrating complete migration workflow...");
157
158 println!("🔄 Complete migration workflow:");
159 println!(" 1. Pull alpine:latest from Docker Hub");
160 println!(" 2. Cache locally");
161 println!(" 3. Push to target registry: {}/alpine:migrated", target_registry);
162
163 // This would involve:
164 // 1. PullAndCache operation
165 // 2. PushFromCacheUsingManifest operation
166
167 logger.info("Migration workflow completed (demo mode)");
168
169 Ok(())
170}
Sourcepub fn success(&self, message: &str)
pub fn success(&self, message: &str)
Success message
Examples found in repository?
examples/concurrency_monitoring_demo.rs (line 78)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 println!("🚀 Docker Image Pusher - Concurrency Monitoring Demo");
13 println!("====================================================");
14
15 let logger = Logger::new(false); // false for non-verbose mode
16
17 // Create blob handler with different concurrency configurations
18 println!("\n📊 Testing different concurrency configurations:");
19
20 // Test 1: Default configuration (should be 3 concurrent tasks now)
21 let default_config = PipelineConfig::default();
22 let _blob_handler_default = BlobHandler::with_config(logger.clone(), default_config.clone());
23
24 println!("✅ Default Configuration:");
25 println!(" - Max concurrent tasks: {}", default_config.max_concurrent);
26 println!(" - Retry attempts: {}", default_config.retry_attempts);
27 println!(" - Timeout: {}s", default_config.timeout_seconds);
28
29 // Test 2: Conservative configuration (1 concurrent task)
30 let conservative_config = PipelineConfig {
31 max_concurrent: 1,
32 ..PipelineConfig::default()
33 };
34 let _blob_handler_conservative = BlobHandler::with_config(logger.clone(), conservative_config.clone());
35
36 println!("\n🔒 Conservative Configuration:");
37 println!(" - Max concurrent tasks: {}", conservative_config.max_concurrent);
38 println!(" - This prevents memory exhaustion for very large images");
39
40 // Test 3: Aggressive configuration (5 concurrent tasks)
41 let aggressive_config = PipelineConfig {
42 max_concurrent: 5,
43 ..PipelineConfig::default()
44 };
45 let _blob_handler_aggressive = BlobHandler::with_config(logger.clone(), aggressive_config.clone());
46
47 println!("\n⚡ Aggressive Configuration:");
48 println!(" - Max concurrent tasks: {}", aggressive_config.max_concurrent);
49 println!(" - Use with caution - may cause SIGKILL for large blobs");
50
51 println!("\n🎯 Key Features of Concurrency Monitoring:");
52 println!(" • Real-time active task count in upload logs");
53 println!(" • Adaptive concurrency based on blob sizes:");
54 println!(" - Blobs > 1GB: Max 1 concurrent task");
55 println!(" - Blobs > 500MB: Max 2 concurrent tasks");
56 println!(" - Memory-based scaling for smaller blobs");
57 println!(" • Peak concurrent tasks summary");
58 println!(" • Periodic progress updates every 5 seconds");
59
60 println!("\n📈 Sample Upload Logs with Concurrency Info:");
61 println!(" Upload task 1: Processing layer blob abcd1234... (150.2 MB) [Active tasks: 1]");
62 println!(" Upload task 2: Processing layer blob efgh5678... (75.8 MB) [Active tasks: 2]");
63 println!(" ✅ Blob abcd1234 uploaded in 15.3s (9.8 MB/s) [Active tasks: 1]");
64 println!(" 📊 Upload progress: 2 active tasks, 1 remaining");
65 println!(" ✅ Unified Pipeline completed successfully (avg speed: 12.5 MB/s) [Peak concurrent tasks: 3]");
66
67 println!("\n🛡️ Memory Protection Benefits:");
68 println!(" • Prevents SIGKILL termination from excessive memory usage");
69 println!(" • 2GB memory limit with intelligent blob size detection");
70 println!(" • Conservative handling of large total image sizes (>10GB)");
71 println!(" • 10MB overhead estimation per concurrent blob");
72
73 println!("\n✨ Enhanced Error Handling:");
74 println!(" • Individual task failure tracking");
75 println!(" • Active task count shown in error messages");
76 println!(" • Graceful degradation under memory pressure");
77
78 logger.success("Demo completed successfully! Your blob uploads now have full visibility into concurrent task execution.");
79
80 Ok(())
81}
Sourcepub fn progress_done(&self)
pub fn progress_done(&self)
Progress completion
pub fn summary(&self, title: &str, items: &[String])
Sourcepub fn summary_kv(&self, title: &str, items: &[(&str, String)])
pub fn summary_kv(&self, title: &str, items: &[(&str, String)])
Key-value pair summary display
pub fn list(&self, title: &str, items: &[String])
Sourcepub fn format_size(&self, bytes: u64) -> String
pub fn format_size(&self, bytes: u64) -> String
Format file size in human-readable units
Sourcepub fn format_duration(&self, duration: Duration) -> String
pub fn format_duration(&self, duration: Duration) -> String
Format duration in human-readable format
Sourcepub fn format_speed(&self, bytes_per_sec: u64) -> String
pub fn format_speed(&self, bytes_per_sec: u64) -> String
Format transfer speed in human-readable format
Sourcepub fn display_live_progress(&self, progress: &ProgressState)
pub fn display_live_progress(&self, progress: &ProgressState)
显示实时进度状态
Sourcepub fn display_detailed_progress(&self, progress: &ProgressState)
pub fn display_detailed_progress(&self, progress: &ProgressState)
Display detailed parallel task status
Sourcepub fn notify_concurrency_adjustment(
&self,
old_value: usize,
new_value: usize,
reason: &str,
)
pub fn notify_concurrency_adjustment( &self, old_value: usize, new_value: usize, reason: &str, )
Display concurrency adjustment notification
Sourcepub fn notify_task_start(
&self,
task_type: &str,
layer_index: usize,
size: u64,
priority: u64,
)
pub fn notify_task_start( &self, task_type: &str, layer_index: usize, size: u64, priority: u64, )
Display task start notification
Sourcepub fn notify_task_complete(
&self,
task_type: &str,
layer_index: usize,
duration: Duration,
size: u64,
)
pub fn notify_task_complete( &self, task_type: &str, layer_index: usize, duration: Duration, size: u64, )
Display task completion notification
Sourcepub fn display_simple_progress(
&self,
completed: usize,
total: usize,
message: &str,
)
pub fn display_simple_progress( &self, completed: usize, total: usize, message: &str, )
Display simple progress information
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Logger
impl RefUnwindSafe for Logger
impl Send for Logger
impl Sync for Logger
impl Unpin for Logger
impl UnwindSafe for Logger
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more