NLog详细教程-2022/12/01

这里写目录标题

  • NLog详细教程
    • NLog的具体介绍,功能,优点等网上一大推,就不具体介绍了,主要说怎么安装使用
      • 安装
        • 需要安装NuGet包。
      • 初级使用
        • 配置文件编写
          • NLog配置原理
          • NLog配置文件形式
          • 最精简的配置文件
        • 代码实现
        • 最终结果
      • 高级使用
        • 配置文件详解
          • 全局配置
          • 根元素
          • 日志的输出目标
          • 日志的路由规则
        • 代码编写
          • 单例模式
          • 封装
          • 可以将异常对象Exception ex直接传递给 NLog.Logger
      • 除此之外NLog还可以集成到其他环境之中,也可以将日志信息不仅只输出成文件,还可以输出到控制台,输出到数据库等等,但是我坚信毛主席的一句话:没有调查,就没有发言权。因为没有实践过,就不发表言论。之后如果接触到了再更新。
    • 暂时就想到这么多,如果对你有帮助,点个赞,留个言:力力+大家所在的城市,不胜感激

NLog详细教程

最近公司使用到了NLog来进行一个日志记录功能,了解了一下,觉得很实用,特此做个分享。

小时候看迪迦,里面一段话特别印象深刻,“努力活完短暂的一生,将成果留给后代继承,人类就是如此反复,真的很了不起!”这些开源软件就是最好的证明,前人帮我们造好了一个又一个轮子,我们需要好好的使用,为往圣继绝学。

NLog的具体介绍,功能,优点等网上一大推,就不具体介绍了,主要说怎么安装使用

安装

需要安装NuGet包。

1.在需要使用的项目点击鼠标右键
NLog详细教程-2022/12/01_第1张图片
2.点击浏览->输入名字->选择如图所示的程序包(这恐怖的下载量)->点击安装(教程写的日期是2022/12/01,NLog最新版就是5.1.0)
NLog详细教程-2022/12/01_第2张图片3.点击确定
NLog详细教程-2022/12/01_第3张图片
4.在项目的引用中可以看到NLog这个dll就算安装成功了。
NLog详细教程-2022/12/01_第4张图片

初级使用

配置文件编写

NLog配置原理

NLog将自动在某些默认位置中搜索其配置文件。当NLog和标准的exe文件配合使用时,将自动按照顺序搜索下列路径,以得到配置文件:

1.应用程序的标准配置文件(通常为applicationname.exe.config)
2.应用程序所在目录中的applicationname.exe.nlog文件
3.应用程序所在目录中的NLog.config文件
4.NLog.dll所在目录中的NLog.dll.nlog文件
5.环境变量NLOG_GLOBAL_CONFIG_FILE所指向的文件
NLog配置文件形式

1.可以写在项目中的App.config文件中。使用标准化的configSection机制
NLog详细教程-2022/12/01_第5张图片
2.可以单独写一个配置文件负责日志记录(取名NLog)
NLog详细教程-2022/12/01_第6张图片
NLog详细教程-2022/12/01_第7张图片
NLog详细教程-2022/12/01_第8张图片
推荐还是单独写一个配置文件,毕竟健壮性更好。

最精简的配置文件
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <targets>
    <!--输出目标:name名称f,xsi:type输出类型文件, fileName输出到程序根目录logs文件夹中, 以日期作为生成log文件名称, layout生成内容的格式-->
    <target name="f"
            xsi:type="File"
            fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
  </targets>
  <rules>
      <!--日志路由规则:最低级别Debug,输出到target目标f-->
    <logger name="*" minlevel="Debug" writeTo="f" />
  </rules>
</nlog>

要记得将NLog的文件属性设置为始终复制。
在这里插入图片描述

代码实现

using NLog;
using NLog.Config;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{

    public partial class Form1 : Form
    {
        //创建日志记录对象
        private Logger Logger = NLog.LogManager.GetCurrentClassLogger();
        public Form1()
        {
            InitializeComponent();
            //初始化配置日志
            LogManager.Configuration = new XmlLoggingConfiguration(string.Format("{0}/NLog.config", AppDomain.CurrentDomain.BaseDirectory.ToString()));
            //打出日志
            Logger.Debug("日志成功打出!--lili");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Logger.Debug("点击按钮1!--lili");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Logger.Debug("点击按钮2!--lili");
        }
    }
}

