Fix gestione allegati e creato metodo di esportazione log

This commit is contained in:
2026-03-04 11:51:42 +01:00
parent 3760e38c8d
commit 2d938fb210
26 changed files with 986 additions and 384 deletions

View File

@@ -0,0 +1,185 @@
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using System.Globalization;
using System.Text;
namespace SteUp.Maui.Core.Logger;
public class FileLogger : ILogger
{
private readonly string _path;
private readonly string _fileNamePrefix;
private readonly string _categoryName;
private readonly Lock _lock = new();
private readonly int _retentionDays;
private string? _currentFileName;
private DateTime _currentFileDate;
private DateTime _lastCleanupDate;
public FileLogger(string path, string fileNamePrefix, string categoryName, int retentionDays = 60)
{
_path = path;
_fileNamePrefix = fileNamePrefix;
_retentionDays = retentionDays;
_lastCleanupDate = DateTime.MinValue;
_categoryName = categoryName;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
UpdateCurrentFileName();
TryCleanOldLogs();
}
/// <summary>
/// Elimina i log più vecchi di <see cref="_retentionDays"/> giorni.
/// Viene eseguita al massimo una volta al giorno.
/// </summary>
private void ClearOldLogs()
{
try
{
var cutoff = DateTime.Now.Date.AddDays(-_retentionDays);
var logFiles = Directory.GetFiles(_path, $"{_fileNamePrefix}-*.log");
foreach (var file in logFiles)
{
try
{
var fileName = Path.GetFileNameWithoutExtension(file);
var datePart = fileName[(_fileNamePrefix.Length + 1)..];
if (!DateTime.TryParseExact(datePart, "yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out var fileDate) || fileDate >= cutoff) continue;
File.Delete(file);
Debug.WriteLine($"[FileLogger] Log eliminato: {file}");
}
catch (Exception ex)
{
Debug.WriteLine($"[FileLogger] Errore durante l'eliminazione del file {file}: {ex.Message}");
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"[FileLogger] Errore durante la pulizia dei log: {ex.Message}");
}
}
/// <summary>
/// Esegue la pulizia dei log solo se non è già stata eseguita oggi.
/// </summary>
private void TryCleanOldLogs()
{
var today = DateTime.Now.Date;
if (_lastCleanupDate == today) return;
_lastCleanupDate = today;
ClearOldLogs();
}
private void UpdateCurrentFileName()
{
var today = DateTime.Now.Date;
if (_currentFileName != null && _currentFileDate == today) return;
_currentFileDate = today;
_currentFileName = $"{_fileNamePrefix}-{today:yyyy-MM-dd}.log";
}
public IDisposable? BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
return;
try
{
lock (_lock)
{
UpdateCurrentFileName();
TryCleanOldLogs();
if (_currentFileName == null) return;
var fullPath = Path.Combine(_path, _currentFileName);
var logEntry = BuildLogEntry(logLevel, eventId, state, exception, formatter);
File.AppendAllText(fullPath, logEntry + Environment.NewLine + Environment.NewLine);
Debug.WriteLine($"[FileLogger] {logEntry}");
}
}
catch (Exception ex)
{
Debug.WriteLine($"[FileLogger] Errore durante la scrittura del log: {ex}");
}
}
private string BuildLogEntry<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception? exception,
Func<TState, Exception?, string> formatter)
{
var sb = new StringBuilder();
sb.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]");
sb.Append($" [{GetLogLevelShort(logLevel)}]");
sb.Append($" [{_categoryName}]");
if (eventId.Id != 0 || !string.IsNullOrEmpty(eventId.Name))
sb.Append($" [{eventId}]");
sb.Append($" {formatter(state, exception)}");
if (exception != null)
AppendException(sb, exception);
return sb.ToString();
}
private static void AppendException(StringBuilder sb, Exception exception, int depth = 0)
{
while (true)
{
var indent = depth == 0 ? "" : " Inner ";
sb.AppendLine();
sb.Append($"{indent}Exception: {exception.GetType().FullName}: {exception.Message}");
if (!string.IsNullOrWhiteSpace(exception.StackTrace))
{
sb.AppendLine();
sb.Append($"{indent}StackTrace: {exception.StackTrace.Trim()}");
}
if (exception.InnerException != null)
{
exception = exception.InnerException;
depth += 1;
continue;
}
break;
}
}
private static string GetLogLevelShort(LogLevel level) => level switch
{
LogLevel.Trace => "TRC",
LogLevel.Debug => "DBG",
LogLevel.Information => "INF",
LogLevel.Warning => "WRN",
LogLevel.Error => "ERR",
LogLevel.Critical => "CRT",
_ => "???"
};
}