using OrpaonVision.Core.Abstractions; using System.IO; using System.Text; namespace OrpaonVision.ConfigApp.Infrastructure.Logging; /// /// 基于文本文件的应用日志实现。 /// public sealed class FileAppLogger : IAppLogger { private static readonly object SyncRoot = new(); private readonly string _logDirectory; /// /// 初始化日志记录器。 /// public FileAppLogger() { _logDirectory = Path.Combine(AppContext.BaseDirectory, "logs"); } /// public void LogInformation(string message, string? traceId = null) { WriteLine("INFO", message, traceId); } /// public void LogWarning(string message, string? traceId = null) { WriteLine("WARN", message, traceId); } /// public void LogError(string message, Exception? exception = null, string? traceId = null) { var fullMessage = exception is null ? message : $"{message}{Environment.NewLine}{exception}"; WriteLine("ERROR", fullMessage, traceId); } private void WriteLine(string level, string message, string? traceId) { Directory.CreateDirectory(_logDirectory); var safeMessage = message.Replace(Environment.NewLine, " | "); var traceSegment = string.IsNullOrWhiteSpace(traceId) ? string.Empty : $"[TraceId:{traceId}] "; var line = $"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff zzz} [{level}] {traceSegment}{safeMessage}"; var filePath = Path.Combine(_logDirectory, $"configapp-{DateTime.Now:yyyyMMdd}.log"); lock (SyncRoot) { File.AppendAllText(filePath, line + Environment.NewLine, Encoding.UTF8); } } }