写了一个log4net的扩展,看过别人写的扩展,觉的不灵活,重写了一下,通过返射自动取属性,特别通用。
大家多提意见。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net.Core;
using log4net;
using System.Reflection;
namespace mylognet
{
    public class MyLogImpl : LogImpl, IMyLog
    {
        private readonly static Type ThisDeclaringType = typeof(MyLogImpl);
        List<String> propList =new List<string>();
        public MyLogImpl(ILogger logger)
           : base(logger)
        {        }
        public void InitpropList(List<String> lst)
        {
            propList = lst;
        }
        private LoggingEvent CreateLogEvent(Object obj,Exception t)
        {
            if (propList.Count == 0)
            {
                throw new Exception("还没有调用InitpropList(List<String> lst),一定要先调用此函数才可用Ex扩展log!");
            }
            String msg=obj.ToString();
            LoggingEvent loggingEvent =new LoggingEvent(ThisDeclaringType, Logger.Repository,                                     Logger.Name, Level.Info,msg,t);
            Type tp=obj.GetType();           
            foreach (String prop in propList)
            {
                PropertyInfo mdinfo = tp.GetProperty(prop);
                loggingEvent.Properties[prop] = mdinfo.GetGetMethod().Invoke(obj, null);
            }
            return loggingEvent;
        }
        public void DebugEx(Object obj)
        {
            DebugEx(obj, null);
        }
        public void DebugEx(Object obj, System.Exception t)
        {
            if (this.IsDebugEnabled)
            {
                LoggingEvent loggingEvent = CreateLogEvent(obj,t);
                Logger.Log(loggingEvent);
            }
        }
        public void InfoEx(Object obj)
        {            InfoEx(obj, null);        }
        public void InfoEx(Object obj, System.Exception t)
        {            if (this.IsInfoEnabled)
            {
                LoggingEvent loggingEvent = CreateLogEvent(obj, t);
                Logger.Log(loggingEvent);
            }
        }
       public void WarnEx(Object obj)
        {            WarnEx(obj, null);        }
        public void WarnEx(Object obj, System.Exception t)
        {            if (this.IsWarnEnabled)
            {
                LoggingEvent loggingEvent = CreateLogEvent(obj, t);
                Logger.Log(loggingEvent);            }        }
        public void ErrorEx(Object obj)
        {            ErrorEx(obj, null);        }
        public void ErrorEx(Object obj, System.Exception t)
        {            if (this.IsErrorEnabled)
            {
                LoggingEvent loggingEvent = CreateLogEvent(obj, t);
                Logger.Log(loggingEvent);
            }        }
        public void FatalEx(Object obj)
        {            FatalEx(obj, null);        }
        public void FatalEx(Object obj, System.Exception t)
        {            if (this.IsFatalEnabled)
            {
                LoggingEvent loggingEvent = CreateLogEvent(obj, t);
                Logger.Log(loggingEvent);
            }
        }
    }    public class MyLogManager    {        private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler));        private MyLogManager() { }
        public static IMyLog Exists(string name)
        {
            return Exists(Assembly.GetCallingAssembly(), name);
        }
        public static IMyLog Exists(string domain, string name)
        {
            return WrapLogger(LoggerManager.Exists(domain, name));
        }
        public static IMyLog Exists(Assembly assembly, string name)        
        {     
            return WrapLogger(LoggerManager.Exists(assembly, name));
        }
        public static IMyLog[] GetCurrentLoggers()
        {
            return GetCurrentLoggers(Assembly.GetCallingAssembly());
        }
        public static IMyLog[] GetCurrentLoggers(string domain)
        {
            return WrapLoggers(LoggerManager.GetCurrentLoggers(domain));
        }        public static IMyLog[] GetCurrentLoggers(Assembly assembly)
        {
            return WrapLoggers(LoggerManager.GetCurrentLoggers(assembly));
        }
        public static IMyLog GetLogger(string name)
        {
            return GetLogger(Assembly.GetCallingAssembly(), name);
        }
        public static IMyLog GetLogger(string domain, string name)
        {
            return WrapLogger(LoggerManager.GetLogger(domain, name));
        }        public static IMyLog GetLogger(Assembly assembly, string name)
        {
            return WrapLogger(LoggerManager.GetLogger(assembly, name));
       }        public static IMyLog GetLogger(Type type)
        {
           return GetLogger(Assembly.GetCallingAssembly(), type.FullName);
        }
        public static IMyLog GetLogger(string domain, Type type)
        {
            return WrapLogger(LoggerManager.GetLogger(domain, type));
        }
        public static IMyLog GetLogger(Assembly assembly, Type type)
        {
           return WrapLogger(LoggerManager.GetLogger(assembly, type));
        }
        private static IMyLog WrapLogger(ILogger logger)
        {
            return (IMyLog)s_wrapperMap.GetWrapper(logger);
        }
        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;
        }
        private static ILoggerWrapper WrapperCreationHandler(ILogger logger)        {            return new MyLogImpl(logger);        }    }
    public interface IMyLog : ILog
    {
        void InitpropList(List<String> lst);
        void DebugEx(Object obj);
        void DebugEx(Object obj, Exception t);
        void InfoEx(Object obj);
        void InfoEx(Object obj, Exception t);
        void WarnEx(Object obj);
        void WarnEx(Object obj, Exception t);
        void ErrorEx(Object obj);
        void ErrorEx(Object obj, Exception t);
        void FatalEx(Object obj);
        void FatalEx(Object obj, Exception t);    }
}

