服务器端

ABP使用Castle Windsor的日志设施。它可以使用不同的日志库:Log4Net、NLog、Serilog等等。Castle为所有日志程序库提供了一个公共接口,这样,我们可以独立的使用某个日志库,并且随时可以变成另外的日志库。

Log4Net是.NET最流行的日志库之一,ABP模板附带了可以使用的Log4Net,Log4Net依赖项只有一行代码(如配置部分所示),因此可以轻松地将其更改为其他想使用的库。

获取日志记录器

不管你使用哪个日志库,,写日志的代码是一样的(多亏了Castle的通用ILogger接口)。

首先我们需要获得一个Logger对象来编写日志,由于ABP强烈的使用依赖注入,所以我们可以使用属性注入(或构造函数注入)模式轻松地注入一个Logger对象。下面是一个写日志行的示例类:

using Castle.Core.Logging; //1: Import Logging namespace

public class TaskAppService : ITaskAppService
{
//2: Getting a logger using property injection
public ILogger Logger { get; set; } public TaskAppService()
{
//3: Do not write logs if no Logger supplied.
Logger = NullLogger.Instance;
} public void CreateTask(CreateTaskInput input)
{
//4: Write logs
Logger.Info("Creating a new task with description: " + input.Description); //TODO: save task to database...
}
}

首先,我们导入了Castle的ILogger接口的名称空间;

其次,我们定义了一个名为Logger的公共ILogger对象。这是我们用来写日志的对象。依赖项注入系统将在创建TaskAppService对象后设置(注入)此属性。这就是所谓的属性注入模式;

第三,我们将Logger设置为NullLogger.Instance。没有这条线,系统可以很好地工作,但是使用属性注入模式是最佳实践。如果没有人设置日志程序,它将是null,当我们想要使用它时,我们将得到一个“object reference…”异常。这保证了它不是null。因此,如果没有人设置日志记录器,它将是NullLogger。这就是所谓的空对象模式。NullLogger实际上什么也不做。它不写任何日志。这样,我们的类可以使用或不使用实际的日志记录器。

最后,我们正在编写一个info级别的日志文本。有不同的级别(请参阅配置部分)。

如果我们调用CreateTask方法并检查日志文件,我们会看到如下所示的日志行:

INFO  -- ::, [    ] SimpleTaskSystem.Tasks.TaskAppService    - Creating a new task with description: Remember to drink milk before sleeping!

ABP为MVC控制器、WebAPI控制器、应用程序服务类等提供基类。它们声明一个Logger属性。这样,就可以直接使用这个日志程序来编写日志,而不需要注入。例如:

public class HomeController : SimpleTaskSystemControllerBase
{
public ActionResult Index()
{
Logger.Debug("A sample log message...");
return View();
}
}

注意,SimpleTaskSystemControllerBase是我们的应用程序特定的基控制器,它继承了AbpController。这样,它就可以直接使用日志程序。还可以为其他类编写自己的公共基类。这样您就不必每次都注入一个logger。

配置

当从ABP模板创建应用程序时,就会为Log4Net完成所有配置。

默认配置的日志格式如下所示(每一行):

日志级别:调试、信息、警告、错误或致命。

日期和时间:日志行被写入的时间。

线程号:写日志行的线程号。

记录器名称:这通常是写日志行的类名称。

日志文本:您编写的实际日志文本。

它被定义在应用程序的log4net.config文件中,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<file value="Logs/Logs.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="" />
<maximumFileSize value="10000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%-5.5thread] %-40.40logger - %message%newline" />
</layout>
</appender>
<root>
<appender-ref ref="RollingFileAppender" />
<level value="DEBUG" />
</root>
<logger name="NHibernate">
<level value="WARN" />
</logger>
</log4net>

Log4Net是高度可配置的,是一个强大的日志库。您可以将日志以不同的格式写入不同的目标(文本文件、数据库……)。您可以设置最低日志级别(在此配置中为NHibernate设置)。您可以将不同的日志记录器写入不同的日志文件。当日志文件达到特定大小时,它可以自动备份并创建一个新的日志文件(在这个配置中,每个文件的RollingFileAppender大小为10000 KB),等等……阅读它自己的配置文档以获得更多信息。

最后在Global.asax文件中,我们声明使用Log4Net与log4net.config文件:

public class MvcApplication : AbpWebApplication
{
protected override void Application_Start(object sender, EventArgs e)
{
IocManager.Instance.IocContainer.AddFacility<LoggingFacility>(f => f.UseLog4Net().WithConfig("log4net.config"));
base.Application_Start(sender, e);
}
}

这是log4net中唯一直接依赖的代码行。只有web项目依赖于log4net库的nuget包。可以轻松地更改到另一个库,而无需更改日志代码。

Abp.Castle.Log4Net 包

ABP使用Castle日志工具进行日志记录,它不直接依赖于log4net,如上所述。然而,Castle的Log4Net集成存在一个问题……它不支持最新的log4net。我们创建了一个NuGet包,app . castle。Log4Net,来解决这个问题。将这个包添加到我们的解决方案后,我们所要做的就是像这样更改应用程序启动方法中的代码:

public class MvcApplication : AbpWebApplication
{
protected override void Application_Start(object sender, EventArgs e)
{
IocManager.Instance.IocContainer.AddFacility<LoggingFacility>(f => f.UseAbpLog4Net().WithConfig("log4net.config"));
base.Application_Start(sender, e);
}
}

