当前位置:网站首页>log4net使用指南(winform版,sqlserver记录)

log4net使用指南(winform版,sqlserver记录)

2022-08-09 11:09:00 一头小驴

参照自:
1,apache官网 这个一定是你入门的最好教材 点击进入
2,C#使用log4net记录日志     https://www.cnblogs.com/kliine/p/10950859.html
3,非常完整的log4net详细说明     https://blog.csdn.net/binnygoal/article/details/79557746
4,C#一个完整的Log4net使用实例 https://blog.csdn.net/dnazhd/article/details/89555517

1,谈谈使用步骤和流程

log4net是.Net下一个非常优秀的开源日志记录组件。步骤如下:
1,visual studio中通过Nuget安装log4net。
2,CS程序,根目录的Program.cs的Main方法中添加log4net.Config.XmlConfigurator.Configure();
BS程序,根目录的Global.asax.cs(没有新建一个)中的Application_Start方法中添加:
log4net.Config.XmlConfigurator.Configure();
无论BS还是CS程序都可直接在项目的AssemblyInfo.cs文件里添加以下的语句:
[assembly: log4net.Config .XmlConfigurator()]
代码中我在AssemblyInfo.cs文件中添加如下:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", ConfigFileExtension = "config", Watch = true)]
3,创建log4net.config文件,并配置文件属性》复制到输出目录》如果较新则复制
4,在程序中使用语法

log4net.ILog log = log4net.LogManager.GetLogger("testApp.Logging");//获取一个日志记录器

log.Info("hello,这是一条日志");

2,主要知识点

Filters

DenyAllFilter 阻止所有的日志事件被记录

LevelMatchFilter 只有指定等级的日志事件才被记录

LevelRangeFilter 日志等级在指定范围内的事件才被记录

LoggerMatchFilter 与Logger名称匹配,才记录

PropertyFilter 消息匹配指定的属性值时才被记录

StringMathFilter 消息匹配指定的字符串才被记录

日志级别
OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL

输出样式总结

%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息

%n(new line):换行

%d(datetime):输出当前语句运行的时刻

%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数

%t(thread id):当前语句所在的线程ID

%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等

%c(class):当前日志对象的名称

%L:输出语句所在的行号

%F:输出语句所在的文件名

%-数字:表示该项的最小长度,如果不够,则用空格填充

3,一个具体的winform例子

最好的干货就是最凝练的代码,如下,亲测可跑,.net4.5
form1窗体:

public partial class Form1 : Form   
    {
       private static readonly log4net.ILog  loginfoDb = LogFactory.GetLogger("loginfoDb");
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string a = "FF";
                int b = Convert.ToInt32(a);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex.Message.ToString(), ex);
                string tempmsg = ex.Message.ToString() + "/r/n" + ex.Source.ToString() + "/r/n" + ex.TargetSite.ToString() + "/r/n" + ex.StackTrace.ToString();
                if (loginfoDb.IsInfoEnabled)
                {
                    Task.Run(()=> { loginfoDb.Info(tempmsg, ex); });
                }
            }
        }
    }

LogHelper类


using log4net;
using log4net.Config;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp1.Helper
{
    public class LogHelper
    {
        public static readonly log4net.ILog loginfo = log4net.LogManager.GetLogger("loginfo");//这里的 loginfo 和 log4net.config 里的名字要一样
        //public static readonly log4net.ILog loginfoDb = log4net.LogManager.GetLogger("loginfoDb");//这里的 loginfoDb 和 log4net.config 里的名字要一样

        public static readonly log4net.ILog logerror = log4net.LogManager.GetLogger("logerror");//这里的 logerror 和 log4net.config 里的名字要一样
        
        public static void WriteLog(string info)
        {
            if (loginfo.IsInfoEnabled)
            {
                loginfo.Info(info);
            }
        }

        public static void WriteLog(string info, Exception ex)
        {
            if (logerror.IsErrorEnabled)
            {
                Task.Run(() => logerror.Error(info, ex));   //异步
                //Task.Factory.StartNew(() => logerror.Error(info, ex));//  这种异步也可以
            }
            if (loginfo.IsInfoEnabled)
            {
                loginfo.Info(info,ex);//同步处理
            }
            //if (loginfoDb.IsInfoEnabled)
            //{
            //    loginfoDb.Info(info, ex);
            //}
            //loginfo.Debug("开始调试");
            //loginfo.Info("这是一个消息");
            //loginfo.Warn("这是一个警告");
            //loginfo.Error("Error", new Exception("这是一个异常"));
        }
    }
    public static class LogFactory
    {
        public const string Log4NetConfig = "log4net.config";

        public static ILog GetLogger(string logger)
        {
            var uri = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase), Log4NetConfig));
            var configFile = new FileInfo(Path.GetFullPath(uri.LocalPath));
            XmlConfigurator.ConfigureAndWatch(configFile);
            ILog log = LogManager.GetLogger(logger);
            return log;
        }
    }
}

