Skip to content

Commit

Permalink
Merge pull request #8 from dotnet-campus/t/lindexi/file-logger
Browse files Browse the repository at this point in the history
加上文件写入
  • Loading branch information
walterlv authored Dec 9, 2020
2 parents c76fcfa + fcb55a0 commit f3470c5
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/dotnetCampus.FileLogger/dotnetCampus.FileLogger.sln
Original file line number Diff line number Diff line change
@@ -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
98 changes: 98 additions & 0 deletions src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/FileLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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<string>(WriteFile);
}

public FileLogger(FileLoggerConfiguration configuration) : this()
{
SetConfiguration(configuration);
}

public void SetConfiguration(FileLoggerConfiguration configuration)
{
if (FileLoggerConfiguration != null)
{
throw new InvalidOperationException($"重复多次设置日志文件");
}

FileLoggerConfiguration = configuration.Clone();

DoubleBufferTask.OnInitialized();

IsInitialized = true;
}

private FileLoggerConfiguration FileLoggerConfiguration { set; get; } = null!;

public bool IsInitialized { private set; get; } = false;

public FileInfo LogFile => FileLoggerConfiguration.LogFile;

private DoubleBufferLazyInitializeTask<string> DoubleBufferTask { get; }

public async ValueTask DisposeAsync()
{
DoubleBufferTask.Finish();
await DoubleBufferTask.WaitAllTaskFinish();
}

public void WriteLog(string logMessage)
{
DoubleBufferTask.AddTask(logMessage);
}

private uint CurrentWriteTextCount { set; get; } = 0;

private async Task WriteFile(List<string> logList)
{
// 最多尝试写10次日志
var maxWriteLogFileRetryCount = FileLoggerConfiguration.MaxWriteLogFileRetryCount;
for (var i = 0; i < maxWriteLogFileRetryCount; i++)
{
try
{
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)
{
Debug.WriteLine("[FileLogger] {0}", e);
}

Debug.WriteLine("[FileLogger] Retry count {0}", i);
await Task.Delay(FileLoggerConfiguration.RetryDelayTime);
}

FileLoggerWriteFailed?.Invoke(this, new FileLoggerWriteFailedArgs(this, FileLoggerConfiguration, logList));
// 如果超过次数依然写入失败,那就忽略失败了
}

public event EventHandler<FileLoggerWriteFailedArgs>? FileLoggerWriteFailed;
}
}
Original file line number Diff line number Diff line change
@@ -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<ILimitTextCountFilter> LimitTextCountFilterList { private set;get; } = new List<ILimitTextCountFilter>();
}

public interface ILimitTextCountFilter
{
Task FilterLogFile(FileInfo logFile);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;

namespace dotnetCampus.FileLogger
{
public class FileLoggerWriteFailedArgs : EventArgs
{
public FileLoggerWriteFailedArgs(FileLogger fileLogger, FileLoggerConfiguration fileLoggerConfiguration,
IReadOnlyList<string> logList)
{
FileLoggerConfiguration = fileLoggerConfiguration;
FileLogger = fileLogger;
LogList = logList;
}

public FileLoggerConfiguration FileLoggerConfiguration { get; }

public FileLogger FileLogger { get; }

public IReadOnlyList<string> LogList { get; }
}
}
35 changes: 35 additions & 0 deletions src/dotnetCampus.FileLogger/dotnetCampus.FileLogger/Program.cs
Original file line number Diff line number Diff line change
@@ -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))
{

}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="dotnetCampus.AsyncWorkerCollection" Version="1.5.2" />
</ItemGroup>
</Project>

0 comments on commit f3470c5

Please sign in to comment.