概述
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-11-09 04:41:29