解决方案 »

  1.   

    配置文件
    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
      </configSections>
      <log4net>
        <!--定义输出到文件中-->
        <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
          <!--定义文件存放位置-->
          <file value="d:\log4netfile.txt"/>
          <appendToFile value="true"/>
          <rollingStyle value="Date"/>
          <datePattern value="yyyyMMdd-HH:mm:ss"/>
          <layout type="log4net.Layout.PatternLayout">
            <!--每条日志末尾的文字说明-->
            <footer value="by Guo"/>
            <!--输出格式-->
            <!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
            <conversionPattern value="记录时间:%date 属性GUO:%property{Guo} 属性Jian:%property{Jian}:属性Zhi%property{Zhi}"/>
          </layout>
        </appender>
        <!--定义输出到控制台命令行中-->
        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
          </layout>
        </appender>
        <!--定义输出到windows事件中-->
        <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
          </layout>
        </appender>
        <!--定义输出到数据库中,这里举例输出到Access数据库中,数据库为C盘的log4net.mdb-->
        <appender name="AdoNetAppender_MySQL" type="log4net.Appender.AdoNetAppender">
          <param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"/>
          <param name="ConnectionString" value="server=localhost;user id=swbbgl; password=swbbgl; database=swbbgl;old syntax=yes"/>
          <CommandText value="INSERT INTO log4_net(Log_Date,Thread,Level,Logger,Message) VALUES (@logDate, @thread, @logLevel, @logger,@message)"/>
          <!--定义各个参数-->
          <parameter>
            <parameterName value="@logDate"/>
            <dbType value="String"/>
            <size value="40"/>
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%date"/>
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@thread"/>
            <dbType value="String"/>
            <size value="40"/>
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%thread"/>
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@logLevel"/>
            <dbType value="String"/>
            <size value="40"/>
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%level"/>
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@logger"/>
            <dbType value="String"/>
            <size value="40"/>
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%logger"/>
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@message"/>
            <dbType value="String"/>
            <size value="240"/>
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%message"/>
            </layout>
          </parameter>
        </appender>
        <!--定义日志的输出媒介,下面定义日志以四种方式输出。也可以下面的按照一种类型或其他类型输出。-->
        <root>
          <!--文件形式记录日志-->
          <appender-ref ref="LogFileAppender"/>
          <!--控制台控制显示日志-->
          <appender-ref ref="ConsoleAppender"/>
          <!--Windows事件日志-->
          <appender-ref ref="EventLogAppender"/>
          <appender-ref ref="AdoNetAppender_MySQL"/>
         <!-- 如果不启用相应的日志记录,可以通过这种方式注释掉
          <appender-ref ref="AdoNetAppender_Access" />
          -->
        </root>
        <logger name="Test">
    <level value="ERROR"/>
    <appender-ref ref="LogFileAppender"/>
        </logger>

      </log4net>  <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
    </configuration>
    测试代码
    public partial class Form1 : Form
        {
            List<String> proList = new List<string>();
            public Form1()
            {
                InitializeComponent();
                proList = typeof(TestObj).GetProperties(System.Reflection.BindingFlags.Public).Select(x => x.Name).ToList();
                log4net.Config.XmlConfigurator.Configure(new FileInfo("c:\\lognet4.xml"));
                TestLog();
            }
            private void TestLog()
            {
                IMyLog log = MyLogManager.GetLogger("LogFileAppender");
              //  log.InitpropList(proList);
                TestObj obj1 = new TestObj() { Guo = 100, Jian = "TestJian" };
                TestObj obj2 = new TestObj() { Guo = 666, Jian = "this is test" };
                log.FatalEx(obj1);
                log.FatalEx(obj2);
            }
        }
        public class TestObj
        {
            public int Guo { get; set; }
            public String Jian { get; set; }
            public DateTime Zhi { get { return DateTime.Now; } }
            public override string ToString()
            {
                return Guo.ToString()+Jian+Zhi.ToString();
            }
        }我用的是LogFileAppender。
      <conversionPattern value="记录时间:%date 属性GUO:%property{Guo} 属性Jian:%property{Jian}:属性Zhi%property{Zhi}"/>