在一次.Net Core小项目的开发中,掌握的不够深入,对日志记录并没有好好利用,以至于一出现异常问题,都得跑动服务器上查看,那时一度怀疑自己肯定没学好,不然这一块日志不可能需要自己扒服务器日志来查看,果然,很多东西没掌握,至此,花点时间看了下日志的相关操作。利用日志服务来查看日志数据。

本文地址:https://www.cnblogs.com/CKExp/p/9246788.html

本文Demo的地址:https://gitee.com/530521314/LogPanel.git

一、日志记录的原则

  日志是为了方便我们观察应用程序是否正常运行,也是当运行不正常是,能够快速找到出现问题,定位问题的方式。

  有几条日志记录原则是我们大多都得遵循的:

  1、日志记录清晰,内容得让我们能够知道应用程序运行正常或运行不正常下能够有关键信息指明哪里出问题了。

  2、不要过度记录,一些场景下我们需要预判是否需要记录日志信息,我们能够控制日志记录的数量,同样,日志内容,要精简记录,无关紧要的文字,废话等无需加入。

  3、控制日志记录级别,或许在一个日志级别下记录了很多信息,可是其中的部分信息才是最为重要的,当调高一个记录级别,这部分最为重要的信息就展示出来了,那就直接调高级别吧。

  4、隐私保护,日志虽然是让开发运维人员看到,可是我们也不能所有信息都记录下来,用户的隐私信息我们得保护好。

二、内置日志组件

  Asp.Net Core中内置了日志组件,功能也很强大,首先来个简单示例:

  直接使用内置日志功能,无需在startup中加入另外的代码。

    private readonly ILogger<HomeController> _logger;

     public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
} public IActionResult Index()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_logger.LogDebug($"开始监控整个网站的日志信息_{DateTime.Now}");
//_logger.LogError($"开始监控整个网站的日志信息Error_{DateTime.Now}");
return View();
}

  在调试框下看到输出的日志信息。

  

  开始控制日志记录级别:

  在StartUp下,对内置日志组件做一些处理,在配置文件中将日志记录的级别提高到Information级别:

     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
   //默认日志功能
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
//loggerFactory.AddSerilog(); if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();//更多错误信息的开发者异常详情页
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}

  appsetting.json文件中,将LogLevel的默认级别设为Information,这样一来在之前的示例中_logger.LogDebug将失去作用。

 {
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Information",
"System": "Error",
"Microsoft": "Error"
}
}
}

  对于异常来讲,出现异常,日志肯定得记录下来,不然出现异常,直接抛出,那还要日志有什么用呢。

     public IActionResult About()
{
try
{
_logger.LogInformation($"业务逻辑执行前,运行正常");
//执行其它业务逻辑
int textInt = ;
int result = textInt / ;
//执行其它业务逻辑
_logger.LogInformation($"业务逻辑执行后,运行正常");
}
catch (Exception ex)
{
_logger.LogError($"出现异常,异常信息{ex.Message}");
throw;
} return View();
}

  异常信息加载出来。

  

  出现异常,拦截异常,记录日志信息,不单单在这里,在Filter或是几个中间件中,都能够记录下来,此处不在多讨论。

三、第三方日志组件

  尽管微软已经内置了日志记录组件,但是一些第三方组件或许是我们中意的,在性能上、记录方式上、操作上等等,如Log4Net、Logger、NLog和Serilog 等。结构化的日志使得我们阅读日志也更加轻松点。

  在此,我利用Serilog组件来替换内置的日志组件,添加相应的依赖包(Serilog.Extensions.Logging和Serilog.Sinks.Literate)。

  然后来更新Startup类,令Serilog组件开始发挥它的作用。

  尽管可以在Program中加入Serilog组件,在这里,我将只在StartUp类中更改代码,为了代码统一存放,对于组件加入有三种方式:

  方式一在StartUp初始化完毕加入进来,利用Log.Logger的全局性,在整个应用程序中发挥作用,而不需要在各处声明注入。

  其中的 .WriteTo.Seq("http://localhost:5341")是为了后面加入Seq组件而提前写入的,可以忽略。

     public Startup(IConfiguration configuration)
{
Configuration = configuration;
//方式一:配置Seq服务器的地址(5341端口为默认地址)
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("LoggingService", Serilog.Events.LogEventLevel.Debug)
.Enrich.FromLogContext()
.WriteTo.Seq("http://localhost:5341")
.WriteTo.LiterateConsole()
.CreateLogger();
}

  在应用程序中的使用方式是直接使用Log.Logger写入即可,如在HomeController的Contact方法中,利用且只能利用这种方式写入,当想用最开始那种方式注入时,在LoggerFactory中并没有SerilogProvider,因为我们并没有把Serilog加入到LoggerFactory中,这也使得Serilog和内置日志出现共存的局面,并可以通过两种方式使用日志功能。

     public IActionResult Contact()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Log.Debug("Log.Debug:Serilog Start Send Message");
