一, 日志记录的原则
日志是为了方便我们观察应用程序是否正常运行, 也是当运行不正常是, 能够快速找到出现问题, 定位问题的方式.
有几条日志记录原则是我们大多都得遵循的:
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 = 5;
- int result = textInt / 0;
- // 执行其它业务逻辑
- _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 5341:80 datalust/seq:latest
页面有了, Linux 下看来也是可以的了, 把应用程序通过 Jenkins 上都发布成功了, 可是访问出现问题, Docker 外部端口无法映射到内部端口, 糟心, 可是应该不是大问题, 就此也就不弄日志信息的展示了.
至此, 日志相关的一系列知识简单带过, 关键是 Seq 那个可视化日志界面, 很 nice.
本文地址: https://www.cnblogs.com/CKExp/p/9246788.html
本文 Demo 的地址: https://gitee.com/530521314/LogPanel.git
来源: https://www.cnblogs.com/CKExp/p/9246788.html