zoukankan      html  css  js  c++  java
  • Log4net记录日志到本地或数据库

    OperatorLog

    /****** Object:  Table [dbo].[OperatorLog]    Script Date: 
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TABLE [dbo].[OperatorLog](
        [Id] [BIGINT] IDENTITY(1,1) NOT NULL,
        [Createdate] [DATETIME] NOT NULL DEFAULT (GETDATE()),
        [CreatedBy] [NVARCHAR](50) NULL,
        [IsDeleted] [BIT] NOT NULL,
        [ModuleName] [NVARCHAR](30) NULL,
        [Origin] [NVARCHAR](50) NULL,
        [Type] [NVARCHAR](50) NULL,
        [LogLevel] [NVARCHAR](20) NOT NULL,
        [LogMessage] [NVARCHAR](500) NULL,
        [Exception] [NVARCHAR](500) NULL,    
        [Logger] [NVARCHAR](500) NULL
     CONSTRAINT [PK_OperatorLog] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日志表主键ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'Id'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'Createdate'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建人' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'CreatedBy'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否删除' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'IsDeleted'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'模块名称' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'ModuleName'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'来源' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'Origin'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'类型' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'Type'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日志级别' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'LogLevel'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日志内容' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'LogMessage'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'异常信息' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'Exception'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日志名称' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog', @level2type=N'COLUMN',@level2name=N'Logger'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日志记录' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'OperatorLog'
    GO

    loghelper:

    using System;
    using System.ComponentModel;
    using System.IO;
    using log4net;
    using ShiShuo.Utilities;
    
    namespace Log4Net
    {
        public enum LogCategory
        {
            [Description("调试")]
            Debug,
            [Description("信息")]
            Info,
            [Description("警告")]
            Warn,
            [Description("错误")]
            Error,
            [Description("过错")]
            Fault
        }
        public class LogHelper
        {
            private static readonly log4net.ILog infoLogger = log4net.LogManager.GetLogger("loginfo");     //选择<logger name="loginfo">的配置 
            private static readonly log4net.ILog errorLogger = log4net.LogManager.GetLogger("logerror");   //选择<logger name="logerror">的配置 
            private static readonly log4net.ILog warnLogger = log4net.LogManager.GetLogger("logwarn");     //选择<logger name="logwarn">的配置 
            private static readonly log4net.ILog debugLogger = log4net.LogManager.GetLogger("logdebug");   //选择<logger name="logdebug">的配置 
            private static OperatorLogModel logEntity;
            public static string CreatedBy = String.Empty;
            
            static LogHelper()
            {
                string configPath = Path.Combine(PathHelper.ConfigDir, "log4net.xml");
                if (!File.Exists(configPath))
                {
                    throw new FileNotFoundException("找不到日志服务配置文件!");
                }
                log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(configPath));
            }
    
            /// <summary>
            /// 记录log信息到文件中  LogHelper.Log("检测更新启动时异常", LogCategory.Error, ex);    LogHelper.Log(ex);
            /// </summary>
            /// <param name="message">需要记录的信息</param>
            /// <param name="category">log类型</param>
            /// <param name="exception">异常信息</param>
            public static void Log(string message, LogCategory category, Exception exception = null)
            {
                try
                {
                    switch (category)
                    {
                        case LogCategory.Debug:
                            {
                               
                                debugLogger.Debug(BuildMessageMode(message));
                                break;
                            }
                        case LogCategory.Info:
                            {
                                infoLogger.Info(BuildMessageMode(message));
                                break;
                            }
                        case LogCategory.Warn:
                            {
                                if (null == exception)
                                {
                                    warnLogger.Warn(BuildMessageMode(message));
                                }
                                else
                                {
                                    warnLogger.Warn(BuildMessageMode(message), exception);
                                }
                                break;
                            }
                        case LogCategory.Error:
                            {
                                if (null == exception)
                                {
                                    errorLogger.Error(BuildMessageMode(message));
                                }
                                else
                                {
                                    errorLogger.Error(BuildMessageMode(message), exception);
                                }
                                break;
                            }
                    }
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
    
            /// <summary>
            /// 构造消息实体
            /// </summary>
            /// <param name="message"></param>
            /// <returns></returns>
            private static OperatorLogModel BuildMessageMode(string message) {
                if (logEntity == null) {
                    logEntity = new OperatorLogModel();
                    logEntity.Createdate = DateTime.Now;
                    logEntity.CreatedBy = CreatedBy;
                    logEntity.IsDeleted = false;
                    logEntity.LogMessage = message;
                }
                else
                    logEntity.LogMessage = message;
    
                return logEntity;
            }
    
            /// <summary>
            /// 写基本信息日志
            /// </summary>
            /// <param name="mesage"></param>
            public static void Log(string mesage)
            {
                Log(mesage, LogCategory.Info, null);
            }
    
            /// <summary>
            /// 出错信息日志
            /// </summary>
            /// <param name="exception"></param>
            public static void Log(Exception exception)
            {
                Log($"error message:{exception.Message}", LogCategory.Error, exception);
            }
    
        }
    }

    pathhelper:

    using System;
    using System.IO;
    using System.Reflection;
    
    namespace ShiShuo.Utilities
    {
        public static class PathHelper
        {
            private static readonly string _appDir;
            private static readonly string _configDir;
            private static readonly string _dataDir;
            static PathHelper()
            {
                //网站与后台服务路径不同,网站需要上翻一级;后台服务则不需要;通过判断使用的配置文件是否是web.config来判断是网站,还是服务。
                bool isWeb = false;
                var appDomain = AppDomain.CurrentDomain;
    
                if (appDomain != null)
                {
                    var startInfo = appDomain.SetupInformation;
                    if (startInfo != null)
                    {
                        if (startInfo.ConfigurationFile != null)
                        {
                            if (startInfo.ConfigurationFile.EndsWith("web.config", StringComparison.OrdinalIgnoreCase))
                            {
                                isWeb = true;   //配置文件是网站
                            }
                        }
                    }
                }
                _appDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Substring(8))); //获取此处配置文件在程序目录
                //_appDir = _appDir.Substring(0, _appDir.Length - 4);
    
                if (isWeb)
                {
                    _appDir = _appDir.Substring(0, _appDir.LastIndexOf("\", StringComparison.Ordinal));  // LastIndexOf("\") => LastIndexOf(@""),向上翻一级
                }
                _configDir = Path.Combine(_appDir, "Config\");
                _dataDir = Path.Combine(_appDir, "App_Data\");
            }
            #region 公共目录
            /// <summary>
            /// 应用程序所在的目录
            /// </summary>
            public static string AppDir => _appDir;
    
            /// <summary>
            /// 根目录中的Cinfig文件夹
            /// </summary>
            public static string ConfigDir => _configDir;
    
            /// <summary>
            /// 根目录中的App_Data文件夹
            /// </summary>
            public static string DataDir => _dataDir;
    
            #endregion
        }
    }

    MyLayout:

    using log4net.Layout;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Log4Net {
        public class MyLayout : PatternLayout {
            public MyLayout() {
                this.AddConverter("property", typeof(MyPatternConverter));
            }
        }
    }

    MyPatternConverter:

    using log4net.Layout.Pattern;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    
    namespace Log4Net {
        public class MyPatternConverter : PatternLayoutConverter {
            protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent) {
                if (Option != null)
                    WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
                else
                    WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
            }
    
            //通过反射获取传入的日志对象的某个属性的值
            private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent) {
                object propertyvalue = string.Empty;
                PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
    
                if (propertyInfo != null)
                    propertyvalue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
                return propertyvalue;
            }
        }
    }

    log4net.xml

    <?xml version="1.0" encoding="utf-8"?>
    <log4net debug="false">
    
      <!--错误日志配置-->
      <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="./Log/Error/" />
        <param name="Encoding" value="utf-8"/>
        <param name="AppendToFile" value="true" />
        <param name="MaxSizeRollBackups" value="100" />
        <param name="MaxFileSize" value="10240" />
        <!--设置单个文件大小,设置文件名使用组合方式-->
        <param name="MaximumFileSize" value="100MB"/>
        <!--最小锁定模型以允许多个进程可以写入同一个文件-->
        <param name="lockingModel"  type="log4net.Appender.FileAppender+MinimalLock" />
        <param name="StaticLogFileName" value="false" />
        <param name="DatePattern" value="&quot;&quot;yyyyMMdd&quot;.log&quot;" />
        <param name="RollingStyle" value="Composite" />
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="ERROR" />
          <levelMax value="FATAL" />
        </filter>
        <!--<layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%n异常时间:%d [%t] %n异常级别:%-5p %n异 常 类:%c [%x] %n%m %n " />
        </layout>-->
        <layout type="Log4Net.MyLayout">
          <param name="ConversionPattern" value="日志时间:%d [%t] %n日志级别:%-5p %n日志信息:%property{LogMessage} %n异常信息:%exception %n%n"/>
        </layout>
      </appender>
    
      <!--信息日志配置-->
      <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="./Log/Info/" />
        <param name="Encoding" value="utf-8"/>
        <param name="AppendToFile" value="true" />
        <param name="MaxSizeRollBackups" value="100" />
        <param name="MaxFileSize" value="10240" />
        <param name="MaximumFileSize" value="100MB"/>
        <param name="lockingModel"  type="log4net.Appender.FileAppender+MinimalLock" />
        <param name="MaxSizeRollBackups" value="100" />
        <param name="StaticLogFileName" value="false" />
        <param name="DatePattern" value="&quot;&quot;yyyyMMdd&quot;.log&quot;" />
        <param name="RollingStyle" value="Composite" />
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="DEBUG" />
          <levelMax value="WARN" />
        </filter>
        <!--<layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%n异常时间:%d [%t] %n异常级别:%-5p %n异 常 类:%c [%x] %n%m %n " />
        </layout>-->
        <layout type="Log4Net.MyLayout">
          <param name="ConversionPattern" value="日志时间:%d [%t] %n日志级别:%-5p %n日志信息:%property{LogMessage} %n异常信息:%exception %n%n"/>
        </layout>
      </appender>
    
      <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
        <bufferSize value="1" />
        <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <connectionString value="Data Source=.sql2014;Initial Catalog=FirstVueAdminDB;Persist Security Info=True;User ID=sa;Password=Aa123456;MultipleActiveResultSets=True;"/>
        <commandText value="INSERT INTO OperatorLog(Createdate,CreatedBy,IsDeleted,ModuleName,Origin,Type,LogLevel,LogMessage,Exception,Logger) VALUES(@Createdate,@CreatedBy,@IsDeleted,@ModuleName,@Origin,@Type,@LogLevel,@LogMessage,@Exception,@logger)" />
        <parameter>
          <parameterName value="@Createdate" />
          <dbType value="DateTime" />
          <layout type="log4net.Layout.RawTimeStampLayout" />
        </parameter>
        <parameter>
          <parameterName value="@CreatedBy" />
          <dbType value="String" />
          <size value="50" />
          <layout type="Log4Net.MyLayout" >
            <conversionPattern value = "%property{CreatedBy}"/>
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@IsDeleted" />
          <dbType value="String" />
          <size value="50" />
          <layout type="Log4Net.MyLayout" >
            <conversionPattern value = "%property{IsDeleted}"/>
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@ModuleName" />
          <dbType value="String" />
          <size value="30" />
          <layout type="Log4Net.MyLayout" >
            <conversionPattern value = "%property{ModuleName}"/>
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@Origin" />
          <dbType value="String" />
          <size value="50" />
          <layout type="Log4Net.MyLayout" >
            <conversionPattern value = "%property{Origin}"/>
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@Type" />
          <dbType value="String" />
          <size value="50" />
          <layout type="Log4Net.MyLayout" >
            <conversionPattern value = "%property{Type}"/>
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@LogLevel" />
          <dbType value="String" />
          <size value="20" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%p" />
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@LogMessage" />
          <dbType value="String" />
          <size value="500" />
          <layout type="Log4Net.MyLayout">
            <conversionPattern value="%property{LogMessage}" />
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@Exception"/>
          <dbType value="String"/>
          <size value="500"/>
          <layout type="log4net.Layout.ExceptionLayout"/>
        </parameter>
        <parameter>
          <parameterName value="@logger" />
          <dbType value="String" />
          <size value="500" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%logger" />
          </layout>
        </parameter>
      </appender>
    
      <!--log4net.LogManager.GetLogger("logerror")用这个来选择这种类型-->
      <!--<logger name="logerror">
        <level value="ERROR" />
        <appender-ref ref="ErrorAppender" />
      </logger>
      <logger name="loginfo">
        <level value="INFO" />
        <appender-ref ref="InfoAppender" />
      </logger>
      <logger name="logwarn">
        <level value="WARN"/>
        <appender-ref ref="WarningAppender"/>
      </logger>
      <logger name="logdebug">
        <level value="DEBUG"/>
        <appender-ref ref="DebugAppender"/>
      </logger>
      -->
      <!--<logger name="logexceptionless">
          <level value="INFO"/>
          <appender-ref ref="Exceptionless"/>
        </logger>-->
      <root>
        <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
        <!--比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录-->
        <!--如果没有定义LEVEL的值,则缺省为DEBUG-->
        <level value="ALL" />
        <!--根据log级别记录到不同的日志文件-->
        <!--文件形式记录日志-->
        <appender-ref ref="InfoAppender"/>
        <appender-ref ref="ErrorAppender" />
        <appender-ref ref="ADONetAppender" />
     
      </root>
    
    </log4net>

    log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局).

    Log4net框架定义了一个ILog接口,所有的logger类都必须实现这个接口。如果你想实现一个自定义的logger,你必须首先实现这个接口。你可以参考在/extension目录下的几个例子。

    log4net.Layout.PatternLayout中的转换模式(ConversionPattern)

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

    %n(new line):换行

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

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

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

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

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

           模式字符串为:%-10c -%m%n

           代码为:

    ILog log=LogManager.GetLogger(“Exam.Log”);

    log.Debug(“Hello”);

        则输出为下面的形式:

    Exam.Log       - Hello

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

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

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

    Logger

    作用:直接与应用交互的组件,用于触发日志事件

    级别(日志事件) 优先级
    OFF                    6
    FATAL       5
    ERROR      4
    WARN        3
    INFO          2
    DEBUG       1
    ALL            0

    其他参考

    http://www.cnblogs.com/zhangchenliang/p/4546352.html 

    http://www.cnblogs.com/RainbowInTheSky/p/5914766.html    自定义记录日志

    https://www.cnblogs.com/maijin/p/4618435.html
    https://www.cnblogs.com/zhihaospace/p/8419946.html
    https://blog.csdn.net/kongwei521/article/details/52242319
    https://blog.51cto.com/790381375/1742018
    https://www.cnblogs.com/izreo/p/5651139.html

  • 相关阅读:
    Web For Pentester 学习笔记
    Vulhub Docker环境部署
    XSS 渗透思路笔记
    文件上传Upload 漏洞挖掘思路
    文件上传Upload 学习笔记
    XCTF-WEB-高手进阶区-upload1-笔记
    XCTF-WEB-高手进阶区-PHP2-笔记
    XCTF-WEB-高手进阶区-NaNNaNaNNaN-Batman-笔记
    XCTF-WEB-高手进阶区-Web_python_template_injection-笔记
    用JavaScript制作简单的计算器
  • 原文地址:https://www.cnblogs.com/shy1766IT/p/5384762.html
Copyright © 2011-2022 走看看