Log4net 自定义错误输出

最近再做一个项目,需要跟踪错误日志。之前一直保存在txt文件中,但是由于部署服务器我们没有访问的权限。很无奈,必须得把错误日志写入数据库(还必须得加入自定义错误,比如是哪一个数据库)。由于之前没有使用过,所有参考了园子中很多大神的作品。。。不知为何,没有调通一个。觉定参考大神的作品自己写。。代码如下。

1.自定义错误模型

/// <summary>
    /// 自定义错误信息模型
    /// </summary>
    public class LogMessage
    {
        /// <summary>
        /// 错误类名
        /// </summary>
        public string ErrorClass { get; set; }


        /// <summary>
        /// 错误方法名
        /// </summary>
        public string ErrorFunction { get; set; }


        /// <summary>
        /// 堆栈信息
        /// </summary>
        public string ExceptionInfo { get; set; }


        /// <summary>
        /// 数据库连接串
        /// </summary>
        public string DbConString
        {
            get;
            set;
        }
    }

2部分说明,由于log4net 中 异常信息message如果你传入一个对象的时候,日志输出后会变成它的全命名,无法查看当前的错误的堆栈信息,所以定义了ExceptionInfo .

 /// <summary>
    /// 异常信息模型转换
    /// </summary>
    internal sealed class ExceptionInfoPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            var logMessage = loggingEvent.MessageObject as LogMessage;
            if (logMessage != null)
                writer.Write(logMessage.ExceptionInfo);
        }
    }

该类继承自log4net 的PatternLayoutConverter,这儿也不打理解,看其中的方法,应该是和写入信息有关.

3. 添加布局

/// <summary>
    /// 自定义输出布局
    /// </summary>
    public class CustomLayout : log4net.Layout.PatternLayout
    {
        public CustomLayout()
        {
            AddConverter("ErrorClass", typeof(ErrorClassPatternConverter));
            AddConverter("ErrorFunction", typeof(ErrorFunctionPatternConverter));
            AddConverter("ExceptionInfo", typeof(ExceptionInfoPatternConverter));
            AddConverter("DbConString", typeof(DbConStringPatternConverter));
        }
    }


4.以下是我对日志写入的方法的封装



    /// <summary>
    /// 日志写入帮助类
    /// </summary>
    public class LogRecord
    {
        #region 日志以及字段
        private static log4net.ILog _log = null;
        private static LogMessage _message = new LogMessage();
        public static string LoggerName = string.Empty;
        private static ILog Log
        {
            get
            {
                //todo 读取配置文件 
                //string path = "d:\app.config";
                //log4net.Config.XmlConfigurator.Configure(new FileInfo(path));
                // log4net.Config.XmlConfigurator.Configure();
                if (_log == null)
                {
                    //从配置文件中读取Logger对象  
                    //WebLogger 里面的配置信息是用来将日志录入到数据库的
                    _log = log4net.LogManager.GetLogger(LoggerName);
                }
                else
                {
                    if (_log.Logger.Name != LoggerName)
                    {
                        _log = log4net.LogManager.GetLogger(LoggerName);
                    }
                }
                return _log;
            }
        }
        #endregion


        #region 日志方法
        /// <summary>
        /// 调试
        /// </summary>
        private static void Debug()
        {
            if (Log.IsDebugEnabled)
            {
                Log.Debug(_message);
            }
        }


        /// <summary>
        /// 记录一般日志
        /// </summary>
        private static void Info()
        {
            if (Log.IsInfoEnabled)
            {
                //log.Info("Jerry");
                Log.Info(_message);
            }
        }


        /// <summary>
        /// 记录警告
        /// </summary>
        private static void Warn()
        {
            if (Log.IsWarnEnabled)
            {
                Log.Warn(_message);
            }
        }




        /// <summary>
        /// 错误
        /// </summary>
        private static void Error()
        {
            if (Log.IsErrorEnabled)
            {
                Log.Error(_message);
            }
        }


        /// <summary>
        /// 严重错误
        /// </summary>
        private static void Fatal()
        {
            if (Log.IsFatalEnabled)
            {
                Log.Fatal(_message);
            }
        }


        #endregion


        #region 保存日志的方法 重载


        /// <summary>  
        /// 需要写日志的地方调用此方法  
        /// </summary>
        /// <param name="logMessage"></param>
        /// <param name="level">自定义级别</param>
        /// <param name="waytype"></param>  
        public static void SaveMessage(LogMessage logMessage, LevelType level, WriteWayType waytype = WriteWayType.Oracle)
        {
            _message = logMessage;
            LoggerName = waytype.ToString();
            Execute(level);
        }


        /// <summary>
        /// 保存日志信息
        /// </summary>
        /// <param name="className">类名</param>
        /// <param name="msg">异常(提示)信息</param>
        /// <param name="waytype"></param>
        /// <param name="level">日志级别 默认Error</param>
        public static void SaveMessage(string className, string msg, WriteWayType waytype = WriteWayType.Oracle, LevelType level = LevelType.Error)
        {
            _message.ErrorClass = className;
            _message.ExceptionInfo = msg;
            LoggerName = waytype.ToString();
            Execute(level);
        }


        /// <summary>
        /// 保存日志信息
        /// </summary>
        /// <param name="className">类名</param>
        /// <param name="funtionName">方法名称</param>
        /// <param name="msg">异常(提示)信息</param>
        /// <param name="waytype"></param>
        /// <param name="level">日志级别 默认Error</param>
        public static void SaveMessage(string className, string funtionName, string msg, WriteWayType waytype = WriteWayType.Oracle, LevelType level = LevelType.Error)
        {
            _message.ErrorClass = className;
            _message.ErrorFunction = funtionName;
            _message.ExceptionInfo = msg;
            LoggerName = waytype.ToString();
            Execute(level);
        }


        /// <summary>
        /// 保存日志信息
        /// </summary>
        /// <param name="className">类名</param>
        /// <param name="funtionName">方法名称</param>
        /// <param name="msg">异常(提示)信息</param>
        /// <param name="dbConString">数据库连接字符串</param>
        /// <param name="waytype">默认写入数据库</param>
        /// <param name="level">日志级别 默认Error</param>
        public static void SaveMessage(string className, string funtionName, string msg, string dbConString, WriteWayType waytype = WriteWayType.Oracle, LevelType level = LevelType.Error)
        {
            _message.ErrorClass = className;
            _message.ErrorFunction = funtionName;
            _message.ExceptionInfo = msg;
            _message.DbConString = dbConString;
            LoggerName = waytype.ToString();
            Execute(level);
        }


        #endregion


        #region 执行方法
        /// <summary>
        /// 执行不同类别的方法
        /// </summary>
        /// <param name="level"></param>
        static void Execute(LevelType level)
        {
            switch (level)
            {
                case LevelType.Debug:
                    Debug();
                    break;


                case LevelType.Info:
                    Info();
                    break;
                case LevelType.Warn:
                    Warn();
                    break;
                case LevelType.Error:
                    Error();
                    break;
                case LevelType.Fatal:
                    Fatal();
                    break;
                default: break;
            }
        }
        #endregion
    }


