一. 整合Log4net

1. 简单说明

  对于log4net 官方的程序集而言,从2.0.7开始就支持.Net Core了,这里我们采用的是2.0.8,虽然好久没更新了,但不影响使用。Core版本与普通的.Net版本下的使用方法非常类似,仅仅多了一步【创建日志仓储对象】CreateRepository而已,在实际框架封装中,建议把ILoggerRepository和ILog对象设置成单例的。

  .Net 版本的Log4Net参考:https://www.cnblogs.com/yaopengfei/p/9428206.html

2. 使用步骤

声明:【使用的是log4net官方程序集,MyLog02项目直接Nuget Log4net 程序集即可,使用的是该层中的Xml文件下的log4net.xml配置文件】

(1).通过Nuget安装【log4net 2.0.8】,并将log4net.xml配置文件拷贝到Xml文件夹下,将其生成操作改为“嵌入的资源”.

PS:log4net.xml文件与.Net版本下使用的一致,直接拷贝过来的,代码如下:

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- 一. 添加log4net的自定义配置节点-->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<!--二. log4net的核心配置代码-->
<log4net>
<!--1. 输出途径(一) 将日志以回滚文件的形式写到文件中--> <!--模式一:全部存放到一个文件夹里-->
<appender name="log0" type="log4net.Appender.RollingFileAppender">
<!--1.1 文件夹的位置(也可以写相对路径)-->
<param name="File" value="D:\CoreLog\" />
<!--相对路径-->
<!--<param name="File" value="Logs/" />-->
<!--1.2 是否追加到文件-->
<param name="AppendToFile" value="true" />
<!--1.3 使用最小锁定模型(minimal locking model),以允许多个进程可以写入同一个文件 -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<!--1.4 配置Unicode编码-->
<Encoding value="UTF-8" />
<!--1.5 是否只写到一个文件里-->
<param name="StaticLogFileName" value="false" />
<!--1.6 配置按照何种方式产生多个日志文件 (Date:日期、Size:文件大小、Composite:日期和文件大小的混合方式)-->
<param name="RollingStyle" value="Composite" />
<!--1.7 介绍多种日志的的命名和存放在磁盘的形式-->
<!--1.7.1 在根目录下直接以日期命名txt文件 注意&quot;的位置,去空格 -->
<param name="DatePattern" value="yyyy-MM-dd&quot;.log&quot;" />
<!--1.7.2 在根目录下按日期产生文件夹,文件名固定 test.log -->
<!--<param name="DatePattern" value="yyyy-MM-dd/&quot;test.log&quot;" />-->
<!--1.7.3 在根目录下按日期产生文件夹,这是按日期产生文件夹,并在文件名前也加上日期 -->
<!--<param name="DatePattern" value="yyyyMMdd/yyyyMMdd&quot;-test.log&quot;" />-->
<!--1.7.4 在根目录下按日期产生文件夹,这再形成下一级固定的文件夹 -->
<!--<param name="DatePattern" value="yyyyMMdd/&quot;OrderInfor/test.log&quot;" />-->
<!--1.8 配置每个日志的大小。【只在1.6 RollingStyle 选择混合方式与文件大小方式下才起作用!!!】可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志,
超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。-->
<param name="maximumFileSize" value="10MB" />
<!--1.9 最多产生的日志文件个数,超过则保留最新的n个 将value的值设置-1,则不限文件个数 【只在1.6 RollingStyle 选择混合方式与文件大小方式下才起作用!!!】
与1.8中maximumFileSize文件大小是配合使用的-->
<param name="MaxSizeRollBackups" value="5" />
<!--1.10 配置文件文件的布局格式,使用PatternLayout,自定义布局-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date %n线程ID:[%thread] %n日志级别:%-5level %n出错类:%logger property: [%property{NDC}] - %n错误描述:%message%newline %n%newline"/>
</layout>
</appender> <!--模式二:分文件夹存放-->
<!--文件夹1-->
<appender name="log1" type="log4net.Appender.RollingFileAppender">
<param name="File" value="D:\CoreLog\OneLog\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyy-MM-dd&quot;.log&quot;" />
<param name="maximumFileSize" value="10MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date %n错误描述:%message%newline %n%newline"/>
</layout>
<!--下面是利用过滤器进行分文件夹存放,两种过滤器进行配合-->
<!--与Logger名称(OneLog)匹配,才记录,-->
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="OneLog" />
</filter>
<!--阻止所有的日志事件被记录-->
<filter type="log4net.Filter.DenyAllFilter" />
</appender>
<!--文件夹2-->
<appender name="log2" type="log4net.Appender.RollingFileAppender">
<param name="File" value="D:\CoreLog\TwoLog\" />
<param name="AppendToFile" value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<Encoding value="UTF-8" />
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="Composite" />
<param name="DatePattern" value="yyyy-MM-dd&quot;.log&quot;" />
<param name="maximumFileSize" value="10MB" />
<param name="MaxSizeRollBackups" value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="记录时间:%date %n错误描述:%message%newline %n%newline"/>
</layout>
<!--下面是利用过滤器进行分文件夹存放,两种过滤器进行配合-->
<!--与Logger名称(TwoLog)匹配,才记录,-->
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="TwoLog" />
</filter>
<!--阻止所有的日志事件被记录-->
<filter type="log4net.Filter.DenyAllFilter" />
</appender> <!--2. 输出途径(二) 记录日志到数据库-->
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<!--2.1 设置缓冲区大小,只有日志记录超设定值才会一块写入到数据库-->
<param name="BufferSize" value="1" />
<!--2.2 引用-->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--2.3 数据库连接字符串-->
<connectionString value="data source=localhost;initial catalog=LogDB;integrated security=false;persist security info=True;User ID=sa;Password=123456" />
<!--2.4 SQL语句插入到指定表-->
<commandText value="INSERT INTO LogInfor ([threadId],[log_level],[log_name],[log_msg],[log_exception],[log_time]) VALUES (@threadId, @log_level, @log_name, @log_msg, @log_exception,@log_time)" />
<!--2.5 数据库字段匹配-->
<!-- 线程号-->
<parameter>
<parameterName value="@threadId" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<!--日志级别-->
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<!--日志记录类名称-->
<parameter>
<parameterName value="@log_name" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<!--日志信息-->
<parameter>
<parameterName value="@log_msg" />
<dbType value="String" />
<size value="5000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<!--异常信息 指的是如Infor 方法的第二个参数的值-->
<parameter>
<parameterName value="@log_exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
<!-- 日志记录时间-->
<parameter>
<parameterName value="@log_time" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
</appender> <!--(二). 配置日志的的输出级别和加载日志的输出途径-->
<root>
<!--1. level中的value值表示该值及其以上的日志级别才会输出-->
<!--OFF > FATAL(致命错误) > ERROR(一般错误) > WARN(警告) > INFO(一般信息) > DEBUG(调试信息) > ALL -->
<!--OFF表示所有信息都不写入,ALL表示所有信息都写入-->
<level value="ALL"></level>
<!--2. append-ref标签表示要加载前面的日志输出途径代码 通过ref和appender标签的中name属性相关联--> <!--<appender-ref ref="AdoNetAppender"></appender-ref>-->
<appender-ref ref="log0"></appender-ref>
<appender-ref ref="log1"></appender-ref>
<appender-ref ref="log2"></appender-ref>
</root>
</log4net> </configuration>

