.NET 8 独立函数应用程序未在调用列表中显示未处理的异常消息

问题描述 投票:0回答:1

我们将 Azure 进程内函数迁移到 .NET 8 中的独立函数。 添加了以下nuget包

<PropertyGroup>
 <TargetFramework>net8.0</TargetFramework>
 <AzureFunctionsVersion>v4</AzureFunctionsVersion>
 <OutputType>Exe</OutputType>
 <ImplicitUsings>enable</ImplicitUsings>
 <Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>   
 <FrameworkReference Include="Microsoft.AspNetCore.App" />    
 <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
 <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
 <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
 <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.0" />
 <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.0.0" />
 <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
 <PackageReference Include="Microsoft.Identity.Client" Version="4.66.2" />
 <PackageReference Include="Insight.Database" Version="8.0.1" />
 <PackageReference Include="Xrm.Tools.CRMWebAPI" Version="1.0.25" />
</ItemGroup>

下面是我的HTTP触发函数,它调用一个名为“MethodThrowingException”的方法进行测试并抛出异常。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System.Net;

namespace CTSCRMIntegration
{
    public class FuncIntegrationDemo
    {
        private readonly ILogger<FuncIntegrationDemo> _logger;
        private readonly ICMHCCRM _crm;
        public FuncIntegrationDemo(ICMHCCRM crm, ILogger<FuncIntegrationDemo> logger)
        {
            _crm = crm;
            _logger = logger;
        }

        [Function("FuncIntegrationDemo")]
        public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
        {
            string logMessage = string.Empty;


            _logger.LogInformation("C# HTTP trigger function processed a request.");

            //Parse SourceViewName Parameter
            var SourceViewName = req.Query.GetValues("sourceViewName")?.FirstOrDefault();


            if (string.IsNullOrEmpty(SourceViewName))
            {
                logMessage = "Please pass a Source view name on the query string";
                _logger.LogInformation(logMessage);

                var reqResponse = req.CreateResponse(HttpStatusCode.BadRequest);
                await reqResponse.WriteStringAsync("Please pass a Source view name on the query string");

                return reqResponse;
            }

            //Check for record exists in CRM
            await _crm.MethodThrowingException(SourceViewName);

            var response = req.CreateResponse(HttpStatusCode.OK);
            await response.WriteStringAsync($"The record successfully synched with CRM !!!");
            return response;

        }
    }
}

调用以下方法抛出异常

public class CMHCCRM : ICMHCCRM
{
    private readonly CRMWebAPIFactory _webApiFactory;

    public async Task MethodThrowingException(string sourceViewName)
    {
        throw new NotImplementedException("The method is not implemented to check the invocation list for blank error message");
    }
}

我们在 Program.cs 文件中添加了配置设置,以启用函数应用程序的应用程序设置。我们删除了应用程序设置的默认行为。代码如下:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;


var host = new HostBuilder()
    .ConfigureFunctionsWebApplication().
    ConfigureAppConfiguration(app => {
        app.SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables();
    })
    .ConfigureServices((context, services) => {

        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
        services.Configure<LoggerFilterOptions>(options => {
            LoggerFilterRule defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName
                == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
            if (defaultRule is not null)
            {
                options.Rules.Remove(defaultRule);
            }           
        });

        services.AddScoped<ICMHCCRM, CMHCCRM>(x => new CMHCCRM());

    }).Build();

host.Run()

这是host.json文件

{
  "version": "2.0"  
}

我们在函数应用程序中使用 ILogger 来记录错误。我们没有使用 try-catch 块来处理异常。当发生任何未处理的异常时,调用列表不显示详细消息,仅显示空白消息

enter image description here

如果我在 Application Insight 中单击“运行查询”,查询结果将返回空白行。

enter image description here

但是如果我们在异常表上运行查询,异常消息会显示在outerMessage字段中

enter image description here

c# azure function azure-functions
1个回答
0
投票

更新 .NET 8 隔离 HTTP 触发器函数模型中的 Program 和 FuncIntegrationDemo 类后,我成功检索了 Azure Function 应用程序中“调用”下的异常日志。

程序.cs:

我将以下内容添加到