Log.Information("Log.Information:Serilog Start send Message");
Log.Logger.Debug("Log.Logger:Serilog Start Send Message");
Log.Logger.Information("Log.Logger.Information:Serilog Start Send Message");
return View();
}

  利用这种方式下的日志输出。  

  

   方式二:在ConfigureServices中将Serilog加入到LoggerFactory中,通过统一的扩展方式加入进来,利用Action委托指定Serilog组件,其中允许我们对Serilog进行相关设置。

     public void ConfigureServices(IServiceCollection services)
{
//方式二
var serilog = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("LoggingService", Serilog.Events.LogEventLevel.Debug)
.Enrich.FromLogContext()
.WriteTo.Seq("http://localhost:5341")
.WriteTo.LiterateConsole(); services.AddLogging(loggerBuilder =>
{
loggerBuilder.AddSerilog(serilog.CreateLogger());
});
services.AddMvc();
}

  这种方式下,我们需要将Logger通过依赖注入的形式加入进来,先来看下是否加入到了LoggerFactory中

  

  加入进来了,并完成了日志的输出。

  

  方式三:和方式二一样都是加入到LoggerFactory中,但是直接利用的是Serilog提供的扩展方法AddSerilog加入进来。

     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//默认日志功能
//loggerFactory.AddConsole(Configuration.GetSection("Logging"));
//loggerFactory.AddDebug(); #region Serilog
//方式三
//默认配置
//loggerFactory.AddSerilog(); //配置Seq服务器的地址(5341端口为默认地址)
//var serilog = new LoggerConfiguration()
// .MinimumLevel.Information()
// .MinimumLevel.Override("LoggingService", Serilog.Events.LogEventLevel.Debug)
// .Enrich.FromLogContext()
// .WriteTo.Seq("http://localhost:5341")
// .WriteTo.LiterateConsole();
//loggerFactory.AddSerilog(serilog.CreateLogger());
#endregion if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();//更多错误信息的开发者异常详情页
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}

  Serilog组件同源加入进来了,输出结果就不展示了和方式二一样的。

  

  具体Serilog的非常优秀的功能就不介绍了,请看Serilog的官方介绍 https://github.com/serilog

