NLog是一个记录日志组件,和log4net一样被广泛使用,它可以将日志保存到文本文件、CSV、控制台、VS调试窗口、数据库等。最近刚用到这个组件,觉得不错,水一篇。

下载

通过Nuget安装NLog,你也可以同时安装NLog.Config,它会在项目目录下帮你建立一个配置文件NLog.config,不过不需要,我们直接手动建立一个,你也可以将配置的信息写入到 App.config/Web.config,我比较喜欢独立出来,不与其它配置掺和在一起。

配置

在项目根目录下新建一个NLog.config,基本目录结构:targets下面配置日志输出目标及相关参数,rules下面配置目标输出规则。

<?xml version="1.0" ?>
<nlog>
<targets>
<target></target>
<target></target>
</targets>
<rules>
<logger></logger>
<logger></logger>
</rules>
</nlog>

记得在NLog.config的属性中设置 Copy to Output Directory: Copy always

现在我们要将日志输出到文本文件,数据库,VS调试窗口,完整配置文件如下:

<?xml version="1.0" ?>

<!--<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Trace"
internalLogFile="D:\work\log.txt">--> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"> <targets> <!-- Log in a separate thread, possibly queueing up to
5000 messages. When the queue overflows, discard any
extra messages--> <!-- write logs to file -->
<target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target xsi:type="File" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} ${level:uppercase=true} ${event-context:item=Action} ${message} ${event-context:item=Amount} ${stacktrace}" />
</target> <!-- write log message to database -->
<target name="db" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target type="Database" dbProvider="mssql" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=EFinance;Persist Security Info=True;User ID=sa;Password=123456;"> <commandText>
INSERT INTO Log(Timestamp,Level,Message,Action,Amount,StackTrace) VALUES(@time_stamp, @level, @message, @action, @amount, @stacktrace);
</commandText> <!-- database connection parameters -->
<parameter name="@time_stamp" layout="${date}" />
<parameter name="@level" layout="${level:uppercase=true}" />
<parameter name="@message" layout="${message}" />
<parameter name="@action" layout="${event-context:item=Action}" />
<parameter name="@amount" layout="${event-context:item=Amount}" />
<parameter name="@stacktrace" layout="${stacktrace}" />
</target>
</target> <!--write log message to Visual Studio Output-->
<target name="debugger" xsi:type="Debugger" layout="NLog: ${date:format=HH\:mm\:ss} | ${level:uppercase=true:padding=-5} | ${message}" />
</targets> <rules>
<!--TRACE,DEBUG,INFO,WARN,ERROR,FATAL-->
<logger name="*" minlevel="Trace" writeTo="debugger" />
<!--INFO,WARN,ERROR,FATAL-->
<logger name="*" minlevel="Info" writeTo="db" />
<!--DEBUG,INFO,WARN,ERROR,FATAL-->
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
  • 如在根节点(nlog)配置 internalLogLevel, internalLogFile,可以查看NLog输出日志时的内部信息,比如你配置文件有错误,很有帮助,不过项目发布后还是关闭比较好,以免影响效率;
  • 在target外面罩了一个 <target>并且xsi:type为 AsyncWrapper,即表示这条 target 将异步输出,这里我将文件和数据库日志异步输出;
  • db target内指定了数据库连接字符串 connectionString,SQL语句,SQL参数,还可以指定数据库/表创建和删除的脚本(推荐看NLog源码示例,这里不介绍),同时我们自定义了2个参数 action和amount;
  • target参数里有些是NLog内置参数,比如message,level,date,longdate,exception,stacktrace等,NLog在输出时会自动赋值;
  • layout设置了每条日志的格式;
  • 在rules节点,我们分别指定了三个target输出日志的级别,NLog用于输出日志的级别包括:Trace,Debug,Info,Warn,Error,Fatal,可以设置 minlevel设置最小级别,也可以用 levels定义你所有需要的级别(多个用逗号分隔)。

封装

简单两句就可以使用NLog了:

NLog.Logger logger = Nlog.LogManager.GetCurrentClassLogger();
logger.Fatal("发生致命错误");
logger.Warn("警告信息");

但是这样只能记录了NLog的内置字段,我们定义的 Amount, Action都不能写入,接下来我们来封装一个Logger:

