Serilog is a very good log library in. NET, and the other one I think is a better log library is nlog.
In my personal ASP. NET Web API 2 Base framework (GitHub address), I used Nlog, but I decided to use Serilog instead of nlog because of my curiosity.
Installation:
Install Serilog First, and install through the Package Manager console or the NuGet Management window:
Pm> Install-package Serilog
Then install Serilog sinks, so-called sink is the way to log log, such as in the console output, in the Debug window output, output to a file, output to the database and so on.
Here is a list of all the Sink:https://github.com/serilog/serilog/wiki/provided-sinks
Since I am using the ASP. NET Framework 4.6+, I do not need to use the console for 2.2 in my project, so I do not install the Serilog.Sinks.Literate of the official tutorial.
But I need to display log in the Debug window of VS, so install Serilog.Sinks.Debug
Install through the Package Manager console or the NuGet Management window:
Pm> Install-package Serilog.Sinks.Debug
I also need to output to a file and SQL Server database, so install Serilog.Sinks.RollingFile and Serilog.Sinks.MSSqlServer
Install through the Package Manager console or the NuGet Management window:
Pm> install-PackageSerilog.Sinks.RollingFilePM> Install-package Serilog.Sinks.MSSqlServer
After these are all installed, we begin to configure.
Configuration:
In the Web project, I set up a configuration class:
Public classserilogconfiguration { Public Static voidCreatelogger () {
This section is sink for configuring SQL ServerConst stringConnectionString =appsettings.defaultconnection;//Database connection stringConst stringTableName ="Logs";//table namevarColumnoptions =Newcolumnoptions//custom field {Additionaldatacolumns=NewCollection<datacolumn> { NewDataColumn {DataType =typeof(string), ColumnName ="User"}, NewDataColumn {DataType =typeof(string), ColumnName ="Class"}, } };
SQL Server tables are added in JSON format to the data field of log event columnOptions.Store.Add (standardcolumn.logevent);
Output template, SQL Server cannot use thisConst stringOutputtemplate ="[{Timestamp:HH:mm:ss. FFF} {level}] {Message} ({sourcecontext:l}) {newline}{exception}"; Serilog.Log.Logger=Newloggerconfiguration (). Minimumlevel.verbose ()//minimum record level for all sink. Enrich.withproperty ("Sourcecontext",NULL)//Join the property Sourcecontext, also the runtime is the specific class that calls logger. Enrich.fromlogcontext ()///Dynamic join attribute, mainly for the above custom field user and class, of course, you can also add other properties at any time ... Writeto.debug (outputtemplate:outputtemplate)//write to vs Output window. Writeto.rollingfile ("Logs\\{date}.log", GKFX:true, RestrictedToMinimumLevel:LogEventLevel.Debug, outputtemplate:outputtemplate)//write to file, one per day, minimum record level is de Bug, file format is YyyyMMdd.log
Logging to SQL Server, the minimum level is information. Writeto.mssqlserver (connectionString, TableName, Columnoptions:columnoptions, autocreatesqltable:true, RestrictedToMinimumLevel:LogEventLevel.Information). Createlogger (); } }
After the configuration is created, it is assigned to Serilog.Log.Logger, which is a static variable.
This configuration class is called before the IOC configuration is performed.
Note that the log to SQL Server line configuration, I set the automatic creation of the table autocreatesqltable:true, but if this part of the configuration (SQL Server Sink) has changed, you need to delete the generated table, and then let it re-establish one automatically, Otherwise, it is no longer possible to log into SQL Server.
Serilog has a total of 6 levels, Verbose-debug-information-warning-error-fatal, as described in its documentation.
Configure IOC
Because my framework uses dependency injection patterns, so after Serilog is configured, we want to configure the IOC, I use AUTOFAC (very good library), it can automatically dispose of the configured class, if this class implements the IDisposable interface, such as Serilog.
First install the Serilog AUTOFAC Integration Library:
Pm> Install-package autofacserilogintegration
Then go to AutofacWebapiConfig.cs to configure:
true);
Very simple, just a word.
Dependency Injection
After configuring the IOC, we can inject serilog ILogger for use, and we inject it into the service layer's commonservice instead of all controllers, so we don't have to change too much code.
namespacelegacyapplication.services.core{ Public InterfaceIcommonservice {iuploadedfilerepository uploadedfilerepository {Get; } Idepartmentrepository Departmentrepository {Get; } ILogger Log {Get; } } Public classCommonservice:icommonservice { PublicIuploadedfilerepository Uploadedfilerepository {Get; } PublicIdepartmentrepository Departmentrepository {Get; } PublicILogger Log {Get; } PublicCommonservice (iuploadedfilerepository uploadedfilerepository, Idepartmentrepository Department Repository, ILogger log) {uploadedfilerepository=uploadedfilerepository; Departmentrepository=departmentrepository; Log=log; } }}
Then, in the parent class of all controllers, you can get to the ILogger.
Public Abstract classApicontrollerbase:apicontroller {protected ReadOnlyIcommonservice Commonservice; protected ReadOnlyiunitofwork unitofwork; protected ReadOnlyidepartmentrepository departmentrepository; protected ReadOnlyiuploadedfilerepository uploadedfilerepository; protected ReadOnlyILogger Log; protectedapicontrollerbase (Icommonservice commonservice, Iunitofwork untofwork) {Com Monservice=Commonservice; Unitofwork=untofwork; Departmentrepository=commonservice.departmentrepository; Uploadedfilerepository=commonservice.uploadedfilerepository; Log=CommonService.Log; }
View Code
In this Controller parent class (ApiControllerBase.cs), continue to encapsulate some log methods so that all derived controllers can be used simply:
#regionLogging[Nonaction]protected voidLogbylevel (Logeventlevel level,stringmsg) { using(Logcontext.pushproperty ("Class", GetType (). FullName))//corresponds to a custom field that functions on SQL Server, IDisposableusing(Logcontext.pushproperty ("User", CurrentUserName)) {Log.write (level, $"{msg} (by {currentusername}, at {now:yyyy-mm-dd HH:mm:ss). FFF})"); }} [Nonaction]protected voidLogverbose (stringmsg) {Logbylevel (Logeventlevel.verbose, msg); } [Nonaction]protected voidLogdebug (stringmsg) {Logbylevel (Logeventlevel.debug, msg); } [Nonaction]protected voidLoginformation (stringmsg) {Logbylevel (logeventlevel.information, msg); } [Nonaction]protected voidLogwarning (stringmsg) {Logbylevel (logeventlevel.warning, msg); } [Nonaction]protected voidLogError (stringmsg) {Logbylevel (Logeventlevel.error, msg); } [Nonaction]protected voidLogfatal (stringmsg) {Logbylevel (logeventlevel.fatal, msg); } #endregion
which
using (Logcontext.pushproperty ("Class", GetType (). FullName))using (Logcontext.pushproperty ("User", CurrentUserName))
This section is a custom field section for SQL Server configuration for Serilog.
Global exception record
For ASP. NET Web API 2, I used the custom global exception record class: MyExceptionLogger.cs
GlobalConfiguration.Configuration.Services.Add (typeofnew Myexceptionlogger ()); GlobalConfiguration.Configuration.Services.Replace (typeofnew Myexceptionhandler ());
namespacelegacystandalone.web.myconfigurations.exceptions{ Public classMyexceptionlogger:exceptionlogger { Public Override voidLog (Exceptionloggercontext context) {#ifDEBUGTrace.traceerror (context. ExceptionContext.Exception.ToString ());#endif using(Logcontext.pushproperty ("Class", context. ExceptionContext.ControllerContext.ControllerDescriptor.ControllerType))using(Logcontext.pushproperty ("User", context. RequestContext.Principal.Identity.Name)) {logexception (context. Exceptioncontext.exception); } } Private voidlogexception (Exception ex) {if(Ex! =NULL) {logexception (ex. innerexception); Serilog.Log.Logger.Error (ex. ToString ()); } } }}
Here I am using the static version of the Serilog logger.
Problem
The output to the Debug window and the SQL Server database is not a problem with the use of tests, but it has not been possible to output to a file in the development environment of the ASP. NET Web API 2 project, and I have created a new Web API project, but there is no problem with the console application. I will continue to study and solve this problem later today.
Logging using Serilog in ASP. NET Web API 2 (IOC AUTOFAC)