在外部库中使用TraceWriter记录Azure函数

本文关键字:TraceWriter 记录 Azure 函数 外部 | 更新日期: 2023-09-27 18:15:57

如何重用Azure函数中可用的TraceWriter对象来记录外部引用库中的信息?我尝试使用构造函数传递对象并引用TraceWriter类(web.http.tracing)。我运气不好,因为课程似乎不同。

在外部库中使用TraceWriter记录Azure函数

简体版使用此工具包中提供的Microsoft.Azure.WebJobs.Host.TraceWriter。

或者,将函数构建为Web项目,然后可以在本地进行调试。你可以在这里找到一个示例。

长版

您的问题是您使用了错误的TraceWriter。

我在Azure函数中使用了Azure函数记录器来输出记录器的类型。

log.Info(log.GetType().ToString());

结果如下:

Microsoft.Azure.WebJobs.Script.InterceptingTraceWriter

我也期待一个Web/Http TraceWriter,并惊讶地发现还有另一个实现要处理。微软真的可以创建一个标准的方法,或者至少给我们一个漂亮的干净的界面,错误,警告,信息,详细等。也许是。net标准…请。

我将创建我自己的接口,并包装我的应用程序记录器和Azure的一个,这样我就可以注入任何我需要的,而不会在我的代码中造成头痛。这也将提供一些保护,避免未来破坏性变化带来的潜在痛苦。

无论如何,我离题了,然后我跟踪Microsoft.Azure.WebJobs.Script.InterceptingTraceWriter到Azure函数/Webjobs脚本GitHub的repo,然后到Nuget包。我已经测试了这一点,它可以很好地将Azure函数日志记录器传递到您的外部程序集,并继续从那里记录到Azure函数环境。

下面是一个例子:

using Microsoft.Azure.WebJobs.Host;
public static void TryLog(TraceWriter azureFunctionsLogger)
{
    azureFunctionsLogger.Info("************** IT WORKED **************");
}

我喜欢Azure功能的潜力,但它仍然有点不成熟和过于复杂。

我希望这对你有帮助。

添加了一个非常简单的单类记录器来说明。

它写入Azure Functions Logger或标准的Systems.Diagnostics.Trace。您需要将其粘贴到标准c#控制台应用程序的Program.cs的内容上。您还需要包含Nuget包Microsoft.Azure.WebJobs。

namespace LoggingTestConsole
{
    using System;
    /// <summary>
    /// Generic logging interface for portability 
    /// </summary>
    public interface ILogger
    {
        void Error(string message);
        void Information(string message);
        void Warning(string message);
    }

    /// <summary>
    /// Azure Functions logger
    /// </summary>
    public class AzureFunctionLogger : ILogger
    {
        private static Microsoft.Azure.WebJobs.Host.TraceWriter _logger;
        public AzureFunctionLogger(Microsoft.Azure.WebJobs.Host.TraceWriter logger)
        {
            _logger = logger;
        }
        public void Error(string message)
        {
            _logger.Error(message);
        }
        public void Information(string message)
        {
            _logger.Info(message);
        }
        public void Warning(string message)
        {
            _logger.Warning(message);
        }
    }

    /// <summary>
    /// Windows Trace logger
    /// </summary>
    public class TraceLogger : ILogger
    {
        public TraceLogger()
        {
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
        }
        public void Error(string message)
        {
            System.Diagnostics.Trace.TraceError(message);
        }

        public void Information(string message)
        {
            System.Diagnostics.Trace.TraceInformation(message);
        }
        public void Warning(string message)
        {
            System.Diagnostics.Trace.TraceWarning(message);
        }
        public void Warning(string format, params object[] args)
        {
            System.Diagnostics.Trace.TraceWarning(format, args);
        }
    }
    /// <summary>
    /// You would put this in a separate project and just share the ILogger interface.
    /// Pass the relevant logger in from Azure Functions or a standard windows Trace logger.
    /// </summary>
    public class DoStuff
    {
        public DoStuff(ILogger logger)
        {
            logger.Information("We are logging to logger you passed in!");
        }
    }
    public class Program
    {
        /// <summary>
        /// Sample usage
        /// </summary>
        static void Main(string[] args)
        {
            // var loggerEnvironment = "AzureFunctions";
            var loggerEnvironment = "ConsoleApp";
            ILogger logger = null;
            if (loggerEnvironment == "AzureFunctions")
            {
                Microsoft.Azure.WebJobs.Host.TraceWriter azureFunctionLogger = null;
                logger = new AzureFunctionLogger(azureFunctionLogger);
            }
            else if (loggerEnvironment == "ConsoleApp")
            {
                logger = new TraceLogger();
            }
            var doStuff = new DoStuff(logger);
            Console.ReadKey();
        }
    }
}

作为更新,Azure Functions现在支持使用ILogger而不是TraceWriter,因此您可以使用任何实现ILogger的日志记录框架。

查看GitHub问题和随后的wiki文档

如果我是正确的,让ILogger与Azure功能工作的必要版本将是Microsoft.Azure.WebJobs 2.1.0-beta1。但是,我似乎无法使用ILogger而不是TraceWriter来运行Azure函数。

关于使用ILogger开发Azure函数的信息和文档也很少。有没有人有更多的信息或技巧来让它工作?

我的c#代码片段:
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.ServiceBus;
using System;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
namespace Experimental.Functions
{
    public static class ListenToEventFunction
    {
        [FunctionName("ListenToEventFunction")]
        public static void Run([EventHubTrigger("events", Connection = "EventHubConnectionString")]string myEventHubMessage, ILogger log)
        {
            log.LogInformation($"C# Event Hub trigger function processed a message: {myEventHubMessage}");
        }
    }
}

在使用VS2017的Azure函数工具调试我的Azure函数时,我得到以下错误:

A ScriptHost error has occurred
Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.EnrichTelemetryLocation'. 
Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'log' to type ILogger. 
Make sure the parameter Type is supported by the binding. 
If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).