(2).创建日志仓储对象, 在框架封装的时候,建议把该对象封装成单例的。

ILoggerRepository repository = LogManager.CreateRepository("myRespository");

(3).加载XML文件,前提要先把xml属性改为“嵌入的资源”,这里主要有两种方式,一种是反射的方式加载,需要加上“程序集名称”,如下面代码中的“MyLog”;另外一种是文件的方式,直接定位到文件路径即可。

A:反射

 Assembly assembly = Assembly.GetExecutingAssembly();
var xml = assembly.GetManifestResourceStream("MyLog.Xml.log4net.xml");
XmlConfigurator.Configure(repository, xml);

B:文件加载

var file = new FileInfo(Directory.GetCurrentDirectory() + "/Xml/log4net.xml");
XmlConfigurator.Configure(repository, file);

(4).创建日志对象,

如: ILog log = LogManager.GetLogger(repository.Name, "all");

  特别注意:这里和.Net平台有区别,第一个参数必须是仓储对象的名称,建议直接这么写:repository.Name,第二个参数就是以前.Net 平台下类似的,可以随意起名,如果要分文件存储的话,要配合xml文件中的过滤器,<filter type="log4net.Filter.LoggerMatchFilter"><loggerToMatch value = "OneLog" /></ filter >,实现分文件夹存储。