public class Logger
{
NLog.Logger _logger; private Logger(NLog.Logger logger)
{
_logger = logger;
} public Logger(string name) : this(LogManager.GetLogger(name))
{ } public static Logger Default { get; private set; }
static Logger()
{
Default = new Logger(NLog.LogManager.GetCurrentClassLogger());
} #region Debug
public void Debug(string msg, params object[] args)
{
_logger.Debug(msg, args);
} public void Debug(string msg, Exception err)
{
_logger.Debug(err, msg);
}
#endregion #region Info
public void Info(string msg, params object[] args)
{
_logger.Info(msg, args);
} public void Info(string msg, Exception err)
{
_logger.Info(err, msg);
}
#endregion #region Warn
public void Warn(string msg, params object[] args)
{
_logger.Warn(msg, args);
} public void Warn(string msg, Exception err)
{
_logger.Warn(err, msg);
}
#endregion #region Trace
public void Trace(string msg, params object[] args)
{
_logger.Trace(msg, args);
} public void Trace(string msg, Exception err)
{
_logger.Trace(err, msg);
}
#endregion #region Error
public void Error(string msg, params object[] args)
{
_logger.Error(msg, args);
} public void Error(string msg, Exception err)
{
_logger.Error(err, msg);
}
#endregion #region Fatal
public void Fatal(string msg, params object[] args)
{
_logger.Fatal(msg, args);
} public void Fatal(string msg, Exception err)
{
_logger.Fatal(err, msg);
}
#endregion #region Custom public void Process(Models.Log log)
{
var level = LogLevel.Info;
if (log.Level == Models.EFLogLevel.Trace)
level = LogLevel.Trace;
else if (log.Level == Models.EFLogLevel.Debug)
level = LogLevel.Debug;
else if (log.Level == Models.EFLogLevel.Info)
level = LogLevel.Info;
else if (log.Level == Models.EFLogLevel.Warn)
level = LogLevel.Warn;
else if (log.Level == Models.EFLogLevel.Error)
level = LogLevel.Error;
else if (log.Level == Models.EFLogLevel.Fatal)
level = LogLevel.Fatal; var ei = new MyLogEventInfo(level, _logger.Name, log.Message);
ei.TimeStamp = log.Timestamp;
ei.Properties["Action"] = log.Action;
ei.Properties["Amount"] = log.Amount; _logger.Log(level, ei);
} #endregion /// <summary>
/// Flush any pending log messages (in case of asynchronous targets).
/// </summary>
/// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
public void Flush(int? timeoutMilliseconds = null)
{
if (timeoutMilliseconds != null)
NLog.LogManager.Flush(timeoutMilliseconds.Value); NLog.LogManager.Flush();
}
} public class MyLogEventInfo : LogEventInfo
{
public MyLogEventInfo() { }
public MyLogEventInfo(LogLevel level, string loggerName, string message) : base(level, loggerName, message)
{ } public override string ToString()
{
//Message format
//Log Event: Logger='XXX' Level=Info Message='XXX' SequenceID=5
return FormattedMessage;
}
}
public class Log : IEntityBase<long>
{
public long Id { get; set; }
/// <summary>
/// 日志级别 Trace|Debug|Info|Warn|Error|Fatal
/// </summary>
public string Level { get; set; }
public string Message { get; set; }
public string Action { get; set; }
public string Amount { get; set; }
public string StackTrace { get; set; }
public DateTime Timestamp { get; set; } private Log() { }
public Log(string level, string message, string action = null, string amount = null)
{
this.Level = level;
this.Message = message;
this.Action = action;
this.Amount = amount;
}
}
  • Models.Log是我们项目里的日志对象,它对应一个数据表Log,NLog将日志数据写入到这个表;
  • Process(Models.Log)是我们处理自定义对象的日志方法,用LogEventInfo来写入;
  • 重写 LogEventInfo.ToString() 是因为 LogEventInfo的Message格式是“Log Event: Logger='XXX' Level=Info Message='XXX' SequenceID=5”,不便于查阅,我们只需要我们设置的Message。

使用:

下面是测试方法,我们一共输出9条日志,这9条日志将输出到哪个目标,由配置文件中的Rules/logger决定

Logger.Default.Trace("Hello World! Trace");
Logger.Default.Info("Hello World! Info");
Logger.Default.Warn("Hello World! Warn");
Logger.Default.Debug("Hello World! Debug");
Logger.Default.Error("Hello World! Error");
Logger.Default.Fatal("Hello World! Fatal"); Logger.Default.Process(new Models.Log(Models.EFLogLevel.Info, "Hello World! Info", "TEST", "100.00"));
Logger.Default.Process(new Models.Log(Models.EFLogLevel.Debug, "Hello World! Debug", "TEST", "100.00"));
Logger.Default.Process(new Models.Log(Models.EFLogLevel.Error, "Hello World! Error", "TEST", "100.00"));
Logger.Default.Flush();

因为我们在Target中设置了异步,所以如果我们想当场看到输出结果,就需要使用Flush()方法,实际输出日志时就不需要了。

结果:

查看日志记录:

