c# - NLog中的顺序文件名
问题描述
我希望动态更改我的文件名并包含一个序列号。每次归档过程/日志轮换时,应更改文件名(增加数字)。归档文件时,归档文件名应与带序号的文件名相同(递增前)。
从文件名“file.log.1”开始,归档时归档文件名将是“file.log.1”,文件名将更改为“file.log.2”。下一个存档文件名将是“file.log.2”等等...
可以使用 NLog 吗?在网络或 NLog 源代码中没有找到任何线索。
解决方案
所以我实现了一个自定义 FileTarget 来满足我的需求:
internal sealed class CustomFileTarget : NLog.Targets.FileTarget
{
private const int _maxOldFilesToKeep = 10;
private readonly string _directory;
private readonly long _fileMaxSize = (long)10.Megabytes().Bytes;
private readonly string _fileNamePrefix;
private int _sequential;
private string FullFileName => $"{Path.Combine(_directory, _fileNamePrefix)}.{_sequential}.log";
public CustomFileTarget(string directory, string fileNamePrefix)
{
_directory = directory;
_fileNamePrefix = fileNamePrefix;
_sequential = GetLatestSequence() ?? 0;
ConcurrentWrites = false;
FileName = FullFileName;
KeepFileOpen = false;
}
protected override void Write(IList<AsyncLogEventInfo> logEvents)
{
base.Write(logEvents);
if (GetFileSize() >= _fileMaxSize)
{
ChangeName();
DeleteOld();
}
}
private long GetFileSize() =>
new FileInfo(FullFileName).Length;
private void ChangeName()
{
_sequential++;
FileName = FullFileName;
LogManager.ReconfigExistingLoggers();
}
private void DeleteOld()
{
var fileNamesAndSequences = GetFileNamesAndSequences();
if (fileNamesAndSequences.Count() > _maxOldFilesToKeep + 1)
{
fileNamesAndSequences.Take(
fileNamesAndSequences.Count() - _maxOldFilesToKeep + 1)
.ForEach(
_ => Directory.Delete(Path.Combine(_directory, _.FileName)));
}
}
private int? GetLatestSequence()
{
var fileNamesAndSequences = GetFileNamesAndSequences();
return fileNamesAndSequences.Any()
? fileNamesAndSequences.Last().Sequence
: (int?)null;
}
private IEnumerable<(string FileName, int Sequence)> GetFileNamesAndSequences() =>
Directory.GetFiles(_directory, $"{_fileNamePrefix}*.log").
Select(
_ =>
{
var fileNameParts = _.Split('.');
return (_, Sequence: int.Parse(fileNameParts[fileNameParts.Length - 2]));
}).
OrderBy(_ => _.Sequence);
}