net core体系-web应用程序-4asp.net core2.0 项目实战(1)-11项目日志解决方案
本文目录
1. Net下日志记录
2. NLog的使用
2.1 添加nuget引用NLog.Web.AspNetCore
2.2 配置文件设置
2.3 依赖配置及调用
2.4 日志类型介绍
2.5 产生的日志文件
3. 基于Microsoft.Extensions.Logging封装
3.1 添加引用Microsoft.Extensions.Logging
3.2 实现我们的Logger
3.3 调用WLogger
2018-03-28 补充
4. 总结
1. Net下日志记录
Net Freamwork框架下在日志记录框架有很多,常见的有NLog、Log4Net、Loggr和内置 Microsoft.Diagnostics.Trace/Debug/TraceSource等。Asp.Net Core 2.0下大部分框架已不支持,Microsoft提供Microsoft.Extensions.Logging供大家实现自己的记录日志框架。现在笔者了解到的NLog已支持Net Core,下面我们介绍下nlog在项目中的使用以及基于Microsoft.Extensions.Logging封装自己的日志记录类。
1. NLog的使用
2.1添加nuget引用NLog.Web.AspNetCore
2.2配置文件设置
在Asp.Net Core 2.0项目实战项目中,我们把配置文件统一放在configs文件夹中,方便管理。读取时用Path.Combine("configs", "nlog.config")即可。下面是nlog.config的配置。
<?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="Warn"internalLogFile="internal-nlog.txt"><!--define various log targets--><targets><!--write logs to file--><target xsi:type="File" name="allfile" fileName="nlog-all-${shortdate}.log"layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" /><target xsi:type="File" name="ownFile-web" fileName="nlog-my-${shortdate}.log"layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" /><target xsi:type="Null" name="blackhole" /></targets><rules><!--All logs, including from Microsoft--><logger name="*" minlevel="Trace" writeTo="allfile" /><!--Skip Microsoft logs and so log only own logs--><logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" /><logger name="*" minlevel="Trace" writeTo="ownFile-web" /></rules></nlog>
2.3依赖配置及调用
在startup.cs中配置日志工厂,添加使用的服务配置后在项目中就可以调用。
/// <summary>/// 配置/// </summary>/// <param name="app"></param>/// <param name="env"></param>/// <param name="loggerFactory"></param>public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){loggerFactory.AddNLog();//添加NLog //读取Nlog配置文件,这里如果是小写,文件也一定是小写,否则linux下不识别 env.ConfigureNLog(Path.Combine("configs", "nlog.config"));}
nlog调用,如在Controller中调用,如:在HomeController中
2.4 日志类型介绍
public enum LogLevel {Debug = 1,Verbose = 2,Information = 3,Warning = 4,Error = 5,Critical = 6,None = int.MaxValue }
2.5产生的日志文件
日志的位置默认是在bin\Debug\netcoreapp2.0下面
日志文件内容根据文件名可以很方便的区分开,其中nlog-all包含的内比较多,nlog-my中就只包含了我们记录日志的内容,大家动手试一下。
3.基于Microsoft.Extensions.Logging封装
由于受老项目webform影响,记录日志是在第三方类库dll中封装好了帮助类,这样在可以在项目中任何位置方便调用,这里我的nc.common工具库WLogger基于Microsoft NET Core的日志模型主要由三个核心对象构成,它们分别是Logger、LoggerProvider和LoggerFactory。现在只实现了文件记录日志txt,数据库模式有业务需求的朋友可自己扩展。
3.1添加引用Microsoft.Extensions.Logging
扩展微软日志记录框架,集成一个自己的Logger,现在扩展的是txt形式,后续可参考完善数据库模式。添加引用dll后,增加配置文件并配置,这里我先加在appsettings.json文件中,主要是配置是否开启日志和日志记录。
3.2 实现我们的Logger
首先实现日志工厂的扩展LoggerFactoryExtensions,为net core 依赖注入LoggerFactory扩张一个方法,提供增加日志写文件方式的入口。
using Microsoft.Extensions.Logging;namespace NC.Common {public static class LoggerFactoryExtensions{public static ILoggerFactory AddFileLogger(this ILoggerFactory factory){factory.AddProvider(new FileLoggerProvider());return factory;}} }
然后实现ILoggerProvider接口,FileLoggerProvider提供程序真正具有日志写入功能的Logger。
using Microsoft.Extensions.Logging;namespace NC.Common {public class FileLoggerProvider : ILoggerProvider{/// <summary>/// 默认构造函数,根据Provider进此构造函数/// </summary>/// <param name="categoryName"></param>/// <returns></returns>public ILogger CreateLogger(string categoryName){return new FileLogger(categoryName);}public void Dispose(){}} }
最后实现ILogger接口FileLogger继承并进行封装,方便写入文本日志。
using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Text;namespace NC.Common {public class FileLogger : ILogger{private string name;private bool IsOpen;private string WPath;public FileLogger(string _name){name = _name;}public IDisposable BeginScope<TState>(TState state){return null;}/// <summary>/// 是否禁用/// </summary>/// <param name="logLevel"></param>/// <returns></returns>public bool IsEnabled(LogLevel logLevel){return true;}/// <summary>/// 实现接口ILogger/// </summary>/// <typeparam name="TState"></typeparam>/// <param name="logLevel"></param>/// <param name="eventId"></param>/// <param name="state"></param>/// <param name="exception"></param>/// <param name="formatter"></param>public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter){IsOpen = UtilConf.GetSection("WLogger")["IsOpen"] == "true" ? true : false;if (IsOpen){//获取日志信息var message = formatter?.Invoke(state, exception);//日志写入文件LogToFile(logLevel, message);}}/// <summary>/// 记录日志/// </summary>/// <param name="level">等级</param>/// <param name="message">日志内容</param>private void LogToFile(LogLevel level, string message){var filename = GetFilename();var logContent = GetLogContent(level, message);File.AppendAllLines(filename, new List<string> { logContent }, Encoding.UTF8);}/// <summary>/// 获取日志内容/// </summary>/// <param name="level">等级</param>/// <param name="message">日志内容</param>/// <returns></returns>private string GetLogContent(LogLevel level, string message){return $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.h3")}]{level}|{name}|{message}";}private string DirectorySeparatorChar = Path.DirectorySeparatorChar.ToString();//目录分隔符/// <summary>/// 获取文件名/// </summary>private string GetFilename(){var dir = "";WPath = UtilConf.GetSection("WLogger")["WPath"];if (WPath.IndexOf(":") > -1){dir = WPath;}else{//此方法不是真正的获取应用程序的当前方法,而是执行dotnet命令所在目录dir = Directory.GetCurrentDirectory() + WPath;}if (!Directory.Exists(dir))Directory.CreateDirectory(dir);var result = $"{dir}/WLog-{DateTime.Now.ToString("yyyy-MM-dd")}.txt".Replace("/",DirectorySeparatorChar);return result;}} }
3.3 调用WLogger
在nc.common类库中封装好logger实现后,在调用连接使用数据库在core类库中调用实例如下。
首先我们先做一下封装调用类
using Microsoft.Extensions.Logging;namespace NC.Common {public class UtilLogger<T>{private static ILogger iLog;public static ILogger Log{get{if (iLog != null) return iLog;第一种写法//ILoggerFactory loggerFactory = new LoggerFactory();//loggerFactory.AddFileLogger();//iLog = loggerFactory.CreateLogger<DbCommand>();//第二种写法iLog = new LoggerFactory().AddFileLogger().CreateLogger<T>();return iLog;}set => iLog = value;}} }
然后在DbCommand中调用就可以直接写成:
public static ILogger Log = UtilLogger<DbCommand>.Log;//日志记录
Log. LogInformation(string);
Log.LogError(string)
详细方法还可以参考
2018-03-28补充:
日志记录与全局错误处理结合,首先创建全局错误过滤类HttpGlobalExceptionFilter并在startup.cs中ConfigureServices方法下添加
services.AddMvc(options =>{options.Filters.Add(typeof(HttpGlobalExceptionFilter));//全局错误过滤日志}).AddControllersAsServices();
然后实现OnException方法并记录日志,这样系统只要报异常,日志 就会被记录下来。
using System; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; using NC.Common;namespace NC.MVC {/// <summary>/// 错误处理类/// </summary>public class HttpGlobalExceptionFilter : IExceptionFilter{private readonly IHostingEnvironment _env;public static ILogger Log = UtilLogger<HttpGlobalExceptionFilter>.Log;//日志记录public HttpGlobalExceptionFilter(IHostingEnvironment env){this._env = env;}public ContentResult FailedMsg(string msg = null){string retResult = "{\"status\":" + JHEnums.ResultStatus.Failed + ",\"msg\":\"" + msg + "\"}";//, msg);string json = JsonHelper.ObjectToJSON(retResult);return new ContentResult() { Content = json };}public void OnException(ExceptionContext filterContext){if (filterContext.ExceptionHandled)return;//执行过程出现未处理异常Exception ex = filterContext.Exception; #if DEBUGif (filterContext.HttpContext.Request.IsAjaxRequest()){string msg = null;if (ex is Exception){msg = ex.Message;filterContext.Result = this.FailedMsg(msg);filterContext.ExceptionHandled = true;return;}}this.LogException(filterContext);return; #endifif (filterContext.HttpContext.Request.IsAjaxRequest()){string msg = null;if (ex is Exception){msg = ex.Message;}else{this.LogException(filterContext);msg = "服务器错误";}filterContext.Result = this.FailedMsg(msg);filterContext.ExceptionHandled = true;return;}else{//对于非 ajax 请求this.LogException(filterContext);return;}}/// <summary>/// 记录日志/// </summary>/// <param name="filterContext"></param>private void LogException(ExceptionContext filterContext){string mid = filterContext.HttpContext.Request.Query["mid"];//codding 后续完善每个action带一个idvar areaName = (filterContext.RouteData.DataTokens["area"] == null ? "" : filterContext.RouteData.DataTokens["area"]).ToString().ToLower();var controllerName = (filterContext.RouteData.Values["controller"]).ToString().ToLower();var actionName = (filterContext.RouteData.Values["action"]).ToString().ToLower();#region --记录日志 codding 后续增加自定义字段的日志。如:记录Controller/action,模块ID等--Log.LogError(filterContext.Exception, "全局错误:areaName:" + areaName + ",controllerName:" + controllerName + ",action:" + actionName);#endregion}} }
4.总结
不管是生产环境还是开发环境,总会碰到这样或那样的问题,这时日志记录就为我们提供了记录分析问题的便利性,net core 2.0下记录日志功能是最需要我们及时实现的功能,这样为我们接下来的学习提供技术支撑。另外net core 生态还不完善,很多功能需要我们自己动手去实现,在这里希望大家多动手去实现去分享,文中有不清楚或有问题欢迎留言讨论。
参考:
https://msdn.microsoft.com/magazine/mt694089
https://www.cnblogs.com/artech/p/inside-net-core-logging-2.html
https://www.cnblogs.com/calvinK/p/5673218.html
转载于:https://www.cnblogs.com/hmit/p/10769576.html
net core体系-web应用程序-4asp.net core2.0 项目实战(1)-11项目日志解决方案相关推荐
- net core体系-web应用程序-4asp.net core2.0 项目实战(1)-10项目各种全局帮助类
本文目录 1. 前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...
- ASP.NET Core开源Web应用程序框架ABP
"作为面向服务架构(SOA)的一个变体,微服务是一种将应用程序分解成松散耦合服务的新型架构风格. 通过细粒度的服务和轻量级的协议,微服务提供了更多的模块化,使应用程序更容易理解,开发,测试, ...
- 使用.NET Core MVC Web应用程序中的ResponseCache属性处理缓存
HTTP响应的缓存意味着当发出HTTP请求时,服务器生成的响应由浏览器或服务器存储在某个地方,以便在对同一资源的连续HTTP请求中重复使用.实质上,我们正在存储生成的响应,并将该响应重用于后续请求一段 ...
- 做这么多年程序员了,才把ELK和springboot的日志解决方案弄明白
日志监控方案 日志对我们进行系统故障定位具有关键的作用.我们的框架代码.系统环境及业务逻辑中一般都会产出一些日志,我们通常会把这些日志记录后统一收集起来,方便在需要的时候进行查询检索.ELK是目前开源 ...
- 微信小程序商城项目实战(第一篇:项目搭建与首页)
商城项目第一篇 项目搭建 项目结构 编写整个项目中需要用到的功能 request.js 全局样式 组件(搜索框) 首页 代码编写 效果图 项目搭建 后端接口:https://www.showdoc.c ...
- ASP .NET Core Web MVC系列教程:使用ASP .NET Core创建MVC Web应用程序
本系列教程翻译自微软官方教程,官方教程地址:Get started with ASP.NET Core MVC | Microsoft Docs 本系列教程介绍了构建MVC Web应用程序的基础知识. ...
- 将NLog与ASP.NET Core Web应用程序集成
目录 介绍 集成步骤 添加NLog NuGet软件包 添加NLog配置 添加NLog提供程序 测试NLog提供程序 总结 下载源代码1.5 MB 介绍 在实际的应用程序中,正确的错误日志记录机制对于跟 ...
- 使用VS 2019,.NET Core 3和Web API创建ASP.NET Core Blazor CRUD应用程序
目录 介绍 Blazor Blazor客户端应用程序 Blazor服务器应用程序 背景 先决条件 使用代码 第1步-创建数据库和表 第2步-创建ASP.NET Core Blazor服务器应用程序 运 ...
- 使用 EF Core Power Tools 和 CoreAdmin 在 5 分钟内将管理员 CRUD 网页添加到您的 ASP.NET Core Web 应用程序
有时,也许在新产品/解决方案开发的早期阶段,您可能会发现自己需要一种简单的方法来让客户编辑解决方案中的某些数据. 一种方法是为现有数据库的简单数据输入创建一个管理页面. 在这篇文章中,我将展示如何使用 ...
最新文章
- [20150601]模拟ora-00600[2608]错误.txt
- [原创]浅谈对华为34岁以上员工“退休”
- 华为S5300系列交换机V100R005SPH008热补丁
- linux 查看文件中数据类型,Linux下使用file命令确定文件中数据的类型-文件类型...
- strlen函数strcpy函数strcat函数的实现
- js模板引擎art template数组渲染的方法
- cover-letter
- yum -y install php-mysql 版本冲突
- linux解压缩6层
- 没有权限角色管理功能菜单加载
- AutoCad二次开发
- BSD许可协议具体限制了什么?
- 【Qt】动画使用及惯性效果
- 运维安全要了解的二三事
- 中登托管行结算路径_在非根路径上托管Next.JS应用
- 5, 10,15,20-四(4-甲氧羰基苯基)卟啉(TPPCOOMe)/5-(对亮氨酸丁氧苯基 )-10 ,15 ,20-三苯基卟啉锌配合物(Zn[Leu-TPP]齐岳定制
- MOOC《Python网络爬虫和信息提取》(第11次)网络爬虫之框架(第4周)
- 哎,又跟HR在小群吵了一架!
- c#中out ref的简单使用说明
- react的行内样式和外链样式