前言

在之前的.NET中,微软还没有提供过像样的日志框架,目前能用的一些框架比如Log4Net、NLog、CommonLogging等,虽然多多少少使用起来有点费劲,但这里还是简单分享一下Log4Net的初步使用方法。

在项目中的配置

第一步:首先在项目用引用Log4Net.dll.[管理NuGet程序包中直接搜索就可以啦]

第二步:Web.config文件中进行添加confIGsections的节点

<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
</configuration>

第三步:在configSections下添加Log4Net配置节点[这里将日志分类了,以便于理解与查看对应的日志信息]

<log4net>
<!--错误日志-->
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log\\LogError\\" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
<staticLogFileName value="false" />
<param name="MaxSizeRollBackups" value="100" />
<layout type="log4net.Layout.PatternLayout">
<!--每条日志末尾的文字说明-->
<!--输出格式-->
<!--样例:2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info-->
<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n" />
</layout>
</appender> <!--Info日志-->
<appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Log\\LogInfo\\" />
<param name="AppendToFile" value="true" />
<param name="MaxFileSize" value="10240" />
<param name="MaxSizeRollBackups" value="100" />
<param name="StaticLogFileName" value="false" />
<param name="DatePattern" value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
<param name="RollingStyle" value="Date" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n日志描述:%message%newline %n" />
</layout>
</appender> <!--监控日志-->
<appender name="MonitorAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Log\\LogMonitor\\" />
<param name="AppendToFile" value="true" />
<param name="MaxFileSize" value="10240" />
<param name="MaxSizeRollBackups" value="100" />
<param name="StaticLogFileName" value="false" />
<param name="DatePattern" value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
<param name="RollingStyle" value="Date" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n跟踪描述:%message%newline %n" />
</layout>
</appender> <!--Error日志-->
<logger name="LogError">
<level value="ERROR" />
<appender-ref ref="RollingLogFileAppender" />
</logger> <!--Info日志-->
<logger name="LogInfo">
<level value="INFO" />
<appender-ref ref="InfoAppender" />
</logger> <!--监控日志-->
<logger name="LogMonitor">
<level value="Monitor" />
<appender-ref ref="MonitorAppender" />
</logger>
</log4net>

  在框架的体系里,所有的日志对象都是根日志(root logger)的后代。 因此如果一个日志对象没有在配置文件里显式定义,则框架使用根日志中定义的属性。在<root>标签里,可以定义level级别值和Appender的列表。如果没有定义LEVEL的值,则缺省为DEBUG。可以通过<appender-ref>标签定义日志对象使用的Appender对象。<appender-ref>声明了在其他地方定义的Appender对象的一个引用。在一个logger对象中的设置会覆盖根日志的设置。而对Appender属性来说,子日志对象则会继承父日志对象的Appender列表。这种缺省的行为方式也可以通过显式地设定<logger>标签的additivity属性为false而改变。

在项目中建立自定义Log日志

第四步:在文件里配置以下类:ApiTrackerFilter.cs[Api接口日志],TrackerFilter.cs[基本日志类],LoggerHelper.cs[日志信息处理类],MonitorLog.cs[监控日志类](对于监控日志,则根据个人需求是否建立),其中的BookException是自定义的错误,可以省略。

public class LoggerHelper
{
private static readonly log4net.ILog LogInfo = log4net.LogManager.GetLogger("LogInfo");
private static readonly log4net.ILog LogError = log4net.LogManager.GetLogger("LogError");
private static readonly log4net.ILog LogMonitor = log4net.LogManager.GetLogger("LogMonitor"); /// <summary>
/// 记录Error日志
/// </summary>
/// <param name="errorMsg"></param>
/// <param name="ex"></param>
public static void Error(string errorMsg, Exception ex = null)
{
if (ex != null)
{
LogError.Error(errorMsg, ex);
}
else
{
LogError.Error(errorMsg);
}
} /// <summary>
/// 记录Info日志
/// </summary>
/// <param name="msg"></param>
/// <param name="ex"></param>
public static void Info(string msg, Exception ex = null)
{
if (ex != null)
{
LogInfo.Info(msg, ex);
}
else
{
LogInfo.Info(msg);
}
} /// <summary>
/// 记录Monitor日志
/// </summary>
/// <param name="msg"></param>
public static void Monitor(string msg)
{
LogMonitor.Info(msg);
}
}

