ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB

一、前言

  在项目开发中,日志系统是系统的一个重要组成模块,通过在程序中记录运行日志、错误日志,可以让我们对于系统的运行情况做到很好的掌控。同时,收集日志不仅仅可以用于诊断排查错误,由于日志同样也是大量的数据,通过对这些数据进行集中分析,可以产生极大的价值。
  在微服务的系统架构中,由于一个系统会被拆成很多个功能模块,每个模块负责不同的功能,对于日志系统的要求也会更高,比较常见的有 EFLK(ElasticSearch + Filebeat + LogStash + Kibana) 方案,而对于我们这种单体应用来说,由于程序的代码比较集中,所以我们主要采用手写日志帮助类或是使用第三方组件的形式进行日志信息的记录。

  系列目录地址:ASP.NET Core 项目实战
  仓储地址:https://github.com/Lanesra712/Grapefruit.VuCore

 二、Step by Step

  1、为什么选择 NLog 和 MongoDB

  在 ASP.NET Core 中,巨硬为我们提供了一个 ILogger 接口,通过 ILogger 接口,我们可以很方便的将日志信息输出到控制台中,不过,在控制台中查看日志信息会显得不太方便,因此,我们可以通过实现该接口或是直接使用第三方的框架来实现将日志信息记录到别的存储介质中。

  在 .NET Framework 时代,对于第三方的日志框架的选择,绝大多数童鞋首选的都会是 log4net 这一根据 Log4j 移植的日志框架,不过,由于 log4net 目前已经接近有3年的时间没更新了,所以就不在考虑范围内。综合比较下官方文档中推荐的几款第三方日志框架,最终还是选择 NLog 这一目前使用人数相对来说比较多的框架,毕竟用户多的话,遇到什么问题也好找资料。

  通常,我们会将日志信息记录到 txt or log 文件中,虽然你可以通过修改日志布局让日志信息具有良好的可读性,不过在信息多的情况下查阅时还是会显得不太方便。因为不仅做到对于错误信息做到记录,还需要记录程序在运行时的访问日志,所以将日志信息写入到关系型数据库中就不是特别合适了。

  而 MongoDB 作为一个文档型的 NoSQL 数据库,相比于传统的关系型数据库,NoSQL 数据库具有更好的扩展性、以及能提供更出色的性能,因此,我最终选择将日志信息记录到 MongoDB 中。当然,最主要的原因还是目前在工作中有开始尝试用 MongoDB 存储用户上传的文件,在找资料的过程中看到有使用 MongoDB 存储日志的案例,Grapefruit.VuCore 既然作为一个学习项目,所以就要多尝试尝试啊。

  2、安装 MongoDB(Windows)

  因为是第一次使用 MongoDB,所以我们需要提前安装 MongoDB Server,我是直接安装到我的开发机上(Windows 10),所以这里只是演示如何在 Windows 上进行 MongoDB 的安装与配置,如何在 Linux or Docker 中进行安装配置,我将在后面的文章中进行演示。毕竟,这个项目的最终准备通过 Docker 部署到 Linux 上的,总在 Windows 上玩是不合适滴。

  首先,打开 MongoDB 官网获取到我们的安装包下载地址(MongoDB Community Download),选择 Server tab 后按照我们的操作系统选择安装包下载即可。

640?wx_fmt=png

  双击下载好的 msi 文件,开始安装,这里我选择 Complete(完整)安装,如果你想要指定安装的组件和安装的位置,你可以选择 Custom(自定义安装)。

