Skip to content

Commit c9e214c

Browse files
authored
Merge pull request #544 from IridiumIO/Logging
Added Logging
2 parents 19c1356 + 528fcfe commit c9e214c

26 files changed

+605
-124
lines changed

CompactGUI.Core/Analyser.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using System.Collections.Concurrent;
1+
using Microsoft.Extensions.Logging;
2+
using Microsoft.Extensions.Logging.Abstractions;
3+
using System.Collections.Concurrent;
24
using System.Diagnostics;
5+
using CompactGUI.Logging.Core;
36

47
namespace CompactGUI.Core;
58

@@ -12,18 +15,22 @@ public class Analyser
1215
public bool ContainsCompressedFiles { get; set; }
1316
public List<AnalysedFileDetails> FileCompressionDetailsList { get; set; } = new List<AnalysedFileDetails>();
1417

18+
private ILogger<Analyser> _logger;
1519

16-
public Analyser(string folder)
20+
public Analyser(string folder, ILogger<Analyser> logger)
1721
{
1822
FolderName = folder;
1923
UncompressedBytes = 0;
2024
CompressedBytes = 0;
2125
ContainsCompressedFiles = false;
26+
_logger = logger;
2227
}
2328

2429

2530
public async Task<Boolean?> AnalyseFolder(CancellationToken cancellationToken)
2631
{
32+
AnalyserLog.StartingAnalysis(_logger, FolderName);
33+
Stopwatch sw = Stopwatch.StartNew();
2734
try
2835
{
2936
var allFiles = await Task.Run(() => Directory.EnumerateFiles(FolderName, "*", new EnumerationOptions { RecurseSubdirectories = true, IgnoreInaccessible = true, AttributesToSkip = FileAttributes.ReparsePoint }).AsShortPathNames(), cancellationToken).ConfigureAwait(false);
@@ -39,22 +46,25 @@ public Analyser(string folder)
3946
ContainsCompressedFiles = fileDetails.Any(f => f.CompressionMode != WOFCompressionAlgorithm.NO_COMPRESSION);
4047

4148
FileCompressionDetailsList = fileDetails;
42-
43-
return ContainsCompressedFiles;
4449
}
4550
catch (Exception ex)
4651
{
47-
Debug.WriteLine(ex.Message);
52+
AnalyserLog.AnalysisFailed(_logger, FolderName, ex.Message);
4853
return null;
4954
}
55+
finally { sw.Stop(); }
56+
57+
AnalyserLog.AnalysisCompleted(_logger, FolderName, Math.Round(sw.Elapsed.TotalSeconds, 3), CompressedBytes, UncompressedBytes, ContainsCompressedFiles);
5058

59+
return ContainsCompressedFiles;
5160

5261

5362
}
5463

5564

5665
private AnalysedFileDetails? AnalyseFile(string file)
5766
{
67+
AnalyserLog.ProcessingFile(_logger, file);
5868
try
5969
{
6070
FileInfo fileInfo = new FileInfo(file);
@@ -67,8 +77,9 @@ public Analyser(string folder)
6777

6878
return new AnalysedFileDetails { FileName = file, CompressedSize = compressedSize, UncompressedSize = uncompressedSize, CompressionMode = compressionMode, FileInfo = fileInfo };
6979
}
70-
catch (IOException)
80+
catch (IOException ex)
7181
{
82+
AnalyserLog.ProcessingFileFailed(_logger, file, ex.Message);
7283
return null;
7384
}
7485
}

CompactGUI.Core/CompactGUI.Core.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@
2020
<PackageReference Include="ZLinq" Version="1.4.10" />
2121
</ItemGroup>
2222

23+
24+
<ItemGroup>
25+
<ProjectReference Include="..\CompactGUI.Logging\CompactGUI.Logging.csproj" />
26+
</ItemGroup>
27+
2328
</Project>

CompactGUI.Core/Compactor.cs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
using CompactGUI.Logging.Core;
3+
using Microsoft.Extensions.Logging;
4+
using Microsoft.Extensions.Logging.Abstractions;
25
using Microsoft.Win32.SafeHandles;
36
using System.Collections.Concurrent;
47
using System.Diagnostics;
@@ -23,13 +26,14 @@ public class Compactor : ICompressor, IDisposable
2326
private readonly SemaphoreSlim pauseSemaphore = new SemaphoreSlim(1, 2);
2427
private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
2528