LoggerHelper.cs

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class TrackerFilter : ActionFilterAttribute, IExceptionFilter
{
private readonly string key = "_thisOnActionMonitorLog_"; #region Action时间监控
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
MonitorLog monLog = new MonitorLog();
monLog.ExecuteStartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff", DateTimeFormatInfo.InvariantInfo));
monLog.ControllerName = filterContext.RouteData.Values["controller"] as string;
monLog.ActionName = filterContext.RouteData.Values["action"] as string;
filterContext.Controller.ViewData[this.key] = monLog;
} public override void OnActionExecuted(ActionExecutedContext filterContext)
{
MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
monLog.ExecuteEndTime = DateTime.Now;
monLog.FormCollections = filterContext.HttpContext.Request.Form;//form表单提交的数据
monLog.QueryCollections = filterContext.HttpContext.Request.QueryString;//Url 参数
LoggerHelper.Monitor(monLog.GetLogInfo());
}
#endregion #region View 视图生成时间监控
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
monLog.ExecuteStartTime = DateTime.Now;
} public override void OnResultExecuted(ResultExecutedContext filterContext)
{
MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
monLog.ExecuteEndTime = DateTime.Now;
LoggerHelper.Monitor(monLog.GetLogInfo(MonitorLog.MonitorType.View));
filterContext.Controller.ViewData.Remove(this.key);
}
#endregion #region 错误日志
public void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled)
{
string controllerName = string.Format("{0}Controller", filterContext.RouteData.Values["controller"] as string);
string actionName = filterContext.RouteData.Values["action"] as string;
string errorMsg = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName);
LoggerHelper.Error(errorMsg, filterContext.Exception);
}
}
#endregion
}

TrackerFilter.cs

    /// <summary>
