项目开发中,记录项目日志是必须的,若是非要说日志的重要性(日志可看作,飞机的黑匣子,或者汽车的行车记录仪),根据等级进行记录,方便咱们排查相关问题,之后项目运维中,也方便不少。基本上咱们进入一家公司,开发你从事什么岗位,公司产品或项目的框架都已经搭建好,咱们有时候进行改版,根据业务延伸框架,记录日志基本都是咱们本身去调用封装的方法。今天咱们就对Log4net进行一下学习,Log4net能够作到:一、邮箱发送日志;二、记录到数据库;三、生成记事本文件。本章Log4net学习,觉得是后面,我会简单一个微服务框架作准备。今天咱们主要对邮箱发送日志,生产记事本文件两种方式研究。后期有时间咱们在研究保存到数据库。web
开发环境:VS2013 ,建立一个WebAPI 模拟项目场景去解析Log4Net数据库
建立WebAPI步骤咱们就作简述说明,下面框架目录,今天咱们主要配置Log4net进行解析,因此只须要关注WebAPI 和WebAPICommon 就行,这里别忘记了三层之间的引用,WebAPI须要引用WebAPICommon 类库app
第一步,WebAPI 和WebAPICommon 中用NuGet搜索Log4net添加:Log4net引用框架
第二部,咱们在WebAPI添加一个Log4net.config配置文件,它主要放咱们的日志配置信息运维
第三部,在新建的Log4net.config配置文件中,添加日志配置,这里咱们作两部分讲解(文本格式,邮件发送),今天主要讲解文本格式,邮箱配置咱们作单独作模块;异步
下面把ERROR 为例,每行配置的具体解析:::微服务
<log4net> <!--错误日志:::记录错误日志--> <!--按日期分割日志文件 一天一个--> <!-- appender 定义日志输出方式 将日志以回滚文件的形式写到文件中。--> <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender"> <!--保存路径:下面路径项目启动的时候自动在C盘中建立log、logError文件--> <file value="C:\\log\\LogError\\"/>
<!-- 若是想在本项目中添加路径,那就直接去掉C:\\ 只设置log\\LogError 项目启动中默认建立文件 --> <appendToFile value="true"/> <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date"/> <!--这是按日期产生文件夹--> <datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/> <!--是否只写到一个文件中--> <staticLogFileName value="false"/> <!--保留的log文件数量 超过此数量后 自动删除以前的 好像只有在 按Size分割时有效 设定值value="-1"为不限文件数--> <param name="MaxSizeRollBackups" value="100"/> <!--每一个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在全部文件名后自动增长正整数从新命名,数字最大的最先写入。可用的单位:KB|MB|GB。不要使用小数,不然会一直写入当前日志--> <maximumFileSize value="1GB" /> <!-- layout 控制Appender的输出格式,也能够是xml 一个Appender只能是一个layout--> <layout type="log4net.Layout.PatternLayout"> <!--每条日志末尾的文字说明--> <!--输出格式 模板--> <!-- <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" />--> <!--样例: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"/>--> <conversionPattern value="%n========== %n【日志级别】%-5level %n【记录时间】%date %n【线程编号】[%thread] %n【执行时间】[%r]毫秒 %n【出错文件】%F %n【出错行号】%L %n【出错的类】%logger 属性[%property{NDC}] %n【错误描述】%message %n【错误详情】%newline"/> </layout> </appender> <!--Error日志::: 错误日志--> <logger name="logerror"> <level value="ERROR" /> <appender-ref ref="ErrorAppender" /> </logger> </log4net>
第四部: 在WebAPICommon类库中添加LogHelper类,该类就是获取配置类的配置,传送错误信息,能够直接复用;性能
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)] namespace WebAPICommon {
//日志的公共帮助类 public class LogHelper { #region /// <summary> /// /// </summary> /// <param name="msg"></param> public static void ErrorLog(object msg) { log4net.ILog log = log4net.LogManager.GetLogger("logerror"); Task.Run(() => log.Error(msg)); //异步 // Task.Factory.StartNew(() =>log.Error(msg));// 这种异步也能够
//log.Error(msg); //这种也行跟你须要,性能越好,越强大,我仍是使用异步方式
} /// <summary> /// /// </summary> /// <param name="ex"></param> public static void ErrorLog(Exception ex) { log4net.ILog log = log4net.LogManager.GetLogger("logerror"); Task.Run(() => log.Error(ex.Message.ToString() + "/r/n" + ex.Source.ToString() + "/r/n" + ex.TargetSite.ToString() + "/r/n" + ex.StackTrace.ToString())); } /// <summary> /// /// </summary> /// <param name="msg"></param> /// <param name="ex"></param> public static void ErrorLog(object msg, Exception ex) { log4net.ILog log = log4net.LogManager.GetLogger("logerror"); if (ex != null) { Task.Run(() => log.Error(msg, ex)); //异步 } else { Task.Run(() => log.Error(msg)); //异步 } } #endregion } }
查看后台代码你会发现,以Error为例有两个方法,两种方式传参数,咱们上面的封装也是根据咱们的业务需求,去扩展封装学习
方法解析重点:: 测试
LogManager类,它用来管理全部的Logger.它的GetLogger静态方法能够获取配置文件中的Logger
log4net.ILog log = log4net.LogManager.GetLogger("logerror");
//该方法也能够写公共的建立,而后直接使用
//static readonly log4net.ILog loginfo = log4net.LogManager.GetLogger("loginfo");
// static readonly log4net.ILog logerror = log4net.LogManager.GetLogger("logerror");
咱们介绍一下 文章中有一句话
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)]咱们来解读一下
首先咱们先说一下 log4net.Config.XmlConifguratorAttribute
XmlConfiguratorAttribute有3个属性: ConfigFile: 配置文件的名字,文件路径相对于应用程序目录(AppDomain.CurrentDomain.BaseDirectory)。ConfigFile属性不能和ConfigFileExtension属性一块儿使用。 ConfigFileExtension: 配置文件的扩展名,文件路径相对于应用程序的目录。ConfigFileExtension属性不能和ConfigFile属性一块儿使用。 Watch: 若是将Watch属性设置为true,就会监视配置文件。当配置文件发生变化的时候,就会从新加载。 若是ConfigFile和ConfigFileExtension都没有设置,则使用应用程序的配置文件App.config(Web.config)。
能够在项目的AssemblyInfo.cs文件里添加如下的语句,根据配置业务项目中配置不一样,能够直接复制粘贴:
//监视默认的配置文件,App.exe.config [assembly: log4net.Config.XmlConfigurator(Watch = true)] //监视配置文件,App.exe.log4net。 [assembly: log4net. Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)] //使用配置文件log4net.config,不监视改变。注意log4net.config文件的目录,BS程序在站点目录//下,CS则在应用程序启动目录下,如调试时在/bin/Debug下,通常将文件属性的文件输出目录调为//始终复制便可 [assembly: log4net. Config.XmlConfigurator(ConfigFile = "log4net.config")] //使用配置文件log4net.config,不监视改变 [assembly: log4net. Config.XmlConfigurator()]
第五部:咱们才用的WebAPI测试,还须要启动项目日志
在WebAPI中找到:Global文件
Global.asax 文件是 ASP.NET 应用程序的中心点。它提供无数的事件来处理不一样的应用程序级任务,好比用户身份验证、应用程序启动以及处理用户会话等。你应该熟悉这个可选文件,这样就能够构建出健壮的ASP.NET 应用程序。
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles);
//启动项日志记录 //若不想把lognet配置文件写在web.config中,也能够另外手动指定。 log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Server.MapPath("/log4net.config"))); } /// <summary> /// 程序出错时经过lognet写日志 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Application_Error(Object sender, EventArgs e) { Exception objExp = HttpContext.Current.Server.GetLastError(); LogHelper.ErrorLog("\r\n客户机IP:" + Request.UserHostAddress + "\r\n错误地址:" + Request.Url + "\r\n异常信息:" + Server.GetLastError().Message, objExp); }
方法解析: Application_Error,该方法我我的建议添加,若是你的项目其中过程就报错,咱们能够捕捉到异常信息。
最后一步:咱们进行测试,在你须要的地方,引用WebAPICommon类库,
在你须要的地方加入 LogHelper.ErrorLog(object);
public bool Add(Department department) { try { return dep.Add(department); } catch (Exception ex) { LogHelper.ErrorLog(ex); //在你须要的地方 加入 LogHelper.ErrorLog(ex)
throw;
} }