640?wx_fmt=png

  在 MongoDB 之前的版本中,如果我们需要将 MongoDB Server 作为 Windows 服务,需要我们在安装完成之后进行配置,但是从 MongoDB 4.0 开始,我们就可以在安装期间直接配置和启动我们的 MongoDB 作为 Windows 服务了,当我们安装成功后就会自动启动 MongoDB 服务。嗯,相信我,如果你上网搜索 Windows 下的 MongoDB 安装,你会发现 90% 的文章因为是针对 MongoDB 之前版本的,都会在安装完成之后需要你指定日志地址、指定存储地址,配置 Windows 服务啊,而如果你和我一样,安装的是 MongoDB 4.0 以上的版本,这些统统都不要,是不是很超值。

  这里勾选上 Install MongoD as a Service,当我们安装完成后就会自动启动 MongoDB 服务,同时,对于这里的配置项,我们不做任何的改动。

  Service Name:创建的 Windows 服务名称,如果已经存在了,则需要更换名称

  Data Directory:存储数据的目录

  Log Directory:存储 MongoDB Log 日志的目录

640?wx_fmt=png

  点击 Next 之后,安装程序会询问你是否需要安装 MongoDB Compass,MongoDB Compass 是官方的一个可视化管理工具,毕竟总是用黑乎乎的 shell 还是不太方便的,这里看你自己的需求,决定是否安装这个工具。

  当我们安装完成后,MongoDB 的服务也就已经启动了,此时,你就可以连接上你的 MongoDB Server 了,这里我是使用 Navicat 进行连接。对于这个服务,你同样可以在计算机管理中对这个服务进行管理。

  在默认情况下,当我们安装好 MongoDB 后是不允许远程访问以及不存在任何的用户权限的。而这些,在我们正式使用中都是需要考虑的。

  首先,配置我们的 MongoDB Server 以允许用户进行远程访问。找到程序安装路径下面的 mongod.cfg 文件(如果你使用的是默认配置,则该文件位于 C:\Program Files\MongoDB\Server\4.0\bin),修改 bindIp 属性值为 0.0.0.0,重启 MongoDB 服务,确保 27017 端口外界可以访问后,则可以远程访问我们的 MongoDB 服务。

640?wx_fmt=png

  当我们允许远程访问我们的 MongoDB 服务后,我们更应该为 MongoDB 配置权限。与我们经常使用的 SQL Server 或是 MySQL 不同,MongoDB 中的权限是针对每一个数据库的,也就是说我们需要为使用到的数据库创建用户并配置权限。

  打开 Navicat,连接安装好的 MongoDB 服务。

640?wx_fmt=png

  第一步将默认数据库切换到 admin 数据库,创建一个管理员用户,这里我就将管理员用户的角色设置为 root 用户。


//切换到 admin 数据库use admin//创建一个管理员用户db.createUser({user: "user name",     pwd: "user password",roles: [ { role: "root", db: "admin" } ]}
)


  当我们创建好管理员用户后,我们就可以为数据库配置用户与权限了。右击连接名称,新建一个数据库 GrapefruitVuCore,切换到 GrapefruitVuCore 数据库后,新建一个可以读写的用户 grapefruit。用户都创建完成后,关闭我们的 MongoDB 连接。


//切换到 admin 数据库use GrapefruitVuCore//创建一个管理员用户db.createUser({user: "grapefruit",     pwd: "grapefruit",roles: [ { role: "readWrite", db: "GrapefruitVuCore" } ]}
)

640?wx_fmt=gif

  当用户已经创建完成之后,我们就可以修改配置文件,启用权限控制。还是在 mongod.cfg 中,取消 security 节点的注释,添加授权配置,修改完成后,重启服务,此时,MongoDB 就必须通过账户密码登录了。

640?wx_fmt=png

  当服务重启之后,如果你还是按照之前的方式连接,则会提示你权限不足,你需要修改 Navicat 的连接配置。将验证方式修改成 Password,输入账户、密码,并指定需要登录的数据库,重新连接即可。

  PS:这里,我使用账户、密码登录进入 GrapefruitVuCore 后,右侧的连接下面是没有显示这个数据库的,但这个数据库是真实存在的,不晓得这是个啥问题。

