-
NuGet添加 NLog.Web.AspNetCore。
<PackageReference Include="Microsoft.AspNetCore.App" />
-
添加配置文件
新建一个文件nlog.config(建议全部小写,linux系统中要注意), 并右键点击其属性,将其“复制到输出目录”设置为“始终复制”。文件内容如下
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true"> <targets> <target xsi:type="File" name="allfile" keepFileOpen="false" encoding="utf-8" fileName="${basedir}/logs/${shortdate}-${level}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> <target xsi:type="Null" name="blackhole" /> <!--需要安装下mysql驱动--> <target name="database" xsi:type="Database" dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" connectionString="server=127.0.0.1;Database=example;user id=root;password=qwe123;SslMode=none" > <commandText> insert into log ( Application, Logged, Level, Message,Username,ServerName, Url,RemoteAddress,Logger, CallSite, Exception ) values ( @Application, @Logged, @Level, @Message,@Username,@ServerName, @Url,@RemoteAddress,@Logger, @Callsite, @Exception ); </commandText> <parameter name="@application" layout="yourappname" /> <parameter name="@logged" layout="${date}" /> <parameter name="@level" layout="${level}" /> <parameter name="@message" layout="${message}" /> <parameter name="@username" layout="${identity}" /> <parameter name="@serverName" layout="${aspnet-request-host}" /> <parameter name="@url" layout="${aspnet-request-url:IncludeQueryString=true}" /> <parameter name="@remoteAddress" layout="${aspnet-Request-ip}" /> <parameter name="@logger" layout="${logger}" /> <parameter name="@callSite" layout="${callsite}" /> <parameter name="@exception" layout="${exception:tostring}" /> </target> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="allfile" /> <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" /> <logger name="dblog" minlevel="Trace" writeTo="database" /> </rules> </nlog> <!-- CREATE TABLE `log` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT, `Application` varchar(50) DEFAULT NULL, `Logged` datetime DEFAULT NULL, `Level` varchar(50) DEFAULT NULL, `Message` text DEFAULT NULL, `UserName` varchar(512) Default Null, `ServerName` text Default Null, `Url` text NULL, `RemoteAddress` nvarchar(100) NULL, `Logger` text DEFAULT NULL, `Callsite` text DEFAULT NULL, `Exception` text DEFAULT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; -->
<Content Update="nlog.config"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content>
-
修改Program.cs文件
添加引用 NLog.Web 和 Microsoft.Extensions.Logging。
在 .UseStartup() 后添加一句.UseNLog()
。如果要禁用默认的输出框日志,可以调用
logging.ClearProviders()
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .ConfigureLogging(logging => { logging.ClearProviders(); logging.SetMinimumLevel(LogLevel.Trace); }) .UseNLog();
-
输出到数据库
除了把日志输出到文件之外,也可以保存到SQL Server, PostgreSQL, MySQL, Elasticsearch等。下面是保存到SQL Server的一个示例配置:
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="info" internalLogFile="d:\temp\logs\internal-nlog.txt"> <!-- enable asp.net core layout renderers --> <extensions> <add assembly="NLog.Web.AspNetCore"/> </extensions> <!-- the targets to write to --> <targets> <!-- write logs to file --> <target xsi:type="File" name="allfile" fileName="d:\temp\logs\all-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> <target name="blackhole" xsi:type="Null" /> <target name="database" xsi:type="Database" dbProvider="System.Data.SqlClient"> <connectionString> Server=.;Database=Log;Trusted_Connection=True </connectionString> <commandText> insert into dbo.Log ( Application, Logged, Level, Message, Logger, CallSite, Exception ) values ( @Application, @Logged, @Level, @Message, @Logger, @Callsite, @Exception ); </commandText> <parameter name="@application" layout="Application" /> <parameter name="@logged" layout="${date}" /> <parameter name="@level" layout="${level}" /> <parameter name="@message" layout="url: ${aspnet-request-url} | action: ${aspnet-mvc-action} | ${message}" /> <parameter name="@logger" layout="${logger}" /> <parameter name="@callSite" layout="${callsite:filename=true}" /> <parameter name="@exception" layout="${exception:tostring}" /> </target> </targets> <!-- rules to map from logger name to target --> <rules> <!--All logs, including from Microsoft--> <logger name="*" minlevel="Info" writeTo="allfile" /> <!--Skip non-critical Microsoft logs and so log only own logs--> <logger name="Microsoft.*" maxLevel="Info" final="true" /> <!-- BlackHole without writeTo --> <logger name="*" minlevel="Info" writeTo="database" /> </rules> </nlog>
-
配置简要说明
targets
:用于配置输出相关内容,比如 type 属性可选项为File、Mail、Console等,用于设置输出目标,layout属性用于设置输出信息的组成元素及格式。rules
: 其实是一个“路由表”,日志是从上到下匹配的。 logger name="Microsoft." maxlevel="Info" final="true" 一句话的 final="true" 过滤掉了"Microsoft." Info级别以下的日志。 -
全局异常中间件
除了输出日志外,可以写一个中间件来处理全局的异常。
public class GlobalErrorHandlingMiddleware { private readonly RequestDelegate next; private readonly ILogger<GlobalErrorHandlingMiddleware> _logger; public GlobalErrorHandlingMiddleware(RequestDelegate next, ILogger<GlobalErrorHandlingMiddleware> logger) { this.next = next; this._logger = logger; } public async Task Invoke(HttpContext context) { try { await next(context); } catch (Exception ex) { var Request = context.Request; ///访问路径 string visit_url = Request.Path; ///URL 请求方法 string method = Request.Method.ToUpper(); ///URL 请求的参数 string url_paramters = string.Empty; if (method == "GET") url_paramters = Request.QueryString.Value; if (method == "POST") { foreach (var item in Request.Form) url_paramters = url_paramters + item.Key + "=" + item.Value + "&"; } ///错识信息 string err_msg = ex.Message;//ex.StackTrace; ///日志格式内容 var logs_msg = $"{visit_url}#{method}#{url_paramters}#{err_msg}"; _logger.LogError(logs_msg); var statusCode = context.Response.StatusCode; var msg = $"Status Code: {statusCode}, Message: {ex.Message}"; await HandleExceptionAsync(context, msg); } } private static Task HandleExceptionAsync(HttpContext context, string msg) { //var data = new Result { Title = "异常中间件返回", Msg = msg }; //var result = JsonConvert.SerializeObject(data); //context.Response.ContentType = "application/json;charset=utf-8"; return context.Response.WriteAsync(msg); } } public static class GlobalErrorHandlingMiddlewareExtensions { public static IApplicationBuilder UseGlobalErrorHandlingMiddleware( this IApplicationBuilder builder) { return builder.UseMiddleware<GlobalErrorHandlingMiddleware>(); } }
来源:oschina
链接:https://my.oschina.net/it110/blog/4358825