国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Util應用框架基礎(chǔ)(六) - 日志記錄(一) - 正文

這篇具有很好參考價值的文章主要介紹了Util應用框架基礎(chǔ)(六) - 日志記錄(一) - 正文。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文介紹Util應用框架如何記錄日志.

日志記錄共分4篇,本文是正文,后續(xù)還有3篇分別介紹寫入不同日志接收器的安裝和配置方法.

概述

日志記錄對于了解系統(tǒng)執(zhí)行情況非常重要.

Asp.Net Core 抽象了日志基礎(chǔ)架構(gòu),支持使用日志提供程序進行擴展,提供控制臺日志等簡單實現(xiàn).

Serilog 是 .Net 流行的第三方日志框架,支持結(jié)構(gòu)化日志,并能與 Asp.Net Core 日志集成.

Serilog 支持多種日志接收器,可以將日志發(fā)送到不同的地方.

我們可以將日志寫入文本文件,但查看文本文件比較困難,文件如果很大,查找問題非常費力.

對于生產(chǎn)環(huán)境,我們需要包含管理界面的日志系統(tǒng).

Seq 是一個日志系統(tǒng),可以很好的展示結(jié)構(gòu)化日志數(shù)據(jù),并提供模糊搜索功能.

Exceptionless 是基于 Asp.Net Core 開發(fā)的日志系統(tǒng).

與 Seq 相比,Exceptionless 搜索能力較弱.

Seq 和 Exceptionless 都提供了 Serilog 日志接收器,可以使用 Serilog 接入它們.

Util應用框架使用 Serilog 日志框架,同時集成了 SeqExceptionless 日志系統(tǒng).

Util簡化了日志配置,并對常用功能進行擴展.

日志配置

選擇日志接收器

Util應用框架默認支持三種 Serilog 日志接收器:

  • 日志文件
  • Seq
  • Exceptionless

你可以從中選擇一種或多種,如果都不能滿足要求,你也可以引用 Serilog 支持的其它日志接收器,或自行實現(xiàn).

配置日志接收器

請轉(zhuǎn)到特定日志接收器章節(jié)查看配置方法.

配置日志級別

Asp.Net Core 使用日志級別表示日志的嚴重程度,定義如下:

  • Trace = 0
  • Debug = 1
  • Information = 2
  • Warning = 3
  • Error = 4
  • Critical = 5
  • None = 6

None不開啟日志,Trace的嚴重程度最低,Critical的嚴重程度最高,需要高度關(guān)注.

可以在 appsettings.json 配置文件設(shè)置日志級別.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Logging 配置節(jié)用于配置日志.

LogLevel 為所有日志提供程序配置日志級別.

Default 為所有日志類別設(shè)置默認的日志級別.

上面的配置將默認日志級別設(shè)置為 Information.

意味著只輸出日志級別等于或大于 Information 的日志.

現(xiàn)在 Trace 和 Debug 兩個級別的日志被禁用了.

可以為特定日志類別設(shè)置日志級別.

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

配置增加了 Microsoft 日志類別,并設(shè)置為 Debug 日志級別.

日志類別用來給日志分類,一般使用帶命名空間的類名作為日志類別.

日志類別支持模糊匹配, Microsoft 日志類別不僅匹配 Microsoft ,而且還能匹配以 Microsoft 開頭的所有日志類別,比如 Microsoft.AspNetCore .

Serilog 的日志級別

Serilog 定義了自己的日志級別,不支持上面介紹的標準配置方式.

Exceptionless 也是如此.

使用第三方框架的日志級別會導致復雜性.

Util應用框架擴展了 Serilog 和 Exceptionless 的日志級別配置,允許以統(tǒng)一的標準方式進行配置.

記錄日志

.Net 提供了標準的日志記錄接口 Microsoft.Extensions.Logging.ILogger.

你可以使用 ILogger 記錄日志.

Util應用框架還提供了一個 Util.Logging.ILog 接口.

當你需要寫入很長的日志時,可能需要使用 StringBuilder 拼接日志內(nèi)容.

ILog 提供了一種更簡單的方式寫入長內(nèi)容日志.

使用 ILogger 記錄日志

ILogger 支持泛型參數(shù), 用來指定日志類別,使用帶命名空間的類名作為日志類別.

namespace Demo;

public class DemoController : WebApiControllerBase {
    public DemoController( ILogger<DemoController> logger ) {
        logger.LogDebug( "Util" );
    }
}

示例在控制器構(gòu)造方法注入 ILogger<DemoController> ,日志類別為 Demo.DemoController .

