web-dev-qa-db-ja.com

外部ライブラリのTraceWriterを使用したAzure Functionのログ

Azure Functionで使用可能なTraceWriterオブジェクトを再利用して、外部参照ライブラリの情報を記録するにはどうすればよいですか?コンストラクタを使用してオブジェクトを渡し、TraceWriterクラス(web.http.tracing)を参照しようとしました。クラスが異なるように見えるので、私は運がありませんでした。

26
Lance

短いバージョンこのnugetパッケージ で利用可能なMicrosoft.Azure.WebJobs.Host.TraceWriterを使用します。

または、関数をWebプロジェクトとしてビルドし、ローカルでデバッグできます。 ここでサンプルを見つけることができます

ロングバージョン

ここでの問題は、間違ったTraceWriterを使用していることです。

Azure関数でAzure Functionロガーを使用して、ロガーのタイプを出力しました。

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

これにより、次のことがわかりました。

Microsoft.Azure.WebJobs.Script.InterceptingTraceWriter

私もWeb/Http TraceWriterを期待していましたが、さらに別の実装が必要なことに驚きました。 Microsoftは本当に標準的なアプローチを作成することで、あるいは少なくともエラー、警告、情報、詳細などのきれいなインターフェイスを提供してくれます。

独自のインターフェイスを作成し、アプリロガーとAzureのインターフェイスをラップして、コードで頭痛を引き起こすことなく必要なものを注入できるようにします。また、これにより、将来の重大な変更によって生じる潜在的な痛みからの保護が提供されます。

とにかく、私は脱線し、Microsoft.Azure.WebJobs.Script.InterceptingTraceWriterから Azure Functions/GitHub repoをスクリプトするWebjobs に進み、Nugetパッケージに進みます。これをテストしましたが、Azure Functionロガーを外部アセンブリに渡し、そこからAzure Function環境へのログインを続行すると正常に機能します。

以下に例を示します。

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();
        }
    }
}
39
Murray Foxcroft

更新として、Azure FunctionsはILoggerの代わりにTraceWritterの使用をサポートするようになったため、ILoggerを実装する任意のログフレームワークを使用できます。

GitHub issue および後続の wikiドキュメント を参照してください。

9
Chris

ILoggerをAzure機能で動作させるために必要なバージョンが正しい場合、Microsoft.Azure.WebJobs 2.1.0-beta1になります。ただし、TraceWriterの代わりにILoggerを使用してAzure機能を実行することはできません。

また、ILoggerを使用したAzure Functionsの開発に関する情報とドキュメントはほとんどありません。これを機能させるための情報やヒントはありますか?

私の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}");
        }
    }
}

Azure Function Tools for VS2017を使用してAzure Functionをデバッグすると、次のエラーが表示されます。

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.).
5
Boxed