.net 尝试记录指标Azure函数时出错

fnatzsnv  于 2022-12-20  发布在  .NET
关注(0)|答案(3)|浏览(110)

我的记录器有一个问题,每当我尝试记录指标时,就会发生错误。下面,我留下发生错误的代码部分。

private void LogBlobExecutionMetric(ILogger log,
                                        BlobMigrationStrategyIdentifier blobMigrationStrategyIdentifier,
                                        ControlMetadataEntity controlMetadataEntity,
                                        BlobMetadataEntity blobMetadataEntity,
                                        long elapsedMilliseconds,
                                        long? fileSizeInBytes)
    {
        // Create the properties for all metrics that will be logged.
        Dictionary<string, object> properties = new Dictionary<string, object>()
        {
            { "BlobMigrationStrategyIdentifier", blobMigrationStrategyIdentifier.ToString() },
            { "ExecutionId", controlMetadataEntity.RowKey },
            { "BlobMetadataId", blobMetadataEntity.RowKey },
            { "BlobState", blobMetadataEntity.State }
        };

        //The error occurs here 
        log.LogMetric("BlobExecutionElapsedMilliseconds", elapsedMilliseconds, properties);
    }

我尝试了几种方法,但都不起作用,唯一的解决方案是从log.LogMetric()切换到log.LogInformation(),但这样会丢失所有指标,而且跟踪应用程序的洞察力也会变得更加困难
我还留下了生成的堆栈跟踪,但即使是警告空参数,我也检查了,没有传递的参数为空或不正确。