640?wx_fmt=png

  MongoDB 内置的用户角色权限:

  read:允许用户读取授权的数据库

  readWrite:允许用户读写授权的数据库

  dbAdmin:允许用户在授权的数据库中执行管理操作,如索引创建、删除,查看统计或访问system.profile

  userAdmin:允许用户向 system.users 集合写入,可以在指定数据库里创建、删除和管理用户

  clusterAdmin:只在 admin 数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

  readAnyDatabase:只在 admin 数据库中可用,赋予用户所有数据库的读权限

  readWriteAnyDatabase:只在 admin 数据库中可用,赋予用户所有数据库的读写权限

  userAdminAnyDatabase:只在 admin 数据库中可用,赋予用户所有数据库的 userAdmin 权限

  dbAdminAnyDatabase:只在 admin 数据库中可用,赋予用户所有数据库的 dbAdmin 权限。

  root:只在admin数据库中可用。超级账号,超级权限

  3、使用 NLog 记录日志信息

  当我们安装配置好 MongoDB 后,有了存储日志信息的介质,我们就可以使用 NLog 来记录我们的程序日志信息了。首先,我们需要为项目中添加对于 NLog 的引用,右击 Grapefruit.WebApi 打开管理 Nuget 程序包页面或是使用程序包管理器控制台选中默认项目为 Grapefruit.WebApi,添加 NLog、NLog.Web.AspNetCore、NLog.Mongo。

Install-Package NLog
Install-Package NLog.Web.AspNetCore
Install-Package NLog.Mongo

640?wx_fmt=png

  NLog 和 NLog.Web.AspNetCore 为 ASP.NET Core 添加了对于 NLog 的平台支持,在 NLog 中,我们可以通过继承 NLog.Targets.TargetWithLayout 来为 NLog 添加更多的输出介质支持,而 NLog.Mongo 就是为 NLog 添加输出日志信息到 MongoDB 的支持。嗯,尝试了自己写,一直有问题,最后还是用的别人写好的,哈哈哈,水平太菜。

  当我们添加好引用后,在 Grapefruit.WebApi 下添加一个 NLog 的配置文件 nlog.config(文件名全部需要小写),右键 nlog.config,打开属性窗口,将复制到输出目录修改成较新才复制或是总是复制都可以。

640?wx_fmt=png

  在配置文件中,nlog 节点必须是 xml 文件的根节点,同时包含三个主要的子节点:extensions、targets、rules。

  extensions:当你不仅仅只使用 NLog 这一个基础的 dll ,并使用了一些基于 NLog 扩展的工具时,你就需要在 extensions 节点下面添加引用的程序集名称。例如,这里,我添加了 NLog.Web.AspNetCore 这个程序集从而达到 NLog 对于 ASP.NET Core 的支持,以及添加了 NLog.Mongo 这个程序集用来将日志信息输出到 MongoDB 中。

  targets:targets 节点下包含了我们需要输出的日志的信息内容以及日志信息的布局,例如,这里我按照日期输出两个文件 nlog-all-date.log 和 nlog-own-date.log,分别记录所有的日志信息以及我们自定义记录的信息。因为我们是需要将日志信息写入 MongoDB 中的,这里我也添加了一个子节点用来设置写入 MongoDB 数据库中的数据字段。

  rules:rules 节点是将需要记录的日志级别关联到记录日志的方式上。这里,我是将只要是 Trace 以上的都进行日志记录。

640?wx_fmt=gif