(5). 开开心心的使用Info、Debug等方法写入日志即可。

 完整代码如下:

   //1.创建日志仓储对象
ILoggerRepository repository = LogManager.CreateRepository("myRespository"); //2.加载xml文件
//2.1 反射的方式加载
//Assembly assembly = Assembly.GetExecutingAssembly();
//var xml = assembly.GetManifestResourceStream("MyLog.Xml.log4net.xml");
//XmlConfigurator.Configure(repository, xml); //2.2 文件的方式加载
var file = new FileInfo(Directory.GetCurrentDirectory() + "/Xml/log4net.xml");
XmlConfigurator.Configure(repository, file); //3. 创建日志对象
ILog log = LogManager.GetLogger(repository.Name, "all");
ILog OneLog = LogManager.GetLogger(repository.Name, "OneLog"); //4. 写入日志
log.Info("alllog");
OneLog.Info("oneLog");

二. 分层封装使用

1.声明:

  MyLog02层仅仅需要添加对Utils层的引用,不需要再引入任何程序集。

2.目的:

  在Utils层中封装Log4net,然后可以在其它层中通过引用,直接调用。

3. 步骤:

(1). 给Utils层通过Nuget安装【log4net 2.0.8】,并将log4net.xml配置文件拷贝到Xml文件夹下,将其生成操作改为“嵌入的资源”。

(2). 新建LogUtils类,对log4net进行封装,其中日志仓储对象利用静态变量做成单例的

代码如下:

  public class LogUtils
{
//日志仓储(单例模式,静态变量,程序在第一次使用的时候被调用,由clr保证)
private static ILoggerRepository loggerRepository;
//1. 适用于全部文件夹
public static ILog log;
//2. OneLog文件夹
public static ILog log1;
//3. TwoLog文件夹
public static ILog log2; //声明文件夹名称(这里分两个文件夹)
static string log1Name = "OneLog";
static string log2Name = "TwoLog"; /// <summary>
/// 初始化Log4net的配置
/// xml文件一定要改为嵌入的资源
/// </summary>
public static void InitLog4Net()
{
//1. 创建日志仓储(单例)
loggerRepository = loggerRepository ?? LogManager.CreateRepository("myLog4net");
//2. 加载xml文件
Assembly assembly = Assembly.GetExecutingAssembly();
var xml = assembly.GetManifestResourceStream("Utils.Xml.log4net.xml");
log4net.Config.XmlConfigurator.Configure(loggerRepository, xml);
//3. 创建日志对象
log = LogManager.GetLogger(loggerRepository.Name,"all");
log1 = LogManager.GetLogger(loggerRepository.Name, log1Name);
log2 = LogManager.GetLogger(loggerRepository.Name, log2Name); } /************************* 五种不同日志级别 *******************************/
//FATAL(致命错误) > ERROR(一般错误) > WARN(警告) > INFO(一般信息) > DEBUG(调试信息) #region 00-将调试的信息输出,可以定位到具体的位置(解决高层封装带来的问题)
/// <summary>
/// 将调试的信息输出,可以定位到具体的位置(解决高层封装带来的问题)
/// </summary>
/// <returns></returns>
private static string getDebugInfo()
{
StackTrace trace = new StackTrace(true);
return trace.ToString();
}
#endregion #region 01-DEBUG(调试信息)
/// <summary>
/// DEBUG(调试信息)
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="logName">文件夹名称</param>
public static void Debug(string msg, string logName = "")
{
if (logName == "")
{
log.Debug(getDebugInfo() + msg);
}
else if (logName == log1Name)
{
log1.Debug(msg);
}
else if (logName == log2Name)
{
log2.Debug(msg);
}
}
/// <summary>
/// Debug
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="exception">错误信息</param>
public static void Debug(string msg, Exception exception)
{
log.Debug(getDebugInfo() + msg, exception);
} #endregion #region 02-INFO(一般信息)
/// <summary>
/// INFO(一般信息)
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="logName">文件夹名称</param>
public static void Info(string msg, string logName = "")
{
if (logName == "")
{
log.Info(getDebugInfo() + msg);
}
else if (logName == log1Name)
{
log1.Info(msg);
}
else if (logName == log2Name)
{
log2.Info(msg);
}
}
/// <summary>
/// Info
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="exception">错误信息</param>
public static void Info(string msg, Exception exception)
{
log.Info(getDebugInfo() + msg, exception);
}
#endregion #region 03-WARN(警告)
/// <summary>
///WARN(警告)
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="logName">文件夹名称</param>
public static void Warn(string msg, string logName = "")
{
if (logName == "")
{
log.Warn(getDebugInfo() + msg);
}
else if (logName == log1Name)
{
log1.Warn(msg);
}
else if (logName == log2Name)
{
log2.Warn(msg);
}
}
/// <summary>
/// Warn
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="exception">错误信息</param>
public static void Warn(string msg, Exception exception)
{
log.Warn(getDebugInfo() + msg, exception);
}
#endregion #region 04-ERROR(一般错误)
/// <summary>
/// ERROR(一般错误)
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="logName">文件夹名称</param>
public static void Error(string msg, string logName = "")
{
if (logName == "")
{
log.Error(getDebugInfo() + msg);
}
else if (logName == log1Name)
{
log1.Error(msg);
}
else if (logName == log2Name)
{
log2.Error(msg);
}
}
/// <summary>
/// Error
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="exception">错误信息</param>
public static void Error(string msg, Exception exception)
{
log.Error(getDebugInfo() + msg, exception);
}
#endregion #region 05-FATAL(致命错误)
/// <summary>
/// FATAL(致命错误)
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="logName">文件夹名称</param>
public static void Fatal(string msg, string logName = "")
{
if (logName == "")
{
log.Fatal(getDebugInfo() + msg);
}
else if (logName == log1Name)
{
log1.Fatal(msg);
}
else if (logName == log2Name)
{
log2.Fatal(msg);
}
}
/// <summary>
/// Fatal
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="exception">错误信息</param>
public static void Fatal(string msg, Exception exception)
{
log.Fatal(getDebugInfo() + msg, exception);
} #endregion }

(3). 对“MyLog”项目添加对“Utils”的引用,然后在Startup类中ConfigureServices方法中进行初始化Log4net,如下:

 LogUtils.InitLog4Net();

(4).根据情况进行调用。

  如:LogUtils.Info("我是二哈"); LogUtils.Info("我是二哈1", "OneLog");

三. 微软出品的日志程序

1. 声明:

   微软的日志扩展库中新增了对Log4Net的支持,仅仅需要在MyLog2项目中引入微软自己的 【Microsoft.Extensions.Logging.Log4Net.AspNetCore】 2.2.11即可,不需要再重复引入log4net官方程序集。

2. 使用步骤:

(1). 通过Nuget安装程序集【Microsoft.Extensions.Logging.Log4Net.AspNetCore】,版本号:2.2.11

(2). 在Xml文件夹中新建一个log4net2.xml的配置文件,并将其改为 “始终复制!!!”【这里和前面处理配置文件的方式不同哦】

(3). 在Startup类中的Configure方法中先注入ILoggerFactory对象,然后初始化log4net,代码如下:

 loggerFactory.AddLog4Net("Xml/log4net2.xml");

  解释:这里加载的是bin最终目录下的文件,所以步骤②中要将其改为“始终复制”(即复制到bin的最终目录下),如果这里不写参数,默认加载的是bin最终目录下的log4net.config文件。

(4). 在控制器里通过构造函数注入ILogger对象,注入的时候一定要注意<out TCategoryName> ,需要传入一个值。

(5). 进行调用,这里有两种方式区分日志级别:Log(LogLevel.Warning, "LogLevel.Warning"); 或者LogWarning("LogLevel.Warning");

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第八节:Asp.Net Core整合Log4net(官方的、微软的两种)的更多相关文章

  1. 第三节:Windows平台部署Asp.Net Core应用(基于IIS和Windows服务两种模式)

    一. 简介 二. 文件系统发布至IIS 三. Web部署发布至IIS 四. FTP发布至IIS 五. Windows服务的形式发布 ! 作       者 : Yaopengfei(姚鹏飞) 博客地址 ...

  2. ASP.NET Core整合Zipkin链路跟踪

