Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了

Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架

Asp.Net Core 2.0 项目实战(3)NCMVC角色权限管理前端UI预览及下载

Asp.Net Core 2.0 项目实战(4)ADO.NET操作数据库封装、 EF Core操作及实例

Asp.Net Core 2.0 项目实战(5)Memcached踩坑,基于EnyimMemcachedCore整理MemcachedHelper帮助类。

Asp.Net Core 2.0 项目实战(6)Redis配置、封装帮助类RedisHelper及使用实例

Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密

Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类

Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例

Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录

Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级

本文目录
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>

nlog.config

  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 = ,
Verbose = ,
Information = ,
Warning = ,
Error = ,
Critical = ,
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;
}
}
}

LoggerFactoryExtensions

    然后实现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()
{
}
}
}

FileLoggerProvider

    最后实现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(":") > -)
{
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;
}
}
}

FileLogger

  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 DEBUG
if (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;
#endif
if (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带一个id
var 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
}
}
}

HttpGlobalExceptionFilter

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

Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例的更多相关文章

  1. Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录

    1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...

  2. Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级

    1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...

  3. Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类

    本文目录 1.  前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...

  4. Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密

    本文目录 1. 摘要 2. MD5加密封装 3. AES的加密.解密 4. DES加密/解密 5. 总结 1.  摘要 C#中常用的一些加密和解密方案,如:md5加密.RSA加密与解密和DES加密等, ...

  5. Asp.Net Core 2.0 项目实战(6)Redis配置、封装帮助类RedisHelper及使用实例

    本文目录 1. 摘要 2. Redis配置 3. RedisHelper 4.使用实例 5. 总结 1.  摘要 由于內存存取速度远高于磁盘读取的特性,为了程序效率提高性能,通常会把常用的不常变动的数 ...

  6. Asp.Net Core 2.0 项目实战(4)ADO.NET操作数据库封装、 EF Core操作及实例

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

  7. Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

  8. Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

  9. Asp.Net Core 2.0 项目实战(3)NCMVC角色权限管理前端UI预览及下载

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

随机推荐

  1. java Socket实现简单在线聊天(三)

    在上一篇,利用线程使服务端实现了能够接收多客户端请求的功能,这里便需要客户端接收多客户端消息的同时还能把消息转发到每个连接的客户端,并且客户端要能在内容显示区域显示出来,从而实现简单的在线群聊. 在实 ...

  2. 【mongodb系统学习之十】mongodb查询(一)

    十.mongodb查询:find ;查询时条件中不能引用文档中其他键的值: 1).查询数据库全部数据:语法db.collectionName.find();默认只显示前20条,如图: 2).按条件查询 ...

  3. 挖一挖不常用到而又很实用的重载-Trim

    这个我想没有那个开发人员说不知道,但是里面有一个重载,这个不知道有多少开发人员知道! 可以看到,我可以去掉字符串前后的指定字符,只要我在char[]中指定即可,而不是仅仅去掉空格,这次为什么要提它,是 ...

  4. Linux以列表格式显示块设备

    Linux以列表格式显示块设备 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ lsblk -l NAME MAJ:MIN RM SIZE RO TYPE MO ...

  5. Linux查询一台机器的IP地址和其对应的域名

    Linux查询一台机器的IP地址和其对应的域名 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ nslookup > 127.0.0.1 Server: ...

  6. python爬虫--爬取某网站电影下载地址

    前言:因为自己还是python世界的一名小学生,还有很多路要走,所以本文以目的为向导,达到目的即可,对于那些我自己都没弄懂的原理,不做去做过多解释,以免误人子弟,大家可以网上搜索. 友情提示:本代码用 ...

  7. MySQL入门笔记(二)

    MySQL的数据类型.数据库操作.针对单表的操作以及简单的记录操作可参考:MySQL入门笔记(一) 五.子查询   子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...

  8. 【BZOJ3527】力(FFT)

    [BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ...

  9. 【Luogu3808】多项式乘法FFT(FFT)

    题目戳我 一道模板题 自己尝试证明了大部分... 剩下的还是没太证出来... 所以就是一个模板放在这里 以后再来补东西吧.... #include<iostream> #include&l ...

  10. kali使用Fluxion钓鱼WiFi

    先介绍一下这个软件 这个软件是一个可以生成一个钓鱼WiFi的软件,可以伪装成一个正常的WiFi,但是是没有密码的,但是其他信息都是一样的,一旦开启这个攻击,正常的那个AP就无法正常连接,只能连到这个伪 ...