/// 监控日志对象
/// </summary>
public class MonitorLog
{
public MonitorLog()
{
this.Watch = new Stopwatch();
this.Watch.Start();
} /// <summary>
/// 监控类型
/// </summary>
public enum MonitorType
{
/// <summary>
/// Action
/// </summary>
Action = 1, /// <summary>
/// 视图
/// </summary>
View = 2
} public string ControllerName { get; set; } public string ActionName { get; set; } public Stopwatch Watch { get; set; } public DateTime ExecuteStartTime { get; set; } public DateTime ExecuteEndTime { get; set; } /// <summary>
/// Form 表单数据
/// </summary>
public NameValueCollection FormCollections { get; set; } /// <summary>
/// URL 参数
/// </summary>
public NameValueCollection QueryCollections { get; set; } /// <summary>
/// 文本流
/// </summary>
public string Raw { get; set; } /// <summary>
/// 获取监控指标日志
/// </summary>
/// <param name="mtype"></param>
/// <returns></returns>
public string GetLogInfo(MonitorType mtype = MonitorType.Action)
{
this.Watch.Stop();
string actionView = "Action执行时间监控:";
string action = "Action";
if (mtype == MonitorType.View)
{
actionView = "View视图生成时间监控:";
action = "View";
}
string msgContent = string.Format(
@"
{0}
ControllerName:{1}Controller
{2}Name:{3}
开始时间:{4}
结束时间:{5}
总 时 间:{6}秒",
actionView,
this.ControllerName,
action,
this.ActionName,
this.ExecuteStartTime,
this.ExecuteEndTime,
this.Watch.ElapsedMilliseconds); if (!string.IsNullOrEmpty(this.Raw))
{
msgContent += @"
Raw:" + this.Raw;
}
else if (this.FormCollections != null)
{
msgContent += @"
Form:" + this.GetCollections(this.FormCollections);
}
else if (this.QueryCollections != null)
{
msgContent += @"
Query:" + this.GetCollections(this.QueryCollections);
} return msgContent;
} /// <summary>
/// 获取Post 或Get 参数
/// </summary>
/// <param name="collections"></param>
/// <returns></returns>
public string GetCollections(NameValueCollection collections)
{
string parameters = string.Empty;
if (collections == null || collections.Count == 0)
{
return parameters;
}
parameters = collections.Keys.Cast<string>()
.Aggregate(parameters, (current, key) => current + string.Format("{0}={1}&", key, collections[key]));
if (!string.IsNullOrWhiteSpace(parameters) && parameters.EndsWith("&"))
{
parameters = parameters.Substring(0, parameters.Length - 1);
}
return parameters;
}

MonitorLog.cs

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class ApiTrackerFilter : ActionFilterAttribute
{
private readonly string key = "_thisOnApiActionMonitorLog_"; public override void OnActionExecuting(HttpActionContext actionContext)
{
var monLog = new MonitorLog();
monLog.ExecuteStartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff", DateTimeFormatInfo.InvariantInfo)); monLog.ControllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
monLog.ActionName = actionContext.ActionDescriptor.ActionName;
actionContext.Request.Properties[this.key] = monLog;
} public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Exception != null)
{
string controllerName = string.Format(
"{0}Controller",
actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName);
string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
string errorMsg = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName);
if (actionExecutedContext.Exception is BookException)
{
LoggerHelper.Info(errorMsg, actionExecutedContext.Exception);
}
else
{
LoggerHelper.Error(errorMsg, actionExecutedContext.Exception);
}
} if (!actionExecutedContext.Request.Properties.ContainsKey(this.key))
{
return;
} var monLog = actionExecutedContext.Request.Properties[this.key] as MonitorLog;
if (monLog != null)
{
monLog.ExecuteEndTime = DateTime.Now; monLog.Raw = actionExecutedContext.Request.Content.ReadAsStringAsync().Result;
LoggerHelper.Monitor(monLog.GetLogInfo());
}
}
}

ApiTrackerFilter.cs

在Global.asax文件中配置以及在MVC的FilterConfig过滤器中配置信息

经过这么多的准备工作,终于最后一步:

1.Global.axax中配置

protected void Application_Start(object sender, EventArgs e)
{ AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
log4net.Config.XmlConfigurator.Configure(); GlobalConfiguration.Configuration.Filters.Add(new Log.ApiTrackerFilter());
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

2.在FilterConfig过滤器中配置信息

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//监控日志
filters.Add(new Log.TrackerFilter()); filters.Add(new HandleErrorAttribute());
}

至此,所有都成功了,最后运行的结果可以在项目根目录下查看相应日期的Log日志信息。

