斗爷

导航

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

Server Side(服务端

ASP.NET Boilerplate uses Castle Windsor's logging facility. It can work with different logging libraries: Log4Net, NLog, Serilog... etc. Castle provides a common interface for all logger libraries. So, you're independent from specific logging library and can easily change it later if you need.

ASP.NET模板使用Castle Windsor的日志库。它可以与不同日志库工作:log4net,NLog,Serilog…Castle为所有的日志库提供了一个公共接口。因此,您可以独立于特定的日志库,如果需要,可以稍后更改它。

Log4Net is one of the most popular logging libraries for .NET. ASP.NET Boilerplate templates come with Log4Net properly configured and working. But, there is just a single-line of dependency to log4net (as seen inconfiguration section), so you can change it to your favourite library.

log4net是最受欢迎的日志库。ASP.NET标准模板来log4net正确配置和工作。但是,只有一行依赖log4net(看结构部分),所以你可以改为你最喜欢的库。

Getting The Logger

No matter which logging library you choice, the code to write log is same (thanks to Castle's common ILogger interface).

无论你选择的日志库,代码写的日志是一样的(感谢ILogger Castle's的通用接口)。

First, we should get a Logger object to write logs. Since ASP.NET Boilerplate strongly uses dependency injection, we can easily inject a Logger object using property injection (or constructor injection) pattern. See a sample class that writes a log line:

首先,我们应该得到一个日志记录器对象来编写日志。自从ASP.NET样板采用依赖注入,我们可以很容易地将使用属性注入记录器对象(或构造函数注入)模式。参见一个编写日志行的示例类:

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...
    }
}

First, we imported namespace of Castle's ILogger interface.

首先,我们导入的Castle的ILogger接口命名空间。

Second, we defined a public ILogger object named Logger. This is the object we will write logs. Dependency injection system will set (inject) this property after creating TaskAppService object. This is known as property injection pattern.

其次,我们定义了一个公共ILogger对象命名为记录器。这是我们将要写入日志的对象。依赖注入(注入)系统将设置此属性在创建taskappservice对象。这就是属性注入模式。

Third, we set Logger to NullLogger.Instance. System will work fine without this line. But this is best practice on property injection pattern. If no one sets the Logger, it will be null and we get an "object reference..." exception when we want to use it. This guaranties that it's not null. So, if no one sets the Logger, it will be NullLogger. This is known as null object pattern. NullLogger actually does nothing, does not write any logs. Thus, our class can work with and without an actual logger.

第三,我们要nulllogger.instance记录器。没有这条线,系统会运转良好。但这是属性注入模式的最佳实践。如果没有人设置记录器,它将是空的,当我们想使用它时,会得到一个“对象引用”…异常。这保证了它不是空的。所以,如果没有一套记录器,它将NullLogger。这就是所谓的空对象模式。nulllogger其实什么都不做,不写任何日志。因此,我们的类可以使用和不使用实际的记录器。

Fourth and the last, we're writing a log text with info level. There are different levels (see configuration section).

第四和最后一个,我们正在用信息级别写一个日志文本。有不同的级别(参见配置部分)。

If we call the CreateTask method and check the log file, we see a log line as like as shown below:

INFO  2014-07-13 13:40:23,360 [8    ] SimpleTaskSystem.Tasks.TaskAppService    - Creating a new task with description: Remember to drink milk before sleeping!

Base Classes With Logger

ASP.NET Boilerplate provides base classes for MVC controllers, Web API controllers, Application service classes and more. They declare a Logger property. So, you can directly use this Logger to write logs, no injection needed. Example:

ASP.NET样板提供了MVC的控制器基类,Web API控制器,应用服务类和更多。它们声明记录器属性。因此,您可以直接使用这个日志记录器来编写日志,不需要注入。例子:

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

Note that SimpleTaskSystemControllerBase is our application specific base controller that inherits AbpController. Thus, it can directly use Logger. You can also write your own common base class for other classes. Then, you will not have to inject logger every time.

注意,simpletasksystemcontrollerbase是我们的基础,inherits abpcontroller应用的专用控制器。因此,它可以直接使用记录器。你也可以写自己的共同基础级给其他类。然后,你将不必每次注射记录器。

Configuration

All configuration is done for Log4Net when you create your application from ASP.NET Boilerplate templates.

所有配置好了log4net当你创建你的应用从ASP.NET标准模板。

Default configuration's log format is as show below (for each line):

  • Log level: DEBUG, INFO, WARN, ERROR or FATAL.
  • Date and time: The time when the log line is written.
  • Thread number: The thread number that writes the log line.
  • Logger name: This is generally the class name which writes the log line.
  • Log text: Actual log text that you write.
  • 日志级别:调试、信息、警告、错误或致命。
    日期和时间:记录日志行的时间。
    线程号:写入日志行的线程号。
    记录器名称:这通常是写入日志行的类名。
    日志文本:您编写的实际日志文本。

It's defined in the log4net.config file of the application as shown below:

<?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="10" />
    <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 is highly configurable and strong logging library. You can write logs in different formats and to different targets (text file, database...). You can set minimum log levels (as set for NHibernate in this configuration). You can write diffent loggers to different log files. It can automatically backup and create new log file when it reaches to a specific size (Rolling file adapter with 10000 KB per file in this configuration) and so on... Read it's own confuguration documentation for more.

log4net是高度可配置的,强大的日志库。你可以用不同的格式和不同的目标(文本文件、数据库……)编写日志。你可以设置最小日志级别(如在这个配置NHibernate)。你可以写不同的伐木工人到不同的日志文件。它可以自动备份和创建新的日志文件,当它达到一个特定的大小(滚动文件适配器10000 KB每文件在这个配置)等…阅读更多它自己的配置文件。

Finally, in the Global.asax file, we declare that we use Log4Net with log4net.config file:

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);
    }
}

This is the only code line we directly depend on log4net. Also, only the web project depends on log4net library's nuget package. So, you can easily change to another library without changing your logging code.

这是唯一的代码行我们直接取决于log4net。同时,只有Web项目取决于log4net库的NuGet包。因此,在不改变日志代码的情况下,您可以轻松地更改到另一个库。

Abp.Castle.Log4Net Package

ABP uses Castle Logging Facility for logging and it does not directly depend on log4net, as declared above. But there is a problem with Castle's Log4Net integration. It does not support the latest log4net. We created a nuget package, Abp.Castle.Log4Net, to solve this issue. After adding this package to our solution, all we should do is to change the code in application start like that:

ABP采用 Castle并不直接取决于log4net,作为以上的声明。但有 Castle log4net整合问题。它不支持最新log4net。我们创建了一个NuGet包,abp.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);
    }
}

The only difference is that we used "UseAbpLog4Net()" method (defined in Abp.Castle.Logging.Log4Net namespace) instead of "UseLog4Net()". When we use Abp.Castle.Log4Net package, it's not needed to useCastle.Windsor-log4net and Castle.Core-log4net packages.

Client Side

ASP.NET Boilerplate defines a simple javascript logging API for client side. It logs to browser's console as default. Sample javascript code to write logs:

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

For more information, see logging API documentation.

posted on 2018-01-16 13:59  斗哥哥  阅读(576)  评论(0编辑  收藏  举报