使用NLog进行日志记录的最佳或最有用的配置是什么?(只要它们有用,它们可以是简单的也可以是复杂的.)
我正在考虑一些示例,例如自动滚动特定大小的日志文件,更改布局(日志消息)是否存在异常,一旦发生错误就升级日志级别等.
以下是一些链接:
我想在我的应用程序中使用nlogger,将来可能需要更改日志记录系统.所以我想使用日志门面.
您是否知道对现有示例的任何建议如何编写这些示例?或者只是给我链接到这个领域的一些最佳实践.
根据NLog的文档:
大多数应用程序将为每个类使用一个记录器,其中记录器的名称与类的名称相同.
这与log4net的运行方式相同.为什么这是一个好习惯?
我有兴趣了解更多有关人们如何使用依赖注入平台注入日志记录的信息.虽然下面的链接和我的示例引用了log4net和Unity,但我不一定会使用其中任何一个.对于依赖注入/ IOC,我可能会使用MEF,因为这是项目的其余部分(大)正在解决的标准.
我是依赖注入/ ioc的新手,对于C#和.NET来说还是新手(在过去10年左右的VC6和VB6中,在C#/ .NET中编写了很少的生产代码).我已经对各种日志解决方案进行了大量调查,所以我认为我对其功能集有一个不错的处理.我只是不熟悉获得一个依赖注入的实际机制(或者,可能更"正确",获得一个依赖注入的抽象版本).
我见过其他与日志记录和/或依赖注入相关的帖子,如: 依赖注入和日志记录接口
我的问题与"如何使用ioc工具yyy注入日志记录平台xxx"无关?相反,我感兴趣的是人们如何处理包装日志记录平台(通常,但并不总是建议)和配置(即app.config).例如,使用log4net作为示例,我可以配置(在app.config中)一些记录器,然后以标准方式使用这样的代码来获取这些记录器(没有依赖注入):
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
Run Code Online (Sandbox Code Playgroud)
或者,如果我的记录器没有为某个类命名,而是为了一个功能区,我可以这样做:
private static readonly ILog logger = LogManager.GetLogger("Login");
private static readonly ILog logger = LogManager.GetLogger("Query");
private static readonly ILog logger = LogManager.GetLogger("Report");
Run Code Online (Sandbox Code Playgroud)
所以,我想我的"要求"将是这样的:
我想将我的产品源与直接依赖于日志记录平台隔离开来.
我希望能够通过某种依赖注入(可能是MEF)直接或间接地解析特定的命名记录器实例(可能在同一命名实例的所有请求者之间共享相同的实例).
我不知道我是否会称之为硬性要求,但我希望能够根据需要获得一个命名记录器(不同于类记录器).例如,我可能会根据类名为我的类创建一个记录器,但是一个方法需要特别重的诊断,我想单独控制.换句话说,我可能希望单个类"依赖"两个独立的记录器实例.
让我们从数字1开始.我已经阅读了很多文章,主要是关于stackoverflow,关于它是否是一个好主意.请参阅上面的"最佳实践"链接,并转到jeffrey hantin的评论,了解一个关于为什么包装log4net不好的观点.如果你确实包装(如果你能有效地包装),你会严格包装以注入/消除直接的倾向吗?或者你也会尝试抽象出部分或全部log4net app.config信息?
假设我想使用System.Diagnostics,我可能想要实现一个基于接口的记录器(甚至可能使用"常见的"ILogger/ILog接口),可能基于TraceSource,以便我可以注入它.你会实现接口,比如TraceSource,只是按原样使用System.Diagnostics app.config信息吗?
像这样的东西:
public class MyLogger : ILogger
{
private TraceSource ts;
public MyLogger(string name)
{
ts = new TraceSource(name);
}
public void ILogger.Log(string msg)
{
ts.TraceEvent(msg);
}
} …
Run Code Online (Sandbox Code Playgroud) 我正在使用NLog记录我的东西.我正在尝试将输出发送到控制台(或colouredconsole)...我希望将其转到任何ASP.NET网站/ app/mvc应用程序的Visual Studio'OUTPUT'窗口.
不是.如果我将目标更改为"文件",那么它肯定会起作用.
NLog可以输出到网络应用的"输出"窗口吗?
当我使用NLog的默认布局时,它只打印例外的名称.我被告知log4jxmlevent布局不会打印关于异常的任何内容.什么布局会对我有帮助?
示例代码:
try
{
throw new SystemException();
}
catch (Exception ex)
{
logger.Error("oi", ex);
}
Run Code Online (Sandbox Code Playgroud)
默认布局输出:
2011-01-14 09:14:48.0343|ERROR|ConsoleApplication.Program|oi
Run Code Online (Sandbox Code Playgroud)
log4jxmlevent输出:
<log4j:event logger="ConsoleApplication.Program"
level="ERROR"
timestamp="1295003776872"
thread="9">
<log4j:message>oi</log4j:message>
<log4j:NDC />
<log4j:locationInfo class="ConsoleApplication.Program"
method="Void Main(System.String[])"
file="C:\Users\User\Documents\Visual Studio 2010\Projects\ConsoleApplication\ConsoleApplication\Program.cs"
line="21" />
<nlog:eventSequenceNumber>3</nlog:eventSequenceNumber>
<nlog:locationInfo assembly="ConsoleApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<log4j:properties>
<log4j:data name="log4japp"
value="true" />
<log4j:data name="log4jmachinename"
value="MACHINE" />
</log4j:properties>
Run Code Online (Sandbox Code Playgroud)
我使用NLog进行下一个配置:
<targets>
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="f" />
</rules>
Run Code Online (Sandbox Code Playgroud)
我试图获得(我检查,集合中只有一个FileTarget)的FileName
属性FileTarget
NLog.LogManager.GetCurrentClassLogger().Info("test");
var logFile = (from t in NLog.LogManager.Configuration.AllTargets
where t is NLog.Targets.FileTarget
select (NLog.Targets.FileTarget)t).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
但是logFile.FileName只包含文件名的模式,确切地说它是如何在设置中指定的.
如何获取当前日志文件的运行时路径?
我的NLog目标是这样的:
<targets>
<target xsi:type="Console" name="console"
layout="${longdate}|${level}|${message}" />
<target xsi:type="File" name="ErrorLog" fileName="${basedir}/error.txt"
layout="${longdate}
Trace: ${stacktrace}
${message}" />
<target xsi:type="File" name="AccessLog" fileName="${basedir}/access.txt"
layout="${shortdate} | ${message}" />
</targets>
Run Code Online (Sandbox Code Playgroud)
但是如果用户不是他们机器上的管理员,这会导致问题,因为他们没有"程序文件"的写入权限.我怎样才能得到类似于%AppData%
NLog而不是BaseDir的东西?
记录的预期开销应该是多少?我试过这个例子
private class Person
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public string Name { get; private set; }
public Person(string name)
{
Name = name;
logger.Info("New person created with name {0}", name);
}
}
List<Person> people = new List<Person>();
for (int i = 0; i < MAXTEST; i++)
{
people.Add(new Person(i.ToString()));
}
Run Code Online (Sandbox Code Playgroud)
MAXTEST值为100,500,1000,5000
结果为MAXTEST,noLogging,Logging
100, 25ms, 186ms
500, 33ms, 812ms
1000, 33ms, 1554ms
5000, 33ms, 7654ms
Run Code Online (Sandbox Code Playgroud)
当然,人们可能永远不会记录这个过多的数量,但是这会对人们所期望的性能造成影响吗?
我也尝试在配置中使用asyncwrapper
<target name="asyncFile" xsi:type="AsyncWrapper">
<target name="file" xsi:type="File" fileName="${basedir}/log.txt" />
</target>
Run Code Online (Sandbox Code Playgroud)