From ab38c8016a4a645f038e89b859d41c8fb864be52 Mon Sep 17 00:00:00 2001 From: lindexi Date: Sun, 25 Oct 2020 20:41:45 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=86=99=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dotnetCampus.FileLogger.sln | 25 +++++++ .../dotnetCampus.FileLogger/FileLogger.cs | 72 +++++++++++++++++++ .../dotnetCampus.FileLogger/Program.cs | 35 +++++++++ .../dotnetCampus.FileLogger.csproj | 10 +++ 4 files changed, 142 insertions(+) create mode 100644 src/dotnetCampus.FileLogger/dotnetCampus.FileLogger.sln create mode 100644 src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs create mode 100644 src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/Program.cs create mode 100644 src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/dotnetCampus.FileLogger.csproj diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger.sln b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger.sln new file mode 100644 index 0000000..6a7978d --- /dev/null +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30523.141 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnetCampus.FileLogger", "dotnetCampus.FileLogger\dotnetCampus.FileLogger.csproj", "{B4F4EAE9-6C2E-4E54-BFE4-EE8BEF991DAC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B4F4EAE9-6C2E-4E54-BFE4-EE8BEF991DAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4F4EAE9-6C2E-4E54-BFE4-EE8BEF991DAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4F4EAE9-6C2E-4E54-BFE4-EE8BEF991DAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4F4EAE9-6C2E-4E54-BFE4-EE8BEF991DAC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {043DBF55-1A43-4E6D-A528-8EE89439DD8B} + EndGlobalSection +EndGlobal diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs new file mode 100644 index 0000000..304ef07 --- /dev/null +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using dotnetCampus.Threading; + +namespace dotnetCampus.FileLogger +{ + public class FileLogger : IAsyncDisposable + { + public FileLogger() + { + DoubleBufferTask = new DoubleBufferLazyInitializeTask(WriteFile); + } + + public FileLogger(FileInfo logFile) : this() + { + SetLogFile(logFile); + } + + public void SetLogFile(FileInfo logFile) + { + if (LogFile != null) + { + throw new InvalidOperationException($"重复多次设置日志文件"); + } + + LogFile = logFile; + DoubleBufferTask.OnInitialized(); + + IsInitialized = true; + } + + public bool IsInitialized { private set; get; } = false; + + public FileInfo LogFile { private set; get; } = null!; + + private DoubleBufferLazyInitializeTask DoubleBufferTask { get; } + + public async ValueTask DisposeAsync() + { + DoubleBufferTask.Finish(); + await DoubleBufferTask.WaitAllTaskFinish(); + } + + public void WriteLog(string logMessage) + { + DoubleBufferTask.AddTask(logMessage); + } + + private Task WriteFile(List logList) + { + // 最多尝试写10次日志 + for (var i = 0; i < 10; i++) + { + try + { + return File.AppendAllLinesAsync(LogFile.FullName, logList); + } + catch (Exception e) + { + Debug.WriteLine("[FileLogger] {0}", e); + } + + Debug.WriteLine("[FileLogger] Retry count {0}", i); + } + + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/Program.cs b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/Program.cs new file mode 100644 index 0000000..0b1bcf6 --- /dev/null +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/Program.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using System.Threading.Tasks; + +namespace dotnetCampus.FileLogger +{ + class Program + { + static async Task Main(string[] args) + { + var logFile = new FileInfo("log.txt"); + + if (logFile.Exists) + { + File.Delete(logFile.FullName); + } + + var fileLogger = new FileLogger(); + + for (int i = 0; i < 100; i++) + { + fileLogger.WriteLog(i.ToString()); + } + + fileLogger.SetLogFile(logFile); + + await fileLogger.DisposeAsync(); + + if (File.Exists(logFile.FullName)) + { + + } + } + } +} diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/dotnetCampus.FileLogger.csproj b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/dotnetCampus.FileLogger.csproj new file mode 100644 index 0000000..ca1370d --- /dev/null +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/dotnetCampus.FileLogger.csproj @@ -0,0 +1,10 @@ + + + + Exe + net5.0 + + + + + From fcb55a00b48f819fc00362bc92c03f741e85bf07 Mon Sep 17 00:00:00 2001 From: lindexi Date: Sun, 25 Oct 2020 21:02:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E9=99=90=E5=88=B6?= =?UTF-8?q?=E5=86=99=E5=85=A5=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #6 #7 --- .../dotnetCampus.FileLogger/FileLogger.cs | 46 +++++++++++++++---- .../FileLoggerConfiguration.cs | 39 ++++++++++++++++ .../FileLoggerWriteFailedArgs.cs | 22 +++++++++ 3 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerConfiguration.cs create mode 100644 src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerWriteFailedArgs.cs diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs index 304ef07..d82c2b4 100644 --- a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs @@ -14,27 +14,30 @@ public FileLogger() DoubleBufferTask = new DoubleBufferLazyInitializeTask(WriteFile); } - public FileLogger(FileInfo logFile) : this() + public FileLogger(FileLoggerConfiguration configuration) : this() { - SetLogFile(logFile); + SetConfiguration(configuration); } - public void SetLogFile(FileInfo logFile) + public void SetConfiguration(FileLoggerConfiguration configuration) { - if (LogFile != null) + if (FileLoggerConfiguration != null) { throw new InvalidOperationException($"重复多次设置日志文件"); } - LogFile = logFile; + FileLoggerConfiguration = configuration.Clone(); + DoubleBufferTask.OnInitialized(); IsInitialized = true; } + private FileLoggerConfiguration FileLoggerConfiguration { set; get; } = null!; + public bool IsInitialized { private set; get; } = false; - public FileInfo LogFile { private set; get; } = null!; + public FileInfo LogFile => FileLoggerConfiguration.LogFile; private DoubleBufferLazyInitializeTask DoubleBufferTask { get; } @@ -49,14 +52,33 @@ public void WriteLog(string logMessage) DoubleBufferTask.AddTask(logMessage); } - private Task WriteFile(List logList) + private uint CurrentWriteTextCount { set; get; } = 0; + + private async Task WriteFile(List logList) { // 最多尝试写10次日志 - for (var i = 0; i < 10; i++) + var maxWriteLogFileRetryCount = FileLoggerConfiguration.MaxWriteLogFileRetryCount; + for (var i = 0; i < maxWriteLogFileRetryCount; i++) { try { - return File.AppendAllLinesAsync(LogFile.FullName, logList); + await File.AppendAllLinesAsync(LogFile.FullName, logList); + + // 当前写入的数据量 + foreach (var logText in logList) + { + CurrentWriteTextCount += (uint)logText.Length; + } + + if (CurrentWriteTextCount > FileLoggerConfiguration.NotifyMinWriteTextCount) + { + foreach (var limitTextCountFilter in FileLoggerConfiguration.LimitTextCountFilterList) + { + await limitTextCountFilter.FilterLogFile(LogFile); + } + } + + return; } catch (Exception e) { @@ -64,9 +86,13 @@ private Task WriteFile(List logList) } Debug.WriteLine("[FileLogger] Retry count {0}", i); + await Task.Delay(FileLoggerConfiguration.RetryDelayTime); } - return Task.CompletedTask; + FileLoggerWriteFailed?.Invoke(this, new FileLoggerWriteFailedArgs(this, FileLoggerConfiguration, logList)); + // 如果超过次数依然写入失败,那就忽略失败了 } + + public event EventHandler? FileLoggerWriteFailed; } } \ No newline at end of file diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerConfiguration.cs b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerConfiguration.cs new file mode 100644 index 0000000..1c903cc --- /dev/null +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerConfiguration.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace dotnetCampus.FileLogger +{ + public class FileLoggerConfiguration + { + public uint MaxWriteLogFileRetryCount { set; get; } = DefaultMaxWriteLogFileRetryCount; + + public const uint DefaultMaxWriteLogFileRetryCount = 10; + + public TimeSpan RetryDelayTime { set; get; } = DefaultRetryDelayTime; + + public static readonly TimeSpan DefaultRetryDelayTime = TimeSpan.FromMilliseconds(100); + + public FileInfo LogFile { set; get; } = null!; + + public uint NotifyMinWriteTextCount { set; get; } = DefaultNotifyMinWriteTextCount; + + public const uint DefaultNotifyMinWriteTextCount = 5 * 1024 * 1024;// 大约是 5-10M 左右 + + public FileLoggerConfiguration Clone() + { + var fileLoggerConfiguration = (FileLoggerConfiguration)MemberwiseClone(); + fileLoggerConfiguration.LimitTextCountFilterList = LimitTextCountFilterList.ToList(); + return fileLoggerConfiguration; + } + + public List LimitTextCountFilterList { private set;get; } = new List(); + } + + public interface ILimitTextCountFilter + { + Task FilterLogFile(FileInfo logFile); + } +} \ No newline at end of file diff --git a/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerWriteFailedArgs.cs b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerWriteFailedArgs.cs new file mode 100644 index 0000000..63cd7ad --- /dev/null +++ b/src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLoggerWriteFailedArgs.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace dotnetCampus.FileLogger +{ + public class FileLoggerWriteFailedArgs : EventArgs + { + public FileLoggerWriteFailedArgs(FileLogger fileLogger, FileLoggerConfiguration fileLoggerConfiguration, + IReadOnlyList logList) + { + FileLoggerConfiguration = fileLoggerConfiguration; + FileLogger = fileLogger; + LogList = logList; + } + + public FileLoggerConfiguration FileLoggerConfiguration { get; } + + public FileLogger FileLogger { get; } + + public IReadOnlyList LogList { get; } + } +} \ No newline at end of file