29+
private ILogger<Compactor> _logger;
2630

27-
public Compactor(string folderPath, WOFCompressionAlgorithm compressionLevel, string[] excludedFileTypes)
31+
public Compactor(string folderPath, WOFCompressionAlgorithm compressionLevel, string[] excludedFileTypes, ILogger<Compactor>? logger = null)
2832
{
2933
workingDirectory = folderPath;
3034
excludedFileExtensions = new HashSet<string>(excludedFileTypes);
3135
wofCompressionAlgorithm = compressionLevel;
32-
36+
_logger = logger ?? NullLogger<Compactor>.Instance;
3337
InitializeCompressionInfoPointer();
3438
}
3539

@@ -47,32 +51,47 @@ public async Task<bool> RunAsync(List<string> filesList, IProgress<CompressionPr
4751
{
4852
if(cancellationTokenSource.IsCancellationRequested) { return false; }
4953

54+
CompactorLog.BuildingWorkingFilesList(_logger, workingDirectory);
5055
var workingFiles = await BuildWorkingFilesList().ConfigureAwait(false);
5156
long totalFilesSize = workingFiles.Sum((f) => f.UncompressedSize);
5257

5358
totalProcessedBytes = 0;
5459

55-
if(maxParallelism <= 0) maxParallelism = Environment.ProcessorCount;
60+
var sw = Stopwatch.StartNew();
61+
62+
if (maxParallelism <= 0) maxParallelism = Environment.ProcessorCount;
5663
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxParallelism, CancellationToken = cancellationTokenSource.Token };
5764

65+
CompactorLog.StartingCompression(_logger, workingDirectory, wofCompressionAlgorithm.ToString(), maxParallelism);
5866
try
5967
{
60-
await Parallel.ForEachAsync(workingFiles, parallelOptions,
68+
await Parallel.ForEachAsync(workingFiles, parallelOptions,
6169
(file, ctx) =>
6270
{
6371
ctx.ThrowIfCancellationRequested();
6472

6573
return new ValueTask(PauseAndProcessFile(file, totalFilesSize, cancellationTokenSource.Token, progressMonitor));
6674
}).ConfigureAwait(false);
6775
}
68-
catch (OperationCanceledException){ return false; }
69-
catch (Exception){ return false; }
76+
catch (OperationCanceledException){
77+
CompactorLog.CompressionCanceled(_logger);
78+
return false;
79+
}
80+
catch (Exception ex){
81+
CompactorLog.CompressionFailed(_logger, ex.Message);
82+
return false;
83+
}
84+
finally { sw.Stop();}
85+
7086

87+
88+
CompactorLog.CompressionCompleted(_logger, Math.Round(sw.Elapsed.TotalSeconds, 3));
7189
return true;
7290
}
7391

7492
private async Task PauseAndProcessFile(FileDetails file, long totalFilesSize, CancellationToken token, IProgress<CompressionProgress> progressMonitor)
7593
{
94+
CompactorLog.ProcessingFile(_logger, file.FileName, file.UncompressedSize);
7695

7796
await pauseSemaphore.WaitAsync(token).ConfigureAwait(false);
7897
pauseSemaphore.Release();
@@ -94,7 +113,7 @@ private async Task PauseAndProcessFile(FileDetails file, long totalFilesSize, Ca
94113
}
95114
catch (Exception ex)
96115
{
97-
Debug.WriteLine(ex.Message);
116+
CompactorLog.FileCompressionFailed(_logger, filePath, ex.Message);
98117
return null;
99118
}
100119
}
@@ -103,7 +122,7 @@ public async Task<IEnumerable<FileDetails>> BuildWorkingFilesList()
103122
{
104123
uint clusterSize = SharedMethods.GetClusterSize(workingDirectory);
105124

106-
var analyser = new Analyser(workingDirectory);
125+
var analyser = new Analyser(workingDirectory, NullLogger<Analyser>.Instance);
107126
var ret = await analyser.AnalyseFolder(cancellationTokenSource.Token);
108127

109128
var filesList = analyser.FileCompressionDetailsList
@@ -123,13 +142,15 @@ public async Task<IEnumerable<FileDetails>> BuildWorkingFilesList()
123142

124143
public void Pause()
125144
{
145+
CompactorLog.CompressionPaused(_logger);
126146
pauseSemaphore.Wait(cancellationTokenSource.Token);
127147
}
128148

129149

130150
public void Resume()
131151
{
132152
if (pauseSemaphore.CurrentCount == 0) pauseSemaphore.Release();
153+
CompactorLog.CompressionResumed(_logger);
133154
}
134155

135156

CompactGUI.Core/Uncompactor.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11

2+
using Microsoft.Extensions.Logging;
3+
using Microsoft.Extensions.Logging.Abstractions;
24
using Microsoft.Win32.SafeHandles;
35
using System.Collections.Concurrent;
46
using Windows.Win32;
7+
using CompactGUI.Logging.Core;
8+
using System.Diagnostics;
59

610
namespace CompactGUI.Core;
711

@@ -12,6 +16,12 @@ public class Uncompactor : ICompressor, IDisposable
1216
private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
1317
private ConcurrentDictionary<string, int> processedFileCount = new ConcurrentDictionary<string, int>();
1418

19+
private readonly ILogger<Uncompactor> _logger;
20+
21+
public Uncompactor(ILogger<Uncompactor>? logger = null)
22+
{
23+
_logger = logger ?? NullLogger<Uncompactor>.Instance;
24+
}
1525

1626
public async Task<bool> RunAsync(List<string> filesList, IProgress<CompressionProgress>? progressMonitor = null, int maxParallelism = 1)
1727
{
@@ -20,6 +30,8 @@ public async Task<bool> RunAsync(List<string> filesList, IProgress<CompressionPr
2030
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxParallelism };
2131
processedFileCount.Clear();
2232

33+
UncompactorLog.StartingDecompression(_logger, totalFiles, maxParallelism);
34+
Stopwatch sw = Stopwatch.StartNew();
2335
try
2436
{
2537
await Parallel.ForEachAsync(filesList, parallelOptions,
@@ -29,14 +41,20 @@ await Parallel.ForEachAsync(filesList, parallelOptions,
2941
return new ValueTask(PauseAndProcessFile(file, totalFiles, progressMonitor, cancellationTokenSource.Token));
3042
});
3143
}
32-
catch (OperationCanceledException) { return false; }
44+
catch (OperationCanceledException) {
45+
UncompactorLog.DecompressionCanceled(_logger);
46+
return false;
47+
}
48+
finally { sw.Stop(); }
3349

50+
UncompactorLog.DecompressionCompleted(_logger, Math.Round(sw.Elapsed.TotalSeconds, 3));
3451
return true;
3552

3653
}
3754

3855
private async Task PauseAndProcessFile(string file, int totalFiles, IProgress<CompressionProgress>? progressMonitor, CancellationToken ctx)
3956
{
57+
UncompactorLog.ProcessingFile(_logger, file);
4058
try
4159
{
4260
await pauseSemaphore.WaitAsync(ctx).ConfigureAwait(false);
@@ -64,18 +82,23 @@ private async Task PauseAndProcessFile(string file, int totalFiles, IProgress<Co
6482
return res;
6583
}
6684
}
67-
catch (Exception) { return null; }
85+
catch (Exception ex) {
86+
UncompactorLog.FileDecompressionFailed(_logger, file, ex.Message);
87+
return null;
88+
}
6889
}
6990

7091
public void Pause()
7192
{
93+
UncompactorLog.DecompressionPaused(_logger);
7294
pauseSemaphore.Wait();
7395
}
7496

7597

7698
public void Resume()
7799
{
78100
if (pauseSemaphore.CurrentCount == 0) pauseSemaphore.Release();
101+
UncompactorLog.DecompressionResumed(_logger);
79102
}
80103

81104

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.5" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Microsoft.Extensions.Logging;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace CompactGUI.Logging.Core;
9+
10+
public static partial class AnalyserLog
11+
{
12+
13+
[LoggerMessage(Level = LogLevel.Debug, Message = "Starting analysis of directory: {Directory}")]
14+
public static partial void StartingAnalysis(ILogger logger, string directory);
15+
16+
[LoggerMessage(Level = LogLevel.Trace, Message = "Processing file: {FileName}")]
17+
public static partial void ProcessingFile(ILogger logger, string fileName);
18+
19+
[LoggerMessage(Level = LogLevel.Warning, Message = "Processing file failed: {FileName} with message: {Message}")]
20+
public static partial void ProcessingFileFailed(ILogger logger, string fileName, string message);
21+
22+
23+
[LoggerMessage(Level = LogLevel.Trace, Message = "Processing folder: {FolderName}")]
24+
public static partial void ProcessingFolder(ILogger logger, string folderName);
25+
26+
[LoggerMessage(Level = LogLevel.Warning, Message = "Analysis failed for: {Path} with error: {ErrorMessage}")]
27+
public static partial void AnalysisFailed(ILogger logger, string path, string errorMessage);
28+
29+
[LoggerMessage(Level = LogLevel.Information, Message = "Analysis completed for directory: {Directory} in {TimeTaken}s. Uncompressed Size: {UncompressedBytes}b, CompressedSize: {CompressedBytes}b, ContainsCompressedFiles: {ContainsCompressedFiles}")]
30+
public static partial void AnalysisCompleted(ILogger logger, string directory, double timeTaken, long compressedBytes, long uncompressedBytes, bool containsCompressedFiles);
31+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Microsoft.Extensions.Logging;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace CompactGUI.Logging.Core;
9+
10+
public static partial class CompactorLog
11+
{
12+
13+
[LoggerMessage(Level = LogLevel.Information, Message = "Starting compression in directory: {Directory} with algorithm: {Algorithm} and using {MaxParallelism} threads")]
14+
public static partial void StartingCompression(ILogger logger, string directory, string algorithm, int maxParallelism);
15+
16+
[LoggerMessage(Level = LogLevel.Debug, Message = "Building working files list for directory: {Directory}")]
17+
public static partial void BuildingWorkingFilesList(ILogger logger, string directory);
18+
19+
[LoggerMessage(Level = LogLevel.Trace, Message = "Processing file: {FileName} ({UncompressedSize} bytes)")]
20+
public static partial void ProcessingFile(ILogger logger, string fileName, long uncompressedSize);
21+
22+
[LoggerMessage(Level = LogLevel.Warning, Message = "File compression failed for: {FileName} with error: {ErrorMessage}")]
23+
public static partial void FileCompressionFailed(ILogger logger, string fileName, string errorMessage);
24+
25+
[LoggerMessage(Level = LogLevel.Information, Message = "Compression paused.")]
26+
public static partial void CompressionPaused(ILogger logger);
27+
28+
[LoggerMessage(Level = LogLevel.Information, Message = "Compression resumed.")]
29+
public static partial void CompressionResumed(ILogger logger);
30+
31+
[LoggerMessage(Level = LogLevel.Information, Message = "Compression canceled.")]
32+
public static partial void CompressionCanceled(ILogger logger);
33+
34+
[LoggerMessage(Level = LogLevel.Information, Message = "Compression completed successfully in {TimeTaken}s.")]
35+
public static partial void CompressionCompleted(ILogger logger, double timeTaken);
36+
37+
[LoggerMessage(Level = LogLevel.Error, Message = "Compression failed with error: {ErrorMessage}")]
38+
public static partial void CompressionFailed(ILogger logger, string errorMessage);
39+
40+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Microsoft.Extensions.Logging;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace CompactGUI.Logging.Core;
9+
10+
public static partial class UncompactorLog
11+
{
12+
[LoggerMessage(Level = LogLevel.Information, Message = "Starting decompression of {FileCount} files with {MaxParallelism} threads")]
13+
public static partial void StartingDecompression(ILogger logger, int fileCount, int maxParallelism);
14+
15+
[LoggerMessage(Level = LogLevel.Trace, Message = "Processing file: {FileName}")]
16+
public static partial void ProcessingFile(ILogger logger, string fileName);
17+
18+
[LoggerMessage(Level = LogLevel.Warning, Message = "File decompression failed for: {FileName} with error: {ErrorMessage}")]
19+
public static partial void FileDecompressionFailed(ILogger logger, string fileName, string errorMessage);
20+
21+
[LoggerMessage(Level = LogLevel.Information, Message = "Decompression paused.")]
22+
public static partial void DecompressionPaused(ILogger logger);
23+
24+
[LoggerMessage(Level = LogLevel.Information, Message = "Decompression resumed.")]
25+
public static partial void DecompressionResumed(ILogger logger);
26+
27+
[LoggerMessage(Level = LogLevel.Information, Message = "Decompression canceled.")]
28+
public static partial void DecompressionCanceled(ILogger logger);
29+
30+
[LoggerMessage(Level = LogLevel.Information, Message = "Decompression completed successfully in {TimeTaken}s.")]
31+
public static partial void DecompressionCompleted(ILogger logger, double timeTaken);
32+
}

0 commit comments

Comments
 (0)