Util應用框架基礎(六) - 日誌記錄(三) - 寫入 Seq

本文是Util應用框架日誌記錄的第三篇,介紹安裝和寫入 Seq 日誌系統的配置方法.

安裝 Seq

Seq是一個日誌管理系統,對結構化日誌數據擁有強大的模糊搜索能力.

Util應用框架目前主要使用 SeqExceptionless 管理日誌.

你可以從中選擇一個合適的.

本節介紹使用 Docker 簡單安裝 Seq,用於開發測試,部署到生產環境請參考官方文檔.

安裝 Seq

創建 seq-data 卷, 運行命令.

docker volume create seq-data

創建 Seq 容器, 運行命令.

docker run --name seq -d --restart=always -e ACCEPT_EULA=Y -v seq-data:/data -p 5380:80 datalust/seq:2023.3

容器名稱: seq

連接端口: 5380

未設置用戶密碼

安裝成功後,Docker容器列表出現 seq 容器.

運行 Seq

打開 http://localhost:5380 ,可以看到 Seq 管理界面.

寫入 Seq

日誌配置

  • 引用Nuget包

    Nuget包名: Util.Logging.Serilog

  • AddSerilog

    使用 AddSerilog 擴展方法啓用 Serilog 日誌操作.

    • 默認配置不帶參數.

      var builder = WebApplication.CreateBuilder( args );
      builder.AsBuild().AddSerilog();
      
    • 如果要清除默認設置的日誌提供程序,傳入 true.

      Asp.Net Core 默認日誌提供程序會把消息輸出到控制檯,你可以清除它們.

      builder.AsBuild().AddSerilog( true );
      
    • 設置應用程序名稱.

      對於微服務應用,記錄產生日誌的應用名稱,能方便排查問題.

      builder.AsBuild().AddSerilog( "權限服務" );
      
    • 你也可以使用委託設置參數.

      • 清除默認設置的日誌提供程序
      builder.AsBuild().AddSerilog( t => t.IsClearProviders = true );
      
  • 添加 appsettings 配置節

    appsettings.json 配置文件添加 Serilog 配置節.

    {
      "Logging": {
        "LogLevel": {
          "Default": "Trace"
        }
      },
      "Serilog": {
        "WriteTo": [      
          {
            "Name": "Seq",
            "Args": {
              "serverUrl": "http://localhost:5380"
            }
          }
        ]
      }
    }
    

    WriteTo 指定日誌接收器爲 Seq.

    最簡化配置僅需設置 Seq 的服務地址.

    本教程 Seq 安裝示例使用 5380 端口.

    其它參數請參考 Serilog 和 Seq 文檔.

查看 Seq

配置完成後,可以啓動你的項目,查看 Seq 日誌界面.

可以看到由 Asp.Net Core 寫入的系統日誌.

結構化日誌支持

下面的示例比較結構化日誌與普通日誌的差別.

範例使用 ILog 接口寫入日誌,你也可以使用 ILogger 替代.

先記錄普通日誌消息,方便後續比較.

_log.Message( "用戶admin已刪除" ).LogInformation();

結構化日誌語法

  • {}

    • {} 用來定義日誌屬性.

    • 範例:

      _log.Message( "用戶{User}已刪除", "admin" ).LogInformation();
      

      {User} 定義了名爲 User 的字符串屬性.

      查看 Seq 操作界面, 可以看到已經添加了 User 屬性.

      識別出了 User 屬性,就可以使用它進行搜索.

      點擊 User 屬性左側的勾,彈出菜單選擇 Find 進行查找.

      搜索框設置 User = 'admin' 表達式,表示搜索 User 屬性爲 admin 的日誌.

      Seq 不僅能使用 = 進行精確匹配,還支持類似Sql like 的模糊匹配方式.

      範例:

      User like '%dm%'
      

      注意: 不要將結構化日誌 {} 與 .Net 字符串語法 $"{}" 混淆.

      var user = "admin";
      _log.Message( $"用戶{user}已刪除" ).LogInformation();
      

      $"" 中的 {user} 將被 user 變量值 'admin' 替換, 等效於.

      _log.Message( "用戶admin已刪除" ).LogInformation();
      

      它僅是普通日誌消息,不是結構化日誌.

    • {@} 用來定義日誌屬性,並強制序列化對象.

      前面的示例使用簡單的字符串參數,如果傳入對象參數是什麼結果?

    • 範例:

      定義 User 對象.

      namespace Demo;
      
      public class User {
        public int Id { get; set; }
        public string Name { get; set; }
      }
      

      現在傳入 User 對象.

      var user = new User { Id = 1, Name = "a" };
      _log.Message( "用戶{User}已刪除", user ).LogInformation();
      

      {User} 被替換爲字符串 "Demo.User" ,這是通過調用 User 對象的 ToString() 方法得到的.

      這與我們的預期不符合,我們希望序列化 User 對象,從而獲取對象的結構進行搜索.

      Serilog 對 {} 參數的處理有一套內置規則,如果傳入對象,有些結構能序列化,比如字典 Dictionary<string,int> ,有些則不能.

      不應該依賴 Serilog 自動序列化的能力,而是應明確指定是否序列化.

      {@} 強制序列化對象,從而保留對象結構,以方便日誌系統展示和搜索.

      var user = new User { Id = 1, Name = "a" };
      _log.Message( "用戶{@User}已刪除", user ).LogInformation();
      

      可以進一步展開對象結構,點擊 {Id: 1, Name: 'a'} 左側的小燈泡,選擇 Expand all 展開.

      現在可以通過對象屬性進行搜索了.

    • {$} 用來定義日誌屬性,並強制字符串化.

      {$} 讓 Serilog 以明確的方式顯示對象的字符串表示.

      var user = new User { Id = 1, Name = "a" };
      _log.Message( "用戶{$User}已刪除", user ).LogInformation();
      

      {$User} 調用user對象的 ToString() 方法顯示爲字符串.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章