    前言     在日常使用ASP.NET Core的开发或学习中,如果有需要使用链路跟踪系统,大多数情况下会优先选择SkyAPM.我们之前也说过SkyAPM设计确实比较优秀,巧妙的利用Diagnosti ...

  3. asp.net core 集成 log4net 日志框架

    asp.net core 集成 log4net 日志框架 Intro 在 asp.net core 中有些日志我们可能想输出到数据库或文件或elasticsearch等,如果不自己去实现一个 Logg ...

  4. Asp.net core 使用log4net作为日志组件,记录日志到本地。

    原文:Asp.net core 使用log4net作为日志组件,记录日志到本地. GitHub demo :https://github.com/zhanglilong23/Asp.NetCore.D ...

  5. ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式

    由于ASP.NET Core应用是一个同时处理多个请求的服务器应用,所以在处理某个请求过程中抛出的异常并不会导致整个应用的终止.出于安全方面的考量,为了避免敏感信息的外泄,客户端在默认的情况下并不会得 ...

  6. ASP.NET Core 整合Autofac和Castle实现自动AOP拦截

    前言: 除了ASP.NETCore自带的IOC容器外,我们还可以使用其他成熟的DI框架,如Autofac,StructureMap等(笔者只用过Unity,Ninject和Castle). 1.ASP ...

  7. ASP.NET Core使用log4net记录日志

    .NET常用的日志组件有NLog.Log4net等,.NET CORE下微软也自带了日志组件,到目前为止还没用过,而我本人常用的是log4net,下面简单讲讲.NET CORE下怎么使用log4net ...

  8. .NET Core整合log4net以及全局异常捕获实现2

    Startup代码 public static ILoggerRepository repository { get; set; } public Startup(IConfiguration con ...

  9. ASP.NET Core 集成测试中模拟登录用户的一种姿势

    不管哪种用户验证方式,最终都是在验证成功后设置 HttpContext.User ,后续处理环节通过 HttpContext.User 获取用户信息.如果能直接修改 HttpContext.User ...

随机推荐

  1. $.fn.extend 与 $.extend的区别

    今天看到别人写的jquery 代码都是这样的 $.fn.extend 所以查询了一下,因为自己不是前端开发,看到这样写的,感觉很牛逼.从百度上搜到的感觉解释的还是挺好的,作为记录,方便以后查找. 搜索 ...

  2. [转]C++ 堆栈溢出的原因以及可行的解决方法

    栈溢出(stackoverflow)的原因及解决办法 大家都知道,Windows程序的内存机制大概是这样的:全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存较大,一般不会溢出: 函数地 ...

  3. iOS相关

    1. fastlane a collection of tools that help you automate building and releasing iOS and Android apps ...

  4. ASP.NET Core MVC 502 bad gateway 超时如何处理

    在网页程序运行需要较长时间运行的时候,ASP.NET Core MVC会出现502 bad gateway请求超时情况.一般默认的超时时间都比较短,我们需要在 web.config 中配置一下.其中  ...

  5. Java数据类型(2)------自动封装拆箱

    目的: 自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象,以使用对象的API和引用类型操作.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下 ...

  6. angular6 监听url查询参数变化刷新页面

    快照snapshot取到的参数是组件第一次渲染时候的参数,当我们在页面中需要根据不同的url查询参数显示不同的内容时,快照就不能满足我们的需要了,这时候就要用ActivatedRoute服务的quer ...

  7. 团队项目-Beta冲刺及发布说明

    请大家在每次作业开头添加格式描述: 这个作业属于哪个课程 <课程的链接> 这个作业要求在哪里 <作业要求的链接> 团队名称 <写上团队名称>(附上团队博客链接) 这 ...

  8. django rest framework 解析器组件 接口设计,视图组件 (2)

    1. 使用视图组件进行接口优化 1.1 使用视图组件的mixin进行接口逻辑优化 - 导入mixin from rest_framework.mixinx import ( ListModelMix, ...

  9. andrlid 处理大图片思路,未实践

    Loading Large Bitmaps Efficiently 先不解码,读取image的宽高,然后降采样显示图片. 参考:http://developer.android.com/trainin ...

  10. 前端html页面,手机查看

    在写前端页面中,经常会在浏览器运行HTML页面,从本地文件夹中直接打开的一般都是file协议,当代码中存在http或https的链接时,HTML页面就无法正常打开,为了解决这种情况,需要在在本地开启一 ...