c# log4net 日志的使用

参考:C# log4net的使用。输出的日志内容添加文件名和行号。_log4net 发布 输出的文件中行号-CSDN博客

 

1.NuGet增加log4net

 2.增加log4net.config文件

 log4net.config的内容如下,没有的功能可以搜一搜,设置 log4net.config的属性 复制到输出目录 设为始终复制

复制代码
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低)-->
    <log4net>
        <!--调试信息-->
        <logger name="InfoLog">
            <level value="ALL" />
            <appender-ref ref="InfoAppender" />
        </logger>

        <!--错误信息-->
        <logger name="ErrorLog">
            <level value="ALL" />
            <appender-ref ref="ErrorAppender" />
        </logger>

        <!--Info日志附加介质-->
        <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
            <!--日志路径-->
            <param name= "File" value= "Logs\"/>
            <!--是否是向文件中追加日志-->
            <param name= "AppendToFile" value= "true"/>
            <!--log保留天数-->
            <param name= "MaxSizeRollBackups" value= "100"/>
            <!--写到一个文件-->
            <staticLogFileName value="false"/>
            <!--单个文件大小。单位:KB|MB|GB-->
            <maximumFileSize value="200MB"/>
            <!--最多保留的文件数,设为"-1"则不限-->
            <maxSizeRollBackups value="-1"/>
            <!--日志文件名格式-->
            <param name= "DatePattern" value= "yyyyMM\\yyyyMMdd'_InfoLog.log'"/>
            <!--不以独占方式记录日志,仅在记录每个日志的最短时间内锁定,因为部署到服务器上遇到了文件被占用无法下载日志-->
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
            <!--日志根据日期滚动-->
            <param name= "RollingStyle" value= "Date"/>
            <!--日志文本格式-->
            <layout type="log4net.Layout.PatternLayout">
                <!--%d  时间,等价于 date-->
                <!--%t  线程-->
                <!--%-5p  日志级别-->
                <!--%C  出错类,等价于 class,可以使用:%class{1},如果给出了精度说明符,
                则只会打印类名中最右边的组件的相应数量。默认情况下,类名以完全限定形式输出。-->
                <!--%L  出错行-->
                <!--%M  方法名,等价于 method-->
                <!--%m  日志信息,等价于 message-->
                <!--%n  换行-->
                <!--这种情况输出的类名方法名输出的是封装的类名<LogHelper>方法名每有意义-->
                <!--<param name="ConversionPattern" value="**********%d 线程[%t] 日志级别[%p]
                **********%n类名:%C        方法名:%M - 第 [%L] 行%n消息:%m%n%n" />-->
                <param name="ConversionPattern" value="**********%d 线程[%t] 日志级别[%p]**********%n消息:%m%n%n"/>
            </layout>
        </appender>
        <!--Error日志附加介质-->
        <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
            <!--日志路径-->
            <param name= "File" value= "Logs\"/>
            <!--是否是向文件中追加日志-->
            <param name= "AppendToFile" value= "true"/>
            <!--log保留天数-->
            <param name= "MaxSizeRollBackups" value= "100"/>
            <!--日志文件名是否是固定不变的-->
            <param name= "StaticLogFileName" value= "false"/>
            <!--日志文件名格式-->
            <param name= "DatePattern" value= "yyyyMM\\yyyyMMdd'_ErrorLog.log'"/>
            <!--日志根据日期滚动-->
            <param name= "RollingStyle" value= "Date"/>
            <param name="MaxFileSize" value="1"/>
            <!--日志文本格式-->
            <layout type="log4net.Layout.PatternLayout">
                <!--%d  时间,等价于 date-->
                <!--%t  线程-->
                <!--%-5p  日志级别-->
                <!--%C  出错类,等价于 class,可以使用:%class{1},如果给出了精度说明符,
                则只会打印类名中最右边的组件的相应数量。默认情况下,类名以完全限定形式输出。-->
                <!--%L  出错行-->
                <!--%M  方法名,等价于 method-->
                <!--%m  日志信息,等价于 message-->
                <!--%n  换行-->
                <!--这种情况输出的类名方法名输出的是封装的类名<LogHelper>方法名每有意义-->
                <!--<param name="ConversionPattern" value="**********%d 线程[%t] 日志级别[%p]
                **********%n类名:%C        方法名:%M - 第 [%L] 行%n消息:%m%n%n" />-->
                <param name="ConversionPattern" value="**********%d 线程[%t] 日志级别[%p]**********%n消息:%m%n%n"/>
            </layout>
        </appender>

    </log4net>
