NetCore微服务实战体系:日志管理


一. 起始

进入NetCore时代,日志的使用有了很大的变化,因为跨平台以及虚拟化技术的使用,日志不能够再像Framework的方式直接记录在文本,文本其实也可以,但是日志的管理以及查看都不太方便。Linux都是指令化,对于开发来说并不友好。

后来Exceptionless进入了视线,选择这个组件的原因很简单,可视化、数据统计、实时性以及对于.net开发人员相当友好。在当前网络上,有很多关于Exceptionless的使用文档,但是个人觉得并不友好,在使用上并不方便。

在微软体系中,Microsoft.Extesions.Logging是官方日志框架,它允许我们自己去实现ILoggerProvider / ILogging,那么根据这两者得特性,由此开发了组件 Overt.Core.Logging

 

二. 组件Overt.Core.Logging

https://github.com/overtly/logging

 

三. 简单介绍使用

1. Nuget包引用

  • Nuget版本:V 1.0.4.1
  • 框架支持: NetStandard 2.0
Install-Package Overt.Core.Logging -Version 1.0.4.1

2. 配置信息

  • NetCore配置案例 appsettings.json

 

{

  "Exceptionless": {
    "ServerUrl": "http://exless.g.lan", // 私有化域名(Exceptionless私有化的文档网上很多)
    "ApiKey": "ugGFmeeriaj1BG12itWWURfiJjwqiyi2o71ll4mm", // 项目Key 如何创建网上文档也很多
    "Tags": "Local" // 日志所属项目环境
  }

}

3. 具体使用

(1)服务注入

  • Web服务使用
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {// Logging
            app.AddExlessLogging();
 }
  • IHost 普通服务使用 
        static void Main(string[] args)
        {
            var host = new HostBuilder() .UseConsoleLifetime() //使用控制台生命周期 .ConfigureAppConfiguration((context, configuration) => { configuration .AddJsonFile("appsettings.json", optional: true) .AddEnvironmentVariables(); }) .ConfigureLogging(logger => { }) .ConfigureServices(ConfigureServices) .Build(); host.Services.AddExlessLogging(); ThreadPool.SetMinThreads(100, 100); AppDomain.CurrentDomain.UnhandledException += (sender, e) => { var logFactory = host.Services.GetService<ILoggerFactory>(); var logger = logFactory.CreateLogger<Program>(); logger.LogError(e.ExceptionObject as Exception, $"UnhandledException"); }; host.Run(); }

(2)日志使用

using Microsoft.Extensions.Logging;

private readonly ILogger _logger; public Test(ILogger<Test> logger) {   _logger = logger; }

_logger.LogInformation("你好");

 

4. 源码详解

(1)实现ILogger

using Exceptionless;
using Microsoft.Extensions.Logging; using System; namespace Overt.Core.Logging { /// <summary> /// Logger实现 /// </summary> public class ExlessLogger : ILogger { private readonly string _categoryName; public ExlessLogger(string categoryName) { _categoryName = categoryName; } /// <summary> /// /// </summary> /// <typeparam name="TState"></typeparam> /// <param name="state"></param> /// <returns></returns> public IDisposable BeginScope<TState>(TState state) { return new NoopDisposable(); } /// <summary> /// 是否可用 /// </summary> /// <param name="logLevel"></param> /// <returns></returns> public bool IsEnabled(LogLevel logLevel) { return true; } /// <summary> /// 记录日志 /// </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) { try { var message = formatter(state, exception); var source = $"{_categoryName}"; var exlessLogLevel = Exceptionless.Logging.LogLevel.Trace; switch (logLevel) { case LogLevel.Trace: exlessLogLevel = Exceptionless.Logging.LogLevel.Trace; break; case LogLevel.Information: exlessLogLevel = Exceptionless.Logging.LogLevel.Info; break; case LogLevel.Warning: exlessLogLevel = Exceptionless.Logging.LogLevel.Warn; break; case LogLevel.Error: exlessLogLevel = Exceptionless.Logging.LogLevel.Error; break; case LogLevel.Critical: exlessLogLevel = Exceptionless.Logging.LogLevel.Fatal; break; default: exlessLogLevel = Exceptionless.Logging.LogLevel.Debug; break; } var eventBuilder = ExceptionlessClient.Default .CreateLog(message, exlessLogLevel) .SetSource(source) .SetException(exception); if (eventId != null) eventBuilder.SetProperty("Event", $"{eventId.ToString()}"); var serverAndPoint = LoggingUtility.GetAddressIP(); if (!string.IsNullOrEmpty(serverAndPoint)) eventBuilder.SetProperty("ServerEndPoint", serverAndPoint); eventBuilder.Submit(); } catch { } } private class NoopDisposable : IDisposable { public void Dispose() { } } } }

 

(2)实现ILoggerProvider

using Microsoft.Extensions.Logging;

namespace Overt.Core.Logging { /// <summary> /// LoggerProvider /// </summary> public class ExlessLoggerProvider : ILoggerProvider { /// <summary> /// Contructor /// </summary> /// <param name="categoryName"></param> /// <returns></returns> public ILogger CreateLogger(string categoryName) { return new ExlessLogger(categoryName); } /// <summary> /// /// </summary> public void Dispose() { } } }

 

(3)依赖注入

using Exceptionless;
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using NLog.Extensions.Logging; using Overt.Core.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace Microsoft.Extensions.DependencyInjection { public static class ServiceCollectionExtensions { #region ExLess /// <summary> /// 注入 /// </summary> /// <param name="loggingBuilder"></param> /// <param name="configFile"></param> public static void AddExlessLogging(this IServiceProvider provider) { var configuration = provider.GetService<IConfiguration>(); var loggerFactory = provider.GetService<ILoggerFactory>(); var client = ExceptionlessClient.Default; client.InitExlessTags(configuration); client.Configuration.ReadFromConfiguration(configuration); client.Configuration.ReadFromEnvironmentalVariables(); client.Configuration.UseInMemoryStorage(); client.Startup(); loggerFactory.AddProvider(new ExlessLoggerProvider()); } /// <summary> /// 注入 /// </summary> /// <param name="loggingBuilder"></param> /// <param name="configFile"></param> public static void AddExlessLogging(this IApplicationBuilder app) { var provider = app.ApplicationServices; var configuration = provider.GetService<IConfiguration>(); var loggerFactory = provider.GetService<ILoggerFactory>(); app.UseExceptionless(configuration); var client = ExceptionlessClient.Default; client.InitExlessTags(configuration); client.Configuration.UseInMemoryStorage(); loggerFactory.AddProvider(new ExlessLoggerProvider()); } /// <summary> /// tags /// </summary> /// <param name="client"></param> /// <param name="configuration"></param> private static void InitExlessTags(this ExceptionlessClient client, IConfiguration configuration) { var tags = configuration?["Exceptionless:Tags"]?.Split(",", StringSplitOptions.RemoveEmptyEntries)?.ToList(); foreach (var tag in tags ?? new List<string>()) { client.Configuration.DefaultTags.Add(tag); } } #endregion } }


5. 最终效果

可实时查看日志信息

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM