Log4net的简单扩展

一、通过重写布局Layout输出传入的 message对象的属性

1、重写Layout类

通过继承log4net.Layout.PatternLayout类,使用log4net.Core.LoggingEvent类的方法得到了要输出的message类的名称,然后通过反射得到各个属性的值,使用PatternLayout类AddConverter方法传入得到的值。


2、配置相应的配置文件

配置文件其他地方不用改动,只是需要改动中的。例如:

<layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
    <param name="ConversionPattern" value="记录时间:%date    操作者ID:%property{Operator}操作类型:%property{Action}%n  消息描述:%property{Message}%n异常:%exception%n " />
</layout>

其中layout的type由原来的log4net.Layout.PatternLayout换为自定义的TGLog.ExpandLayout2.ReflectionLayout(TGLog.ExpandLayout2为命名空间)。%property{Operator}输出的即为message类对象的属性Operator的值。数据库配置同样,相应的字段如果是自定义的,则输出选用自定义的layout。例:

<!--动作类型-->
<parameter>
    <parameterName value="@action_type" />
    <dbType value="Int16" />
    <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
        <conversionPattern value="%property{ActionType}" />
    </layout>
</parameter>

3、程序中如何使用

和一般使用方法基本相同,只是传入的参数是一个自定义的类,类的属性和配置文件中所有的%property{属性}是一致的,即%property{属性}在输出的时候就查找传入message类中有无对应的属性,如果有就输出值,没有则输出null。例:

log4net.ILog log =log4net.LogManager.GetLogger("ReflectionLayout");
try
{
    log.Debug(new LogMessage(1,"操作对象:0",(int)TGLog.ActionType.Other,"这是四个参数测试"));
}
catch(Exception ec)
{
    log.Error(new LogMessage(1,"操作对象:0",(int)TGLog.ActionType.Other,"这是全部参数测试","192.168.1.1","MyComputer","Maxthon(MyIE2)Fans"),ec);
}

LogMessage的全部属性的构造方法如下:

public LogMessage(
    int operatorID,
    string operand,
    int ActionType,
    string message,
    string ip,
    string machineName,
    string browser)
{
    this.ActionType = ActionType;
    this.Operator = operatorID;
    this.Message = message;
    this.Operand = operand;
    this.IP = ip;
    this.Browser = browser;
    this.MachineName = machineName;
}

二、通过重新实现ILog接口来增加输入的参数

1、重写LogImpl,LogManager类及实现ILog接口

这种方式是通过构造一个名为IMyLog接口,是继承Ilog接口而来,然后分别在MyLogImpl,MyLogManager重新实现IMyLog接口,增加了每种方法的参数。MyLogImpl,MyLogManager分别继承LogImpl,LogManager而来。

代码分别见4.1、4.2、4.3:


2、配置相应的配置文件

配置文件其他地方不用改动,只是需要改动appender中的layout元素name为ConversionPattern的value中输出格式。例如:

<layout type=" log4net.Layout.PatternLayout ">
    <param name="ConversionPattern" value="记录时间:%date    操作者ID:%property{Operator}操作类型:%property{Action}%n  消息描述:%property{Message}%n异常:%exception%n " />
</layout>

%property{参数}中的参数在MyLogImpl类中定义,如语句:

loggingEvent.Properties[“Operator”] = operatorID;

就定义了Operator输出参数,即%property{Operator}输出的即为IMyLog中的参数operatorID的值。

数据库配置同样。例:

<!--动作类型-->
<parameter>
    <parameterName value="@action_type" />
    <dbType value="Int16" />
    <layout type=" log4net.Layout.PatternLayout ">
        <conversionPattern value="%property{ActionType}" />
    </layout>
</parameter>

3、程序中如何使用

先引用IMyLog ,MyLogManager所在的命名空间,创建一个IMyLog对象,myLog的5 个方法,每个方法都有四个重载,增加了多参数的重载。例:

IMyLog myLog = MyLogManager.GetLogger("ExpandILog");
try
{
    myLog.Debug("这是一个参数重载测试!");          
}
catch(Exception ec)
{
    log.Error(1,"操作对象:0",(int)TGLog.ActionType.Other,"这是全部参数测试","192.168.1.1","MyComputer","Maxthon(MyIE2)Fans",ec);
}

4、附录

4.1MyLogImpl类代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net.Core;

namespace TGLog.ExpandILog
{
    public class MyLogImpl : LogImpl, IMyLog
    {
    /// <summary>
    /// The fully qualified name of this declaring type not the type of any subclass.
    /// </summary>
    private readonly static Type ThisDeclaringType = typeof(MyLogImpl);
    public MyLogImpl(ILogger logger): base(logger)
    {       

    }
    #region Implementation of IMyLog
    public void Debug(int operatorID, string operand, int actionType,object message,string ip, string browser, string machineName)
    {
        Debug(operatorID,  operand,  actionType, message,ip,  browser, machineName, null);
    }
    public void Debug(int operatorID, string operand, int actionType,object message,string ip, string browser, string machineName, System.Exception t)
    {
        if (this.IsDebugEnabled)
        {
            LoggingEvent loggingEvent =new LoggingEvent(ThisDeclaringType, Logger.Repository,Logger.Name, Level.Info, message, t);
            loggingEvent.Properties["Operator"] = operatorID;
            loggingEvent.Properties["Operand"] = operand;
            loggingEvent.Properties["ActionType"] = actionType;
            loggingEvent.Properties["IP"] = ip;
            loggingEvent.Properties["Browser"] = browser;
            loggingEvent.Properties["MachineName"] = machineName;
            Logger.Log(loggingEvent);
        }
    }
    public void Info(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName)
    {
        Info(operatorID, operand, actionType, message, ip, browser, machineName, null);
    }
    public void Info(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, System.Exception t)
    {
        if (this.IsInfoEnabled)
        {
            LoggingEvent loggingEvent =new LoggingEvent(ThisDeclaringType, Logger.Repository,Logger.Name, Level.Info, message, t);
            loggingEvent.Properties["Operator"] = operatorID;
            loggingEvent.Properties["Operand"] = operand;
            loggingEvent.Properties["ActionType"] = actionType;
            loggingEvent.Properties["IP"] = ip;
            loggingEvent.Properties["Browser"] = browser;
            loggingEvent.Properties["MachineName"] = machineName;
            Logger.Log(loggingEvent);
        }
    }
    public void Warn(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName)
    {
        Warn(operatorID, operand, actionType, message, ip, browser, machineName, null);
    }
    public void Warn(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, System.Exception t)
    {
        if (this.IsWarnEnabled)
        {
            LoggingEvent loggingEvent =new LoggingEvent(ThisDeclaringType, Logger.Repository,Logger.Name, Level.Info, message, t);
            loggingEvent.Properties["Operator"] = operatorID;
            loggingEvent.Properties["Operand"] = operand;
            loggingEvent.Properties["ActionType"] = actionType;
            loggingEvent.Properties["IP"] = ip;
            loggingEvent.Properties["Browser"] = browser;
loggingEvent.Properties["MachineName"] = machineName;
            Logger.Log(loggingEvent);
            }
        }
        public void Error(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName)
        {
            Error(operatorID, operand, actionType, message, ip, browser, machineName, null);
        }public void Error(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, System.Exception t)
        {
            if (this.IsErrorEnabled)
            {
                LoggingEvent loggingEvent =new LoggingEvent(ThisDeclaringType, Logger.Repository,Logger.Name, Level.Info, message, t);
                loggingEvent.Properties["Operator"] = operatorID;
                loggingEvent.Properties["Operand"] = operand;
                loggingEvent.Properties["ActionType"] = actionType;
                loggingEvent.Properties["IP"] = ip;
                loggingEvent.Properties["Browser"] = browser;
                loggingEvent.Properties["MachineName"] = machineName;
                Logger.Log(loggingEvent);
            }
        }
        public void Fatal(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName)
        {
            Fatal(operatorID, operand, actionType, message, ip, browser, machineName, null);
        }
        public void Fatal(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, System.Exception t)
        {
            if (this.IsFatalEnabled)
            {
                LoggingEvent loggingEvent =new LoggingEvent(ThisDeclaringType, Logger.Repository,Logger.Name, Level.Info, message, t);
                loggingEvent.Properties["Operator"] = operatorID;
                loggingEvent.Properties["Operand"] = operand;
                loggingEvent.Properties["ActionType"] = actionType;
                loggingEvent.Properties["IP"] = ip;
                loggingEvent.Properties["Browser"] = browser;
                loggingEvent.Properties["MachineName"] = machineName;
                Logger.Log(loggingEvent);
            }
        }
    #endregion Implementation of IMyLog
    }
}

4.2 MyLogManager类代码

using System;
using System.Reflection;
using System.Collections;
using log4net;
using log4net.Core;
using log4net.Repository;
using log4net.Repository.Hierarchy;

