只有累積,沒有奇蹟

顯示具有 Logging 標籤的文章。 顯示所有文章
顯示具有 Logging 標籤的文章。 顯示所有文章

2019年6月13日 星期四

[Tool] Log Parser Studio - 搜尋 Log 好幫手

前言
這幾天專案遇到些小亂流,必須找到特定條件的應用程式 Log 做資料的確認及重送機制,雖然系統有使用 ELK但由於專案太舊導致 Log 沒紀錄在 ELK 上面,為了快速找到多台應用程式中的 Log 資訊,在搜尋過程中爬 Log 使用 Log Parser 工具來快速搜尋 Log 資訊,避免過度花費人工的方式逐一進行搜尋 Log,這篇文章就針對 Log Paresr Studio 工具做簡單的介紹與說明,若有問題歡迎提出一起討論或是給予指導。

安裝
Log Parser 是一套強大的文字搜尋工具,可以針對單一或是多個 Log 檔案進行搜尋,支援多種 常見的Log 類型,最新版為 Log Parser 2.2 可以在微軟官網下載 : 傳送門 ,安裝後開啟應用程式如下
可以輸入 command line 指定關鍵字與資料夾進行搜尋,舉例來說我想要在 C:\ Filemon 檔案搜尋 Access Denied 關鍵字,可以輸入下面指令取得
LOGPARSER "Select Text from C:\Filemon.log where Text like '%Access Denied%'" -i:TEXTLINE -q:Off
輸入後按下執行會跳出下列
// 搜尋的結果

Statistics
Elements processed: 640444
Elements output:    1
Execution time:     12.75 seconds 
如果對於使用指令搜尋有興趣,可以嘗試看看常用搜尋指令 : Log Parser Rocks! More than 50 Examples!

Log Parser Studio
我自己在使用上都是用 Log Parser Studio 工具,對於在使用上懶人會較為方便一些,Log Parser Studio 下載位置 : 傳送門,下載完畢開啟應用程式如下
首頁會顯示常用的查詢 Lib 語法,可以提供使用者快速進行搜尋的動作,如果要自訂搜尋的話可以透過下列方式