5.log4net 的配置 (我所使用的)一是直接写入引用改组件的配置文件中.2,在当前类库中添加配置文件app.config.

再这我使用的是第二种,原因是再部署的时候在项目配置中以防更改配置文件引发错误.但是在生成后直接引用会抛出异常.没有找到配置信息.解决方法是在当前类库项目下的AssemblyInfo.cs文件中添加[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "config", Watch = true)] .会在你的类库生成时生成一个"类库名+dll.config"的配置文件.只要将其放在引用项目下即可.配置如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<log4net>
<root>
<level value="INFO"></level>
</root>
<logger name="File">
<appender-ref ref="RollingFileAppender"/>
<level value="ALL"/>
</logger>
<logger name="Oracle">
<level value="ALL"/>
<appender-ref ref="ADONetAppender_Oracle"/>
</logger>
<!--Oracle数据库-->
<appender name="ADONetAppender_Oracle" type="log4net.Appender.ADONetAppender">
<!--缓存-->
<bufferSize value="1"/>
<!-- SQL数据源 ,本地安装SQL客户端-->
<connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient
,Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<!-- SQL连接字符串-->
<connectionString value="Oracle连接字符串" />
<!--sql语句-->
<commandText value="INSERT INTO log_record_tb(id,RecordTime,thread,RECORDLEVEL,ERRORCLASS,ERRORFUNCTION,Message,DbConString)
VALUES (seq_log_record_tb.nextval,:log_date,:thread,:log_level,:ERRORCLASS,:ErrorFunction,:ExceptionInfo,:DbConString)"/>
<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=":ErrorClass" />
<dbType value="String" />
<size value="200"/>
<layout type="LogRecordBySwt.CustomLayout">
<conversionPattern value="%ErrorClass" />
</layout>
</parameter>
<parameter>
<parameterName value=":ErrorFunction" />
<dbType value="String" />
<size value="200"/>
<layout type="LogRecordBySwt.CustomLayout">
<conversionPattern value="%ErrorFunction" />
</layout>
</parameter>
<parameter>
<parameterName value=":ExceptionInfo" />
<dbType value="String" />
<size value="4000"/>
<layout type="LogRecordBySwt.CustomLayout">
<conversionPattern value="%ExceptionInfo" />
</layout>
</parameter>
<parameter>
<parameterName value=":DbConString" />
<dbType value="String" />
<size value="200"/>
<layout type="LogRecordBySwt.CustomLayout">
<conversionPattern value="%DbConString" />
</layout>
</parameter>
</appender>
<!--文本文件-->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<!--当前安装目录下-->
<param name="File" value="log\" />
<param name="AppendToFile" value="true" />
<param name="MaxFileSize" value="10240" />
<param name="MaxSizeRollBackups" value="100" />
<param name="StaticLogFileName" value="false" />
<param name="DatePattern" value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
<param name="RollingStyle" value="Date" />
<layout type="LogRecordBySwt.CustomLayout">
<param name="ConversionPattern" value="[日志时间:%d]%n[线程ID:[%t]][日志级别:%-5p]%n[出错类:%ErrorClass][出错方法:%ErrorFunction]%n[异常信息:%ExceptionInfo]%n[数据库连接串:%DbConString]%n%n" />
</layout>
</appender>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

6.最后新建测试项目

static void Main(string[] args)
        {


            var ds = new DataSet();
             try
            {
                if (ds.Tables[0] == null)
                {


                }
            }
            catch (Exception ex)
            {
                LogRecord.SaveMessage("Program"
                    , "main"
                    , ex.Message + ex.StackTrace
                    , WriteWayType.Oracle
                    , LevelType.Info);
            }
        }测试通过. 

问题总结,刚开始测试,一直没有写入数据库,查了很多园子中的.主要是配置文件写的不规范.....由于也是第一次写,可能会很乱.还请给我多多指点.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值