Result: Failure
Exception: System.AggregateException: One or more errors occurred. (An error occurred while writing to logger(s). (Value cannot be null. (Parameter 'value')))
 ---> System.AggregateException: An error occurred while writing to logger(s). (Value cannot be null. (Parameter 'value'))
 ---> System.ArgumentNullException: Value cannot be null. (Parameter 'value')
   at Google.Protobuf.ProtoPreconditions.CheckNotNull[T](T value, String name)
   at Microsoft.Azure.Functions.Worker.Logging.GrpcFunctionsHostLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter) in D:\a\1\s\src\DotNetWorker.Grpc\GrpcFunctionsHostLogger.cs:line 44
   at Microsoft.Extensions.Logging.Logger.<Log>g__LoggerLog|12_0[TState](LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, Func`3 formatter, List`1& exceptions, TState& state)
   --- End of inner exception stack trace ---
   at Microsoft.Extensions.Logging.Logger.ThrowLoggingError(List`1 exceptions)
   at Microsoft.Extensions.Logging.Logger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
   at Microsoft.Extensions.Logging.LoggerExtensions.LogMetric(ILogger logger, String name, Double value, IDictionary`2 properties) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Loggers\Logger\LoggerExtensions.cs:line 33
   at ThomsonReuters.DocMi.BlobMigration.Execution.AzureFunctions.Functions.BlobMigration.RunBlobMigration.LogBlobExecutionMetric(ILogger log, BlobMigrationStrategyIdentifier blobMigrationStrategyIdentifier, ControlMetadataEntity controlMetadataEntity, BlobMetadataEntity blobMetadataEntity, Int64 elapsedMilliseconds, Nullable`1 fileSizeInBytes) in /home/runner/work/DocMi_Functions/DocMi_Functions/src/BlobMigration/ExecutionServices/ThomsonReuters.DocMi.BlobMigration.Execution.AzureFunctions/Functions/BlobMigration/RunBlobMigration.cs:line 195
   at ThomsonReuters.DocMi.BlobMigration.Execution.AzureFunctions.Functions.BlobMigration.RunBlobMigration.RunAsync(String messageBrokerMessageString, FunctionContext context) in /home/runner/work/DocMi_Functions/DocMi_Functions/src/BlobMigration/ExecutionServices/ThomsonReuters.DocMi.BlobMigration.Execution.AzureFunctions/Functions/BlobMigration/RunBlobMigration.cs:line 164
   at Microsoft.Azure.Functions.Worker.Invocation.VoidTaskMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments) in D:\a\1\s\src\DotNetWorker.Core\Invocation\VoidTaskMethodInvoker.cs:line 24
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   --- End of stack trace from previous location ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of stack trace from previous location ---
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.ExecuteAsync(FunctionContext context) in D:\a\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
   at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 16
   at Microsoft.Azure.Functions.Worker.GrpcWorker.InvocationRequestHandlerAsync(InvocationRequest request, IFunctionsApplication application, IInvocationFeaturesFactory invocationFeaturesFactory, ObjectSerializer serializer, IOutputBindingsInfoProvider outputBindingsInfoProvider) in D:\a\1\s\src\DotNetWorker.Grpc\GrpcWorker.cs:line 167
Stack:   
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   --- End of stack trace from previous location ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of stack trace from previous location ---
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.ExecuteAsync(FunctionContext context) in D:\a\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
   at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 16
   at Microsoft.Azure.Functions.Worker.GrpcWorker.InvocationRequestHandlerAsync(InvocationRequest request, IFunctionsApplication application, IInvocationFeaturesFactory invocationFeaturesFactory, ObjectSerializer serializer, IOutputBindingsInfoProvider outputBindingsInfoProvider) in D:\a\1\s\src\DotNetWorker.Grpc\GrpcWorker.cs:line 167

感谢每一个能为这个错误提出解决方案或替代方案的人,非常感谢。

vm0i2vca

vm0i2vca1#

要处理此错误,我们需要检查记录器是否使用任何其他记录器函数(如ConsoleLogger)进行了初始化
还要检查saftimufti的SO答案。如果日志度量是自定义的,则检查自定义度量。
跟踪指标的示例代码:

TelemetryConfiguration.Active.InstrumentationKey = "your key";
TelemetryClient client = new TelemetryClient(); 
client.TrackMetric("my metric", 60);
client.GetMetric("my metric").TrackValue(89);
client.Flush();
rjzwgtxy

rjzwgtxy2#

我遇到了完全相同的问题。当ILogger被注入到函数中时,它在v3 Azure函数中工作正常。但是,在更新到.NET 6并在进程外运行函数后,它不再工作。文档说我们必须注入FunctionContext context,并在函数内执行context.GetLogger<MyType>();。返回的日志记录器似乎应该完全初始化,但是这样我得到了和OP相同的异常。简单地将ILogger注入类构造函数会导致相同的异常。将ILogger直接注入函数Run方法不会导致异常,但是指标不会被记录,只是被忽略。
我通过重写使其工作,以便更直接地使用ApplicationInsights日志记录,这与第一个答案大致相同,但这里有一个更详细的示例:
首先确保Program.cs文件包含以下内容:

static async Task Main(string[] args)
{
    var host = new HostBuilder()
        .ConfigureServices(s =>
        {
            s.AddLogging();
            s.AddApplicationInsightsTelemetryWorkerService();
        }
}

假设您正在使用DI,请确保按如下所示创建遥测客户端:

private readonly TelemetryClient _telemetryClient;

public MyClass(TelemetryConfiguration telemetryConfiguration)
{
    _telemetryClient = new TelemetryClient(telemetryConfiguration);
}

然后,在您的函数中,您可以记录自定义指标,如下所示:

var myMetric = new MetricTelemetry
{
    Name = "MyMetricName",
    Sum = 123
};
myMetric.Properties.Add("MyCustomProperty1", "My custom property value 1.");
myMetric.Properties.Add("MyCustomProperty2", "My custom property value 2.");

_telemetryClient.TrackMetric(myMetric);
vshtjzan

vshtjzan3#

你是如何初始化你的日志记录器?我有一个类似的问题,当我初始化日志记录器如下:

class MyClass {
    private readonly ILogger _logger;
    
    public MyClass(ILogger logger) {
        _logger = logger;
    }
}

我可以通过在构造函数的变量定义中传递一个类型MyClass给ILogger来解决这个问题。

class MyClass {
    private readonly ILogger _logger;
    
    public MyClass(ILogger<MyClass> logger) {
        _logger = logger;
    }
}

相关问题