ILogger 擴展了一些以 Log 開頭的方法,比如 LogDebug,表示寫入日志級別為 Debug 的消息.

logger.LogDebug( "Util" ) 以 Debug 日志級別寫入消息'Util'.

使用 ILog 記錄日志

Util應用框架定義了 ILog 接口.

ILog 是對 ILogger 接口的簡單包裝, 對日志內(nèi)容的設(shè)置進行了擴展.

ILog 也使用泛型參數(shù)來指定日志類別.

使用 ILog 完成上面相同的示例.

public class DemoController : WebApiControllerBase {
    public DemoController( ILog<DemoController> log ) {
        log.Message( "Util" ).LogDebug();
    }
}

Message 是 ILog 定義的方法, 用來設(shè)置日志消息,可以多次調(diào)用它拼接內(nèi)容.

當你需要寫比較長的日志內(nèi)容, ILog 可以幫你拼接內(nèi)容,這樣省去了定義 StringBuilder 的麻煩.

可以在 ILog 添加自定義擴展方法來設(shè)置內(nèi)容, Util應用框架內(nèi)置了一些設(shè)置日志消息的擴展方法, 比如 AppendLine.

public class DemoController : WebApiControllerBase {
    public DemoController( ILog<DemoController> log ) {
        log.AppendLine( "內(nèi)容1" )
            .AppendLine( "內(nèi)容2" )
            .LogDebug();
    }
}

你可以定義自己的擴展方法,以更加語義化的方式記錄日志.

范例:

public class DemoController : WebApiControllerBase {
    public DemoController( ILog<DemoController> log ) {
        log.Caption( "標題" )
            .Content( "內(nèi)容" )
            .Sql( "Sql" )
            .LogDebug();
    }
}

ILog 與 ILogger 比較:

ILog 更擅長記錄內(nèi)容很長的日志.

ILog 是有狀態(tài)服務,不能在多個線程共享使用.

可以使用 ILog 記錄業(yè)務日志,其它場景應使用 ILogger.

結(jié)構(gòu)化日志支持

Serilog 日志框架對結(jié)構(gòu)化日志提供了支持.

結(jié)構(gòu)化日志使用特定語法的消息模板日志格式,可以從日志文本中提取搜索元素.

結(jié)構(gòu)化日志的優(yōu)勢主要體現(xiàn)在日志系統(tǒng)對日志消息的展示和搜索方式上.

不同的日志系統(tǒng)對結(jié)構(gòu)化日志的展示方式和搜索能力不同.

請參考 Seq 和 Exceptionless 的 結(jié)構(gòu)化日志支持 小節(jié).

日志操作上下文

記錄日志時,我們除了需要記錄業(yè)務內(nèi)容,還需要知道一些額外的信息,比如操作用戶是誰.

我們希望記錄日志時僅設(shè)置業(yè)務內(nèi)容,這些額外的信息最好能自動記錄.

Util應用框架通過日志上下文自動設(shè)置這些額外信息.

  • UserId 設(shè)置當前操作用戶標識

  • Application 設(shè)置當前應用程序名稱.

  • Environment 設(shè)置當前環(huán)境名稱.

  • TraceId 設(shè)置跟蹤號.

  • Stopwatch 設(shè)置計時器,用于記錄請求執(zhí)行花了多長時間.

在 Asp.Net Core 環(huán)境, 日志上下文由日志上下文中間件 Util.Applications.Logging.LogContextMiddleware 創(chuàng)建.

無需手工添加日志上下文中間件,只要引用 Util.Application.WebApi 類庫, 就會自動添加到中間件管道.

對于 Web 請求, 跟蹤號是一個重要的信息,可以通過查詢跟蹤號,將相關(guān)的請求日志全部查出來.

另外, Exceptionless 會自動收集很多系統(tǒng)信息.

源碼解析

ILog 日志操作

ILog 日志操作接口提供鏈式調(diào)用方式設(shè)置日志內(nèi)容.

  • Message 方法設(shè)置日志消息.

  • Property 方法設(shè)置擴展屬性.

  • State 設(shè)置日志參數(shù)對象.

Log 開頭的日志記錄方法,將日志操作委托給 ILogger 相關(guān)方法.

/// <summary>
/// 日志操作
/// </summary>
/// <typeparam name="TCategoryName">日志類別</typeparam>
public interface ILog<out TCategoryName> : ILog {
}

