使用当前日期和时间创建NLog文件而不缓存它,保持存档文件名相同

时间:2014-12-03 16:14:28

标签: c# nlog

我正在使用NLog进行日志记录,但我遇到了归档和文件名的问题。

我正在代码中创建日志记录配置(我正在编写一个包装器以公开某些特定功能),并且我已经使用这些选项创建了FileTarget对象:

this._fileTarget.FileName = "${date:format=yyyy-MM-dd hh.mm.ss}.log";
this._fileTarget.ArchiveAboveSize = Math.Pow(1024, 2) * 5; //5MB
this._fileTarget.ArchiveNumbering = ArchiveNumberingMode.Date;
this._fileTarget.ArchiveEvery = FileArchivePeriod.Day;
this._fileTarget.ArchiveDateFormat = "yyyy-MM-dd hh.mm.ss";

我不确定为什么NLog会这样做,但是文件名布局会每秒创建一个新的日志文件,而不是仅仅使用文件名,直到存档期间结束。

我将缓存的目标包装器添加到文件名中:

this._fileTarget.FileName = "${cached:cached=true:inner=${date:format=yyyy-MM-dd hh.mm.ss}.log}";

但是所有购买的东西都是一个现在永远不会改变的文件名,在归档时看起来像这样

2014-12-03 12.00.00.2014-12-03 12.00.00.log
2014-12-03 12.00.00.2014-12-03 12.10.00.log
etc...

是否可以告诉NLog仅根据文件大小和日期归档文件并忽略归档编号和日期格式?我正在尝试生成日志文件,其名称是创建时间的时间戳,其中新文件仅在特定大小或每天创建。

修改 这就是我想要实现的目标:

在申请开始时

  1. 使用当前时间戳创建日期文件,文件名格式为"yyyy-MM-dd hh.mm.ss".txt(示例 - >“2014-04-29 11:11:11.txt”)
  2. 应用程序会在该文件中记录一段时间,直到它为止
    • 变得太大(超出定义的限制)或
    • 存档时间过去了(在我的情况下,这是一天)
  3. 然后记录器停止写入1中创建的文件(“2014-04-29 11.11.11.txt”),并且不重命名或以其他方式添加顺序/滚动数字或日期格式。
  4. 重复步骤1-3直到时间结束。
  5. 给我一​​个看起来像这样的Log文件夹:

    Logs
    |
    |> 2014-12-10 12:50:50.txt    (1024 kb)
    |> 2014-12-10 12:50:55.txt    (1020 kb)
    |> 2014-12-10 12:51:01.txt    (1024 kb)
    |> 2014-12-10 12:51:10.txt    (1003 kb)  
    |> 2014-12-10 12:51:20.txt    (400 kb)  <-The currently active log file.
    

3 个答案:

答案 0 :(得分:4)

这是一个老问题,但最近有一些改进此案例。

  

我不确定为什么NLog会这样做,但是文件名布局会每秒创建一个新的日志文件,而不是仅仅使用文件名,直到存档期间结束。

由于NLog 4.3.9可以配置“cachekey”,因此您可以控制缓存何时无效。

对于这种情况,以下配置会在文件名中为您提供日期时间,但每天只有1个文件。文件名中的时间将是当天第一个日志事件的时间。

filename="${cached:cached=true:Inner=${date:format=yyyy-MM-dd hh.mm.ss}:CacheKey=${shortdate}}.log"

答案 1 :(得分:1)

我不知道你是否可以使用原生布局来实现这一点,但实现自己的LayoutRenderer相对容易实现。

我做了一些非常接近你想要的事情:

    [LayoutRenderer("UniqueName")]
    public class UniqueNameLayoutRenderer : LayoutRenderer
    {
        #region Fields (1)

        private string _constantName;

        #endregion Fields

        #region Enums (1)

        public enum PatternType
        {
            /// <summary>
            /// Long date + current process ID
            /// </summary>
            LongDateAndPID,
            /// <summary>
            /// Long date (including ms)
            /// </summary>
            LongDate,
        }

        #endregion Enums

        #region Properties (2)

        public string ConstantName
        {
            get
            {
                if (_constantName == null)
                {
                    if (Format == PatternType.LongDateAndPID)
                    {
                        string pid;
                        try
                        {
                            pid = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture);
                        }
                        catch
                        {
                            pid = "000"; 
                        }

                        _constantName = DateTime.Now.ToString("yyyy-MM-dd_HHmmss-ffff") + "_pid" + pid;
                    }
                    else if (Format == PatternType.LongDate)
                    {
                        _constantName = DateTime.Now.ToString("yyyy-MM-dd_HHmmss-ffff");
                    }
                }

                return _constantName;
            }
        }

        [DefaultParameter]
        public PatternType Format { get; set; }

        #endregion Properties

        #region Methods (2)

        // Protected Methods (1) 

        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            builder.Append(ConstantName);
        }
        // Private Methods (1) 

        #endregion Methods
    }
}

它将在第一次调用时使用当前长时间生成文件的名称,并将其保留到执行结束。 我主要使用它与NLog 2,但它似乎与NLog 3.2一起使用。

它打算与

一起使用
"{UniqueName:format=LongDate}" 
例如,在NLog配置文件中

。 “LongDateAndPID”在名称末尾添加进程ID,在启用滚动日志的情况下跟踪不同的实例非常有用。

在使用它之前,你应该注册appender:

<extensions><add assembly="MyAssemblyWhichContainsRenderer"/></extensions>

要在启用滚动的情况下使用它,只需使用以下内容:

<target xsi:type="File"
        name="logfile"
        fileName="${logDirectory}\logs-${UniqueName:format=LongDateAndPID}.txt"
        layout="${longdate} | ${level:uppercase=true} (${threadid}) | ${callsite} : ${message} ${exception:format=ToString}"
        archiveFileName="${logDirectory}\logs-${UniqueName:format=LongDateAndPID}_{##}.txt"
        archiveAboveSize="25165824"
        concurrentWrites="false"
        archiveNumbering="Sequence"
        maxArchiveFiles="99999" />

(当然这只是一个例子)

您可以随意根据自己的需要调整布局渲染器。

答案 2 :(得分:0)

问题是您使用的文件名中包含HOURS,MINUTES和SECONDS的掩码。我在传球中有同样的问题。 如果你有每日滚动,你可能需要考虑在日志文件名中拥有HOURS,MINUTES和SECONDS的真正好处是什么。 要正确设置,请使用与归档条件匹配的格式。 EX: ArchiveEvery =日 yyyyMMdd.log

ArchiveEvery =小时 yyyyMMdd hh.log

ArchiveEvery =分 yyyyMMdd hh.mm.log

另一方面:你真的需要两种行为的混合存档吗?

如果答案为是,请继续执行您自己的appender,如另一篇文章所述。 否则每小时尝试滚动文件,这会使你的文件更小。

希望这个帮助