Logging using Serilog in ASP. NET Web API 2 (IOC AUTOFAC)

Source: Internet
Author: User
Tags log log mssqlserver

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)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.