/// <summary>
/// 日志操作
/// </summary>
public interface ILog {
    /// <summary>
    /// 設(shè)置日志事件標識
    /// </summary>
    /// <param name="eventId">日志事件標識</param>
    ILog EventId( EventId eventId );
    /// <summary>
    /// 設(shè)置異常
    /// </summary>
    /// <param name="exception">異常</param>
    ILog Exception( Exception exception );
    /// <summary>
    /// 設(shè)置自定義擴展屬性
    /// </summary>
    /// <param name="propertyName">屬性名</param>
    /// <param name="propertyValue">屬性值</param>
    ILog Property( string propertyName, string propertyValue );
    /// <summary>
    /// 設(shè)置日志狀態(tài)對象
    /// </summary>
    /// <param name="state">狀態(tài)對象</param>
    ILog State( object state );
    /// <summary>
    /// 設(shè)置日志消息
    /// </summary>
    /// <param name="message">日志消息</param>
    /// <param name="args">日志消息參數(shù)</param>
    ILog Message( string message, params object[] args );
    /// <summary>
    /// 是否啟用
    /// </summary>
    /// <param name="logLevel">日志級別</param>
    bool IsEnabled( LogLevel logLevel );
    /// <summary>
    /// 開啟日志范圍
    /// </summary>
    /// <typeparam name="TState">日志狀態(tài)類型</typeparam>
    /// <param name="state">日志狀態(tài)</param>
    IDisposable BeginScope<TState>( TState state );
    /// <summary>
    /// 寫跟蹤日志
    /// </summary>
    ILog LogTrace();
    /// <summary>
    /// 寫調(diào)試日志
    /// </summary>
    ILog LogDebug();
    /// <summary>
    /// 寫信息日志
    /// </summary>
    ILog LogInformation();
    /// <summary>
    /// 寫警告日志
    /// </summary>
    ILog LogWarning();
    /// <summary>
    /// 寫錯誤日志
    /// </summary>
    ILog LogError();
    /// <summary>
    /// 寫致命日志
    /// </summary>
    ILog LogCritical();
}

ILogExtensions 日志操作擴展

Util應用框架內(nèi)置了幾個日志操作擴展方法,你可以定義自己的擴展方法,以方便內(nèi)容設(shè)置.

/// <summary>
/// 日志操作擴展
/// </summary>
public static class ILogExtensions {
    /// <summary>
    /// 添加消息
    /// </summary>
    /// <param name="log">配置項</param>
    /// <param name="message">消息</param>
    /// <param name="args">日志消息參數(shù)</param>
    public static ILog Append( this ILog log,string message, params object[] args ) {
        log.CheckNull( nameof( log ) );
        log.Message( message, args );
        return log;
    }

    /// <summary>
    /// 當條件為true添加消息
    /// </summary>
    /// <param name="log">配置項</param>
    /// <param name="message">消息</param>
    /// <param name="condition">條件,值為true則添加消息</param>
    /// <param name="args">日志消息參數(shù)</param>
    public static ILog AppendIf( this ILog log, string message,bool condition, params object[] args ) {
        log.CheckNull( nameof( log ) );
        if ( condition )
            log.Message( message, args );
        return log;
    }

    /// <summary>
    /// 添加消息并換行
    /// </summary>
    /// <param name="log">配置項</param>
    /// <param name="message">消息</param>
    /// <param name="args">日志消息參數(shù)</param>
    public static ILog AppendLine( this ILog log, string message, params object[] args ) {
        log.CheckNull( nameof( log ) );
        log.Message( message, args );
        log.Message( Environment.NewLine );
        return log;
    }

    /// <summary>
    /// 當條件為true添加消息并換行
    /// </summary>
    /// <param name="log">配置項</param>
    /// <param name="message">消息</param>
    /// <param name="condition">條件,值為true則添加消息</param>
    /// <param name="args">日志消息參數(shù)</param>
    public static ILog AppendLineIf( this ILog log, string message, bool condition, params object[] args ) {
        log.CheckNull( nameof( log ) );
        if ( condition ) {
            log.Message( message, args );
            log.Message( Environment.NewLine );
        }
        return log;
    }

    /// <summary>
    /// 消息換行
    /// </summary>
    /// <param name="log">配置項</param>
    public static ILog Line( this ILog log ) {
        log.CheckNull( nameof(log) );
        log.Message( Environment.NewLine );
        return log;
    }
}

LogContext 日志上下文

通過日志上下文自動記錄重要的額外信息.

/// <summary>
/// 日志上下文
/// </summary>
public class LogContext {
    /// <summary>
    /// 初始化日志上下文
    /// </summary>
    public LogContext() {
        Data = new Dictionary<string, object>();
    }

