决不轻言放弃,否则对不起自己

永不言败

常用链接

统计

cnblogs

同事

最新评论

Log4Net添加自定义日志信息

   

Log4Net添加自定义日志信息

一、     前言

该文章是针对在Log4Net中添加自定义日志信息。我们在写日志的时候并不是只写消息(Message,有些情况需要记录自定义的日志信息等。下面将说明在Log4Net中增加自定义字段UserName(用户名),Category(类别)这两个字段。

二、     建立数据库

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

其中Date,Thread,Level,Logger,Message,Exceptionlog4net内置的信息。UserCategory是自定义的字段。

三、     编写配置文件

<configuration>
    
<configSections>
        
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
    
</configSections>
    
<log4net>
        
<logger name="AA">
            
<level value="All" />
            
<appender-ref ref="ADONetAppender" />
        
</logger>
    
<!--<root>
            <level value="All" />
      <appender-ref ref="ADONetAppender" /> 
        </root>
-->
        
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
            
<!--BufferSize为缓冲区大小-->
            
<param name="BufferSize" value="1" />
      
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      
<connectionString value="database=aa;server=(local);User ID=sa;Password=;" />
      
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception],[User],[Category]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@User,@Category)" />
      
<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>
      
<parameter>
        
<parameterName value="@User" />
        
<dbType value="String" />
        
<size value="50" />
        
<layout type="Log4NetToDatabase.CustomLayout">
          
<conversionPattern value="%UserName" />
        
</layout>
      
</parameter>
      
<parameter>
        
<parameterName value="@Category" />
        
<dbType value="String" />
        
<size value="50" />
        
<layout type="Log4NetToDatabase.CustomLayout">
          
<conversionPattern value="%Category" />
        
</layout>
      
</parameter>
    
</appender>
  
</log4net>
</configuration>

配置文件说明:该配置文件在应用程序项目中的App.config配置文件中编写。配置文件中的Log4NetToDatabase.CustomLayout为自定义类的名称,具体实现请关注编写代码。配置文件中如果将<root>节点的注释打开则会产生两条同样的信息,因为在<root>节点中有一个appender-ref子节点,它也引用了ADONetAppender附着器。由于<logger>节点已经引用了ADONetAppender附着器,并且加载它。我个人怀疑<root>节点的内容为自动加载,所以会连续产生两条同样的信息。解决该问题只要将<Root>节点注释,或将<root>节点中的<appender-ref>子节点注释就解决了。

 

一、     编写代码

1.     编写自定义PatternLayoutConverter

internal sealed class UserNamePatternConverter : PatternLayoutConverter 
{
    
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
    
{
        LogMessage logMessage 
= loggingEvent.MessageObject as LogMessage;
        
if (logMessage != null)
            
// 将UserName作为日志信息输出
            writer.Write(logMessage.UserName);
   }

}

internal sealed class CategoryPatternConverter : PatternLayoutConverter
{
    
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
    
{
        LogMessage logMessage 
= loggingEvent.MessageObject as LogMessage;
        
if (logMessage != null)
            writer.Write(logMessage.Category);
    }

}

2.     编写自定义日志输出类

public class LogMessage
    
{
        
private string m_UserName;
        
private string m_Category;
        
public LogMessage()
        
{
        }

        
public LogMessage(string userName, string category)
        
{
            m_UserName 
= userName;
            m_Category 
= category;
        }

        
public string UserName
        
{
            
get
            
{
                
return m_UserName;
            }

            
set
            
{
                m_UserName 
= value;
            }

        }

        
public string Category
        
{
            
get
            
{
                
return m_Category;
            }

            
set
            
{
                m_Category 
= value;
            }

        }

    }

3.     编写由log4net.Layout.LayoutSkeleton继承的类CustomLayout

由于内容过多,将在附件中给出源代码。

在此对该类做一些说明:

如果要添加自定义的字段,可以在静态构造函数static CustomLayout()中加入s_globalRulesRegistry.Add("UserName", typeof(UserNamePatternConverter));其中UserNamePatternConverter是继承于PatternLayoutConverter的类。注册完之后就可以在配置文件中使用%UserName使用了。在此只要做这些修改就能使用了,其它的代码如果有趣,可以一起交流。

4.     加载配置文件并记录日志

AssemblyInfo.cs文件中添加[assembly: XmlConfigurator()]。它的作用同于log4net.Config.XmlConfigurator.Configure();用来读取配置文件信息。

log4net.ILog log;

form1中添加下列代码:

private static int count = 0;
        
public Form1()
        
{
            InitializeComponent();
                
// 如果配置文件中存在名称为AA的logger,则加载
            log = LogManager.Exists("AA");        
}

        
private void button1_Click(object sender, EventArgs e)
        
{
            
++count;
            LogMessage message 
= new LogMessage();
            message.UserName 
= "xds"+count.ToString();
            message.Category 
= count.ToString();
                
// 输出日志信息
            log.Error(message);
        }


解决方案二:

与上面的方案只需做以下的更改:将CustomLayout类继承自log4net.Layout.PatternLayout并在构造函数中调用AddConverter()方法。该方法将占用较多的系统内存,但它代码简单易于理解。它的代码如下:

 

public class CustomLayout : log4net.Layout.PatternLayout
    
{
        
public CustomLayout2()
        
{
            
this.AddConverter("UserName"typeof(UserNamePatternConverter));
            
this.AddConverter("Category"typeof(CategoryPatternConverter));
        }

}
源代码下载:Log4NetToDatabase 下载
参考信息:

Log4Net使用指南:http://www.tongyi.net/develop/.net/1053472.html

log4net 文章集http://myx.cnblogs.com/archive/2005/06/28/182617.html

posted on 2007-03-06 10:55 XDS 阅读(1814) 评论(18) 编辑 收藏

评论

#1楼 2007-04-16 10:54 xlf[未注册用户]

很高兴看到这篇文章。这正是我迫切需要的。
一个请求,能否把代码和配置文件给我一份,万分感谢。

lifengsh.xue@gamail.com

 回复 引用   

#2楼[楼主] 2007-04-18 13:29 XDS      

@xlf
我发邮件给你后,被系统退信了。请给我其它的通信方式。
 回复 引用 查看   

#3楼 2007-05-28 19:16 余波涛[未注册用户]

我还是个菜鸟,正在学习中.也觉得自定义的信息很方便做以后的工作.
也想请求一份CustomLayout的代码.感激不尽!
我邮箱:surf816@163.com ,谢谢.
 回复 引用   

#4楼 2007-05-30 21:48 小白[未注册用户]

最近正在做一个小网站
看到log4net功能强大,但是还有些地方不尽人意,比如说message一行只能输出个,
看到了你的博客中关于自定义输出的例子,希望能学习一下,麻烦把源码发一下,小弟先谢过了


另外还有个问题请教一下,我用的是vs2005
新建的一个网站JZ_test
然后添加了一个类库JZ.log
在类库中添加了一个配置文件App.net,里边是log4net的配置文件
类库中的一个类的函数实现日志输出
网站文件引用该类库

当我在网站的后台代码中调用上述函数时,并不能输出任何日志!调试时发现得到的logger对象的isdebugenablled,isinfoenablled等属性均为false

最后只能把log4net的配置文件放到了网站的web.config中才得以实现日志输出

我用原来的方法问题出在哪儿呢?

我的邮箱是bailm1984@163.com
 回复 引用   

#5楼 2007-06-08 15:31 kitzone[未注册用户]

也给我一份,谢谢
kitzone@msn.com
 回复 引用   

#6楼 2007-07-14 11:45 qianhuajuan[未注册用户]

也给我一份 代码,非常感谢!!
qianhuajuan@126.com
 回复 引用   

#7楼 2007-07-14 11:46 qianhuajuan[未注册用户]

也给我一份 代码,非常感谢!!
qianhuajuan@126.com
 回复 引用   

#8楼 2007-08-10 11:12 yuming[未注册用户]

怎么没提供下载的啊,,

楼主看到了能否也给我一份,,:pengliaoyuan@.hotmail.com
 回复 引用   

#9楼 2007-12-27 17:23 musicgood[未注册用户]

楼主你好,我试了一下你这个自定义消息,我把log4net里面的操作封装到一个dll里面,log4net的配置程序是单独和dll放在一起的,名字是LOG.config,在dll
里面有[assembly: log4net.Config.XmlConfigurator(ConfigFile = "LOG.config", Watch = true)],然后在BS程序里面不能使用,老是log4net.ILog log = log4net.LogManager.GetLogger("MYLOGGER");这一句执行不到,就是一直没有读出配置文件吧,但是我用控制台程序测试可以,
是不是配置文件放的地方不对呢,谢谢指教,俺的邮箱musicgood86@163.com
 回复 引用   

#10楼 2008-01-05 14:14 ray@@[未注册用户]

thanks  回复 引用   

#11楼 2008-04-30 17:54 流花榭[未注册用户]

有没有不占用Message的方法呢,项目经理要求我想出Message信息和字段同时得兼的方法,我一直想不出来。  回复 引用   

#12楼 2008-05-08 17:30 huishi[未注册用户]

谢谢楼主
我最近正在研究和学习这个
 回复 引用   

#13楼 2008-07-16 17:06 sa1[未注册用户]

这样的话,原来的message记到哪?
log.Error(message);这里的参数已经是自定义的对象了,那日志描述信息怎么办?
 回复 引用   

#14楼 2008-08-08 14:57 夜猫子[未注册用户]

--引用--------------------------------------------------
sa1: 这样的话,原来的message记到哪?
log.Error(message);这里的参数已经是自定义的对象了,那日志描述信息怎么办?
--------------------------------------------------------

这个问题我也遇到,希望楼主解决

 回复 引用   

#15楼 2009-02-07 22:17 liangwei389      

如何我想自定义的信息,输出到记事本,又该如何操作。
希望博主帮忙解决一下,
谢谢
 回复 引用 查看   

#16楼 2009-08-27 11:32 lohcve[未注册用户]

引用夜猫子:--引用--------------------------------------------------
<br/>sa1: 这样的话,原来的message记到哪?
<br/>log.Error(message);这里的参数已经是自定义的对象了,那日志描述信息怎么办?
<br/>--------------------------------------------------------
<br/>
<br/>这个问题我也遇到,希望楼主解决
<br/>
<br/>


你不会记到自定义的message里面呀,真是的。  回复 引用   

#17楼[楼主] 2009-08-28 10:03 XDS      

@夜猫子
@lohcve
有两种方法可以试试
1. 通过将LogMessage实体类,继承自Log4net的消息实体类,然后通过Log.Error()等方法写入消息
2. 不通过继承方式,直接在LogMessage实体类中添加Message等属性
每个属性都要在配置文件中定义。

 回复 引用 查看   

#18楼 2010-07-11 15:39 daconglee      

<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
如果把, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 去掉就写不了数据,真是奇怪,害得我搞了3个小时
 回复 引用 查看