Log4net保存自定义信息到数据库

概述

Log4net将自身定义信息保存到文本文件和数据库的操作很简单,但是,这些信息有时不符合我们的要求,例如:我想多一些属性值,此时就不不行了。

实现

1、下载log4net,添加log4net引用。

2、创建数据库

<span style="font-size:18px;">create talbe MyLogTable
(
    id int primary key identity(1,1),
    userid varchar(32),
    username varchar(32)
)</span>

3、添加实体类,属性为自定义的字段

namespace Log4NetToDatabase
{
    public class LogMessage:IRequiresSessionState
    {
        public LogMessage() { }
        public LogMessage(string userID, string UserName)
        {
            this.userid = userID;
            this.username = UserName;
        }
        private string userid;
        public string Userid
        {
            get { return userid; }
            set { userid = value; }
        }
        private string username;
        public string Username
        {
            get { return username; }
            set { username = value; }
        }
    }
}

4、添加参数转换器类,每个字段一个模式转化类

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

    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);
        }
    }
}

5、自定义layout类

namespace Log4NetToDatabase
{
    public class CustomLayout : log4net.Layout.LayoutSkeleton
    {
        public const string DefaultConversionPattern = "%message%newline";
        public const string DetailConversionPattern = "%timestamp [%thread] %level %logger %ndc - %message%newline";
        private static Hashtable s_globalRulesRegistry;
        private string m_pattern;
        private PatternConverter m_head;
        private Hashtable m_instanceRulesRegistry = new Hashtable();
        //这里是重点-------------------------------------------------------
        /// <summary>
        /// 把自定义的字段放进Hashtable
        /// 定义多少个写多少个
        /// 注意这里有名称要和配置文件中的名称一致
        /// 注意命名空间
        /// 在配置文件中要用到命名空间
        /// </summary>
        static CustomLayout()
        {
            s_globalRulesRegistry = new Hashtable(2);
            s_globalRulesRegistry.Add("username", typeof(UserNamePatternConverter));
            s_globalRulesRegistry.Add("userid", typeof(UserIdPatternConverter));
        }
        //--------------------------------------------------------------------
        public CustomLayout()
            : this(DefaultConversionPattern)
        { }
        public CustomLayout(string pattern)
        {
            IgnoresException = true;
            m_pattern = pattern;
            if (m_pattern == null)
            {
                m_pattern = DefaultConversionPattern;
            }
            ActivateOptions();
        }
        public string ConversionPattern
        {
            get { return m_pattern; }
            set { m_pattern = value; }
        }
        virtual protected PatternParser CreatePatternParser(string pattern)
        {
            PatternParser patternParser = new PatternParser(pattern);
            foreach (DictionaryEntry entry in s_globalRulesRegistry)
            {
                patternParser.PatternConverters[entry.Key] = entry.Value;
            }
            foreach (DictionaryEntry entry in m_instanceRulesRegistry)
            {
                patternParser.PatternConverters[entry.Key] = entry.Value;
            }
            return patternParser;
        }
        override public void ActivateOptions()
        {
            m_head = CreatePatternParser(m_pattern).Parse();

            PatternConverter curConverter = m_head;
            while (curConverter != null)
            {
                PatternLayoutConverter layoutConverter = curConverter as PatternLayoutConverter;
                if (layoutConverter != null)
                {
                    if (!layoutConverter.IgnoresException)
                    {
                        this.IgnoresException = false;

                        break;
                    }
                }
                curConverter = curConverter.Next;
            }
        }
        override public void Format(TextWriter writer, LoggingEvent loggingEvent)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (loggingEvent == null)
            {
                throw new ArgumentNullException("loggingEvent");
            }
            PatternConverter c = m_head;
            while (c != null)
            {
                c.Format(writer, loggingEvent);
                c = c.Next;
            }
        }
        public void AddConverter(ConverterInfo converterInfo)
        {
            AddConverter(converterInfo.Name, converterInfo.Type);
        }
        public void AddConverter(string name, Type type)
        {
            if (name == null) throw new ArgumentNullException("name");
            if (type == null) throw new ArgumentNullException("type");

            if (!typeof(PatternConverter).IsAssignableFrom(type))
            {
                throw new ArgumentException("The converter type specified [" + type + "] must be a subclass of log4net.Util.PatternConverter", "type");
            }
            m_instanceRulesRegistry[name] = type;
        }
        public sealed class ConverterInfo
        {
            private string m_name;
            private Type m_type;
            public ConverterInfo()
            { }
            public string Name
            {
                get { return m_name; }
                set { m_name = value; }
            }
            public Type Type
            {
                get { return m_type; }
                set { m_type = value; }
            }
        }
    }
}

6、添加配置信息

    <configSections>
	<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
    </configSections>
    <log4net>
        <logger name="<span style="font-family: Arial, Helvetica, sans-serif;">log4netToSqlServer</span><span style="font-family: Arial, Helvetica, sans-serif;">"></span>
            <level value="INFO"/>
            <appender-ref ref="AdoNetAppender_SqlServer"/>
        </logger>

	<!--SqlServer数据库-->
	<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
   	    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
	    <connectionString value="server=****;database=***;user id=***;password=***"/>
	    <commandText value="INSERT INTO MyLogTable(userid,username) VALUES (@userid,@username)"/>
	    <bufferSize value="1"/>
	    <!--自定义成员 -->
	    <parameter>
		<parameterName value="@userid"/>
		<dbType value="String"/>
		<size value="50"/>
		<!--自定义layout类的信息-->
		<layout type="Log4NetToDatabase.CustomLayout">
	  	    <conversionPattern value="%userid"/>
		</layout>
	    </parameter>
	    <parameter>
		<parameterName value="@username"/>
		<dbType value="String"/>
		<size value="20"/>
		<layout type="Log4NetToDatabase.CustomLayout">
 		    <conversionPattern value="%username"/>
		</layout>
 	    </parameter>
	</appender>
    </log4net>