namespace TGLog.ExpandILog
{
    public class MyLogManager
    {
        #region Static Member Variables
        /// <summary>
        /// The wrapper map to use to hold the <see cref="EventIDLogImpl"/> objects
        /// </summary>
        private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler));
        #endregion

        #region Constructor
        /// <summary>
        /// Private constructor to prevent object creation
        /// </summary>
        private MyLogManager() { }
        #endregion

        #region Type Specific Manager Methods
        /// <summary>
        /// Returns the named logger if it exists
        /// </summary>
        /// <remarks>
        /// <para>If the named logger exists (in the default hierarchy) then it
        /// returns a reference to the logger, otherwise it returns
        /// <c>null</c>.</para>
        /// </remarks>
        /// <param name="name">The fully qualified logger name to look for</param>
        /// <returns>The logger found, or null</returns>
        public static IMyLog Exists(string name)
        {
            return Exists(Assembly.GetCallingAssembly(), name);
        }
        /// <summary>
        /// Returns the named logger if it exists
        /// </summary>
        /// <remarks>
        /// <para>If the named logger exists (in the specified domain) then it
        /// returns a reference to the logger, otherwise it returns
        /// <c>null</c>.</para>
        /// </remarks>
        /// <param name="domain">the domain to lookup in</param>
        /// <param name="name">The fully qualified logger name to look for</param>
        /// <returns>The logger found, or null</returns>
        public static IMyLog Exists(string domain, string name)
        {
            return WrapLogger(LoggerManager.Exists(domain, name));
        }
        /// <summary>
        /// Returns the named logger if it exists
        /// </summary>
        /// <remarks>
        /// <para>If the named logger exists (in the specified assembly's domain) then it
        /// returns a reference to the logger, otherwise it returns
        /// <c>null</c>.</para>
        /// </remarks
        /// <param name="assembly">the assembly to use to lookup the domain</param>
        /// <param name="name">The fully qualified logger name to look for</param>
        /// <returns>The logger found, or null</returns>
        public static IMyLog Exists(Assembly assembly, string name)
        {
            return WrapLogger(LoggerManager.Exists(assembly, name));
        }
        /// <summary>
        /// Returns all the currently defined loggers in the default domain.
        /// </summary>
        /// <remarks>
        /// <para>The root logger is <b>not</b> included in the returned array.</para>
        /// </remarks>
        /// <returns>All the defined loggers</returns>
        public static IMyLog[] GetCurrentLoggers()
        {
        return GetCurrentLoggers(Assembly.GetCallingAssembly());
        }
        /// <summary>
        /// Returns all the currently defined loggers in the specified domain.
        /// </summary>
        /// <param name="domain">the domain to lookup in</param>
        /// <remarks>
        /// The root logger is <b>not</b> included in the returned array.
        /// </remarks>
        /// <returns>All the defined loggers</returns>
        public static IMyLog[] GetCurrentLoggers(string domain)
        {
            return WrapLoggers(LoggerManager.GetCurrentLoggers(domain));
        }
        /// <summary>
        /// Returns all the currently defined loggers in the specified assembly's domain.
        /// </summary>
        /// <param name="assembly">the assembly to use to lookup the domain</param>
        /// <remarks>
        /// The root logger is <b>not</b> included in the returned array.
        /// </remarks>
        /// <returns>All the defined loggers</returns>
        public static IMyLog[] GetCurrentLoggers(Assembly assembly)
        {
            return WrapLoggers(LoggerManager.GetCurrentLoggers(assembly));
        }
        /// <summary>
        /// Retrieve or create a named logger.
        /// </summary>
        /// <remarks>
        /// <para>Retrieve a logger named as the <paramref name="name"/>
        /// parameter. If the named logger already exists, then the
        /// existing instance will be returned. Otherwise, a new instance is
        /// created.</para>
        /// <para>By default, loggers do not have a set level but inherit
        /// it from the hierarchy. This is one of the central features of
        /// log4net.</para>
        /// </remarks>
        /// <param name="name">The name of the logger to retrieve.</param>
        /// <returns>the logger with the name specified</returns>
        public static IMyLog GetLogger(string name)
        {
            return GetLogger(Assembly.GetCallingAssembly(), name);
        }
        /// <summary>
        /// Retrieve or create a named logger.
        /// </summary>
        /// <remarks>
        /// <para>Retrieve a logger named as the <paramref name="name"/>
        /// parameter. If the named logger already exists, then the
        /// existing instance will be returned. Otherwise, a new instance is
        /// created.</para>
        /// <para>By default, loggers do not have a set level but inherit
        /// it from the hierarchy. This is one of the central features of
        /// log4net.</para>
        /// </remarks>
        /// <param name="domain">the domain to lookup in</param>
        /// <param name="name">The name of the logger to retrieve.</param>
        /// <returns>the logger with the name specified</returns>
        public static IMyLog GetLogger(string domain, string name)
        {
            return WrapLogger(LoggerManager.GetLogger(domain, name));
        }
        /// <summary>
        /// Retrieve or create a named logger.
        /// </summary>
        /// <remarks>
        /// <para>Retrieve a logger named as the <paramref name="name"/>
        /// parameter. If the named logger already exists, then the
        /// existing instance will be returned. Otherwise, a new instance is
        /// created.</para>
        /// <para>By default, loggers do not have a set level but inherit
        /// it from the hierarchy. This is one of the central features of
        /// log4net.</para>
        /// </remarks>
        /// <param name="assembly">the assembly to use to lookup the domain</param>
        /// <param name="name">The name of the logger to retrieve.</param>
        /// <returns>the logger with the name specified</returns>
        public static IMyLog GetLogger(Assembly assembly, string name)
        {
            return WrapLogger(LoggerManager.GetLogger(assembly, name));
        }
        /// <summary>
        /// Shorthand for <see cref="LogManager.GetLogger(string)"/>.
        /// </summary>
        /// <remarks>
        /// Get the logger for the fully qualified name of the type specified.
        /// </remarks>
        /// <param name="type">The full name of <paramref name="type"/> will
        /// be used as the name of the logger to retrieve.</param>
        /// <returns>the logger with the name specified</returns>
        public static IMyLog GetLogger(Type type)
        {
            return GetLogger(Assembly.GetCallingAssembly(), type.FullName);
        }
        /// <summary>
        /// Shorthand for <see cref="LogManager.GetLogger(string)"/>.
        /// </summary>
        /// <remarks>
        /// Get the logger for the fully qualified name of the type specified.
        /// </remarks>
        /// <param name="domain">the domain to lookup in</param>
        /// <param name="type">The full name of <paramref name="type"/> will
        /// be used as the name of the logger to retrieve.</param>
        /// <returns>the logger with the name specified</returns>
        public static IMyLog GetLogger(string domain, Type type)
        {
            return WrapLogger(LoggerManager.GetLogger(domain, type));
        }
        /// <summary>
        /// Shorthand for <see cref="LogManager.GetLogger(string)"/>.
        /// </summary>
        /// <remarks>
        /// Get the logger for the fully qualified name of the type specified.
        /// </remarks>
        /// <param name="assembly">the assembly to use to lookup the domain</param>
        /// <param name="type">The full name of <paramref name="type"/> will
        /// be used as the name of the logger to retrieve.</param>
        /// <returns>the logger with the name specified</returns>
        public static IMyLog GetLogger(Assembly assembly, Type type)
        {
            return WrapLogger(LoggerManager.GetLogger(assembly, type));
        }
        #endregion

        #region Extension Handlers
        /// <summary>
        /// Lookup the wrapper object for the logger specified
        /// </summary>
        /// <param name="logger">the logger to get the wrapper for</param>
        /// <returns>the wrapper for the logger specified</returns>
        private static IMyLog WrapLogger(ILogger logger)
        {
            return (IMyLog)s_wrapperMap.GetWrapper(logger);
        }
        /// <summary>
        /// Lookup the wrapper objects for the loggers specified
        /// </summary>
        /// <param name="loggers">the loggers to get the wrappers for</param>
        /// <returns>Lookup the wrapper objects for the loggers specified</returns>
        private static IMyLog[] WrapLoggers(ILogger[] loggers)
        {
            IMyLog[] results = new IMyLog[loggers.Length];
            for (int i = 0; i < loggers.Length; i++)
            {
                results[i] = WrapLogger(loggers[i]);
            }
            return results;
        }
        /// <summary>
        /// Method to create the <see cref="ILoggerWrapper"/> objects used by
        /// this manager.
        /// </summary>
        /// <param name="logger">The logger to wrap</param>
        /// <returns>The wrapper for the logger specified</returns>
        private static ILoggerWrapper WrapperCreationHandler(ILogger logger)
        {
            return new MyLogImpl(logger);
        }
        #endregion
    }
}

4.3IMyLog类代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;

namespace TGLog.ExpandILog
{
    public interface IMyLog : ILog
    {
        void Debug(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName);
        void Debug(int operatorID, string operand, int actionType,object message,string ip, string browser, string machineName, Exception t);
        void Info(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName);
        void Info(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, Exception t);
        void Warn(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName);
        void Warn(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, Exception t);
        void Error(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName);
        void Error(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, Exception t);
        void Fatal(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName);
        void Fatal(int operatorID, string operand, int actionType, object message,string ip, string browser, string machineName, Exception t);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值