【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题

简介: 【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题

问题描述

在.Net Core 5.0 项目中,添加 Microsoft.Extensions.Logging.AzureAppServicesMicrosoft.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后,通过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中运行应用的日志:

 

 

问题解决

这是因为App Service没有启用App Service Logs. 当在门户上启用后,在此查看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());

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
5月前
|
Java 应用服务中间件 API
【App Service】部署War包到Azure云上遇404错误
Java应用部署至Azure App Service for Windows后报404,本地运行正常。经排查,日志提示类文件版本不兼容:应用由Java 17(class file version 61.0)编译,但环境仅支持到Java 11(55.0)。错误根源为Java版本不匹配。调整App Service的Java版本至17后问题解决,成功访问接口。
405 2
|
10月前
|
人工智能 文件存储 数据中心
Ollama部署本地大模型并通过Infortress APP远程访问保姆级教程
本文介绍如何快速上手本地大模型部署工具Ollama及AI远程访问工具Infortress。通过Ollama,开发者可轻松部署如Llama、Deepseek等主流开源模型,仅需几行命令即可完成安装与运行。结合Infortress,用户能实现对本地大模型的远程访问,支持多设备无缝对接,同时提供便捷的模型切换与知识库管理功能。Infortress更兼具NAS软件特性,成为个人AI数据中心的理想选择。
|
9月前
|
域名解析 监控 NoSQL
即时通讯APP应用开发的部署策略
随着移动互联网发展,即时通讯APP成为生活和工作的必备工具。本文探讨其开发部署的关键环节,包括用户界面设计、通讯协议选择、数据库设计与服务器搭建等方面,以及部署过程中的环境准备、应用打包、服务器部署、域名解析和监控维护等步骤。通过优化每个环节,确保APP稳定高效运行,提升用户体验,在市场中保持竞争力。
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
4529 31
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
497 9
|
10月前
|
监控 容灾 算法
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
1024 54
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
1503 3
|
存储 SQL 关系型数据库
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log、原理、写入过程;binlog与redolog区别、update语句的执行流程、两阶段提交、主从复制、三种日志的使用场景;查询日志、慢查询日志、错误日志等其他几类日志
1030 35
MySQL日志详解——日志分类、二进制日志bin log、回滚日志undo log、重做日志redo log
|
存储 缓存 关系型数据库
图解MySQL【日志】——Redo Log
Redo Log(重做日志)是数据库中用于记录数据页修改的物理日志,确保事务的持久性和一致性。其主要作用包括崩溃恢复、提高性能和保证事务一致性。Redo Log 通过先写日志的方式,在内存中缓存修改操作,并在适当时候刷入磁盘,减少随机写入带来的性能损耗。WAL(Write-Ahead Logging)技术的核心思想是先将修改操作记录到日志文件中,再择机写入磁盘,从而实现高效且安全的数据持久化。Redo Log 的持久化过程涉及 Redo Log Buffer 和不同刷盘时机的控制参数(如 `innodb_flush_log_at_trx_commit`),以平衡性能与数据安全性。
756 5
图解MySQL【日志】——Redo Log