Application Insights 整合NLog

前言
   這兩天將寫好的LineBot程式部署到Azure上測試,過程中發生錯誤及功能無法成功執行時候,要檢查是什麼原因? 頓覺寸步難行,沒有記錄可以查詢......也不知該如何查XD。花了些功夫,將這塊補上。

Application Insight - 啟用
  • App Service --> Application Insights 啟用。


  • 啟用後,此時程式不用任何修改,只要有Request就可以在Azure上的Application Insights Transaction search查詢基本的資訊。

Application Insight - 程式修改
  • nuget參考  : Microsoft.ApplicationInsights.AspNetCore
  • Program.cs 
builder.Services.AddApplicationInsightsTelemetry();
  • appsettings.json 加入連線字串 (在Applicaiton Insights 頁面取得)


    "ApplicationInsights": {
        "ConnectionString": "Your Connection String"
    }
  • 此時你在本機測試(任何Request),可以在Azure上的Application Insights Transaction search查詢
  • 或在Visual Studio查詢

Application Insight-搭配NLog
  • 加入nuget參考
    • NLog.Web.AspNetCore
    • Microsoft.ApplicationInsights.NLogTarget
  • 新增NLog.config 設定如下,<instrumentationKey> 須換成你的 ,instrumentationKey在跟你取得ConnectionStrings同一位置。
    • 設定內容:寫入檔案及Application Insights,並忽略開發時期的一堆底層資訊。
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="false"
      xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <extensions>
    <add assembly="Microsoft.ApplicationInsights.NLogTarget" />
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <variable name="layoutDefine"
    value="${longdate} [${event-properties:item=EventId_Id:whenEmpty=0}][${level:padding=-5}] ${message} ${exception:format=tostring} (${callsite:includeNamespace=false:fileName=true:includeSourcePath=false})" />
  <targets>
    <!---預設所有資訊先寫到Trace-->
    <target xsi:type="Trace" name="TraceOutput" rawWrite="true" layout="${layoutDefine}" />
    <!---寫到Console-->
    <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
    <!--寫入檔案-->
    <target name="NLogFile" xsi:type="File"
    layout="${longdate}-[${level}]-${logger}:${message} ${exception:format=tostring}"
    fileName="${aspnet-appbasepath}\wwwroot\Logs\current_.log"
    archiveFileName="${aspnet-appbasepath}\wwwroot\Logs\{#}_.log"
    maxArchiveFiles="10" encoding="utf-8" archiveDateFormat="yyyyMMdd" archiveNumbering="Date" archiveEvery="Day"
        />
    <!--寫入Application Insights-->
 
    <target type="ApplicationInsightsTarget" name="aiTarget" >
      <instrumentationKey>換成你的</instrumentationKey>
    </target>
  </targets>
  <rules>
    <!---預設所有資訊先寫到Trace-->
    <logger name="*" writeTo="TraceOutput" />
    <!--Host資訊寫到Console -->
    <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole" final="true" />
    <!--略過微軟及Http相關資訊,避免寫入下方的NLogFile -->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <logger name="System.Net.Http.*" maxlevel="Info" final="true" />
    <logger name="*" minlevel="Info" writeTo="aiTarget" />
    <logger name="*" minlevel="Info" writeTo="NLogFile" />
  </rules>
</nlog>

  • 使用LogFilter針對Web API每個Action作記錄
public class LogFilter : IActionFilter
{
    private ILogger<LogFilter> _log;
    public LogFilter(ILogger<LogFilter> log)
    {
        _log = log;
    }
  public void OnActionExecuting(ActionExecutingContext context)
    {
        try
        {
            string json = JsonSerializer.Serialize(context.ActionArguments);
            _log.LogInformation($"{context.ActionDescriptor.DisplayName},{json}");
        }
        catch (Exception ex)
        {
            _log.LogDebug($"{context.ActionDescriptor.DisplayName},{ex}");
        }
    }
    public void OnActionExecuted(ActionExecutedContext context)
    {
    }
}
  • Program.cs 引用
builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<LogFilter>();
})
  • Application Insights Transaction search查詢時,會出現在Type 為Trace,如下寫入查詢,測試的幾筆資料在Trace,Level=Information,如下圖紅框,使用Logger記錄的Action Name及參數內容。

記錄若是LogError(例外),則Type=Exception


查詢的Request,若有再呼叫其他Request,本例在收到Request後,再呼叫Line API


  • 使用Logs 作進階查詢,類似SQL語法



其它參考

這個網誌中的熱門文章

IIS 設定只允許特定IP進入

[Sql Server] 資料庫備份筆記