    /// <summary>
    /// 計時器
    /// </summary>
    public Stopwatch Stopwatch { get; set; }
    /// <summary>
    /// 跟蹤標識
    /// </summary>
    public string TraceId { get; set; }
    /// <summary>
    /// 用戶標識
    /// </summary>
    public string UserId { get; set; }
    /// <summary>
    /// 應用程序
    /// </summary>
    public string Application { get; set; }
    /// <summary>
    /// 執(zhí)行環(huán)境
    /// </summary>
    public string Environment { get; set; }
    /// <summary>
    /// 擴展數(shù)據(jù)
    /// </summary>
    public IDictionary<string, object> Data { get; }
}

LogContextMiddleware 日志上下文中間件

日志上下文中間件創(chuàng)建日志上下文,并添加到 HttpContext 對象的 Items .

/// <summary>
/// 日志上下文中間件
/// </summary>
public class LogContextMiddleware {
    /// <summary>
    /// 下個中間件
    /// </summary>
    private readonly RequestDelegate _next;

    /// <summary>
    /// 初始化日志上下文中間件
    /// </summary>
    /// <param name="next">下個中間件</param>
    public LogContextMiddleware( RequestDelegate next ) {
        _next = next;
    }

    /// <summary>
    /// 執(zhí)行中間件
    /// </summary>
    /// <param name="context">Http上下文</param>
    public async Task Invoke( HttpContext context ) {
        var traceId = context.Request.Headers["x-correlation-id"].SafeString();
        if ( traceId.IsEmpty() )
            traceId = context.TraceIdentifier;
        var session = context.RequestServices.GetService<Util.Sessions.ISession>();
        var environment = context.RequestServices.GetService<IWebHostEnvironment>();
        var logContext = new LogContext {
            Stopwatch = Stopwatch.StartNew(), 
            TraceId = traceId, 
            UserId = session?.UserId,
            Application = environment?.ApplicationName,
            Environment = environment?.EnvironmentName
        };
        context.Items[LogContextAccessor.LogContextKey] = logContext;
        await _next( context );
    }
}

ILogContextAccessor 日志上下文訪問器

日志上下文訪問器從 HttpContext.Items 獲取日志上下文.

/// <summary>
/// 日志上下文訪問器
/// </summary>
public interface ILogContextAccessor {
    /// <summary>
    /// 日志上下文
    /// </summary>
    LogContext Context { get; set; }
}

/// <summary>
/// 日志上下文訪問器
/// </summary>
public class LogContextAccessor : ILogContextAccessor {
    /// <summary>
    /// 日志上下文鍵名
    /// </summary>
    public const string LogContextKey = "Util.Logging.LogContext";

    /// <summary>
    /// 日志上下文
    /// </summary>
    public LogContext Context {
        get => Util.Helpers.Convert.To<LogContext>( Web.HttpContext.Items[LogContextKey] );
        set => Web.HttpContext.Items[LogContextKey] = value;
    }
}

LogContextEnricher 日志上下文擴展

Serilog 提供 ILogEventEnricher 接口用于設(shè)置擴展屬性.

LogContextEnricher 使用 Ioc.Create 方法獲取依賴服務 ILogContextAccessor.

這是因為不能使用依賴注入,它要求實現(xiàn)類必須是無參構(gòu)造函數(shù).

Ioc.Create 在 Asp.Net Core 環(huán)境獲取依賴服務是安全的,但在其它環(huán)境則可能獲取失敗.

如果獲取日志上下文失敗,也不會對功能造成影響,只是丟失了一些上下文信息.

/// <summary>
/// 日志上下文擴展屬性
/// </summary>
public class LogContextEnricher : ILogEventEnricher {
    /// <summary>
    /// 擴展屬性
    /// </summary>
    /// <param name="logEvent">日志事件</param>
    /// <param name="propertyFactory">日志事件屬性工廠</param>
    public void Enrich( LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        var accessor = Ioc.Create<ILogContextAccessor>();
        if ( accessor == null )
            return;
        var context = accessor.Context;
        if ( context == null )
            return;
        if ( logEvent == null )
            return;
        if ( propertyFactory == null )
            return;
        RemoveProperties( logEvent );
        AddDuration( context,logEvent, propertyFactory );
        AddTraceId( context, logEvent, propertyFactory );
        AddUserId( context, logEvent, propertyFactory );
        AddApplication( context, logEvent, propertyFactory );
        AddEnvironment( context, logEvent, propertyFactory );
        AddData( context, logEvent, propertyFactory );
    }

