NLog 中的顺序文件名
Sequential file name in NLog
我希望动态更改我的文件名并包含一个序列号。每次归档 process/log 轮转时都应更改文件名(增加数字)。
归档文件时,归档文件名与文件名加序号(递增前)相同。
起始文件名为'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);
}
我希望动态更改我的文件名并包含一个序列号。每次归档 process/log 轮转时都应更改文件名(增加数字)。 归档文件时,归档文件名与文件名加序号(递增前)相同。
起始文件名为'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);
}