我正在使用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仅根据文件大小和日期归档文件并忽略归档编号和日期格式?我正在尝试生成日志文件,其名称是创建时间的时间戳,其中新文件仅在特定大小或每天创建。
修改 这就是我想要实现的目标:
在申请开始时
"yyyy-MM-dd hh.mm.ss".txt
(示例 - >“2014-04-29 11:11:11.txt”)给我一个看起来像这样的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.
答案 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,如另一篇文章所述。 否则每小时尝试滚动文件,这会使你的文件更小。
希望这个帮助