我希望动态更改我的文件名并包含序列号。在每次归档过程/日志轮换时,都应更改文件名(增加编号)。 归档文件时,归档文件名应与带有序号的文件名相同(递增之前)。
从文件名开始为“ file.log.1”,在归档存档文件时,文件名将为“ file.log.1”,文件名将更改为“ file.log.2”。 下一个存档文件名将为“ file.log.2”,依此类推...
是否可以使用NLog? 在网络或NLog源代码中找不到任何线索。
答案 0 :(得分:0)
所以我实现了一个自定义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);
}