C# 使用NLog记录日志的更多相关文章

  1. [转]C# 使用Nlog记录日志到数据库

    本文转自:http://www.cnblogs.com/weixing/archive/2013/04/26/3044422.html 摘要]Nlog是一个很不错的.NET日志记录组件,它可以将日志输 ...

  2. .NET中使用NLog记录日志

    以前小编记录日志使用的是Log4Net,虽然好用但和NLog比起来稍显复杂.下面小编就和大伙分享一下NLog的使用方式. 引用NLog.Config 在使用NLog之前,我们要首先添加对NLog.Co ...

  3. Nlog 记录日志到 sqlite

    最近研究了一下Nlog这个日志框架,这里记录一下如何将日志写到sqlite中. 第一步:使用NuGet获取Nlog和Sqlite 第二步:在sqlite中创建一个database,这里我用了SQLit ...

  4. C# 使用Nlog记录日志到数据库 使用LogEventInfo类获取,命名空间名称、类名、方法名

    原文地址:http://dotnet.9sssd.com/csbase/art/793 [摘要]Nlog是一个很不错的.NET日志记录组件,它可以将日志输出到控件台,保存到文本,也可以很方便的记录到数 ...

  5. EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  6. C# 使用Nlog记录日志到数据库

    [摘要]Nlog是一个很不错的.NET日志记录组件,它可以将日志输出到控件台,保存到文本,也可以很方便的记录到数据库中.本文为你介绍C# 使用Nlog记录日志到数据库. Nlog是一个很不错的.NET ...

  7. .Net Core 使用NLog记录日志到文件和数据库

    NLog 记录日志是微软官方推荐使用. 接下来,通过配置日志记录到文件和Sql Server数据库. 第一步:首先添加包NLog.Config (可通过微软添加包命令Install-Package 包 ...

  8. .netcore3.1使用log4net/nlog记录日志

    .netcore3.1使用log4net/nlog记录日志 .netcore3.1与2.x之间很是有不少差异的.本来想通过ctrl+c,ctrl+v将在2.2中实现的简单日志记录搬到.netcore3 ...

  9. 转:C# 使用NLog记录日志

    原文:http://www.cnblogs.com/felixnet/p/5498759.html NLog是一个记录日志组件,和log4net一样被广泛使用,它可以将日志保存到文本文件.CSV.控制 ...

随机推荐

  1. 【NOIP训练】【Tarjan求割边】上学

    题目描述 给你一张图,询问当删去某一条边时,起点到终点最短路是否改变. 输入格式 第一行输入两个正整数,分别表示点数和边数.第二行输入两个正整数,起点标号为,终点标号为.接下来行,每行三个整数,表示有 ...

  2. AC自动机---病毒侵袭

    HDU 2896 题目网址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110773#problem/B Description 当太 ...

  3. python flask应用部署

    失败版本:flask+uwsgi ini配置文件 [uwsgi] callable = app ;//程序内启用的application变量名 home = /home/jcuan/code/pyth ...

  4. R语言-神经网络包RSNNS

    code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs && docu ...

  5. 硅谷新闻4--解决页签手指按下从左到右滑动的bug

    有一种方法可以阻止父层的View截获touch事件,就是调用 getParent().requestDisallowInterceptTouchEvent(true);方法.一旦底层View收到tou ...

  6. java线程控制、状态同步、volatile、Thread.interupt以及ConcurrentLinkedQueue

    在有些严格的系统中,我们需要做到干净的停止线程并清理相关状态.涉及到这个主题会带出很多的相关点,简单的总结如下: 我们知道,在java中,有一个volatile关键字,其官方说明(https://do ...

  7. JVM的ClassLoader过程分析

    本文来自网络:深入分析Java ClassLoader原理 http://my.oschina.net/zhengjian/blog/133836 一. JVM的ClassLoader过程以及装载原理 ...

  8. 我所了解的WEB开发(3) - 彩虹的颜色

    据说彩虹有七彩颜色,从外至内分别为:红.橙.黄.绿.青.蓝.紫.这些我倒是没有验证过,但是学生时代就不止一次色盲检测,还是让我足够确信对颜色的分辨应该和大多数人相似的. 还听说大多数哺乳动物是色盲.如 ...

  9. touch触摸事件

    事件对象 事件对象是用来记录一些事件发生时的相关信息的对象.事件对象只有事件发生时才会产生,并且只能是事件处理函数内部访问,在所有事件处理函数运行结束后,事件对象就被销毁! W3C DOM把事件对象作 ...

  10. CRM 2013 系统设置新功能一:界面自动保存 及 SDK 中 Xrm.Page.data.entity.save

    CRM 2013 界面会自动保存了..在系统设置中默认“是”,如果不需要可以调整. CRM实体记录在新建时会有出现“保存”按钮,非新建状态下,没有“保存”按钮只有“新建”按钮,系统将会自动为你保存最后 ...