最终结果

NLog详细教程-2022/12/01_第9张图片

高级使用

NLog如果只是可以做到上文那样的日志管理,也就名不副实了。上文只是它强大功能的冰山一角,我抛砖引玉,介绍一下我所了解到的其他功能。

配置文件详解

配置文件大致分为 全局配置、根元素、targets定义日志的输出目标、rules定义路由规则
NLog详细教程-2022/12/01_第10张图片

全局配置

NLog详细教程-2022/12/01_第11张图片我把常用的属性功能都进行了翻译,也深知大家都喜欢拿来主义,代码附上

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	  autoReload="true"
	  throwExceptions="false"
	  throwConfigExceptions="true"
	  >
根元素

NLog详细教程-2022/12/01_第12张图片其中targets和rules是必需的,其他可以没有

日志的输出目标

NLog详细教程-2022/12/01_第13张图片其中最重要也是最关键的属性就是layout
NLog详细教程-2022/12/01_第14张图片layout中属性真的很全面,基本上所有你想的到可能需要记录的信息,都有对应的属性,这里我只选择了一些我需要或者我觉得以后可能需要的属性进行了备注。(其他详细属性信息可以去官网查看)

layout="${longdate} ${uppercase:${level}} ${message} ${onexception:inner=${exception:format=message} ${newline} ${stacktrace}}"

本文中layout语句的含义是:正常情况下只记录日志的时间 等级和消息,一旦在记录消息时候传入了Exception参数,就额外记录报错信息和当时的程序调用栈信息。
效果如下图
在这里插入图片描述
代码附上

		<target name="f"
				xsi:type="File"
				fileName="${basedir}/logs/${shortdate}.log"
				layout="${longdate} ${uppercase:${level}} ${message} ${onexception:inner=${exception:format=message} ${newline} ${stacktrace}}"
				maxArchiveFiles="999"
				archiveFileName="${basedir}/archives/${logger}-${level}-${shortdate}-{#####}.txt"
				createDirs="true"
				archiveAboveSize="102400"
				archiveEvery="Day"
				keepFileOpen="true"
				openFileCacheTimeout="30"
				autoFlush="false"
				openFileFlushTimeout="10"
				concurrentWrites="true"
				encoding="UTF-8">
		</target>
日志的路由规则

NLog详细教程-2022/12/01_第15张图片本文中使用到的路由规则比较简单,按照个人需求是可以设置的比较复杂的。
例如:

<logger name="Name.Space.Class1" writeTo="target2" /> 
<logger name="Name.Space.*" writeTo="target1" />
					
NameSpace.Class1 记录的信息 往target2 + target1 都写。
其他的logger记录的信息 只往target1 里写。
					
这时候如果在第一条rule里加上 final=true,那么NameSpace.Class1 记录的信息就只往target2里写了。
其他的logger记录的信息 依旧往target1 里写。

<logger name="Name.Space.Class2" maxlevel="Warn" final="true" /> 
<logger name="Name.Space.*" writeTo="target1" />
					
所有的日志信息都会往target1 里写,但是Class2的只会记录 <=Warn等级的消息

<logger name="Name.Space.Class3" maxlevel="Off" final="true" /> 
<logger name="Name.Space.*" writeTo="target1" />
					
Class3啥都写不出去
其他的logger 写到target1里

如果以上例子还满足不了个人的需求的话,NLog还提供了日志过滤器 filters
例如

<logger name="*" minlevel="Debug" maxlevel="Error" writeTo="f">
	<filters>
		//忽略消息长度>100的日志
		<when condition="length('${message}') > 100" action="Ignore" />
		//过滤在10:00和12:59之间记录的日志
		<hourRange fromHour="10" toHour="12" action="Ignore"/> 
	</filters>
</logger>

代码编写

如果需要使用日志管理系统,为了尽可能的不浪费资源,除了在配置文件的属性中做好对应的设置,推荐一下几种做法。

单例模式

大多数应该都能够想到,新建 NLog.Logger 对象肯定消耗一定的开销,所以用单例模式,只创建一个对象就可以了。

封装

将NLog的方法进行简单的封装,避免直接调用。以及别忘记资源的释放。本人写的简单封装如下,抛砖引玉