唯一的区别是我们使用了“UseAbpLog4Net()”方法(在Abp.Castle.Logging.Log4Net中定义)替代了 “UseLog4Net()”,当我们使用Abp.Castle.Log4Net包,不需要使用Castle.Windsor-log4net 和Castle.Core-log4net包.

如果你需要在运行时更改你的log4Net配置文件,并希望在不重启应用程序的情况下使更改立即生效,你可以使用以下方法:

public class MvcApplication : AbpWebApplication
{
protected override void Application_Start(object sender, EventArgs e)
{
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.LogUsing(new Log4NetLoggerFactory("log4net.config", reloadOnChange:true))
);
base.Application_Start(sender, e);
}
}

客户端

ABP为客户端定义了一个简单的JavaScript日志API。它默认登录到浏览器的控制台。这里有一些JavaScript代码来写日志:

abp.log.warn('a sample log message...');

更多信息, 请看 logging API documentation.

ABP之Logging的更多相关文章

  1. ABP框架 - 日志

    文档目录 本节内容: 服务端 获取Logger(记录器) Logger的基类 配置 Abp.Castle.Log4Net 包 客户端 服务端 ABP使用Castle Windsor的日志记录工具,它可 ...

  2. 手工搭建基于ABP的框架(3) - 登录,权限控制与日志

    为了防止不提供原网址的转载,特在这里加上原文链接: http://www.cnblogs.com/skabyy/p/7695258.html 本篇将实现登录.权限控制.日志配置与审计日志的功能.首先我 ...

  3. ABP .Net Core 日志组件集成使用NLog

    一.说明 NLog介绍和使用说明官网:http://nlog-project.org/ NLog和Log4net对比:https://www.cnblogs.com/qinjin/p/5134982. ...

  4. Abp.Castle.Log4Net : Method 'get_IsTraceEnabled' does not have an implementation

    异常内容 System.TypeLoadException HResult=0x80131522 Message=Method 'get_IsTraceEnabled' in type 'Abp.Ca ...

  5. ABP框架系列之三十二:(Logging-登录)

    Server Side(服务端) ASP.NET Boilerplate uses Castle Windsor's logging facility. It can work with differ ...

  6. 学习ABP遇到的问题汇总

    1,在abp官网下载的模板(asp.net+ef)写Application层的时候需要使用AutoMapper.结果ObjectMapper一直为null 解决:需要在当前项目的Module依赖Abp ...

  7. ABP官方文档翻译 2.4 日志

    日志 服务端 获取记录器 基类日志记录器 配置 Abp.Castle.Log4Net包 客户端 服务端 ABP使用Castle Windsor`s 日志设备.它可以使用不同的日志类库:Log4Net, ...

  8. abp集成IdentityServer4和单点登录

    在abp开发的系统后,需要使用这个系统作单点登录,及其他项目登录账号依靠abp开发的系统.在官方文档上只找到作为登录服务Identity Server Integration,但是host项目却无法使 ...

  9. .Net Core微服务化ABP之六——处理Authentication

    上篇中我们已经可以实现sso,并且为各个服务集成sso认证.本篇处理权限系统的角色问题,权限系统分两层,第一层为整体系统角色权限,区分app用户.后台用户.网站用户的接口权限,第二层为业务系统权限,对 ...

随机推荐

  1. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  2. Codeforces Round #599 (Div. 2)

    久违的写篇博客吧 A. Maximum Square 题目链接:https://codeforces.com/contest/1243/problem/A 题意: 给定n个栅栏,对这n个栅栏进行任意排 ...

  3. 《Dotnet9》系列-FluentValidation在C# WPF中的应用

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

  4. Python--合并2个字典成1个新字典的9种方法

    d1 = {'name': 'revotu', 'age': 99} d2 = {'age': 24, 'sex': 'male'} 输出: {'name': 'revotu', 'age': 24, ...

  5. JS---DOM---part4 课程介绍 & part3 复习

    part4 课程介绍 事件 1. 绑定事件的区别 2. 移除绑定事件的方式及区别和兼容代码 3. 事件的三个阶段 4. 事件冒泡 5. 为同一个元素绑定多个不同的事件,指向的是同一个事件处理函数 6. ...

  6. Python 下JSON的两种编解码方式实例解析

    概念   JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写.在日常的工作中,应用范围极其广泛.这里就介绍python下它的两种编解码方法: ...

  7. 【转载】记一次因 Redis 使用不当导致应用卡死 bug 的排查及解决!

    说明:此篇文章 作者分析问题的思路很好,值得学习记录,原文转载自公众号. 首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象 刚开始当测试抱怨环境响应慢的时候 , ...

  8. python3内置函数回忆

    1.数学运算类 # 1.数学运算类 # abs:计算绝对值 print(abs(-23)) # divmod,返回一个tuple,第一个值为商,第二个值为余数 print(divmod(10,4)) ...

  9. Java每日一面(Part2数据库)[19/11/28]

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 1.如何设计一个关系型数据库 如上图,首先划分成两大部分: ​ 1.存储部分:类似一个文件系统,把数据存储到一个持久化设备中,如机械硬盘,固态等 ​ ...

  10. 2.Python 赋值与内存

    定义变量和赋值其实就是系统处理内存的过程和问题,这篇文章分别从申请和释放内存两部分讨论 一.申请内存   python定义一个变量时,会为变量的对象申请一个内存,该变量会存储指向该对象内存中的地址 这 ...