Последовательное имя файла в NLog - PullRequest
0 голосов
/ 18 июня 2019

Я бы хотел, чтобы имя моего файла изменялось динамически и включало порядковый номер.Имя файла следует менять (увеличивать число) при каждом процессе архивирования / ротации журнала.При архивировании файла имя файла архива должно совпадать с именем файла с порядковым номером (до приращения).

Начиная с имени файла «file.log.1», при архивированииимя файла архива будет «file.log.1», а имя файла будет изменено на «file.log.2».Следующее имя файла архива будет «file.log.2» и т. Д. ...

Возможно ли использовать NLog?Не нашел никакой подсказки в сети или исходном коде NLog.

1 Ответ

0 голосов
/ 23 июня 2019

Итак, я реализовал пользовательскую 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);
}
...