log4net.config文件:然后的话就是RollingFileAppender 内部有设置文件大小的,其实这里写的是每天一个文件,根据年月日命名文件。可能不怎么需要文件大小的设置,你设置了也不一定起作用。RollingFileAppender 配置具体可以看。Log4net中的RollingFileAppender解析

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <!-- Level的级别,由高到低 -->
  <!-- None > Fatal > ERROR > WARN > DEBUG > INFO > ALL-->
  <!-- 解释:如果level是ERROR,则在cs文件里面调用log4net的info()方法,则不会写入到日志文件中-->
  <log4net debug="false" update="Merge" threshold="ALL">
    <!--root,所有的logger都继承自root-->
    <root >
      <level value="ALL" />
      <appender-ref ref="AdoNetAppender"/>
    </root>
    <!--错误日志类-->
    <logger name="logerror" additivity="false">
      <!--日志类的名字-->
      <level value="ERROR" />
      <!--定义记录的日志级别-->
      <appender-ref ref="ErrorAppender" /><!--这里你是可以添加多个appender的,从而输出到多个介质-->
      <!--记录到哪个介质中去-->
    </logger>
    <!--信息日志类-->
    <logger name="loginfo">
      <level value="INFO" />
      <appender-ref ref="InfoAppender" />
    </logger>
    <!--信息日志类 数据库-->
    <logger name="loginfoDb">
      <level value="INFO" />
      <level value="ERROR" />
      <appender-ref ref="AdoNetAppender"/>
    </logger>
    <!--错误日志附加介质  文本文件-->
    <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
      <threshold value="Error"/>
      <!-- name属性指定其名称,type则是log4net.Appender命名空间的一个类的名称,意思是,指定使用哪种介质-->
      <param name="File" value="Log\\LogError\\" />
      <!--日志输出到exe程序这个相对目录下-->
      <param name="AppendToFile" value="true" />
      <!--输出的日志不会覆盖以前的信息   是否追加到文件-->
      <param name="MaxSizeRollBackups" value="100" />
      <!--备份文件的个数-->
      <param name="MaxFileSize" value="10240" />
      <!--当个日志文件的最大大小-->
      <param name="StaticLogFileName" value="false" />
      <!--是否使用静态文件名  日志文件名,是否固定不变 -->
      <param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" />
      <!--日志文件名  生成格式;每天生成一个日志-->
      <param name="RollingStyle" value="Date" />
      <!--文件创建的方式,这里是以Date方式创建-->
      
      <!--错误日志布局-->
      <layout type="log4net.Layout.PatternLayout">
      
        <param name="ConversionPattern" value="
               %n &#xA;====================================================&#xA;
               %n &#xA;======================开始==========================&#xA;
               %n【异常时间】%d
               %n【日志级别】%-5level
               %n【记录时间】%date
               %n【线程编号】[%thread]
               %n【执行时间】[%r]毫秒
               %n【出错文件】%F
               %n【异 常 类】%c 
               %n【出错行号】%L
               %n【出错的类】%logger 属性[%property{NDC}]
               %n【错误描述】%message
               %n【错误详情】%newline"/>
        <!--<param name="Header" value="&#xA;========header============&#xA;"/>-->
        <!--<param name="Header" value="&#xA;========日志文件Header========xA;"/>-->
       
      </layout>
    </appender>
    <!--信息日志附加介质  文本文件-->
    <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
      <threshold value="Info"/>
      <!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <!--使用Unicode编码-->
      <Encoding value="UTF-8" />
      <!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数-->
      <param name="MaxSizeRollBackups" value="10" />
      <param name="File" value="Log\\LogInfo\\" />
      <param name="AppendToFile" value="true" />
    
      <!--是否只写到一个文件中-->
      <param name="StaticLogFileName" value="false" />
      <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
      <param name="RollingStyle" value="Date" />
      <!--按日期产生文件的文件名格式-->
      <param name="DatePattern" value="yyyyMMdd&quot;.htm&quot;" />
      <!--此处按日期产生文件夹,文件名固定。注意&quot; 的位置<param name="DatePattern" value="yyyy-MM-dd/&quot;ReflectionLayout.log&quot;"  />
      这是按日期产生文件夹,并在文件名前也加上日期 <param name="DatePattern" value="yyyyMMdd/yyyyMMdd&quot;-TimerServer.log&quot;"  />
      这是先按日期产生文件夹,再形成下一级固定的文件夹<param name="DatePattern" value="yyyyMMdd/&quot;TimerServer/TimerServer.log&quot;"  />-->
      <!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。
      可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
      <param name="maximumFileSize" value="500KB" />
      <param name="MaxFileSize" value="10240" />
      <!--计数类型为1,2,3…-->
      <!--<param name="CountDirection" value="1"/>-->
      <!--信息日志布局-->
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="&lt;HR COLOR=blue&gt;%n日志时间:%d [%t] &lt;BR&gt;%n日志级别:%-5p &lt;BR&gt;%n日 志 类:%c [%x] &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />
      </layout>
    </appender>
    <!--信息日志附加介质  数据库文件-->
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="1" /><!--或者写成<param name="BufferSize" value="10" />-->
      <threshold value="Info"/><!--log when >= Fatal  然后你就会发现很多日志都无法记录了 -->
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <connectionString value="data source=.;initial catalog=log4netdemo;integrated security=false;persist security info=True;User ID=sa;Password=123456" />
      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%thread" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
      <!--过滤器-->
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="WARN" />
      </filter>
    </appender>
  </log4net>
</configuration>

创建数据表的sql (db名称为log4netdemo)

CREATE TABLE [dbo].[Log] (
    [Id] [int] IDENTITY (1, 1) NOT NULL,
    [Date] [datetime] NOT NULL,
    [Thread] [varchar] (255) NOT NULL,
    [Level] [varchar] (50) NOT NULL,
    [Logger] [varchar] (255) NOT NULL,
    [Message] [varchar] (4000) NOT NULL,
    [Exception] [varchar] (2000) NULL
)

日志记录效果如下:(cs端我们要记录客户端的登录信息,还有一些重大服务端错误信息?)

sql server的如下:
在这里插入图片描述
txt的如下:
在这里插入图片描述
html的如下:
在这里插入图片描述
那么常用的输出格式我们大概都涉猎了,而且html格式的还是比较美观的吧。而且日志的话我们往往每天单独的一个文件。
其他类型config的配置可以看:apache log4net官网 https://logging.apache.org/log4net/release/config-examples.html

原网站

版权声明
本文为[一头小驴]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_37326058/article/details/105326199