    /// <summary>
    /// 移除默認設(shè)置的部分屬性
    /// </summary>
    private void RemoveProperties( LogEvent logEvent ) {
        logEvent.RemovePropertyIfPresent( "ActionId" );
        logEvent.RemovePropertyIfPresent( "ActionName" );
        logEvent.RemovePropertyIfPresent( "RequestId" );
        logEvent.RemovePropertyIfPresent( "RequestPath" );
        logEvent.RemovePropertyIfPresent( "ConnectionId" );
    }

    /// <summary>
    /// 添加執(zhí)行持續(xù)時間
    /// </summary>
    private void AddDuration( LogContext context, LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        if ( context?.Stopwatch == null )
            return;
        var property = propertyFactory.CreateProperty( "Duration", context.Stopwatch.Elapsed.Description() );
        logEvent.AddOrUpdateProperty( property );
    }

    /// <summary>
    /// 添加跟蹤號
    /// </summary>
    private void AddTraceId( LogContext context, LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        if ( context == null || context.TraceId.IsEmpty() )
            return;
        var property = propertyFactory.CreateProperty( "TraceId", context.TraceId );
        logEvent.AddOrUpdateProperty( property );
    }

    /// <summary>
    /// 添加用戶標識
    /// </summary>
    private void AddUserId( LogContext context, LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        if ( context == null || context.UserId.IsEmpty() )
            return;
        var property = propertyFactory.CreateProperty( "UserId", context.UserId );
        logEvent.AddOrUpdateProperty( property );
    }

    /// <summary>
    /// 添加應用程序
    /// </summary>
    private void AddApplication( LogContext context, LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        if ( context == null || context.Application.IsEmpty() )
            return;
        var property = propertyFactory.CreateProperty( "Application", context.Application );
        logEvent.AddOrUpdateProperty( property );
    }

    /// <summary>
    /// 添加執(zhí)行環(huán)境
    /// </summary>
    private void AddEnvironment( LogContext context, LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        if ( context == null || context.Environment.IsEmpty() )
            return;
        var property = propertyFactory.CreateProperty( "Environment", context.Environment );
        logEvent.AddOrUpdateProperty( property );
    }

    /// <summary>
    /// 添加擴展數(shù)據(jù)
    /// </summary>
    private void AddData( LogContext context, LogEvent logEvent, ILogEventPropertyFactory propertyFactory ) {
        if ( context?.Data == null || context.Data.Count == 0 )
            return;
        foreach ( var item in context.Data ) {
            var property = propertyFactory.CreateProperty( item.Key, item.Value );
            logEvent.AddOrUpdateProperty( property );
        }
    }
}

LoggerEnrichmentConfigurationExtensions

將 LogContextEnricher 擴展到 LoggerEnrichmentConfiguration 上.

/// <summary>
/// Serilog擴展屬性配置擴展
/// </summary>
public static class LoggerEnrichmentConfigurationExtensions {
    /// <summary>
    /// 添加日志上下文擴展屬性
    /// </summary>
    /// <param name="source">日志擴展配置</param>
    public static LoggerConfiguration WithLogContext( this LoggerEnrichmentConfiguration source ) {
        source.CheckNull( nameof( source ) );
        return source.With<LogContextEnricher>();
    }

    /// <summary>
    /// 添加日志級別擴展屬性
    /// </summary>
    /// <param name="source">日志擴展配置</param>
    public static LoggerConfiguration WithLogLevel( this LoggerEnrichmentConfiguration source ) {
        source.CheckNull( nameof( source ) );
        return source.With<LogLevelEnricher>();
    }
}

AddSerilog 配置方法

AddSerilog 配置方法封裝了 Serilog 的配置.

  • 配置 ILog 接口服務依賴.

  • 將 Asp.Net Core 日志級別轉(zhuǎn)換為 Serilog 日志級別.

  • 設(shè)置日志上下文擴展.文章來源地址http://www.zghlxwxcb.cn/news/detail-746083.html

