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