1、添加log4net引用
2、在项目里添加log4net.config文件
3、log4net.config代码如下,可修改添加字段
需要注意的是,如果有新增字段,需要自己转换,添加一个自定义的Layout,修改方式:
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">,这里我添加一个CustomLayout,type需要赋值为CustomLayout的路径。
数据库链接字符串需要自己去配置:将数据库的地址、名称、账号、密码替换为你对应的数据库即可
<connectionString value="data source={数据库地址};initial catalog={数据库名称};Integrated Security=false;user id={数据库账号};password={数据库密码};" />
<?xml version="1.0"?>
<configuration>
<!--声明一个名为“log4net”的自定义配置节-->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<!--log4net配置信息-->
<log4net>
<logger name="InfoLogger">
<level value="INFO"/>
<!--定义在这个级别之上的日志才会被记录-->
<appender-ref ref="InfoAppender" />
<!--定义日志对象使用的Appender对象-->
</logger>
<logger name="ErrorLogger">
<level value="Erros"/>
<!--定义在这个级别之上的日志才会被记录-->
<appender-ref ref="ErrorAppender" />
<!--定义日志对象使用的Appender对象-->
</logger>
<!--Appenders用来定义日志的输出方式 -->
<!--name = “AdoNetAppender” sql数据库-->
<appender name="InfoAppender" type="log4net.Appender.ADONetAppender">
<!--缓冲区大小为10,缓存10条记录同时写入数据库,避免每次都去请求数据库连接写数据-->
<bufferSize value="1"/>
<!-- SQL数据源 ,本地安装SQL客户端-->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<!-- SQL连接字符串,修改为自己的-->
<connectionString value="data source={数据库地址};initial catalog={数据库名称};Integrated Security=false;user id={数据库账号};password={数据库密码};" />
<!-- 数据库插入-->
<commandText value="INSERT INTO tLogInfos (
[ThreadId],
[Level],
[Message],
[Exception],
[LogTime],
[IP],
[ControllerName],
[ActionName],
[Url],
[UserBrowser],
[UserBrowserVersion]
)
VALUES (
@thread,
@log_level,
@message,
@exception,
@log_date,
@IP,
@ControllerName,
@ActionName,
@Url,
@UserBrowser,
@UserBrowserVersion
)"/>
<!--线程号-->
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%t" />
</layout>
</parameter>
<!--日志记录时间,RawTimeStampLayout 为默认的时间输出格式-->
<parameter>
<parameterName value="@log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout"/>
</parameter>
<!--日志等级-->
<parameter>
<parameterName value="@log_level"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level"/>
</layout>
</parameter>
<!--异常 ExceptionLayout 默认的异常输出格式-->
<parameter>
<parameterName value="@exception"/>
<dbType value="String"/>
<size value="6000"/>
<layout type="log4net.Layout.ExceptionLayout"/>
</parameter>
<parameter>
<parameterName value="@message"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%Description"/>
</layout>
</parameter>
<!--自定义成员-->
<parameter>
<parameterName value="@IP" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%IP" />
</layout>
</parameter>
<parameter>
<parameterName value="@ControllerName" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%ControllerName" />
</layout>
</parameter>
<parameter>
<parameterName value="@ActionName" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%ActionName" />
</layout>
</parameter>
<parameter>
<parameterName value="@Url" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%Url" />
</layout>
</parameter>
<parameter>
<parameterName value="@UserBrowser" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%UserBrowser" />
</layout>
</parameter>
<parameter>
<parameterName value="@UserBrowserVersion" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%UserBrowserVersion" />
</layout>
</parameter>
</appender>
<!--name ="ErroAppender"-->
<appender name="ErrorAppender" type="log4net.Appender.ADONetAppender">
<!--缓冲区大小为10,缓存10条记录同时写入数据库,避免每次都去请求数据库连接写数据-->
<bufferSize value="1"/>
<!-- SQL数据源 ,本地安装SQL客户端-->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<!-- SQL连接字符串,修改为自己的-->
<connectionString value="data source={数据库地址};initial catalog={数据库名称};Integrated Security=false;user id={数据库账号};password={数据库密码};" />
<!-- 数据库插入-->
<commandText value="INSERT INTO tLogInfos (
[ThreadId],
[Level],
[Message],
[Exception],
[LogTime],
[IP],
[ControllerName],
[ActionName],
[Url],
[UserBrowser],
[UserBrowserVersion]
)
VALUES (
@thread,
@log_level,
@message,
@exception,
@log_date,
@IP,
@ControllerName,
@ActionName,
@Url,
@UserBrowser,
@UserBrowserVersion
)"/>
<!--线程号-->
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%t" />
</layout>
</parameter>
<!--日志记录时间,RawTimeStampLayout 为默认的时间输出格式-->
<parameter>
<parameterName value="@log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout"/>
</parameter>
<!--日志等级-->
<parameter>
<parameterName value="@log_level"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level"/>
</layout>
</parameter>
<!--异常 ExceptionLayout 默认的异常输出格式-->
<parameter>
<parameterName value="@exception"/>
<dbType value="String"/>
<size value="6000"/>
<layout type="log4net.Layout.ExceptionLayout"/>
</parameter>
<parameter>
<parameterName value="@message"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%Description"/>
</layout>
</parameter>
<!--自定义成员-->
<parameter>
<parameterName value="@IP" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%IP" />
</layout>
</parameter>
<parameter>
<parameterName value="@ControllerName" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%ControllerName" />
</layout>
</parameter>
<parameter>
<parameterName value="@ActionName" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%ActionName" />
</layout>
</parameter>
<parameter>
<parameterName value="@Url" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%Url" />
</layout>
</parameter>
<parameter>
<parameterName value="@UserBrowser" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%UserBrowser" />
</layout>
</parameter>
<parameter>
<parameterName value="@UserBrowserVersion" />
<dbType value="String" />
<layout type="ITCGB.Intel._10th.Web.Common.Logger.CustomLayout">
<conversionPattern value="%UserBrowserVersion" />
</layout>
</parameter>
</appender>
<!--<root>
<level value="DEBUG"/>
<appender-ref ref="InfoAppender"/>
</root>-->
</log4net>
<startup>
<supportedRuntime version="v4.7.2" sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>
4、创建CustomLayout类
public class CustomLayout : log4net.Layout.PatternLayout
{
public CustomLayout()
{
this.AddConverter("IP", typeof(IPPatternConverter));
this.AddConverter("ControllerName", typeof(ControllerNamePatternConverter));
this.AddConverter("ActionName", typeof(ActionNamePatternConverter));
this.AddConverter("Description", typeof(DescriptionPatternConverter));
this.AddConverter("Url", typeof(UrlPatternConverter));
this.AddConverter("UserId", typeof(UserIdPatternConverter));
this.AddConverter("UserBrowser", typeof(UserBrowserPatternConverter));
this.AddConverter("UserBrowserVersion", typeof(UserBrowserVersionPatternConverter));
}
}
internal sealed class IPPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.IP);
}
}
internal sealed class DescriptionPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.Description);
}
}
internal sealed class ControllerNamePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.ControllerName);
}
}
internal sealed class ActionNamePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.ActionName);
}
}
internal sealed class UrlPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.Url);
}
}
internal sealed class UserBrowserPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.UserBrowser);
}
}
internal sealed class UserIdPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.UserId);
}
}
internal sealed class UserBrowserVersionPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogModel logMessage = loggingEvent.MessageObject as LogModel;
if (logMessage != null)
writer.Write(logMessage.UserBrowserVersion);
}
}
5、创建LogModel类,需要的字段
public class LogModel
{
public string IP { get; set; }
public string ControllerName { get; set; }
public string ActionName { get; set; }
public string Description { get; set; }
public string Url { get; set; }
public int UserId { get; set; }
public string UserBrowser { get; set; }
public string UserBrowserVersion { get; set; }
}
6、创建LoggerHelper类
//这里需要配置log4net.config的所在的位置
[assembly: XmlConfigurator(ConfigFile = "Configs/log4net.config", Watch = true)]
namespace ITCGB.Intel._10th.Web.Common.Logger
{
public class LogHelper
{
private static readonly ILog loginfo = LogManager.GetLogger("InfoLogger");
private static readonly ILog logerror = LogManager.GetLogger("ErrorLogger");
/// <summary>
/// 记录一般日志
/// </summary>
public static void LogInfo(LogModel opLog)
{
try
{
if (loginfo.IsInfoEnabled)
{
loginfo.Info(opLog);
}
}
catch (Exception ex)
{
throw;
}
}
/// <summary>
/// 记录错误
/// </summary>
public static void LogError(LogModel opLog, Exception ex)
{
if (logerror.IsErrorEnabled)
{
logerror.Error(opLog, ex);
}
}
/// <summary>
/// 记录严重错误
/// </summary>
public static void LogFatal(LogModel opLog, Exception ex)
{
if (logerror.IsFatalEnabled)
{
logerror.Fatal(opLog, ex);
}
}
/// <summary>
/// 记录警告
/// </summary>
public static void LogWarn(LogModel opLog)
{
if (logerror.IsWarnEnabled)
{
logerror.Warn(opLog);
}
}
}
}
7、添加LogInfo的过滤器和异常过滤器
LogInfoAttribute 过滤器
/// <summary>
/// 日志过滤
/// </summary>
public class LogInfoAttribute : ActionFilterAttribute
{
/// <summary>
/// 描述
/// </summary>
private string _description;
/// <summary>
/// 日志记录过滤
/// </summary>
/// <param name="title">日志标题</param>
/// <param name="content">日志描述</param>
public LogInfoAttribute(
string description)
{
_description = description;
}
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
try
{
var s = actionContext.ControllerContext.Controller;
string controllerName = (string)actionContext.ControllerContext.RouteData.Values["controller"];
string actionName = (string)actionContext.ControllerContext.RouteData.Values["action"];
LogModel infoLog = new LogModel
{
IP = HttpContext.Current.Request.UserHostAddress,
ActionName = actionName,
ControllerName = controllerName,
Description = _description,
Url = HttpContext.Current.Request.Url.ToString(),
UserId = 1,
UserBrowser = HttpContext.Current.Request.Browser.Browser,
UserBrowserVersion = HttpContext.Current.Request.Browser.Version,
};
LogHelper.LogInfo(infoLog);//调用
}
catch
{
}
}
}
ExceptionFilterAttribute 异常过滤器
/// <summary>
/// 全局异常过滤
/// </summary>
public class ExceptionFilterAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
base.OnException(filterContext);
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
var ex = filterContext.Exception;
LogModel exLog = new LogModel
{
IP = HttpContext.Current.Request.UserHostAddress,
ActionName = actionName,
ControllerName = controllerName,
Description = ex.Message,
Url = HttpContext.Current.Request.Url.ToString(),
UserBrowser = filterContext.HttpContext.Request.Browser.Browser,
UserBrowserVersion = filterContext.HttpContext.Request.Browser.Version
};
LogHelper.LogError(exLog, new Exception(ex.ToString()));//调用
filterContext.ExceptionHandled = true;
//如果是Ajax访问,则返回Json的错误提示
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new { success = false, msg = "服务器错误!" }
};
}
else
{
filterContext.Result = new ViewResult() { ViewName = "~/Views/Shared/Error.cshtml" };
}
}
}
数据库字段脚本
USE [这里是数据库名称]
GO
/****** Object: Table [dbo].[tLogInfos] Script Date: 2020/7/22 14:48:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tLogInfos](
[IntId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NULL,
[LogTime] [datetime] NULL,
[ControllerName] [varchar](20) NULL,
[ActionName] [varchar](20) NULL,
[Message] [varchar](max) NULL,
[Exception] [varchar](max) NULL,
[IP] [varchar](20) NULL,
[Url] [varchar](max) NULL,
[UserBrowser] [varchar](100) NULL,
[UserBrowserVersion] [varchar](100) NULL,
[Level] [varchar](10) NULL,
[ThreadId] [int] NULL,
[CreateTime] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
网友评论