<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Serilog 日志記錄庫(kù)

      Serilog 是一個(gè) .NET 平臺(tái)上的強(qiáng)大的日志記錄庫(kù)。它提供了豐富的 API 以及可插拔的日志格式化器和輸出器,使得在 .NET 應(yīng)用程序中實(shí)現(xiàn)可定制化的、可擴(kuò)展的日志記錄變得輕而易舉。

      在本文中,我們將探討 Serilog 的一些基礎(chǔ)知識(shí)、API、配置和示例。

      基礎(chǔ)知識(shí)

      日志級(jí)別

      Serilog 支持多個(gè)日志級(jí)別,包括以下級(jí)別(按照嚴(yán)重程度從高到低排列):

      • Fatal: 程序已經(jīng)無法繼續(xù)運(yùn)行,需要立即解決的問題。
      • Error: 一個(gè)錯(cuò)誤發(fā)生,需要被處理。
      • Warning: 一個(gè)警告,通常需要被留意,但是不需要立即處理。
      • Information: 提供有用的信息,通常只有在調(diào)試應(yīng)用程序時(shí)才需要關(guān)注。
      • Debug: 提供調(diào)試信息,有助于調(diào)試應(yīng)用程序。
      • Verbose: 提供大量的細(xì)節(jié)信息,通常只用于調(diào)試復(fù)雜的問題。

      日志輸出

      Serilog 支持多種日志輸出,包括:

      • Console
      • File
      • Seq
      • Elasticsearch

      此外,Serilog 還支持自定義日志輸出器。

      日志格式

      Serilog 支持多種日志格式化方式,包括:

      • 簡(jiǎn)單文本格式
      • JSON 格式
      • Message Templates 格式(一種更加靈活的格式)

      安裝

      可以通過 NuGet 安裝 Serilog。

      Install-Package Serilog

       

      使用

      基礎(chǔ)使用

      在應(yīng)用程序中使用 Serilog 很簡(jiǎn)單。下面的示例演示了如何在控制臺(tái)輸出日志:

      using Serilog;
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console()
                  .CreateLogger();
      
              Log.Information("Hello, Serilog!");
      
              Log.CloseAndFlush();
          }
      }

       

      上面的代碼將 Hello, Serilog! 輸出到控制臺(tái)。

      詳細(xì)使用

      日志級(jí)別

      下面的示例演示了如何在 Serilog 中設(shè)置不同的日志級(jí)別:

      using Serilog;
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Verbose()
                  .WriteTo.Console()
                  .CreateLogger();
      
              Log.Verbose("This is a verbose log message.");
              Log.Debug("This is a debug log message.");
              Log.Information("This is an informational log message.");
              Log.Warning("This is a warning log message.");
              Log.Error("This is an error log message.");
              Log.Fatal("This is a fatal log message.");
      
              Log.CloseAndFlush();
          }
      }

       

      
      
      上面的代碼將演示如何使用不同的日志級(jí)別來記錄日志消息。
      
      #### 消息模板
      
      Serilog 采用消息模板來格式化日志消息。下面是一個(gè)簡(jiǎn)單的消息模板示例:
      using Serilog;
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
                  .CreateLogger();
      
              Log.Information("Hello, {Name}!", "Serilog");
      
              Log.CloseAndFlush();
          }
      }

       

      在上面的示例中,我們使用了一個(gè)帶有模板的控制臺(tái)輸出器,并且在消息模板中使用了占位符 {Name}。當(dāng)日志記錄方法被調(diào)用時(shí),{Name} 將被替換為 Serilog。我們可以看到 Hello, Serilog! 在控制臺(tái)輸出。

      日志屬性

      Serilog 支持日志屬性,這使得我們可以在日志消息中記錄更多的信息。下面的示例演示了如何在日志消息中添加屬性:

      using Serilog;
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console()
                  .CreateLogger();
      
              Log.Information("Processed {@Count} records in {Time} ms.", new { Count = 10, Time = 123 });
      
              Log.CloseAndFlush();
          }
      }

       

      在上面的示例中,我們使用了一個(gè)匿名類型來表示日志屬性。在日志消息中,我們使用了 @ 符號(hào)來引用這個(gè)匿名類型。當(dāng)日志記錄方法被調(diào)用時(shí),Serilog 將自動(dòng)將匿名類型的屬性添加到日志消息中。上面的代碼將輸出 Processed { Count: 10, Time: 123 } records in 0 ms.。

      輸出模板定義

      outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")

      這個(gè)也是官方的默認(rèn)模板,我們可以這個(gè)擴(kuò)展

      .WriteTo.File("log.txt",
          outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")

       

      輸出到文件

      rollingInterval: RollingInterval.Day 每天一個(gè)日志文件

      outputTemplate 輸出格式模板

      .WriteTo.File(
                          $"logs\\log-.txt" ,
                          //每天一個(gè)文件 ,生成類似:log-20230914.txt
                          //fileSizeLimitBytes: null 文件限制大?。簾o   如果不配置默認(rèn)是:1GB 1GB就不記錄了
                          //retainedFileCountLimit: null   保留文件數(shù)量   如果不配置只保留31天的日志
                          //https://github.com/serilog/serilog-sinks-file 
                          rollingInterval: RollingInterval.Day , retainedFileCountLimit: null ,
                          //fileSizeLimitBytes: null,
                          //單個(gè)文件大?。?1024000 1024000是1M
                          //rollOnFileSizeLimit: true 就是滾動(dòng)文件,如果超過單個(gè)文件大小,會(huì)滾動(dòng)文件 產(chǎn)生類似:log.txt log_001.txt log_002.txt
                          fileSizeLimitBytes: 3024000 , rollOnFileSizeLimit: true ,
                          //非必填:指定最小等級(jí)
                          restrictedToMinimumLevel: LogEventLevel.Information ,
                          //非必填: 也可以指定輸出格式:這種格式好像與系統(tǒng)默認(rèn)沒有什么區(qū)別
                          //outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
      
                          //outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {NewLine}{Version}{myval}"
      
                          outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {NewLine}{Version}{myval} {NewLine}{UserId}{myid}{NewLine}"
                      )

       

      結(jié)構(gòu)化記錄日志

      寫入變量
      var itemNumber = 10;
      var itemCount = 999;
      
      // 使用占位符寫入
      // 結(jié)果:2023-09-15 22:23:54.576 +08:00 [INF] Processing item 10 of 999
      this._logger.LogDebug( "Processing item {ItemNumber} of {ItemCount}" , itemNumber , itemCount );

       

      寫入類

      特別提示:記錄對(duì)象后 1.日志中會(huì)多一個(gè)$type屬性 2.日期類型數(shù)據(jù)格式化后都是這樣格式:2023-09-16T22:26:27.5905512+08:00

      var wf = new WeatherForecast
              {
                  Date = DateTime.Now.AddDays( 1 ) ,
                  TemperatureC = 55 ,
                  Summary = ""
              };
              
      // @表示一個(gè)對(duì)象 這樣就可以把一個(gè)對(duì)象直接傳遞進(jìn)去
      // 特別提示:記錄對(duì)象后
      // 1.日志中會(huì)多一個(gè)$type屬性
      // 2.日期類型數(shù)據(jù)格式化后都是這樣格式:2023-09-16T22:26:27.5905512+08:00
      //結(jié)果:2023-09-15 22:26:27.601 +08:00 [INF] WeatherForecast 的數(shù)據(jù) {"Date":"2023-09-16T22:26:27.5905512+08:00","TemperatureC":55,"TemperatureF":130,"Summary":"","$type":"WeatherForecast"}
      this._logger.LogInformation( "WeatherForecast 的數(shù)據(jù) {@wf}" , wf );

       

      寫入集合
      List<string> list1 = new List<string>() { "q1" , "q2" };
              
      //寫入集合
      //結(jié)果:2023-09-15 22:36:46.751 +08:00 [INF] 集合的數(shù)據(jù) ["q1","q2"]
      this._logger.LogInformation( "集合的數(shù)據(jù) {@list1}" , list1 );
      List<WeatherForecast> listw = new List<WeatherForecast>() {
              new WeatherForecast
              {
                  Date = DateTime.Now.AddDays( 1 ) ,
                  TemperatureC = 11 ,
                  Summary = "one"
              },
              new WeatherForecast
              {
                  Date = DateTime.Now.AddDays( 2 ) ,
                  TemperatureC = 22 ,
                  Summary = "two"
              }};
              
      //寫入集合
      //結(jié)果: 2023-09-15 22:39:53.863 +08:00 [INF] 集合的數(shù)據(jù) [{"Date":"2023-09-16T22:39:53.8634787+08:00","TemperatureC":11,"TemperatureF":51,"Summary":"one","$type":"WeatherForecast"},{"Date":"2023-09-17T22:39:53.8634842+08:00","TemperatureC":22,"TemperatureF":71,"Summary":"two","$type":"WeatherForecast"}]
      this._logger.LogInformation( "集合的數(shù)據(jù) {@listw}" , listw );

       

      寫入匿名類
      var user = new
                  {
                      Name = "Nick" ,
                      Id = "nblumhardt" ,
                      add = new List<string>() { "add1" , "add2" } ,
                      man = new
                      {
                          age = 1 ,
                          names = "qq"
                      }
                  };
                  
      // @表示一個(gè)對(duì)象(上面這個(gè)是匿名類也可以寫入的)  
      //結(jié)果:2023-09-15 22:23:54.576 +08:00 [INF] Logged on user {"Name":"Nick","Id":"nblumhardt","add":["add1","add2"],"man":{"age":1,"names":"qq"}}
      this._logger.LogInformation( "Logged on user {@user}" , user );

       

      輸出上下文

      方式1:固定值的上下文
      Log.Logger = new LoggerConfiguration()
           // 注冊(cè)日志上下文
          .Enrich.FromLogContext()
          //  上下文
          .Enrich.WithProperty( "Version" , "1.0.0" )
          .Enrich.WithProperty( "myval" , 123 )

       

      配置模版定義上下文

      //outputTemplate中配置寫入上下文
      outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {NewLine}{Version}{myval}"

       

      方式2:動(dòng)態(tài)傳遞上下文

      配置模版定義上下文

      outputTemplate中定義了2個(gè)上下文:UserId和myid
      outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {NewLine}{Version}{myval} {NewLine}{UserId}{myid}{NewLine}"

       

      代碼傳遞值

      //利用BeginScope傳遞上下文
      using ( this._logger.BeginScope( new Dictionary<string , object>
      {
          ["UserId"] = "svrooij" ,
          ["myid"] = 123456 ,
      } ) )
      {
          this._logger.LogInformation( "我傳遞上下文參數(shù)過來了"  );
      }
      
      
      
      //不是每個(gè)都要傳遞上下文,沒有傳遞也不報(bào)錯(cuò)
      this._logger.LogError( new Exception( "0異常啦" ) , "我自己造的" );
      this._logger.LogInformation( new Random().Next( 10000 ).ToString() );

       

      日志過濾器

      Serilog 支持過濾器來控制日志輸出。下面的示例演示了如何使用過濾器來僅輸出錯(cuò)誤級(jí)別以上的日志:

      using Serilog;
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console()
                  .Filter.ByIncludingOnly(logEvent => logEvent.Level >= LogEventLevel.Error)
                  .CreateLogger();
      
              Log.Verbose("This is a verbose log message.");
              Log.Debug("This is a debug log message.");
              Log.Information("This is an informational log message.");
              Log.Warning("This is a warning log message.");
              Log.Error("This is an error log message.");
              Log.Fatal("This is a fatal log message.");
      
              Log.CloseAndFlush();
          }
      }

       

      在上面的示例中,我們使用了 ByIncludingOnly 過濾器來僅輸出錯(cuò)誤級(jí)別以上的日志。

      幾種常用過濾方式

      Filter.ByIncludingOnly:是包括

      Filter.ByExcluding:是不包括

      a.不同等級(jí),輸出不同文件
      Func<LogEvent , bool> isInformation = ( logEvent ) => logEvent.Level == LogEventLevel.Information;
      Func<LogEvent , bool> isError = ( logEvent ) => logEvent.Level == LogEventLevel.Error;
             // 輸出到文件
             //不同等級(jí),輸出不同文件
             .WriteTo.Logger( lg =>
             {
                 lg.Filter.ByIncludingOnly( p => isInformation( p ) )
                             .WriteTo.File( $"logs\\log_Information-.txt" , rollingInterval: RollingInterval.Day );
             } )
             .WriteTo.Logger( lg =>
             {
                 lg.Filter.ByIncludingOnly( p => isError( p ) )
                         .WriteTo.File( $"logs\\log_Error-.txt" , rollingInterval: RollingInterval.Day );
             } )

       

      b.不同類,輸出不同文件
      //不同類,輸出不同文件
          .WriteTo.Logger( lg =>
          {
              lg.Filter.ByIncludingOnly( Matching.FromSource<WeatherForecastController>() )
                  .WriteTo.File( $"logs\\WeatherForecastController-.txt" , rollingInterval: RollingInterval.Day );
          } )
          .WriteTo.Logger( lg =>
          {
              lg.Filter.ByIncludingOnly( Matching.FromSource<ValuesController>() )
                 .WriteTo.File( $"logs\\ValuesController-.txt" , rollingInterval: RollingInterval.Day );
          } )

       

      c.根據(jù)消息內(nèi)容過濾,輸出不同文件
      Func<LogEvent , bool> isbsWeatherForecastController = ( p ) =>
      {
          var msg = p.RenderMessage();
      
          if ( !string.IsNullOrEmpty( msg ) )
          {
              return msg.Contains( "bs:WeatherForecastController" , StringComparison.OrdinalIgnoreCase );
          }
      
          return false;
      };
       //根據(jù)消息內(nèi)容過濾,輸出不同文件
      .WriteTo.Logger( lg =>
      {
          lg.Filter.ByIncludingOnly( p => isbsWeatherForecastController( p ) )
          .Filter.ByIncludingOnly( isMidServices )
          .WriteTo.File( $"logs\\WeatherForecastController-.txt" , rollingInterval: RollingInterval.Day );
      } )

       

      d.根據(jù)上下文值,輸出不同文件
      //根據(jù)上下文值,輸出不同文件
          .WriteTo.Logger( lg =>
          {
              //lg.Filter.ByIncludingOnly( Matching.WithProperty( "UserId" , "svrooij" ) )
              
              //下面這個(gè),也是等效寫法
              lg.Filter.ByIncludingOnly( Matching.WithProperty<string>( "UserId" , str => !string.IsNullOrEmpty( str ) && str.Equals( "svrooij" , StringComparison.OrdinalIgnoreCase ) ) )
                  .WriteTo.File( $"logs\\WeatherForecastController-.txt" ,
                      rollingInterval: RollingInterval.Day ,
                      outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}   {NewLine}{UserId}{myid}{NewLine}" );
          } )

       

      e.實(shí)現(xiàn)接口ILogEventFilter
      public class CustomFilter : ILogEventFilter
          {
              private readonly string _propertyName;
              private readonly string _propertyValue;
      
              public CustomFilter ( string propertyName , string propertyValue )
              {
                  _propertyName = propertyName;
                  _propertyValue = propertyValue;
              }
      
      
              public bool IsEnabled ( LogEvent logEvent )
              {
                  //下面的判斷邏輯是:Information等級(jí)的,MidServices類產(chǎn)生的,判斷某個(gè)上下文是否為某個(gè)值
      
                  if ( logEvent.Level == LogEventLevel.Information )
                  {
                      var f = Matching.FromSource<MidServices>();
                      bool bl = f.Invoke( logEvent );
      
                      if ( bl )
                      {
                          var f2 = Matching.WithProperty<string>( _propertyName ,
                                                                                      str => !string.IsNullOrEmpty( str ) && str.Equals( _propertyValue , StringComparison.OrdinalIgnoreCase ) );
      
                          bool bl2 = f2.Invoke( logEvent );
      
                          if ( bl2 )
                          {
                              return true;
                          }
                      }
      
                  }
      
                  return false;
              }
          }

       

      配置文件

      Serilog 還支持使用配置文件來配置日志記錄。下面是一個(gè)配置文件示例:

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
      <appSettings>
      <add key="serilog:minimum-level" value="Verbose" />
      <add key="serilog:write-to:Console" />
      </appSettings>
      <startup>
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
      </startup>
      </configuration>

       

      在上面的示例中,我們使用了一個(gè)配置文件來配置 Serilog。我們將日志級(jí)別設(shè)置為 Verbose,并且將輸出器設(shè)置為 Console。

      擴(kuò)展

      Serilog 提供了豐富的擴(kuò)展方式,包括:

      • 日志輸出器擴(kuò)展
      • 日志過濾器擴(kuò)展
      • 日志格式化器擴(kuò)展

      日志輸出器擴(kuò)展

      Serilog 提供了多種擴(kuò)展方式來添加自定義日志輸出器。

      控制臺(tái)輸出器擴(kuò)展

      以下示例演示了如何添加一個(gè)自定義的控制臺(tái)輸出器:

      using Serilog;
      using Serilog.Configuration;
      using Serilog.Events;
      using Serilog.Formatting;
      
      public static class CustomConsoleSinkExtensions
      {
          public static LoggerConfiguration CustomConsole(
              this LoggerSinkConfiguration sinkConfiguration,
              ITextFormatter formatter = null,
              LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
          {
              return sinkConfiguration.Sink(
                  new CustomConsoleSink(formatter),
                  restrictedToMinimumLevel);
          }
      }
      
      public class CustomConsoleSink : ILogEventSink
      {
          private readonly ITextFormatter _formatter;
      
          public CustomConsoleSink(ITextFormatter formatter)
          {
              _formatter = formatter ?? throw new ArgumentNullException(nameof(formatter));
          }
      
          public void Emit(LogEvent logEvent)
          {
              var message = new StringWriter();
              _formatter.Format(logEvent, message);
              Console.WriteLine(message.ToString());
          }
      }
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.CustomConsole()
                  .CreateLogger();
      
              Log.Information("Hello, Serilog!");
      
              Log.CloseAndFlush();
          }
      }

       

      在上面的示例中,我們定義了一個(gè)名為 CustomConsoleSink 的自定義控制臺(tái)輸出器,并將其添加到 Serilog 的輸出器列表中。

      Elasticsearch 輸出器擴(kuò)展

      以下示例演示了如何添加一個(gè)自定義的 Elasticsearch 輸出器:

      using Serilog;
      using Serilog.Configuration;
      using Serilog.Events;
      using Serilog.Formatting;
      using Serilog.Sinks.Elasticsearch;
      
      public static class CustomElasticsearchSinkExtensions
      {
          public static LoggerConfiguration CustomElasticsearch(
              this LoggerSinkConfiguration sinkConfiguration,
              ITextFormatter formatter = null,
              ElasticsearchSinkOptions elasticsearchOptions = null,
              LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
          {
              return sinkConfiguration.Sink(
                  new CustomElasticsearchSink(formatter, elasticsearchOptions),
                  restrictedToMinimumLevel);
          }
      }
      
      public class CustomElasticsearchSink : ElasticsearchSink
      {
          public CustomElasticsearchSink(
              ITextFormatter formatter,
              ElasticsearchSinkOptions elasticsearchOptions) :
              base(elasticsearchOptions)
          {
              Formatter = formatter;
          }
      
          public ITextFormatter Formatter { get; }
      
          protected override void EmitBatch(
              IEnumerable<LogEvent> events,
              IBulkWriter writer)
          {
              foreach (var logEvent in events)
              {
                  var message = new StringWriter();
                  Formatter.Format(logEvent, message);
                  var json = message.ToString();
                  writer.IndexDocument(json);
              }
          }
      }
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.CustomElasticsearch(new ElasticsearchSinkOptions(new Uri("[http://localhost:9200](http://localhost:9200/) ")),new ElasticsearchJsonFormatter(),LogEventLevel.Information)
                  .CreateLogger();
      
              Log.Information("Hello, Serilog!");
      
              Log.CloseAndFlush();
          }
      }

       

      在上面的示例中,我們定義了一個(gè)名為 CustomElasticsearchSink 的自定義 Elasticsearch 輸出器,并將其添加到 Serilog 的輸出器列表中。

      日志過濾器擴(kuò)展

      Serilog 提供了多種擴(kuò)展方式來添加自定義日志過濾器。

      以下示例演示了如何添加一個(gè)自定義的日志過濾器:

      using Serilog;
      using Serilog.Configuration;
      using Serilog.Events;
      
      public static class CustomFilterExtensions
      {
          public static LoggerConfiguration CustomFilter(
              this LoggerFilterConfiguration filterConfiguration,
              string propertyName,
              string propertyValue,
              LogEventLevel minimumLevel = LevelAlias.Minimum)
          {
              return filterConfiguration.Add(
                  new CustomFilter(propertyName, propertyValue),
                  minimumLevel);
          }
      }
      
      public class CustomFilter : ILogEventFilter
      {
          private readonly string _propertyName;
          private readonly string _propertyValue;
      
          public CustomFilter(string propertyName, string propertyValue)
          {
              _propertyName = propertyName;
              _propertyValue = propertyValue;
          }
      
          public bool IsEnabled(LogEvent logEvent)
          {
              if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
      
              var property = logEvent.Properties[_propertyName];
              if (property == null) return false;
      
              return property.ToString().Equals(_propertyValue);
          }
      }
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console()
                  .Filter.CustomFilter("Environment", "Production")
                  .CreateLogger();
      
              Log.Information("Hello, Serilog!");
      
              Log.CloseAndFlush();
          }
      }

       

      在上面的示例中,我們定義了一個(gè)名為 CustomFilter 的自定義過濾器,并將其添加到 Serilog 的過濾器列表中。該過濾器將僅輸出 Environment 屬性為 Production 的日志。

      日志格式化器擴(kuò)展

      Serilog 提供了多種擴(kuò)展方式來添加自定義日志格式化器。

      以下示例演示了如何添加一個(gè)自定義的日志格式化器:

      using Serilog;
      using Serilog.Configuration;
      using Serilog.Events;
      using Serilog.Formatting.Display;
      
      public static class CustomFormatterExtensions
      {
          public static LoggerConfiguration CustomFormatter(
              this LoggerConfiguration loggerConfiguration,
              string format,
              IFormatProvider formatProvider = null,
              LogEventLevel minimumLevel = LevelAlias.Minimum)
          {
              return loggerConfiguration.Sink(
                  new CustomFormatterSink(format, formatProvider),
                  minimumLevel);
          }
      }
      
      public class CustomFormatterSink : ILogEventSink
      {
          private readonly MessageTemplateTextFormatter _formatter;
      
          public CustomFormatterSink(string format, IFormatProvider formatProvider = null)
          {
              _formatter = new MessageTemplateTextFormatter(format, formatProvider);
          }
      
          public void Emit(LogEvent logEvent)
          {
              var message = new StringWriter();
      
              _formatter.Format(logEvent, message);
                  Console.WriteLine(message.ToString());
              }
      }
      
      class Program
      {
          static void Main()
          {
              Log.Logger = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.CustomFormatter("Hello, {Name}!", null, LogEventLevel.Information)
                  .CreateLogger();
              Log.Information("{Name}", "Serilog");
              Log.CloseAndFlush();
          }
      }

       

       
      posted @ 2024-03-20 22:29  一事冇誠(chéng)  閱讀(1477)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 视频一区二区 国产视频| 九九热在线免费视频观看| xxxx丰满少妇高潮| 蜜桃视频一区二区三区四| 四虎国产精品永久入口| 亚洲一本二区偷拍精品| 欧美亚洲另类制服卡通动漫 | 99久久99久久精品国产片| 国产成人av一区二区三| 国产成人午夜福利院| 亚洲a∨无码一区二区三区| 人妻无码久久精品| 欧美日韩另类国产| 国产精品久久久一区二区三区| 国产性色av高清在线观看| 熟女激情乱亚洲国产一区| 国产在线午夜不卡精品影院| 四虎永久播放地址免费| 97se亚洲综合自在线| 欧美白妞大战非洲大炮| 亚洲精品色国语对白在线| 无码精品国产va在线观看dvd| 国产乱码精品一区二三区| 蜜臀久久精品亚洲一区| 55大东北熟女啪啪嗷嗷叫| 人妻av中文字幕无码专区| 五月婷婷开心中文字幕| 亚洲国产成人久久一区久久| 男受被做哭激烈娇喘gv视频| 日本免费一区二区三区久久 | 亚洲综合黄色的在线观看| 国产在线中文字幕精品| 性虎精品无码AV导航| 精品一日韩美女性夜视频| 蜜桃AV抽搐高潮一区二区| 日韩精品中文字幕第二页| 国产午夜影视大全免费观看| 欧洲一区二区中文字幕| 亚洲区一区二区激情文学| 亚洲老熟女一区二区三区| 精品国产这么小也不放过|