Files
BizTalkPlatformManagementTool/src/BizTalkPlatformManagementTool/Services/OperationLogger.cs
T

137 lines
3.5 KiB
C#

using System;
using System.Globalization;
using System.IO;
using System.Threading;
namespace BizTalkPlatformManagementTool.Services
{
public enum LogLevel
{
Info,
Warning,
Error,
Success
}
public sealed class LogEntry
{
public DateTime Timestamp { get; set; }
public LogLevel Level { get; set; }
public string Message { get; set; }
}
public sealed class OperationLogger
{
private const string LogFilePrefix = "BizTalkPlatformManagementTool-";
private const string LogFileExtension = ".log";
private const int RetentionDays = 5;
private static readonly object FileLock = new object();
private static int _cleanupDone;
private readonly Action<LogEntry> _sink;
private readonly string _logDirectory;
public OperationLogger(Action<LogEntry> sink)
{
_sink = sink;
_logDirectory = AppDomain.CurrentDomain.BaseDirectory;
CleanupOldLogs();
}
public string LogFilePath
{
get
{
return Path.Combine(_logDirectory, LogFilePrefix + DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) + LogFileExtension);
}
}
public void Info(string message)
{
Write(LogLevel.Info, message);
}
public void Warning(string message)
{
Write(LogLevel.Warning, message);
}
public void Error(string message)
{
Write(LogLevel.Error, message);
}
public void Success(string message)
{
Write(LogLevel.Success, message);
}
private void Write(LogLevel level, string message)
{
var entry = new LogEntry
{
Timestamp = DateTime.Now,
Level = level,
Message = message
};
WriteToFile(entry);
if (_sink == null)
{
return;
}
_sink(entry);
}
private void WriteToFile(LogEntry entry)
{
try
{
var line = string.Format(
CultureInfo.InvariantCulture,
"[{0:yyyy-MM-dd HH:mm:ss}][{1}] {2}{3}",
entry.Timestamp,
entry.Level.ToString().ToUpperInvariant(),
entry.Message,
Environment.NewLine);
lock (FileLock)
{
File.AppendAllText(LogFilePath, line);
}
}
catch
{
// Logging must never interrupt BizTalk operations.
}
}
private void CleanupOldLogs()
{
if (Interlocked.Exchange(ref _cleanupDone, 1) == 1)
{
return;
}
try
{
var cutoff = DateTime.Now.Date.AddDays(-(RetentionDays - 1));
foreach (var file in Directory.GetFiles(_logDirectory, LogFilePrefix + "*" + LogFileExtension))
{
var lastWrite = File.GetLastWriteTime(file);
if (lastWrite.Date < cutoff)
{
File.Delete(file);
}
}
}
catch
{
// Log retention cleanup is best-effort.
}
}
}
}