四、Seq组件

  到了本文的主题——Seq组件,通过网页UI的形式将日志展现出来,内容更加多样化,并赋予了更多功能日志搜索。

  首先,安装Seq组件,Seq下载地址:https://getseq.net/Download

  本地开发情形下是免费使用的,如果需要在生产环境中使用,需要商业许可(你懂的,money).在目前的版本中,4.2是只能够在windows下跑,也就是说我们如果是在windows下开发,在测试时可以借助这个方便的查看日志信息,按照给定的安装步骤完成安装。

  在应用程序中,我们通过Nuget管理Serilog.Sinks.Seq包,该组件隶属于Serilog旗下。Seq默认的端口是利用5341端口,如果我们想要使用其它端口,我们可以更改在应用程序中的地址

  以上一节的方式三为例,在其中加入一行.WriteTo.Seq(“http://localhost:5341”)便可指定Seq服务器地址。

     var serilog = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("LoggingService", Serilog.Events.LogEventLevel.Debug)
.Enrich.FromLogContext()
.WriteTo.Seq("http://localhost:5341")
.WriteTo.LiterateConsole();
loggerFactory.AddSerilog(serilog.CreateLogger());

  在本地windows运行起来看下,启动Seq服务器,当然,你这里或许需要配置一些账号密码之类的,都是小问题。

  

  启动应用程序,并进入那些写了日志的方法中,日志信息已经进来了,我们可以查看这些日志信息,并通过日志搜索功能搜索。

  

  

  在这里要说明一下,同时也在Seq组件的网站中也写明了。使用这些方式都可以直接使用Seq组件,第三方组件也不是必须的,直接利用Asp.Net Core的内置日志组件一样可以使用Seq组件。

     

  可是,Linux下可以吗? 假如我的开发环境在Linux下岂不是不行。现在有一个预览版5.0的,在Docker Hub中有Seq的镜像,虽然是预览版,可是我还是想试试。

  Docker Hub中Seq镜像地址:https://docs.getseq.net/v5.0/docs/docker

  现在,开始Linux中弄起来。

  首先完成镜像的爬取,之后会自动启动该镜像内部的服务。我们直接输入地址访问即可。默认地址ip:5341端口

docker run -e ACCEPT_EULA=Y -p : datalust/seq:latest

  页面有了,Linux下看来也是可以的了,把应用程序通过Jenkins上都发布成功了,可是访问出现问题,Docker外部端口无法映射到内部端口,糟心,可是应该不是大问题,就此也就不弄日志信息的展示了。

  

  至此,日志相关的一系列知识简单带过,关键是Seq那个可视化日志界面,很nice。

  本文地址:https://www.cnblogs.com/CKExp/p/9246788.html

  本文Demo的地址:https://gitee.com/530521314/LogPanel.git

2018-6-30,望技术有成后能回来看见自己的脚步

Asp.Net Core中利用Seq组件展示结构化日志功能的更多相关文章

  1. Asp.Net Core 中利用QuartzHostedService 实现 Quartz 注入依赖 (DI)

    QuartzHostedService  是一个用来在Asp.Net Core 中实现 Quartz 的任务注入依赖的nuget 包: 基本示例如下: using System; using Syst ...

  2. 【Blazor】在ASP.NET Core中使用Blazor组件 - 创建一个音乐播放器

    前言 Blazor正式版的发布已经有一段时间了,.NET社区的各路高手也创建了一个又一个的Blazor组件库,其中就包括了我和其他小伙伴一起参与的AntDesign组件库,于上周终于发布了第一个版本0 ...

  3. .NET Core中的验证组件FluentValidation的实战分享

    今天有人问我能不能出一篇FluentValidation的教程,刚好今天在实现我们的.NET Core实战项目之CMS的修改密码部分的功能中有用到FluentValidation,所以就以修改用户密码 ...

  4. ASP.NET Core 中的SEO优化(4):自定义视图路径及主题切换

    系列回顾 <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET Core 中的SEO优化(2):中间件中渲染Razor视图> < ...

  5. ASP.NET Core中的ActionFilter与DI

    一.简介 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或 ...

  6. 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志

    前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改. 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基 ...

  7. 如何利用NLog输出结构化日志,并在Kibana优雅分析日志?

    上文我们演示了使用NLog向ElasticSearch写日志的基本过程(输出的是普通文本日志),今天我们来看下如何向ES输出结构化日志.并利用Kibana中分析日志. NLog输出结构化日志 Elas ...

  8. 玩转ASP.NET Core中的日志组件

    简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...

  9. ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作

    前言:马上要过年了,祝大家新年快乐!在过年回家前分享一篇关于Zookeeper的文章,我们都知道现在微服务盛行,大数据.分布式系统中经常会使用到Zookeeper,它是微服务.分布式系统中必不可少的分 ...

随机推荐

  1. 彻底卸载MySQL服务

    前言 由于安装某个项目的执行文件,提示要卸载MySQL以便它自身MySQL安装,然后我禁用了MYSQL服务,再把这个文件夹删除后,发现还是提示请卸载MYSQL服务. ----------------- ...

  2. ubuntu频繁出现 安装包依赖关系

    折腾了一下午,还差点重装一次,最后记下解决办法,引以为戒! 第一步,备份官方的默认源 避免自己手贱操作失误,重装系统太费时间 cp /etc/apt/sources.list /etc/apt/sou ...

  3. HeadDoc自动注释语法

    记录于2013/4/23: 关于HeaderDoc注释和标签的简要介绍 每个HeaderDoc注释可分为顶级标签和第二级标签: (1)顶级标签:宣布API的声明类型 (function, struct ...

  4. margin-top的兼容问题

    产生的条件:子元素给了margin-top,并且父元素没有浮也没有其他样式,浏览器解析的结果是父元素下去了. 解决方法:1.给子元素或者父元素添加浮动,缺点:如果不需要浮动,添加浮动也页面布局会乱 2 ...

  5. yarn一直在跑一个用户为dr.who的application

    现象: 访问yarn:8088页面发现一直有任务在跑如图: 用户为dr.who,问下内部使用人员,都没有任务在跑: 结论: 恭喜你,你中毒了,攻击者利用Hadoop Yarn资源管理系统REST AP ...

  6. yii2 httpClient的用法

    yii2 httpClient的用法示例: <?php /* * @Purpose : yii2 httpClient 请求示例 * @Author : Chrdai * @Time : 201 ...

  7. 如何把if-else代码重构成高质量代码

    原文:https://blog.csdn.net/qq_35440678/article/details/77939999 本文提纲: 为什么我们写的代码都是if-else? 这样的代码有什么缺点? ...

  8. react-router路由地址变了页面却没有跳转的解决办法

    最近,自己在摸索react的时候,遇到一个很奇葩的问题,大概是这样的: 我从列表页使用Link跳转到详情页面,列表页面的路由是'/list',详情页面的路由是'/list/detail',由于详情页面 ...

  9. grafana--邮箱告警配置

    安装 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-6.0.2-1.x86_64.rpm yum l ...

  10. Devexpress Ribbon 动态生成菜单

    /// <summary> /// 动态加载菜单 /// </summary> private void GetMenuBind() { //根据登录用户角色菜单动态创建 // ...