using System; using System.IO; using System.Linq; using System.Text; using Vinno.FIS.Sonopost.Common; using Vinno.IUS.Common.Log; namespace Vinno.FIS.Sonopost.Helpers { public class SonopostLogEngine : LogEngine { private const string InfoTag = "I ; "; private const string DebugTag = "D ; "; private const string WarnTag = "W ; "; private const string ErrorTag = "E ; "; private const string VerboseTag = "V ; "; private const string UserOperationTag = "U ; "; private StreamWriter _logWriter; private readonly object _mutex = new object(); private DateTime _date; private bool _disposed; public SonopostLogEngine() { var freeSpace = SystemHelper.GetHardDiskFreeSpace(AppDomain.CurrentDomain.BaseDirectory); if (freeSpace <= 10)//小于10个G { string[] logsType = { "Logs", "SmartLogs", "TRTCClientLogs", "TRTCLogs" }; foreach (var type in logsType) { var logDirectory = Path.Combine(SonopostConstants.DataFolder, type); RemoveOldLogs(logDirectory); } } } ~SonopostLogEngine() { DoDispose(); } public override void Write(LogLevel level, string msg) { lock (_mutex) { var now = DateTime.Today.AddHours(DateTime.Now.Hour); if (now != _date) { InitializeLogger(); _date = now; } try { var message = RecombinateMessage(level, msg); WriteMessage(message); } catch (Exception) { // There is exception during writing log, so just ignore } } } private void InitializeLogger() { var today = DateTime.Today; var parentLogDirectory = Path.Combine(SonopostConstants.DataFolder, "Logs"); var logDirectory = Path.Combine(parentLogDirectory, today.Year.ToString(), today.Month.ToString("D2"), today.Day.ToString("D2")); DirectoryHelper.CreateDirectory(logDirectory); var now = DateTime.Now; var logTag = $"{now:yyyyMMddHH}"; var logFileName = $"Log_{logTag}.log"; var logFilePath = Path.Combine(logDirectory, logFileName); if (!File.Exists(logFilePath)) { _logWriter?.Dispose(); var logFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); _logWriter = new StreamWriter(logFileStream); } else { _logWriter?.Dispose(); var logFileStream = new FileStream(logFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); logFileStream.Position = logFileStream.Length; _logWriter = new StreamWriter(logFileStream); } } private void WriteMessage(string message) { _logWriter.WriteLine(message); _logWriter.Flush(); } private string RecombinateMessage(LogLevel level, string msg) { var now = DateTime.Now; StringBuilder sb = new StringBuilder(); sb.Append($"[{now:yyyyMMddHHmmss},{now.Millisecond:d3}]-"); string message = msg; if (level == LogLevel.Error) { sb.Append(ErrorTag); } else if (level == LogLevel.Warn) { sb.Append(WarnTag); } else if (level == LogLevel.Info) { sb.Append(InfoTag); } else if (level == LogLevel.Verbose) { sb.Append(VerboseTag); } else if (level == LogLevel.Debug) { sb.Append(DebugTag); } else if (level == LogLevel.UserOperation) { sb.Append(UserOperationTag); } sb.Append(message); return sb.ToString(); } private void RemoveOldLogs(string logDirectory) { if (Directory.Exists(logDirectory)) { var folders = Directory.GetDirectories(logDirectory); foreach (var folder in folders) { RemoveOldLogs(folder); } //删除超过7天的日志 var files = Directory.GetFiles(logDirectory).Select(m => new FileInfo(m)) .Where(t => t.Exists && DateTime.Now - t.CreationTime >= TimeSpan.FromDays(7)); foreach (var file in files) { file.Delete(); } if (Directory.GetFiles(logDirectory).Count() == 0 && Directory.GetDirectories(logDirectory).Count() == 0) { Directory.Delete(logDirectory); } } } private void DoDispose() { if (!_disposed) { _logWriter?.Dispose(); _disposed = true; } } public override void Dispose() { DoDispose(); GC.SuppressFinalize(this); } } }