/// <summary>
/// Serilog日志操作擴展
/// </summary>
public static class AppBuilderExtensions {
    /// <summary>
    /// 配置Serilog日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    public static IAppBuilder AddSerilog( this IAppBuilder builder ) {
        return builder.AddSerilog( false );
    }

    /// <summary>
    /// 配置Serilog日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="isClearProviders">是否清除默認設(shè)置的日志提供程序</param>
    public static IAppBuilder AddSerilog( this IAppBuilder builder, bool isClearProviders ) {
        return builder.AddSerilog( options => {
            options.IsClearProviders = isClearProviders;
        } );
    }

    /// <summary>
    /// 配置Serilog日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="appName">應用程序名稱</param>
    public static IAppBuilder AddSerilog( this IAppBuilder builder, string appName ) {
        return builder.AddSerilog( options => {
            options.Application = appName;
        } );
    }

    /// <summary>
    /// 配置Serilog日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="setupAction">日志配置操作</param>
    public static IAppBuilder AddSerilog( this IAppBuilder builder, Action<LogOptions> setupAction ) {
        builder.CheckNull( nameof( builder ) );
        var options = new LogOptions();
        setupAction?.Invoke( options );
        builder.Host.ConfigureServices( ( context, services ) => {
            services.AddSingleton<ILogFactory, LogFactory>();
            services.AddTransient( typeof( ILog<> ), typeof( Log<> ) );
            services.AddTransient( typeof( ILog ), t => t.GetService<ILogFactory>()?.CreateLog( "default" ) ?? NullLog.Instance );
            var configuration = context.Configuration;
            services.AddLogging( loggingBuilder => {
                if ( options.IsClearProviders )
                    loggingBuilder.ClearProviders();
                SerilogLog.Logger = new LoggerConfiguration()
                    .Enrich.WithProperty( "Application", options.Application )
                    .Enrich.FromLogContext()
                    .Enrich.WithLogLevel()
                    .Enrich.WithLogContext()
                    .ReadFrom.Configuration( configuration )
                    .ConfigLogLevel( configuration )
                    .CreateLogger();
                loggingBuilder.AddSerilog();
            } );
        } );
        return builder;
    }
}

AddExceptionless 配置方法

AddExceptionless 配置方法封裝了 Serilog 和 Exceptionless 的配置.

  • 配置 ILog 接口服務依賴.

  • 將 Asp.Net Core 日志級別轉(zhuǎn)換為 Exceptionless 日志級別.

  • 設(shè)置日志上下文擴展.

/// <summary>
/// Exceptionless日志操作擴展
/// </summary>
public static class AppBuilderExtensions {
    /// <summary>
    /// 配置Exceptionless日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="isClearProviders">是否清除默認設(shè)置的日志提供程序</param>
    public static IAppBuilder AddExceptionless( this IAppBuilder builder, bool isClearProviders = false ) {
        return builder.AddExceptionless( null, isClearProviders );
    }

    /// <summary>
    /// 配置Exceptionless日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="appName">應用程序名稱</param>
    public static IAppBuilder AddExceptionless( this IAppBuilder builder, string appName ) {
        return builder.AddExceptionless( null, appName );
    }

    /// <summary>
    /// 配置Exceptionless日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="configAction">Exceptionless日志配置操作</param>
    /// <param name="isClearProviders">是否清除默認設(shè)置的日志提供程序</param>
    public static IAppBuilder AddExceptionless( this IAppBuilder builder, Action<ExceptionlessConfiguration> configAction, bool isClearProviders = false ) {
        return builder.AddExceptionless( configAction, t => t.IsClearProviders = isClearProviders );
    }

    /// <summary>
    /// 配置Exceptionless日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="configAction">Exceptionless日志配置操作</param>
    /// <param name="appName">應用程序名稱</param>
    public static IAppBuilder AddExceptionless( this IAppBuilder builder, Action<ExceptionlessConfiguration> configAction, string appName ) {
        return builder.AddExceptionless( configAction, t => t.Application = appName );
    }

    /// <summary>
    /// 配置Exceptionless日志操作
    /// </summary>
    /// <param name="builder">應用生成器</param>
    /// <param name="configAction">Exceptionless日志配置操作</param>
    /// <param name="setupAction">日志配置</param>
    public static IAppBuilder AddExceptionless( this IAppBuilder builder, Action<ExceptionlessConfiguration> configAction, Action<LogOptions> setupAction ) {
        builder.CheckNull( nameof( builder ) );
        var options = new LogOptions();
        setupAction?.Invoke( options );
        builder.Host.ConfigureServices( ( context, services ) => {
            services.AddSingleton<ILogFactory, LogFactory>();
            services.AddTransient( typeof( ILog<> ), typeof( Log<> ) );
            services.AddTransient( typeof( ILog ), t => t.GetService<ILogFactory>()?.CreateLog( "default" ) ?? NullLog.Instance );
            var configuration = context.Configuration;
            services.AddLogging( loggingBuilder => {
                if ( options.IsClearProviders )
                    loggingBuilder.ClearProviders();
                ConfigExceptionless( configAction, configuration );
                SerilogLog.Logger = new LoggerConfiguration()
                    .Enrich.WithProperty( "Application", options.Application )
                    .Enrich.FromLogContext()
                    .Enrich.WithLogLevel()
                    .Enrich.WithLogContext()
                    .WriteTo.Exceptionless()
                    .ReadFrom.Configuration( configuration )
                    .ConfigLogLevel( configuration )
                    .CreateLogger();
                loggingBuilder.AddSerilog();
            } );
        } );
        return builder;
    }

    /// <summary>
    /// 配置Exceptionless
    /// </summary>
    private static void ConfigExceptionless( Action<ExceptionlessConfiguration> configAction, IConfiguration configuration ) {
        ExceptionlessClient.Default.Startup();
        if ( configAction != null ) {
            configAction( ExceptionlessClient.Default.Configuration );
            ConfigLogLevel( configuration, ExceptionlessClient.Default.Configuration );
            return;
        }
        ExceptionlessClient.Default.Configuration.ReadFromConfiguration( configuration );
        ConfigLogLevel( configuration, ExceptionlessClient.Default.Configuration );
    }

    /// <summary>
    /// 配置日志級別
    /// </summary>
    private static void ConfigLogLevel( IConfiguration configuration, ExceptionlessConfiguration options ) {
        var section = configuration.GetSection( "Logging:LogLevel" );
        foreach ( var item in section.GetChildren() ) {
            if ( item.Key == "Default" ) {
                options.Settings.Add( "@@log:*", GetLogLevel( item.Value ) );
                continue;
            }
            options.Settings.Add( $"@@log:{item.Key}*", GetLogLevel( item.Value ) );
        }
    }

    /// <summary>
    /// 獲取日志級別
    /// </summary>
    private static string GetLogLevel( string logLevel ) {
        switch ( logLevel.ToUpperInvariant() ) {
            case "TRACE":
                return "Trace";
            case "DEBUG":
                return "Debug";
            case "INFORMATION":
                return "Info";
            case "ERROR":
                return "Error";
            case "CRITICAL":
                return "Fatal";
            case "NONE":
                return "Off";
            default:
                return "Warn";
        }
    }
}