<?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="c:\Temp\GrapefruitVuCore\internal-nlog.txt"><!-- enable asp.net core and mongodb layout renderers --><extensions><add assembly="NLog.Web.AspNetCore"/><add assembly="NLog.Mongo"/></extensions><!--internal-nlog:NLog启动及加载config信息--><!--nlog-all:所有日志记录信息--><!--nlog-own:自定义日志记录信息--><!-- the targets to write to --><targets><!-- write logs to file  --><target xsi:type="File" name="allfile" fileName="c:\Temp\GrapefruitVuCore\nlog-all-${shortdate}.log"layout="日志记录时间:${longdate}${newline}日志级别:${uppercase:${level}}${newline}日志来源:${logger}${newline}日志信息:${message}${newline}错误信息:${exception:format=tostring}${newline}==============================================================${newline}" /><!-- another file log, only own logs. Uses some ASP.NET core renderers --><target xsi:type="File" name="ownFile-web" fileName="c:\Temp\GrapefruitVuCore\nlog-own-${shortdate}.log"layout="日志记录时间:${longdate}${newline}日志级别:${uppercase:${level}}${newline}日志来源:${logger}${newline}日志信息:${message}${newline}错误信息:${exception:format=tostring}${newline}url: ${aspnet-request-url}${newline}action: ${aspnet-mvc-action}${newline}==============================================================${newline}" /><!-- write log to mongodb--><target xsi:type="Mongo"name="mongo" databaseName="GrapefruitVuCore"collectionName="Logs"connectionString="mongodb://grapefruit:grapefruit@localhost:27017/GrapefruitVuCore"cappedCollectionSize="26214400"><property name="LongDate" layout="${longdate}" bsonType="DateTime" /><property name="Level" layout="${level}" /><property name="Logger" layout="${logger}"/><property name="Message" layout="${message}" /><property name="Exception" layout="${exception:format=tostring}" /><property name="Url" layout="${aspnet-request-url}" /><property name="Action" layout="${aspnet-mvc-action}" /><property name="UserName" layout="${windows-identity}" /></target></targets><!-- rules to map from logger name to target --><rules><!--All logs, including from Microsoft--><logger name="*" minlevel="Trace" 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="Trace" writeTo="ownFile-web" /><!--Add logs to mongodb--><logger name="*" minlevel="Trace" writeTo="mongo"/></rules></nlog>    

640?wx_fmt=gif

640?wx_fmt=png

  当我们设置好配置文件后就可以在 Program.cs 中启用 NLog 去记录日志。运行我们的项目后,就可以查看记录的日志信息了,这里我在 txt 文件中和 MongoDB 中都有记录日志信息,具体看你自己的需求了。


public class Program
{    public static void Main(string[] args){        //加载日志配置信息文件后去捕获所有的错误var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();        try{logger.Info("Init Log API Information");CreateWebHostBuilder(args).Build().Run();}        catch (Exception ex){logger.Error(ex, "Stop Log Information Because Of Exception");}        finally{LogManager.Shutdown();}}    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().ConfigureLogging(logging =>{logging.ClearProviders();//移除其它已经注册的日志处理程序logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);//记录最小日志级别            }).UseNLog();//注入 NLog 服务}


  另外,在 appsettings.json 中指定的 Logging 配置会覆盖任何对于 SetMinimumLevel 方法的调用。因此,你可以删除配置文件中的 default 属性,或是根据你自己的需要进行调整。

{    "Logging": {        "LogLevel": {            "Default": "Trace",            "Microsoft": "Information"}}
}


 三、总结

   本章主要是演示如何在 Windows 上安装 MongoDB Server 以及在 ASP.NET Core 项目中使用 NLog 将日志信息记录到 MongoDB 中。在我们使用这些这些第三方开源框架时,可能会遇到很多问题,当你无法解决的时候,项目的 Issue 是个好地方,多搜搜,很大可能你就会得到解决方案。

原文地址:https://www.cnblogs.com/danvic712/p/10226557.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317996.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

532. 货币系统

532. 货币系统 题意&#xff1a; 有 n 种不同面额的货币&#xff0c;第 i 种货币的面额为 a[i]&#xff0c;每一种货币都有无穷多张&#xff0c;货币之间可以彼此代替&#xff0c;比如6等于两张3&#xff0c;问有多少种货币是不可替代的 题解&#xff1a; 我们换一个问…

概率期望题(期望 DP)做题记录

概率期望题(期望 DP)做题记录 P3830 [SHOI2012]随机树 难点在于第二问&#xff1a;生成树的期望深度。 不 wei zhuo 捏&#xff0c;设 \(dp_{i,j}\) 表示已经有了 \(i\) 个叶子结点&#xff0c;深度大于 \(j\) 的概率。 考虑枚举一棵子树的大小&#xff0c;转移方程如下&#x…

[学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]

文章目录引入概念全套模板变量声明updaterotate旋转splay操作insert插入delete删除查找x的位置查找第k大前驱/后继极小值-inf和极大值inf的作用例题&#xff1a;P3369 【模板】普通平衡树题目code声明一下&#xff0c;许多代码的注解都在模板代码里面写了的&#xff0c;所以正文…

2021.9.23模拟

前言 174pts 40502460 四个暴力分 qwq T1想切结果矩乘T飞了。。。 不要迷信矩乘&#xff0c;这玩意也是会T的… 考场 先看题 感觉T1和T最可做 T3期望想到zld的全排列大法了&#xff0c;但是似乎只能线性… T4是初始化加强版&#xff0c;思路倒是有&#xff0c;但是不想写&am…

AT1981-[AGC001C]Shorten Diameter

正题 题目链接:https://www.luogu.com.cn/problem/AT1981 题目大意 给出nnn个点的一棵树&#xff0c;每次你可以删除一个叶子&#xff0c;求最少的操作数使得树的直径长度不超过kkk。 1≤n,k≤20001\leq n,k\leq 20001≤n,k≤2000 解题思路 开始以为是dpdpdp啥的&#xff0c…

手写AspNetCore 认证授权代码

在普通的MVC项目中 我们普遍的使用Cookie来作为认证授权方式&#xff0c;使用简单。登录成功后将用户信息写入Cookie&#xff1b;但当我们做WebApi的时候显然Cookie这种方式就有点不适用了。在dotnet core 中 WebApi中目前比较流行的认证授权方式是Jwt (Json Web Token) 技术。…

FWT 学习笔记

FWT 学习笔记 学的时候比较匆忙&#xff0c;于是就学一个 \(\texttt{or,and,xor}\) 卷积跑路。 P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT) 前置知识&#xff1a;高维前缀和&#xff0c;下面前缀和的操作大多都是用高维前缀和来实现的。 设有两个长度为 \(2^n\) 的序列 …

大盗阿福

大盗阿福 题意&#xff1a; 长度为n的数组a&#xff0c;不能取连续的数&#xff0c;问所能取的最大值是多少 题解&#xff1a; 设dp[i][0]表示第i个数不选&#xff0c;dp[i][1]表示第i个数选 如果第i个数不选&#xff0c;那么第i-1个数可以选也可以不选&#xff0c;我们取最…

YBTOJ:采矿战略(线段树维护dp、树链剖分)

文章目录题目描述解析代码题目描述 所谓线段树维护dp&#xff0c;就是在线段树上维护dp &#xff08;逃&#xff09; 解析 把树剖一下后就变成了区间问题 考虑建一棵线段树&#xff0c;每一个结点都是一个背包 这样就能区间查询&#xff0c;也能带修了 这种做法复杂度其实并不…

【用皇宫三十六计生存法则带你走进LCT(动态树)】LCT概念+模板+例题【洛谷P3690 Link Cut Tree(动态树)】

文章目录LCT概念模板rotatoisrootsplayaccessmakerootsplitfindrootlinkcut封装版例题题目code普通版code封装版这篇博客主要是帮助大家理解各个模板及LCTLCTLCT的意思&#xff0c;方便理解&#xff0c;模板写法的理解在代码里有注释详解&#xff0c;如果要看原理的话&#xff…

AGC002(D~F)【Kruskal重构树,博弈论,dp】

正题 AT1998 [AGC002D] Stamp Rally【Kruskal重构树,倍增】 https://www.luogu.com.cn/problem/AT1998 题目大意 给出nnn个点mmm条边的一张无向图&#xff0c;qqq次询问两个人分别从x,yx,yx,y&#xff0c;要求总共经过zzz个点的情况下经过边的最大编号的最小值。 1≤n,m,q≤…

迈向现代化的 .Net 配置指北

1. 欢呼 .NET Standard 时代我现在已不大提 .Net Core&#xff0c;对于我来说&#xff0c;未来的开发将是基于 .NET Standard&#xff0c;不仅仅是 面向未来 &#xff0c;也是 面向过去&#xff1b;不只是 .Net Core 可以享受便利&#xff0c; .NET Framework 不升级一样能享受…

DP 套 DP

DP 套 DP 学习笔记 大致内容 DP 套 DP 就是将一个简单 DP 的状态压缩起来放到新的 DP 中当做状态进行 DP 的过程。 常用于计算简单 DP 的答案为 \(k\) 的转移方案的数量。 一般都需要 decode 和 recode 操作&#xff0c;这里和 插头DP/轮廓线DP 有异曲同工之妙&#xff01; 例题…

acwing提高组 第一章 动态规划

文章目录数字三角形模型最长上升子序列模型背包模型状态机模型状态压缩DP区间DP树形DP数位DP单调队列优化DP斜率优化DPoj链接数字三角形模型 AcWing 1015. 摘花生1357人打卡 AcWing 1018. 最低通行费1279人打卡 AcWing 1027. 方格取数1158人打卡 AcWing 275. 传纸条933人打卡 …

YBTOJ洛谷P2042:维护数列(平衡树)

文章目录题目描述解析删除区间插入数列修改&翻转区间和&最大子段和代码传送门题目描述 解析 阴间题… 这不是裸的板子吗&#xff1f; 国赛真的有人能把这题写出来吗… 应该算一道练习作用很强的题了 写完这题&#xff0c;各种平衡树维护区间操作的方法可以说是毕业了吧…

CAP 2.4版本发布,支持版本隔离特性

前言自从上次 CAP 2.3 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;这几个月比较忙&#xff0c;所以也没有怎么写博客&#xff0c;趁着2019年到来之际&#xff08;现在应该是2019年开始的时候&#xff09;&#xff0c;CAP也发布了2018年的最后一个大版本 2.4&…

AT2005-[AGC003E]Sequential operations on Sequence【差分,思维】

正题 题目链接:https://www.luogu.com.cn/problem/AT2005 题目大意 开始有一个1∼n1\sim n1∼n依次排列的序列&#xff0c;然后QQQ次&#xff0c;第iii次把序列长度变为aia_iai​&#xff0c;不足的从前往后循环填充。 求最后每个数字的出现次数。 1≤n,q≤105,1≤ai≤10181…

多项式工业基础与全家桶

多项式工业基础与全家桶 开坑待填&#xff0c;放个常数巨大的板子先 别忘了这道题&#xff01;P3338 [ZJOI2014]力 #define Maxn 200005 #define mod 998244353 inline int ksm(int x,int ymod-2) {int ret1;for(;y;y>>1,x1ll*x*x%mod) if(y&1) ret1ll*ret*x%mod;ret…

【周末狂欢赛7】【NOIP模拟赛】七夕祭,齿轮(dfs),天才黑客

文章目录T1题目题解codeT2题目题解codeT3题目题解codeT1 题目 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕&#xff0c;于是他们决定去TYVJ七夕祭游玩。 TYVJ七夕祭和11区的夏祭的…

股票买卖 IV

股票买卖 IV 题意&#xff1a; 给定一个长度为 N 的数组&#xff0c;数组中的第 i 个数字表示一个给定股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润&#xff0c;你最多可以完成 k 笔交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再…