log4net.config
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> <!--CREATE TABLE [dbo].[NatinalUnionLog](
[ID] [int] IDENTITY(,) NOT NULL,
[IP] [nvarchar]() NULL,
[sMessage] [nvarchar]() NULL,
[sMethod] [nvarchar]() NULL,
[User] [nvarchar]() NULL,
[dtDate] [datetime] NULL,
[sthread] [nvarchar]() NULL,
[sLevel] [nvarchar]() NULL,
[sLogger] [nvarchar]() NULL,
[sException] [nvarchar]() NULL,
CONSTRAINT [PK_NatinalUnionLog] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]-->
<bufferSize value="" />
<connectionString value="data source=.\sqlxu;initial catalog=NatinalUnionLog;Persist Security Info=True;User ID=sa;Password=101;Connect Timeout=1000" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089" />
<commandText value="INSERT INTO NatinalUnionLog ([IP],[sMessage],[sMethod],[User],[dtDate],[sThread],[sLevel],[sLogger],[sException]) VALUES (@IP,@message,@method, @user, @log_date, @thread, @log_level, @logger, @exception)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%t" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%p" />
</layout>
</parameter> <parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="" />
<layout type="NationalUnion.Common.Log.NationalUnionLayout">
<conversionPattern value="%o{message}" />
</layout>
</parameter> <parameter>
<parameterName value="@method" />
<dbType value="String" />
<size value="" />
<layout type="NationalUnion.Common.Log.NationalUnionLayout">
<conversionPattern value="%o{method}" />
</layout>
</parameter> <parameter>
<parameterName value="@IP" />
<dbType value="String" />
<size value="" />
<layout type="NationalUnion.Common.Log.NationalUnionLayout">
<conversionPattern value="%o{IP}" />
</layout>
</parameter> <parameter>
<parameterName value="@user" />
<dbType value="String" />
<size value="" />
<layout type="NationalUnion.Common.Log.NationalUnionLayout">
<conversionPattern value="%o{user}" />
</layout>
</parameter> <parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<!--<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%m" />
</layout>
</parameter>-->
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter> </appender> <appender name="InfoLayout" type="log4net.Appender.RollingFileAppender,log4net"> <!--日志文件路径,“/”与“/”作用相同,到达的目录相同,文件夹不存在则新建 --> <!--按文件大小方式输出时在这里指定文件名,并且当天的日志在下一天时在文件名后自动追加当天日期形成新文件。--> <!--按照日期形式输出时,直接连接元素DatePattern的value形成文件路径。此处使用这种方式--> <!--param的名称,可以直接查对应的appender类的属性名即可,这里要查的就是RollingFileAppender类的属性 --> <param name="File" value="c:/Log/" />
<!--是否追加到文件-->
<param name="AppendToFile" value="true" />
<!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<!--使用Unicode编码-->
<Encoding value="UTF-8" />
<!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数-->
<param name="MaxSizeRollBackups" value="-1" />
<!--是否只写到一个文件中-->
<param name="StaticLogFileName" value="false" />
<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
<param name="RollingStyle" value="Date" />
<!--按日期产生文件夹和文件名[在日期方式与混合方式下使用]-->
<!--此处按日期产生文件夹,文件名固定。注意" 的位置-->
<param name="DatePattern" value="yyyy-MM-dd"info.log"" /> <!--<param name="DatePattern" value="yyyy-MM-dd/"ReflectionLayout.log"" />-->
<!--这是按日期产生文件夹,并在文件名前也加上日期-->
<!--<param name="DatePattern" value="yyyyMMdd/yyyyMMdd"-TimerServer.log"" />-->
<!--这是先按日期产生文件夹,再形成下一级固定的文件夹-->
<!--<param name="DatePattern" value="yyyyMMdd/"TimerServer/TimerServer.log"" />-->
<!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
<!--<param name="maximumFileSize" value="500KB" />-->
<!--计数类型为1,,…默认值为-。当文件超过MaximumFileSize的大小时,如果要创建新的文件来存储日志,会根据CountDirection的值来重命名文件。大于-1的值时,file里指定的文件名会依次加上.,.,.2递增。当等于或小于-1时,创建依赖于MaxSizeRollBackups参数值,创建备份日志数。-->
<!--<param name="CountDirection" value=""/>-->
<!--过滤设置,LevelRangeFilter为使用的过滤器。 -->
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="INFO" />
</filter>
<!--记录的格式。一般用log4net.Layout.PatternLayout布局-->
<!--此处用继承了log4net.Layout.PatternLayout的自定义布局,TGLog.ExpandLayout2为命名空间。%property{Operator}、%property{Action}是自定义的输出-->
<!--<layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
<param name="ConversionPattern" value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger 操作者ID:%property{Operator} 操作类型:%property{Action}%n 当前机器名:%property%n当前机器名及登录用户:%username %n 记录位置:%location%n 消息描述:%property{Message}%n 异常:%exception%n 消息:%message%newline%n%n" />
</layout>-->
<layout type="NationalUnion.Common.Log.NationalUnionMemberLayout,NationalUnion.Common">
<header value=" --------------------------------------------------------------------------------------------------------------------------- " />
<param name="ConversionPattern" value="记录时间:%date 消息:%message 操作者ID:%property{UserID} IP:%property{IP}消息描述:%property{Description} 线程ID:[%thread] 日志级别:%-5level%newline" />
</layout>
</appender>
<appender name="ErrorLayout" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="c:/Log/" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="MaxSizeRollBackups" value="-1" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="yyyy-MM-dd"Error.log"" />
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ERROR" />
<param name="LevelMax" value="ERROR" />
</filter>
<layout type="NationalUnion.Common.Log.NationalUnionMemberLayout,NationalUnion.Common">
<header value="--------------------------------------------------------------------------------------------------------------------------- " />
<param name="ConversionPattern" value="记录时间:%date 消息:%message 线程ID:[%thread] 日志级别:%-5level%n%exception%newline" />
</layout>
</appender> <!-- setup the root category, add the appenders and set the default level -->
<root>
<!--<level value="WARN"/>
<level value="INFO"/>
<level value="DEBUG"/>
<level value="FINE"/>-->
<level value="ALL"/>
<!--<appender-ref ref="AdoNetAppender" />--><!--关闭数据库记录日志功能-->
<appender-ref ref="InfoLayout" />
<appender-ref ref="ErrorLayout" />
</root> </log4net>
<!--Log4net End--> </configuration>
LogExtension.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using log4net.Layout.Pattern;
using log4net.Layout;
using log4net.Util; namespace NationalUnion.Common.Log
{
public class NationalUnionPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)
{ object obj = loggingEvent.MessageObject;
if (obj == null)
{
writer.Write(SystemInfo.NullText);
return;
}
if (Option == null)
{
writer.Write(obj.ToString());
return;
}
if (Option != null)
{
WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
}
//throw new NotImplementedException();
} private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)
{
object propertyValue = string.Empty;
Type type = loggingEvent.MessageObject.GetType();
PropertyInfo propertyInfo = type.GetProperty(property);
if (propertyInfo != null)
propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null); return propertyValue;
} } public class NationalUnionLayout : PatternLayout
{
public NationalUnionLayout()
{
this.AddConverter("o", typeof(NationalUnionPatternConverter));
}
}
public class NationalUnionMemberLayout : PatternLayout
{
public NationalUnionMemberLayout()
{
this.AddConverter("property", typeof(NationalUnionPatternConverter));
}
}
}
LogUtility.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using log4net;
using log4net.Appender;
using log4net.Layout; namespace NationalUnion.Common.Log
{
public static class Logger
{
public static ILog log; static Logger()
{
string strPath = HttpContext.Current.Server.MapPath("//");
strPath = System.IO.Path.Combine(strPath, "log");
strPath = System.IO.Path.Combine(strPath, "log4net.config");
System.IO.FileInfo log4file = new System.IO.FileInfo(strPath);
log4net.Config.XmlConfigurator.Configure(log4file);
log = LogManager.GetLogger("AdoNet");
} /// <summary>
/// 将日志记录到数据库中,缺省值都为空,需要开发人员填充
/// </summary>
/// <param name="message">日志信息</param>
/// <param name="Ip">IP地址</param>
/// <param name="user">用户账号</param>
/// <param name="methodname">当前的方法名称</param>
public static void InfoMessage(string message = "", string Ip = "", string user = "", string methodname = "")
{
if (message == null || Ip == null || user == null || methodname == null)
log.Info(new { message = "null param" });
else
{
log.Info(new { message = message, IP = Ip, user = user, method = methodname });
}
} /// <summary>
/// 将异常信息记录到数据库中,缺省值都为空,需要开发人员填充
/// </summary>
/// <param name="ex">异常实例</param>
/// <param name="message">日志信息</param>
/// <param name="Ip">IP地址</param>
/// <param name="user">用户账号</param>
/// <param name="methodname">方法名称</param>
public static void InfoMessageWithEx(System.Exception ex, string message = "", string Ip = "", string user = "", string methodname = "")
{
if (message == null || Ip == null || user == null || methodname == null)
{
log.Info(new { message = "null param" });
}
else
{
if (ex != null)
{
log.Warn(new { message = message, IP = Ip, user = user, method = methodname }, ex);
}
else
{
log.Info(new { message = message, IP = Ip, user = user, method = methodname });
}
}
} /// <summary>
/// 记录信息
/// </summary>
/// <param name="argUserID"></param>
/// <param name="argIP"></param>
/// <param name="argDescription"></param>
/// <param name="argMethod"></param>
public static void Info(long argUserID = , string argIP = "", string argDescription = "", string argMethod = "")
{
log.Info(new { UserID = argUserID, IP = argIP, Description = argDescription, Method = argMethod });
} /// <summary>
/// 记录错误
/// </summary>
/// <param name="argEx">异常信息</param>
/// <param name="argUserID">用户ID</param>
/// <param name="argIP">访问者IP</param>
/// <param name="argDescription">描述</param>
public static void LogError(System.Exception argEx, long argUserID = , string argIP = "", string argDescription = "")
{
log.Error(new { UserID = argUserID, IP = argIP, Description = argDescription }, argEx);
} /// <summary>
/// 记录错误
/// </summary>
/// <param name="argEx"></param>
/// <param name="argObj"></param>
public static void LogError(System.Exception argEx, object argObj)
{
log.Error(argObj, argEx);
}
}
}
调用方式:
try
{
int i = ;
int j = ;
int value = i / j;
}
catch (Exception e)
{
NationalUnion.Common.Log.Logger.LogError(e, this.MemberNo, this.IPAddress, "转换出错");
} NationalUnion.Common.Log.Logger.Info(this.MemberNo, this.IPAddress, "测试INfo", "NationalUnion.Member.Controllers.Index");
主要还是Filter里的设置记录的不同方式。
log配置文件
记录载图为:
更详细的参数说明参见