到了這里,關(guān)于Util應用框架基礎(chǔ)(六) - 日志記錄(一) - 正文的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • Util 應用框架 UI 全新升級

    Util 應用框架 UI 全新升級

    Util UI 已經(jīng)開發(fā)多年, 并在多家公司的項目使用. 不過一直以來, Util UI 存在一些缺陷, 始終未能解決. 最近幾個月, Util 團隊下定決心, 終于徹底解決了所有已知缺陷. Util 應用框架 UI 建立在 Angular , Ng-Zorro, Ng-Alain 基礎(chǔ)之上, 用于開發(fā)企業(yè)中后臺. 簡潔 Util UI 通??梢詫碗s組件的

    2024年04月28日
    瀏覽(28)
  • Util應用框架 UI 開發(fā)快速入門

    Util應用框架 UI 開發(fā)快速入門

    本文是Util應用框架 Angular UI 開發(fā)快速入門教程. Util 應用框架目前僅支持用于開發(fā)管理后臺的 UI. 本文介紹了 Util UI 的技術(shù)特點和功能支持. Js語言 TypeScript TypeScript 是 微軟開發(fā)的腳本語言, 擴展了弱類型的 Javascript,提供增強的語法和強類型支持. 為編輯器代碼提示和語法錯誤檢

    2024年02月08日
    瀏覽(19)
  • Util應用框架快速入門(4) - 集成測試開發(fā)入門

    Util應用框架快速入門(4) - 集成測試開發(fā)入門

    本文演示Util應用框架開發(fā)的項目中如何編寫集成測試. 完成 Web Api 快速入門,本文將在之前生成的示例項目上講解集成測試的開發(fā). 自動化測試對于Util應用框架的開發(fā)非常重要,它能保證基礎(chǔ)功能的穩(wěn)定性. 對于使用 Util 開發(fā)的業(yè)務項目,自動化測試不是必須的,但掌握它可能很有

    2024年02月08日
    瀏覽(93)
  • Spring Boot中集成各種日志框架Logback、Log4j2和Java Util Logging

    Spring Boot中集成各種日志框架Logback、Log4j2和Java Util Logging

    Spring Boot支持多種日志框架,包括Logback、Log4j2和Java Util Logging(JUL)。在Spring Boot中,可以通過簡單的配置來集成這些熱門的日志框架。 下面將詳細說明如何集成Logback、Log4j2和Java Util Logging,并提供相應的源代碼示例。 集成Logback: Logback是Spring Boot默認的日志框架,它提供了高

    2024年02月05日
    瀏覽(53)
  • 設(shè)置word目錄從正文開始記錄頁碼,并解決word目錄正常,但正文頁腳處只顯示第一頁的頁碼

    設(shè)置word目錄從正文開始記錄頁碼,并解決word目錄正常,但正文頁腳處只顯示第一頁的頁碼

    問題詳情1:如何設(shè)置目錄從正文開始記錄頁碼 問題詳情2:word目錄處的頁碼正常,但正文只有第一頁的頁腳處顯示頁碼 在設(shè)置目錄從正文開始記錄頁碼時需在目錄后插入分節(jié)符(相同的節(jié)可以把當前頁的頁腳鏈接到上一頁,但是不同的節(jié)就不行,因此可以利用分節(jié)來從 正文

    2024年03月10日
    瀏覽(29)
  • 深入理解 SpringBoot 日志框架:從入門到高級應用——(一)日志框架原理

    深入理解 SpringBoot 日志框架:從入門到高級應用——(一)日志框架原理

    日志框架的歷史可以追溯到計算機編程的早期。在早期的編程語言中,如 C 和 Pascal,程序員通常使用 printf 或 fprintf 函數(shù)將程序的狀態(tài)信息輸出到控制臺或文件中,以便調(diào)試和排查問題。 隨著計算機應用程序的不斷發(fā)展,人們對日志管理的需求越來越高。當我們在開發(fā)項目時

    2024年02月09日
    瀏覽(27)
  • 深入理解 SpringBoot 日志框架:從入門到高級應用——(七)SpringBoot日志配置

    深入理解 SpringBoot 日志框架:從入門到高級應用——(七)SpringBoot日志配置

    SpringBoot 官方文檔:https://docs.spring.io/spring-boot/docs/2.7.12/reference/htmlsingle Spring Boot 對所有內(nèi)部日志記錄使用 Commons Logging,但使底層日志實現(xiàn)保持為打開狀態(tài)。 為 Java Util Logging、Log4J2 和 Logback 提供了默認配置。默認情況下,Logback、 Java Util Logging、Commons Logging、Log4J 或 SLF4J 都能

    2024年02月09日
    瀏覽(37)
  • 日志文件之間關(guān)系和介紹及應用

    Log4j: Log4j是Java中廣泛使用的日志框架之一。它提供了靈活的配置選項和豐富的功能,支持日志級別、日志輸出目標等。Log4j有1.x版本和2.x版本,其中Log4j 2.x是對1.x的升級和擴展。 Logback: Logback是由Log4j創(chuàng)始人設(shè)計的Log4j的后繼者,也是一個非常流行的Java日志框架。它具有高性能

    2024年02月10日
    瀏覽(12)
  • 【前端打怪升級日志之微前端框架篇】微前端qiankun框架子應用間跳轉(zhuǎn)方法

    參考鏈接 qiankun官網(wǎng):微應用之間如何跳轉(zhuǎn)? 1.主應用、子應用路由都是hash模式 ? ?主應用根據(jù) hash 來判斷微應用,無需考慮該問題 2.主應用根據(jù)path判斷子應用 方法 實現(xiàn) 適用條件 參數(shù)傳遞 存在問題 a標簽跳轉(zhuǎn) a href=\\\"/toA\\\"/a 頁面重新刷新,原來的狀態(tài)丟失,用戶體驗不好 h

    2024年02月07日
    瀏覽(25)
  • 深入理解 SpringBoot 日志框架:從入門到高級應用——(六)Log4j2 輸出日志到 QQ郵箱

    深入理解 SpringBoot 日志框架:從入門到高級應用——(六)Log4j2 輸出日志到 QQ郵箱

    要實現(xiàn)將 log4j2 輸出日志到 QQ 郵箱,需按照以下步驟進行: 在 QQ 郵箱中設(shè)置 SMTP 服務,開啟 POP3/SMTP 服務,獲取 SMTP 服務地址、端口號、登錄郵箱賬號和密碼。 在 Java 項目中添加 Mail 依賴。 在 log4j2.xml 配置文件中,添加 SMTPAppender,指定SMTP服務器地址、端口號、郵箱賬號和

    2024年02月09日
    瀏覽(98)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包