設定 Log
在一開始使用前需要設定要搜尋的 Log 位置,設定步驟如下
步驟如下

  • Step 1 : 新增 Query 
  • Step 2 : 開啟要查詢的 Log 檔案或是資料夾位置
  • Step 3 : 新增檔案
  • Step 4 : 設定完成

  • 查詢
    設定要搜尋的 Log 來源後 (單一檔案或是多個檔案) , 接著就是要使用最重要的搜尋功能,在 Log Parser Studio 工具下方可以輸入搜尋語法,主要搜尋欄位為 Text,以下例子為找 Log 中含有關鍵字 'Service -Start' 字眼的 Log 內容
    步驟如下

  • Step 1 : 選擇要查詢的 Log Type 
  • Step 2 : 在下方搜尋區塊輸入要找的關鍵字內容
  • Step 3 : 按下搜尋,查詢結果區塊就會顯示符合的內容

  • 匯出
    在 Log Parser Studio 中提供將查詢的結果匯出的功能,點擊左上角 File > export,選擇要輸出的檔案類型
    以上透過簡單的情境介紹了 Log Parser Studio 的基本使用方式,如果想要了解更多內容的話,可以透過作者的詳細介紹文章跟進階情境使用方式,來讓自己更熟悉這套強大的軟體

  • Getting started with Log Parser Studio
  • Getting started with Log Parser Studio, part 2
  • Getting started with Log Parser Studio, part 3
  • 希望可以透過以上簡單說明,讓你有知道有這麼好用的工具可以使用,也可以省下人工爬 Log 的困擾,如果下次有搜尋 Log 的需求時,不妨也可以考慮看看用 Log Parser Studio :)

    2019年5月13日 星期一

    [NETCore] 在 ASP.NET Core Web API 中使用 Serilog

    前言
    近期專案都在嘗試 Serilog,對於使用上有點小小心得,因此整理這篇文章分享 Serilog 在 ASP.NET Core API 上的使用與設定,也接續之前 Serilog 的系列介紹文 : 傳送門 的實際應用心得,希望可以幫到有需要的朋友若有問題或是錯誤的地方歡迎提出來一起討論或是給予指導

    ASP.NET Core logging
    首先先建立新的 ASP.NET Core Web Application 專案,開啟 Visual Studio 2019 選擇建立新專案,專案名稱輸入 SerilogWebAppLab,模板部分選擇 API,然後按下確定送出
    新增完專案之後,可以看到專案中 program.cs 內建 CreateWebHostBuilder 方法,此方法會在 Application 啟動時,使用預設方法也會一併註冊內建 logging,接著我們來看一下內建 logging 輸出樣式,在 ValueController 中建構式加入 _Logger 並在 GET 方法中使用 log.Information、Warning 以及 Error
    public class ValuesController : ControllerBase
    {
        private readonly ILogger _logger;
    
        public ValuesController(ILogger<ValuesController> logger)
        {
            _logger = logger;
        }
    
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            _logger.LogInformation("This is LogInformation");
            _logger.LogWarning("This is LogWarning");
            _logger.LogError("This is LogError");
    
            return new[] { "value1", "value2" };
        }
    ...
    執行專案按下 F5,輸出內容如下
    從預設 logging 內容可以發現紀錄了除了自己紀錄的 log 之外資料,紀錄了 Application 以及 Request 的內容還有執行的時間,CreateWebHostBuilder 方法預設的情況下使用的 Config 為專案檔底下的 appsettings.json 及 appsettings.Development.json (依設定環境決定),之前有撰寫過一篇關於設定環境變數的文章,有興趣可以參考 : 傳送門。在此如果希望不啟用內建的 logging 紀錄資訊,可以在 CreateWebHostBuilder 方法中加上  config.ClearProviders()  刪除預設的 logging 提供者
    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, config) =>
            {
                config.ClearProviders();
            })
            .UseStartup<Startup>();
    在重新執行一次 Application,就會看到 Console output 僅剩三個 log。

    Serilog
    接著輪到今天的重頭戲 Serilog 登場,首先先透過 Nuget 下載 Serilog for .NET Core 套件
    Install-Package Serilog.AspNetCore
    Serilog 核心負責紀錄 Log 事件的內容,要將 Log 輸出則是透過 Sink,如果想瞭解更多細節可以參考 結構化日誌 Serilog 初體驗,這裡就不在多加介紹,這裡範例是使用 Console 與寫入實體檔案作為輸出,因此需要另外透過 Nuget 下載相關套件 Sinks.Console 與 Sinks.File 兩種,如果有其他需
    Install-Package Serilog.Sinks.Console 
    Install-Package Serilog.Sinks.File
    
    下載完 Serilog 相關 Package,接著就是在 WebHost 啟動時設定 Serilog 資訊也就是 Program.cs 中的 main 方法加下以下代碼
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Information()
                .WriteTo.Console()
                .WriteTo.File("logs/log_.txt", rollingInterval: RollingInterval.Day)
                .CreateLogger();
    
            CreateWebHostBuilder(args).Build().Run();
        }
    
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureLogging((hostingContext, config) =>
                {
                    config.ClearProviders();
                })
                .UseStartup<Startup>();
    }
    程式說明

  • MinimumLevel.Information : 定義 Log 輸出 Level 
  • WriteTo.Console : 設定使用 Console 輸出 
  • WriteTo.File : 設定使用 File 檔案輸出,輸出位置及檔名為 log & log_txt 
  • 上述是在 Program.cs 中加上 Serilog 設定組態設定,在 Serilog 中也支援使用 Config 檔案來設定的動作,如果想要透過定義檔則需要至 Nuget 下載 Settings library
    Install-Package Serilog.Settings.Configuration
    在 appSettings.json 加以下 config 定義內容,設定目的與內容與剛剛在 Program 寫 Log 方式相同
    {
      "Serilog": {
        "MinimumLevel": "Information",
        "WriteTo": [
          {
            "Name": "Console",
            "Args": {
              "outputTemplate": "{Timestamp:yyyy/MM/dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
            }
          },
          {
            "Name": "File",
            "Args": {
              "Path": "logs/log_.txt",
              "rollingInterval": "Day"
            }
          }
        ]
      }
    }
    在來修改 Program.cs 中的代碼,要調整新增 Configuration 時以檔案的內容為主
    public class Program
    {
        private static string _envName;
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{_envName}.json", optional: true, reloadOnChange: true)
                .Build();
    
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateLogger();
    
            CreateWebHostBuilder(args).Build().Run();
        }
    
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureLogging((hostingContext, config) =>
                {
                    config.ClearProviders();
                    _envName = hostingContext.HostingEnvironment.EnvironmentName;
                })
                .UseStartup<Startup>();
    }
    configuration 部分代碼為定義設定檔的來源,也就是使用建立專案時內建的 appsettings.json,指定 Config 會隨不同環境取得不同的 appsettings.json,其中 CreateLogger 時用  ReadFrom.Configuation()  指定用 檔案內容指定取代原先落落長的代碼。
    下一步就需要在 Startup.cs 中的  ConfigureService()  新增 Serilog 至服務中,這裡使用的是內建的 DI Framework,如果用習慣 Autofac 的朋友也可以下載 autofac-serilog-integration
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        services.AddLogging(loggingBuilder =>
            loggingBuilder.AddSerilog()
        );
    }
    以上設定 Serilgo 完畢,接著重新執行 Application 並觀察其輸出內容,可以看到 logging 紀錄內容已透過 Console 與檔案輸出如下
    也成功寫入檔案,預設會在指定檔名 File 後加上 日期,log_ 變成 log_20190101.txt 
    2019-05-13 13:00:06.279 +08:00 [INF] User profile is available. Using 'C:\Users\marcustung\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
    2019-05-13 13:00:08.112 +08:00 [INF] Request starting HTTP/1.1 GET https://localhost:5001/api/values  
    2019-05-13 13:00:08.178 +08:00 [INF] Executing endpoint 'SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)'
    2019-05-13 13:00:08.202 +08:00 [INF] Route matched with {action = "Get", controller = "Values"}. Executing action SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)
    2019-05-13 13:00:08.216 +08:00 [INF] Executing action method SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) - Validation state: "Valid"
    2019-05-13 13:00:08.221 +08:00 [INF] This is LogInformation
    2019-05-13 13:00:08.222 +08:00 [WRN] This is LogWarning
    2019-05-13 13:00:08.224 +08:00 [ERR] This is LogError
    2019-05-13 13:00:08.230 +08:00 [INF] Executed action method SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 5.7992ms.
    2019-05-13 13:00:08.240 +08:00 [INF] Executing ObjectResult, writing value of type 'System.String[]'.
    2019-05-13 13:00:08.340 +08:00 [INF] Executed action SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) in 131.7199ms
    2019-05-13 13:00:08.344 +08:00 [INF] Executed endpoint 'SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)'
    2019-05-13 13:00:08.351 +08:00 [INF] Request finished in 245.3211ms 200 application/json; charset=utf-8
    成功紀錄 Log 在 Console 與 File 檔案,如果想要的輸出不只是檔案在 Serilog 提供多種 Provider,詳細可以參考官方網站所列的 Provided Sinks : 傳送門

    感想
    透過以上的說明,希望可以讓對 Serilog 有興趣的的朋友可以快速入門,之前也花了點時間介紹 Serilog 相關的入門 & 基本設定方式,若有興趣想了解細節的也可以了解看看,系列文連結 : 傳送門 :)

    參考
    Structured logging concepts in .NET Series
    Serilog series post
    Loggly in ASP.NET Core using Serilog

    2019年3月8日 星期五

    [.NETCore] ASP.NET Core - Logging 日誌初體驗 (二)

    前言
    在上一篇文章介紹了在 ASP.Net Core 如何使用內建的 logging,以及 ILogger 與 ILoggerFactory 還有篩選記錄的方法,這篇再繼續介紹在 logging 中一些基本觀念與應用,如果有寫不清楚的地方可以搭配 MSDN 官網的 ASP.NET Core logging 一起服用,若有問題歡迎提出一起討論或是給予指導

    LogLevel
    紀錄 log 時候都會指定紀錄的等級  LogLevel 在 ASP.NET Core 提供六個等級,每個等級都具有代表其意義,舉例來說在開發 API 接口時會使用 info 紀錄 Request 的參數資訊,找不到 id 資料時可能會用  warning 方法,當執行異常時會用 Error 記錄其 exception 內容;LogLevel 列舉如下
    public enum LogLevel
    {
        Trace = 0,
        Debug = 1,
        Information = 2,
        Warning = 3,
        Error = 4,
        Critical = 5, 
        None = 6
    }
    列舉值代表等級高越需要記錄 (除了 None ),MSDN 也有列出相關說明這裡就不在多介紹
    舉個實際簡單的範例 API 應用,在下面範例中會建立 Information、Warning 與 Error紀錄
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        _logger.LogInformation("輸入的參數 id : {id}", id);
        if (id == 0)
        {
            _logger.LogWarning("參數 id 為 0, 方法不支援也找不到資料唷");
        }
    
        try
        {
            // to do something
        }
        catch (Exception e)
        {
            _logger.LogError("發生異常 !");
        }
    }

    Configuration
    介紹完 LogLevel 之後接著提到 logging 的設定,還記得在介紹要使用 Logging 時會在 configureServices 加上下列代碼  
    builder.AddConfiguration(Configuration.GetSection("Logging"))
    這裡的  "Logging"  讀取的設定檔內容來源之一是 appsettings.Development.json 設定的內容,檔案位置可以在 ASP.NET Core 專案檔根目錄找到,開啟檔案內容如下
    {
      "Logging": {
        "LogLevel": {
          "Default": "Debug",
          "System": "Information",
          "Microsoft": "Information"
        }
      }
    }
    可以發現 Logging 底下有 Default、System、Microsoft 三個屬性,分別可以設定其對應的 LogLevel 紀錄層級,在上面介紹 LogLevel 時有提到每個層級都有對應自己的層級值,此設定值也會影響到寫到 output 視窗或是搭配 log 套件的紀錄數量,這句話有點抽象舉例會比較好懂。舉例來說當今天設定檔 LogLevel 設定 Information 時,會排除 Information 層級以下的紀錄層級比 information 低的 log 就不會出現,換句話說也就是不會輸出 Debug 和 trace 的 log 紀錄。
    知道輸出層級會有影響我們可以直接改 LogLevel 設定看看兩者差異,或許會對上述說明更容易了解些。為了避免過多資訊影響到判斷,因此測試前先在 ConfigureServices 加上過濾掉 Microsoft Log 相關紀錄,讓輸出資料單純些
    .AddFilter("Microsoft", LogLevel.Warning);
    接著在到 ValueController 的建構子加上 debug 紀錄
    public ValuesController(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("MyDemoProject");
        _logger.LogDebug("ValuesController logger done");
    } 
    在 appsettings.json 預設 Default  LogLevel 是 debug 當測試時會輸出下列資料
    NETCoreLogging> Now listening on: http://127.0.0.1:19603
    NETCoreLogging> Application started. Press Ctrl+C to shut down.
    NETCoreLogging> dbug: MyDemoProject[0]
    NETCoreLogging>       ValuesController logger done
    NETCoreLogging> dbug: MyDemoProject[0]
    NETCoreLogging>       ValuesController logger done
    NETCoreLogging> info: MyDemoProject[0]
    NETCoreLogging>       輸入參數 id : 7777
    NETCoreLogging> dbug: MyDemoProject[0]
    NETCoreLogging>       To do something start 
    可以看到輸出 LogLevel 包含了 dbug 和 info 紀錄資訊,接著我們調整 appsettings.Development.json 中的 Default LogLevel為 information,在重新看輸出
    NETCoreLogging> Now listening on: http://127.0.0.1:23663
    NETCoreLogging> Application started. Press Ctrl+C to shut down.
    NETCoreLogging> info: MyDemoProject[0]
    NETCoreLogging>       輸入參數 id : 7777 
    從輸出 Log 可以發現 debug 的紀錄都消失了,驗證上述所說的,調整 LogLevel 為 information 之後會排除層級以下的紀錄並不會輸出。可以透過 json 設定在開發環境輸出較多 Log 資料方便 debug 使用;在正式環境時輸出必要的 Log 層級資訊。

    載入 config
    如果想確認專案啟動時 config 正常載入,可以再 Configuration.GetSection("Logging") 加上中斷點確認

    EventID
    在每次紀錄 log 時候可以記錄指定的   EventID ,可以從 ILogger 所提供的 API 看到 log.LoginInfomatrion 提供多載的方法可以傳入指定的 EventID 值,在輸出時會將 EventID 值帶到輸出的 ClassName 用括弧 [] 顯示事件代碼,以下範例是自訂 APILoggingEventID 與使用方式
    public class APILoggingEventID
    {
        public const int GenerateItems = 1000;
        public const int ListItems = 1001;
        public const int GetItem = 1002;
        public const int InsertItem = 1003;
        public const int UpdateItem = 1004;
        public const int DeleteItem = 1005;
    
        public const int GetItemNotFound = 4000;
        public const int UpdateItemNotFound = 4001;
    
        public const int GetDataFromThirdParty = 8001;
    }
    
    
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        _logger.LogInformation(APILoggingEventID.GetItem, "輸入的參數 id : {id}", id);
    
        try
        {
            // to do something
            _logger.LogDebug(APILoggingEventID.GetDataFromThirdParty, "Json Text balala");
        }
        catch (Exception ex)
        {
            _logger.LogError(APILoggingEventID.GetItemNotFound, ex, "發生異常 ! GetById({ID}) NOT FOUND", id);
        }
    
        return "value";
    }
    測試完畢之後輸出結果如下,紀錄的都會加上 EventID 結果為  MyDemoProject[1000] 
    NETCoreLogging> dbug: MyDemoProject[4000]
    NETCoreLogging>       ValuesController logger done
    NETCoreLogging> info: MyDemoProject[1002]
    NETCoreLogging>       輸入參數 id : 7777
    NETCoreLogging> dbug: MyDemoProject[8001]
    NETCoreLogging>       Json Text balala

    後記
    分享了兩篇在介紹 .NET Core logging 機制與寫一些簡單的 Sample Code 說明使用方式,自己心得對於 logging 更加了解,提供統一撰寫日誌的機制且可以搭配第三方元件輸出使用上覺得蠻容易上手的,不用在 代碼中寫很多 log.info 之類的代碼,也可以讓代碼看起來更加乾淨與增加易讀性,這些都算是基礎且簡單的應用,之後若有遇到不錯的使用方式會在分享出來,也希望有錯誤或是更好的寫法歡迎給予指教,Happy Coding !!!

    參考
    ASP.NET Core 中的記錄
    ASP.NET Core 源码学习之 Logging[1]:Introduction
    .NET Core下的日志(1):记录日志信息
    ASP.NET Core 所使用的 Logging


    Copyright © m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com