using NLog;
using NLog.Config;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp1
{
    public sealed class LogHelper
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        //单例模式
        private static readonly LogHelper instance = new LogHelper();
        private LogHelper()
        {
            //初始化配置日志
            LogManager.Configuration = new XmlLoggingConfiguration(string.Format("{0}/NLog.config", AppDomain.CurrentDomain.BaseDirectory.ToString()));
        }
        /// 
        /// 日志等级
        /// 
        public enum LogLevel
        {
            /// 
            /// 最常见的记录信息,一般用于普通输出
            /// 
            Trace = 0,
            /// 
            /// 记录信息,,一般用来调试程序
            /// 
            Debug,
            /// 
            /// 信息类型的消息
            /// 
            Info,
            /// 
            /// 警告信息
            /// 
            Warn,
            /// 
            /// 错误信息
            /// 
            Error,
            /// 
            /// 致命异常信息
            /// 
            Fatal
        }
        /// 
        /// 添加日志
        /// 
        /// 日志信息
        /// 日志等级
        public static void AddLogger(string message, LogLevel logLevel = LogLevel.Debug)
        {
            switch (logLevel)
            {
                case LogLevel.Trace:
                    logger.Trace(message);
                    break;
                case LogLevel.Debug:
                    logger.Debug(message);
                    break;
                case LogLevel.Info:
                    logger.Info(message);
                    break;
                case LogLevel.Warn:
                    logger.Warn(message);
                    break;
                case LogLevel.Error:
                    logger.Error(message);
                    break;
                case LogLevel.Fatal:
                    logger.Fatal(message);
                    break;
                default:
                    logger.Debug(message);
                    break;
            }
        }
        /// 
        /// 添加日志(catch到的Exception建议使用此方法)
        /// 
        /// 错误信息
        /// 日志等级
        public static void AddLogger(Exception exception, LogLevel logLevel = LogLevel.Error)
        {
            switch (logLevel)
            {
                case LogLevel.Trace:
                    logger.Trace(exception);
                    break;
                case LogLevel.Debug:
                    logger.Debug(exception);
                    break;
                case LogLevel.Info:
                    logger.Info(exception);
                    break;
                case LogLevel.Warn:
                    logger.Warn(exception);
                    break;
                case LogLevel.Error:
                    logger.Error(exception);
                    break;
                case LogLevel.Fatal:
                    logger.Fatal(exception);
                    break;
                default:
                    logger.Error(exception);
                    break;
            }
        }
        /// 
        /// 添加日志(catch到的Exception建议使用此方法)
        /// 
        /// 错误信息
        /// 错误描述
        /// 日志等级
        public static void AddLogger(Exception exception, string message, LogLevel logLevel = LogLevel.Error)
        {
            switch (logLevel)
            {
                case LogLevel.Trace:
                    logger.Trace(exception, message);
                    break;
                case LogLevel.Debug:
                    logger.Debug(exception, message);
                    break;
                case LogLevel.Info:
                    logger.Info(exception, message);
                    break;
                case LogLevel.Warn:
                    logger.Warn(exception, message);
                    break;
                case LogLevel.Error:
                    logger.Error(exception, message);
                    break;
                case LogLevel.Fatal:
                    logger.Fatal(exception, message);
                    break;
                default:
                    logger.Error(exception, message);
                    break;
            }
        }
        /// 
        /// 释放日志资源
        /// 
        public static void Dispose()
        {
            NLog.LogManager.Shutdown();
        }
    }
}

可以将异常对象Exception ex直接传递给 NLog.Logger

可以将异常对象Exception ex直接传递给 NLog.Logger,这和传ex.Message+ex.StackTrace是不同的效果,区别如下图,各有优劣。(但是大型软件的ex.StackTrace真的是太长了)
在这里插入图片描述

除此之外NLog还可以集成到其他环境之中,也可以将日志信息不仅只输出成文件,还可以输出到控制台,输出到数据库等等,但是我坚信毛主席的一句话:没有调查,就没有发言权。因为没有实践过,就不发表言论。之后如果接触到了再更新。

暂时就想到这么多,如果对你有帮助,点个赞,留个言:力力+大家所在的城市,不胜感激

因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激。

你可能感兴趣的:(杂七杂八,graylog,c#,log4j,开源软件,经验分享)