ASP.NET MVC4中加入Log4Net日志记录功能的更多相关文章

  1. 个人理解---在开发中何时加入日志记录功能[java]

    是这样的:俩个月前做的一个小功能,今天经理突然问我这个'清除复投记录'功能是不是我做的,我说是,很久以前了.他说昨天一个客户找过来了,后台把人家的复投记录清除掉了,不知道何时清除的,我记得当时做的时候 ...

  2. C#面试题(转载) SQL Server 数据库基础笔记分享(下) SQL Server 数据库基础笔记分享(上) Asp.Net MVC4中的全局过滤器 C#语法——泛型的多种应用

    C#面试题(转载) 原文地址:100道C#面试题(.net开发人员必备)  https://blog.csdn.net/u013519551/article/details/51220841 1. . ...

  3. 如何在通用权限管理系统中集成log4net日志功能

    开发人员都知道,在系统运行中要记录各种日志,自己写一个日志功能,无论是在效率还是功能扩展上来说都不是很好,目前大多用的是第三方的日志系统,其中一个非常有名,用的最多的就是log4net.下面是关于这个 ...

  4. ASP.NET MVC4中使用NHibernate

    ASP.NET MVC4中使用NHibernate 1:下载安装NHibernate 打开 VS 2012新建一个 MVC4项目. 在项目名称上右击选择Manage NuGet Packages.你会 ...

  5. ASP.NET MVC4中的App_start中BundleConfig的介绍使用

    在BundleConfig.cs中,指定CSS和JS,主要用来压缩JS和CSS   在ASP.NET MVC4中(在WebForm中应该也有),有一个叫做Bundle的东西,它用来将js和css进行压 ...

  6. ASP.NET MVC4中对JS和CSS的引用

    https://www.cnblogs.com/madyina/p/3702314.html ASP.NET MVC4中对JS和CSS的引用又做了一次变化,在MVC3中我们这样引用资源文件: < ...

  7. ASP.NET MVC4中的bundles特性引发服务器拒绝访问(403错误)

    在ASP.NET MVC4中微软引入了bundles特性,这个特性可以将服务器端的多个Javascript或多个css文件捆绑在一起作为一个单一的URL地址供客户端浏览器调用,从而减少了页面上Http ...

  8. WebSocket在ASP.NET MVC4中的简单实现

    WebSocket在ASP.NET MVC4中的简单实现 2013-12-21 20:48 by 小白哥哥, 810 阅读, 3 评论, 收藏, 编辑 WebSocket 规范的目标是在浏览器中实现和 ...

  9. 在ASP.NET MVC4中实现同页面增删改查,无弹出框02,增删改查界面设计

    在上一篇"在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建"中,已经搭建好了Repository层,本篇就剩下增删改查的界面了......今 ...

随机推荐

  1. Struts2 框架使用 核心以及其他详细配置

    因为在使用SSH框架的过程,关于struts2的配置比较繁琐,所以做个总结. 一.导入并且关联其他XML 1.   因为在核心配置文件(Struts2.xml)中,如果存在很多需要配置的Action项 ...

  2. PCI 设备调试手段

    Author: Younix Platform: RK3399 OS: Android 6.0 Kernel: 4.4 Version: v2017.04 一PCI 设备调试手段 busybox ls ...

  3. ajax post get

    1.Ajax   post 方法 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind=&qu ...

  4. 2014年蓝桥杯省赛A组c++第1题(暴力求解)

    /* 小明带两个妹妹参加元宵灯会.别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍”. 小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊.” 请你写出:小明的较小的妹妹的年 ...

  5. iOS中的静态库与动态库,区别、制作和使用

    如果我们有些功能要给别人用,但是又不想公开代码实现,比如高德地图.第三方登录分享等等,这时候我们就要打包成库了.库分静态库和动态库两种: 静态库:以.a 和 .framework为文件后缀名.动态库: ...

  6. HBase 笔记

    参考资料:HBase权威指南 一行由若干列组成,若干列又构成一个列族一个列族的所有列存储在同一个底层的存储文件里,这个文件叫HFile列族的数量有限制:一个列族里列的数量没限制谓词删除:例如允许用户只 ...

  7. 前端 HTML form表单标签 textarea标签 多行文本

    <textarea></textarea>作用:允许用户录入多行数据到表单控件中 <!DOCTYPE html> <html lang="en&qu ...

  8. wamp支持win10吗?怎么设置?

    上周ytkah总算把系统升级到win10了,可怎么设置wamp支持win10呢?启动wampwerver是处于黄色状态,打开本地页面是空白,应该是端口问题. 单击右下角wamp图标,点Apache,修 ...

  9. Dockerfile语法解析

    Dockfile介绍 从上到下依次执行 每次执行一条指令就创建一个镜像层 第一条指令必须是FROM    表示需要构建的镜像是由哪个镜像为基础镜像   后续的指令运行于此基准镜像所提供的运行环境 可以 ...

  10. 005-优化web请求一-gzip压缩、http缓存控制和缓存校验[Pragma、Expires、Cache-Control、max-age、Last-Modified、用户刷新访问、避免过度304]

    优化Web应用的典型技术:缓存控制头信息.Gzip.应用缓存.ETag.反应型技术[异步方法调用和WebSocket] 一.模板缓存 spring.thymeleaf.cache=true sprin ...