</configuration>
复制代码

3.创建LogHelper.cs类

复制代码
using System.Diagnostics;
using System.IO;
using log4net;

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net\\log4net.config", Watch = true)]

namespace TestLog4net.Log4net
{
    /// <summary>
    /// 日志助手类
    /// </summary>
    internal class LogHelper
    {
        private static ILog InfoLog = LogManager.GetLogger("InfoLog");
        private static ILog ErrorLog = LogManager.GetLogger("ErrorLog");

        //Debug Info Warn Error方法 在日志里体现在日志级别上

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="message">日志信息</param>

      public static void WriteInfoLog(string message)
      {
        InfoLog.Info(AppendClassLine(message));
      }

/// <summary>
        /// 写错误日志
        /// </summary>
        /// <param name="message">日志信息</param>
        public static void WriteErrorLog(string message)
        {
            ErrorLog.Error(AppendClassLine(message));
        }

        /// <summary>
        /// 给日志信息附加所在文件名和行
        /// </summary>
        /// <param name="msg">日志信息</param>
        /// <returns>附加后的日志信息</returns>
        static string AppendClassLine(string msg)
        {
            string logStr = msg;
            try
            {
                //测试了一下这个new StackTrace(true) 10w次耗时1.3秒,性能可以接收啊
                //这个原理是读pdb文件,也许大项目读这个文件会更耗时
                StackTrace st = new StackTrace(true);
                StackFrame sf = st.GetFrame(2);
                logStr = $"{msg} [{Path.GetFileName(sf.GetFileName())}:{sf.GetFileLineNumber().ToString()}]";
            }
            catch
            {
                logStr = $"{msg} [没找到文件名和所在行]";
            }
            return logStr;
        }
    }
}
复制代码

这里的new StackTrace(true)性能测试代码如下

复制代码
using System;
using System.Diagnostics;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            const int iterations = 100000;

            // 测试 new StackTrace(false) 的性能
            var stopwatch1 = Stopwatch.StartNew();
            for (int i = 0; i < iterations; i++)
            {
                var stackTrace = new StackTrace(false);
            }
            stopwatch1.Stop();
            Console.WriteLine($"new StackTrace(false) 耗时: {stopwatch1.ElapsedMilliseconds} 毫秒");

            // 测试 new StackTrace(true) 的性能
            var stopwatch2 = Stopwatch.StartNew();
            for (int i = 0; i < iterations; i++)
            {
                var stackTrace = new StackTrace(true);
            }
            stopwatch2.Stop();
            Console.WriteLine($"new StackTrace(true) 耗时: {stopwatch2.ElapsedMilliseconds} 毫秒");
        }
    }
}
复制代码

4.日志调用

复制代码
using TestLog4net.Log4net;

namespace TestLog4net
{
    internal class Program
    {
        static void Main(string[] args)
        {
            LogHelper.WriteInfoLog("info日志");
            LogHelper.WriteErrorLog("error日志");
        }
    }
}
复制代码

5.日志效果

 

posted @   ckrgd  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
历史上的今天:
2022-02-14 C# 读写opc ua服务器,浏览所有节点,读写节点,读历史数据,调用方法,订阅,批量订阅操作(转载)
2022-02-14 使用KEPServerv6进行OPC_UA的服务器搭建(转载)
点击右上角即可分享
微信分享提示