7、程序编码

        log4net.Config.XmlConfigurator.Configure();
        ILog log = log4net.LogManager.GetLogger("log4netToSqlServer");
        LogMessage message = new Log4NetToDatabase.LogMessage(userID, UserName);
        log.Info(message);

总结

自定义字段信息到数据库和自定义字段信息到文本的操作是一样的,不一样的是配置文件的修改.

时间: 2024-08-28 09:38:05

Log4net保存自定义信息到数据库的相关文章

log4net修改数据库连接字符串和写自定义信息

最近项目需要用log4net来写日志,因为整个平台式在sharepoint上,我们需要记录具体是哪个子站点发生的日志,因此需要再原来的log表里面添加一个自定义信息列.由于平台的安全性要求,我们需要对连接字符串加密.连接字符串的信息是在AdoNetAppender读取的,所以我们要扩展该类.而自定义消息我们需要扩展PatternLayout类.其实有关log4net的介绍网上已经很多了,如log4net.dll使用 具体的代码如下: #region Log helper public class

使用Log4Net将系统日志信息记录到记事本和数据库中

一.使用Log4Net将日志记录到记事本中步骤 1,将log4net.dll文件添加到项目引用中 2,写日志记录器类如下: /// <summary> /// 日志记录器 /// </summary> public class LogWriter { /// <summary> /// 记录调试信息 /// </summary> /// <param name="message"></param> public s

Log4net 自定义字段到数据库

今天要求做个log4net自定义字段到数据库,在网上找了好多例子,都运行不成功.最后找了个国外的,很简单的就解决了. log4net它已经定义的字段有 <commandText value="INSERT INTO xiao_log(Date,Thread,Level,Logger,Message)VALUES(@log_date, @thread, @log_level, @logger, @message)"/> 中的Date,Thread,Level,Logger,M

mysql 保存emoji时报,数据库报错:Caused by: java.sql.SQLException: Incorrect string value: &#39;\xF0\x9F\x98\x82\xF0\x9F...&#39; for column &#39;review&#39; at row 1

错误原因:我们可以看到错误提示中的字符0xF0 0x9F 0x98 0x84 ,这对应UTF-8编码格式中的4字节编码(UTF-8编码规范).正常的汉字一般不会超过3个字节,为什么为出现4个字节呢?实际上是它对应的是智能手机输入法中的表情.那为什么会报错呢?因为mysql中的utf-8并不是真正意义上的utf-8,它只能存储1~3个字节长度的utf-8编码,如果想存储4个字节的必须用utf8mb4类型.不而要使用utf8mb4类型,首先要保证Mysql版本要不低于 MySQL 5.5.3. 常用

.net中保存用户信息的九种方法

.net中保存用户信息的九种方法 在ASP.NET中,有几种保持用户请求间数据的途径--实际上太多了,使没有经验的开发者对在哪个特定的环境下使用哪个对象很困惑.为了回答这个问题,需要考虑下面三个条件: .谁需要数据? .数据需要保持多长时间? .数据集有多大? 通过回答这些问题,你能决定哪个对象为保持ASP.NET应用程序请求间数据提供了最佳的解决方案.图1列出了不同的状态管理对象并描述了什么时候使用它们.ASP.NET中添加了四个新的对象:Cache.Context.ViewState和Web

几个数据库的小案例(一):将文本文件中的信息导入数据库的表中

从文本文件添加到数据库用户表的记录(有两个文件:frmMain.cs  SqlHelper.cs  ) //FrmMain.cs//作者:Meusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Fo

百度地图JavaScript API自定义覆盖物、自定义信息窗口增删时的显示问题

项目中,需求:在百度地图上实时画出车辆,并能点击车辆弹出信息框查看实时信息. 实现:通过不停的画覆盖物并删除掉.点击覆盖物时弹出信息窗口. 问题:删除掉覆盖物后信息窗也删除掉了.因为信息窗是建立在覆盖物的基础上的. 如何做到,我点击覆盖物弹出信息框,信息框能够持续显示实时信息,直到点击关闭? 做下笔记,包括了自定义覆盖物标识.自定义信息窗口.信息窗口显示实时信息.清除覆盖物时信息窗口的显示问题等等. 贴张效果图:     代码: <script type="text/javascript&

SSM练手-增删改查-5-新增_保存员工信息

保存员工信息 1 后台保存到数据库: @RequestMapping(value = {"/emp/save"}, method = {RequestMethod.POST}) @ResponseBody public Msg addEmp(Employee employee){ employeeService.saveEmp(employee); return Msg.success(); } 2 前台发送AJAX请求: //保存员工信息 $("#emp_save_btn&

qsettings 保存自定义结构体(QVariant与自定义结构体相互转化)

参考博文:QVariant与自定义数据类型转换的方法. 这里摘取其关键内容: 1.将自定义数据类型使用Q_DECLARE_METATYPE宏进行声明,便于编译器识别. 2.在插入对象的时候,声明QVariant对象,使用其setValue方法添加自定义对象. 3.在读取的时候,采用QVariant对象的value方法返回自定义对象. 写入: //类型转换 QVariant v; v.setValue(MyStruct);  读取: //转换为自定义的结构体实例 MyStruct s = v.va