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

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

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

      結構化日志組件 Serilog

      什么是結構化日志

      我們記錄日志慣常使用 log4j2NLog 等日志組件,這些組件提供了輸出到多種終端的能力,但是大部分時候我們選擇將日志輸出到操作系統的文件系統中,為什么呢?至少有一部分原因是記錄的每條日志為字符串格式,且按時間由遠往進順序記錄,打開文件可以直接人肉檢索;如果這些日志記錄到其它終端比如數據庫中,由于是字符串格式,無法依靠數據庫的機制提高檢索效率,反而日志的頻繁寫入和數據量的持續增大,對數據庫造成很大壓力,還需要花時間調優數據庫結構。

      但 22 世紀都快到了,還在用古老的人肉檢索實在說不過去,于是出現了流行一時的 EFKELK框架,它們是幾個組件的集合。大致流程如下:

      1. 首先是日志采集組件比如 filebeats,定時從配置好的路徑中采集增量日志;
      2. 上傳到消息隊列比如 kafka,緩解日志過多時的傳輸壓力;
      3. 然后送達日志處理組件比如 logstash, logstash 使用 filter 對日志進行拆分、映射、過濾等,抽取關鍵內容并形成符合目標數據庫特性的格式。注意此處出來的就是結構化日志;
      4. 將結構化日志存儲到特定的數據庫比如 elasticsearch 中;
      5. 通過用戶界面如 Kibana 進行日志檢索。

      上述流程在不同場景下有一些變種,不再贅述。 它們的主要目的就是使得傳統的文件日志可以被計算機高效檢索。

      那么有沒有一種可能,跳過文件存儲,直接將日志按特定格式寫入到目標存儲容器,可能是 elasticsearch,也可能是 mysql,甚至是文件系統。同樣代碼,輸出不同的格式到不同的終端,同時滿足 human-friendly and machine-readable

      在 .NET 世界中, 本文的主角 Serilog 就可以幫我們省去那些彎彎繞繞,依靠它,記錄與查詢日志顯得簡單而純粹。

      Serilog

      以官方例子說明:

      var position = new { Latitude = 25, Longitude = 134 };
      var elapsedMs = 34;
      
      log.Information("Processed {@Position} in {Elapsed} ms", position, elapsedMs);
      

      按字面意思,最終會輸出:

      09:14:22 [INF] Processed {"Latitude": 25, "Longitude": 134} in 34 ms.
      

      當 Serilog 將日志直接輸出到文件系統或命令行時,結果是這樣沒錯,其它日志組件也能做到(廢話)。

      當輸出到 MongoDB 時,結果就不一樣了:

      { "Position": { "Latitude": 25, "Longitude": 134 }, "Elapsed": 34 }
      

      Sink

      Serilog 將輸出目標稱之為 sink,不同的 sink 可以有各自的格式要求。其實原理很簡單,輸出到特定 sink 時,日志對象會先格式化處理(注意不是先生成字符串再格式化)。Serilog.Formatting.Compact 就是格式化為 json 的類庫,輸出到 elasticsearch 還需要 Serilog.Formatting.Elasticsearch。不過除非自定義 sink,這些我們都不用關心,使用時只要引入需要的 sink 類庫即可。

      使用

      下面介紹在 .NET6 中使用 Serilog。

      先引入 Serilog 類庫和需要的 Sink 庫比如這里的 Serilog.Sinks.File

      <PackageReference Include="Serilog" Version="2.12.0" />
      <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
      

      以通用宿主程序為例:

      IHost host = Host.CreateDefaultBuilder(args).Build();
      
      // 配置并創建 logger 實例
      var log = new LoggerConfiguration()
          .MinimumLevel.Warning()
          .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 10485760, rollOnFileSizeLimit: true, retainedFileCountLimit: 100, buffered: true)
          .CreateLogger();
      
      log.Information("Hello, Serilog!"); // 直接使用(可以創建多個實例使用)
      
      Log.Logger = log;   // Serilog 并沒有實例狀態需要線程間維護,所以為了方便我們可以使用單例模式,將實例賦給全局靜態屬性
      Log.Information("The global logger has been configured");   // 項目內任意其它地方均可使用
      
      await host.RunAsync().ContinueWith(_=> Log.CloseAndFlush());    // app 退出時釋放 logger 占用資源
      

      如果想以 .NET 內置的方式調用 Serilog,對于通用宿主程序,須引入 Serilog.Extensions.Hosting,其扮演適配器的角色,將 Serilog 自己的接口 Serilog.ILogger 轉換為 Microsoft.Extensions.Logging.ILogger 使用。如果是 web 項目的話,引入的是 Serilog.AspNetCore.NET Core 1.0, 1.1 等版本需要引入的是 Serilog.Extensions.Logging

      更改后的版本如下:

      IHost host = Host
          .CreateDefaultBuilder(args)
          .UseSerilog()   // 新增該行
          .Build();
      
      // ... 其余代碼同上
      

      另外,上述代碼是直接硬編碼配置 logger,更好的方式是通過 appsettings.json 配置 logger。首先引入 Serilog.Settings.Configuration,然后在 appsettings.json 中移除默認的 Logging 配置節,替換為 Serilog 配置節如下:

      {
        "Serilog": {
          "Using": [ "Serilog.Sinks.File" ],
          "MinimumLevel": "Warning",
          "WriteTo": [
            {
              "Name": "File",
              "Args": {
                "path": "Logs/log.txt",
                "rollingInterval": "Day",
                "fileSizeLimitBytes": 10485760,
                "rollOnFileSizeLimit": true,
                "retainedFileCountLimit": 100,
                "buffered": true
              }
            }
          ]
        }
      }
      

      代碼更改如下:

      IHost host = Host
          .CreateDefaultBuilder(args)
          .UseSerilog((ctx, config) => config
              .ReadFrom.Configuration(ctx.Configuration))
          .Build();
      
      //以下注釋
      //var log = new LoggerConfiguration()
      //    .MinimumLevel.Warning()
      //    .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 10485760, rollOnFileSizeLimit: true, retainedFileCountLimit: 100, shared: true, buffered: true)
      //    .CreateLogger();
      //Log.Logger = log;
      
      await host.RunAsync(); //注釋.ContinueWith(_ => Log.CloseAndFlush());
      

      采用這種方式,Log.Logger 會隱式賦值,并在系統退出時自動釋放資源。

      參考資料

      Docker+EFK 快速搭建日志收集系統
      Message Templates
      .NET Worker Service 添加 Serilog 日志記錄

      posted @ 2023-01-05 10:46  萊布尼茨  閱讀(1700)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 亚洲男人天堂2018| 精品无人乱码一区二区三区的优势 | 国产成人无码A区在线观| 国产精品欧美福利久久| 午夜精品一区二区三区成人| 白嫩少妇无套内谢视频| 亚洲日韩一区精品射精| 久久亚洲色www成人| 蜜臀久久精品亚洲一区| 天天躁夜夜踩很很踩2022| 日韩区中文字幕在线观看| 色狠狠综合天天综合综合| 伊人成人在线视频免费| 久久中精品中文字幕入口| 久久精品国产最新地址| 久久99热精品这里久久精品| 国产99青青成人A在线| 中文字幕日韩国产精品| 五月婷婷深开心五月天| 116美女极品a级毛片| 色综合久久久久综合体桃花网| 成人3D动漫一区二区三区 | 日韩精品人妻中文字幕| 国产在线观看码高清视频| 梁河县| 日韩精品久久不卡中文字幕| 蜜臀av一区二区国产在线| 欧洲成人在线观看| 国产在线午夜不卡精品影院| 综合久青草视频在线观看| 亚洲国产精品一二三四五| 最新亚洲av日韩av二区| 国产无遮挡吃胸膜奶免费看| 99精品国产成人一区二区| 精品国产这么小也不放过| 亚洲精品国产精品国自产| 亚洲第四色在线中文字幕| 成人午夜在线观看日韩| 国产av不卡一区二区| 亚洲av第二区国产精品| 99久久国产综合精品成人影院|