【Azure 應用服務】App Service .NET Core專案在Program.cs中自定義新增的logger.LogInformation,部署到App Service上後日志不顯示Log Stream中的問題

路邊兩盞燈發表於2021-08-24

問題描述

在.Net Core 5.0 專案中,新增 Microsoft.Extensions.Logging.AzureAppServices 和 Microsoft.Extensions.Logging.Abstractions外掛後,需要在構建Host的程式碼中新增  logging.AddAzureWebAppDiagnostics() 。

    return Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging =>
                {
                    //logging.AddConsole();
                    logging.AddAzureWebAppDiagnostics();
                })

然後 初始化Logger物件,新增 Console方式輸出日誌( var _logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<Program>();

 

全部程式碼為:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace hellodotnetcore
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }


        public static IHostBuilder CreateHostBuilder(string[] args)
        {
             var _logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<Program>();
            //初始化當前Host例項時候隨機生成一個GUID,用於在此後的請求中判斷當前時候是否被標記為健康,非健康,回收。
            var instance = Guid.NewGuid();
            //firstFailure來記錄第一個失敗請求所進入當前例項的時間,firstFailure儲存在記憶體中
            DateTime? firstFailure = null;
            //ILogger _logger = null;

            return Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging =>
                {
                    //logging.AddConsole();
                    logging.AddAzureWebAppDiagnostics();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                webBuilder.Configure(configureApp =>
                configureApp.Run(async context =>
                {
                    _logger.LogInformation("TEST THE SELF LOG INFORMATION...");

                    _logger.LogError("TEST THE SELF LOG ERROR...");

                    _logger.LogDebug("TEST THE SELF LOG Debug...");

                    _logger.LogTrace("TEST THE SELF LOG Trace...");

                    _logger.LogWarning("TEST THE SELF LOG Warning...");//當請求URL為fail時候,認為設定返回狀態為500,告訴App Service的Health Check功能,當前例項出現故障。
                    if (firstFailure == null && context.Request.Path.Value.ToLower().Contains("fail"))
                    {
                        firstFailure = DateTime.UtcNow;
                    }

                    if (context.Request.Path.Value.ToLower().Contains("exception"))
                    {
                        throw new Exception("this is custom exception for logging ...");

                    }

                    if (firstFailure != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "text/html; charset=utf-8";
                        await context.Response.WriteAsync(
                           $"當前例項的GUID為 {instance}.\n<br>" +
                            $"這個例項最早出現錯誤的時間是 {firstFailure.Value}. 當前時間為是{DateTime.UtcNow}\n\n<br><br>" +
                            $"根據文件的描述 https://docs.microsoft.com/en-us/azure/app-service/monitor-instances-health-check, 如果一個例項在一直保持unhealthy狀態一小時,它將會被一個新例項所取代\n\n<br>" +
                            $"According to https://docs.microsoft.com/en-us/azure/app-service/monitor-instances-health-check, If an instance remains unhealthy for one hour, it will be replaced with new instance.<br>");
                    }
                    else
                    {
                        context.Response.StatusCode = 200;
                        context.Response.ContentType = "text/html; charset=utf-8";
                        await context.Response.WriteAsync($"當前例項的GUID為 {instance}.\n<br>" +
                            $"此例項報告顯示一切工作正常.");
                    }
                })));
        }
    }
}

 

在本地通過dotnet run測試發現,訪問 http://localhost:5000/ 和 http://localhost:5000/exception 就可以看見在程式碼中的加入的日誌資訊,達到期望。

【Azure 應用服務】App Service .NET Core專案在Program.cs中自定義新增的logger.LogInformation,部署到App Service上後日志不顯示Log Stream中的問題

 

但是把程式碼釋出到Azure App Service後,通過Log Stream發現,卻沒有觀察到 _logger 日誌:

_logger.LogInformation("TEST THE SELF LOG INFORMATION...");

_logger.LogError("TEST THE SELF LOG ERROR...");

_logger.LogDebug("TEST THE SELF LOG Debug...");

_logger.LogTrace("TEST THE SELF LOG Trace...");

_logger.LogWarning("TEST THE SELF LOG Warning...");

App Service 中檢視Docker中執行應用的日誌:

【Azure 應用服務】App Service .NET Core專案在Program.cs中自定義新增的logger.LogInformation,部署到App Service上後日志不顯示Log Stream中的問題

 

 

問題解決

這是因為App Service沒有啟用App Service Logs. 當在門戶上啟用後,在此檢視Log Stream檔案資訊,就可以看見和本地同樣的日誌資訊:

【Azure 應用服務】App Service .NET Core專案在Program.cs中自定義新增的logger.LogInformation,部署到App Service上後日志不顯示Log Stream中的問題

 

 

 

 

參考資料

為 Azure 應用服務配置 ASP.NET 應用: https://docs.azure.cn/zh-cn/app-service/configure-language-dotnet-framework#access-diagnostic-logs


'ILoggerFactory' does not contain a definition for 'AddConsole': https://stackoverflow.com/questions/58259520/iloggerfactory-does-not-contain-a-definition-for-addconsole

There is a seperate issue at play, previously the signature for AddConsole() expected an ILoggerFactory, that has since changed to an ILoggerBuilder, as hinted at in the error message.

The following it seems is the new way to stand up a new Console logger:

var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());

 

相關文章