Program.cs
文件中,以使
GlobalExceptionMiddleware
能够全局捕获异常、记录它们并返回标准化响应。

        services.AddSingleton<TelemetryClient>();
        services.AddSingleton<IFunctionsWorkerMiddleware, GlobalExceptionMiddleware>();
        services.AddScoped<ICMHCCRM, CMHCCRM>();

以下是完整的

Program
课程。

using FunctionApp14.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.ApplicationInsights;
using Microsoft.Azure.Functions.Worker.Middleware;
using FunctionApp14.Middleware;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureAppConfiguration((context, config) =>
    {
        config.SetBasePath(Directory.GetCurrentDirectory())
              .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
              .AddEnvironmentVariables();
    })
    .ConfigureServices((context, services) =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.AddSingleton<TelemetryClient>();
        services.AddSingleton<IFunctionsWorkerMiddleware, GlobalExceptionMiddleware>();
        services.AddScoped<ICMHCCRM, CMHCCRM>();
    })
    .Build();
host.Run();

函数/FuncIntegrationDemo.cs:

我使用以下代码在

FuncIntegrationDemo
类中获取详细的异常信息。

                _logger.LogError(ex, "Unhandled exception in FuncIntegrationDemo");
                _logger.LogError($"Exception details: {ex}");

以下是完整的

FuncIntegrationDemo
课程。

using FunctionApp14.Models;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System.Net;

namespace FunctionApp14
{
    public class FuncIntegrationDemo
    {
        private readonly ILogger<FuncIntegrationDemo> _logger;
        private readonly ICMHCCRM _crm;

        public FuncIntegrationDemo(ICMHCCRM crm, ILogger<FuncIntegrationDemo> logger)
        {
            _crm = crm;
            _logger = logger;
        }

        [Function("FuncIntegrationDemo")]
        public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
        {
            string logMessage = string.Empty;

            _logger.LogInformation("C# HTTP trigger function processed a request.");
            var SourceViewName = req.Query.GetValues("sourceViewName")?.FirstOrDefault();
            if (string.IsNullOrEmpty(SourceViewName))
            {
                logMessage = "Please pass a Source view name on the query string";
                _logger.LogInformation(logMessage);

                var reqResponse = req.CreateResponse(HttpStatusCode.BadRequest);
                await reqResponse.WriteStringAsync("Please pass a Source view name on the query string");

                return reqResponse;
            }
            try
            {
                await _crm.MethodThrowingException(SourceViewName);
                var response = req.CreateResponse(HttpStatusCode.OK);
                await response.WriteStringAsync($"The record successfully synched with CRM !!!");
                return response;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Unhandled exception in FuncIntegrationDemo");
                _logger.LogError($"Exception details: {ex}");

                var errorResponse = req.CreateResponse(HttpStatusCode.InternalServerError);
                await errorResponse.WriteStringAsync("An unexpected error occurred. Please try again later.");
                return errorResponse;
            }
        }
    }
}

中间件/GlobalExceptionMiddleware.cs:

using Microsoft.ApplicationInsights;
using Microsoft.Azure.Functions.Worker.Middleware;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace FunctionApp14.Middleware;
public class GlobalExceptionMiddleware : IFunctionsWorkerMiddleware
{
    private readonly ILogger<GlobalExceptionMiddleware> _logger;
    private readonly TelemetryClient _telemetryClient;

    public GlobalExceptionMiddleware(ILogger<GlobalExceptionMiddleware> logger, TelemetryClient telemetryClient)
    {
        _logger = logger;
        _telemetryClient = telemetryClient;
    }

    public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unhandled exception occurred in function execution.");
            var telemetryProperties = new Dictionary<string, string>
            {
                { "FunctionName", context.FunctionDefinition.Name },
                { "InvocationId", context.InvocationId }
            };

            _telemetryClient.TrackException(ex, telemetryProperties);
            throw;
        }
    }
}

.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.0.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
    <PackageReference Include="Microsoft.Identity.Client" Version="4.66.2" />
    <PackageReference Include="Insight.Database" Version="8.0.1" />
    <PackageReference Include="Xrm.Tools.CRMWebAPI" Version="1.0.25" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext"/>
  </ItemGroup>
</Project>

Azure 函数应用程序调用:

我成功检索了 Azure 函数应用程序中“调用”下的异常日志。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.