Azure Functions를 실행할 때 로그를 Application Insights에 데이터 보내기

개요



Azure에는 Azure Functions이라는 AWS Lambda과 같은 서비스가 있습니다.
Azure Functions는 Lambda와 마찬가지로 일정 시간마다 한 WebHook이 호출되었을 때 등 어떤 이벤트가 발생했을 때 서버에있는 C# 및 JavaScript (NodeJS) 코드가 실행된다는 것입니다.

그 때, Functions 자체의 동작 로그를 Application Insights 에 송신해 두고, Application Insights상에서 볼 수 있으면 좋다고 생각했으므로, 그 방법을 조사했습니다.

잘 전송할 수 있게 되면 아래 그림과 같이 Application Insights에서 로그를 볼 수 있게 됩니다.


아래 준비



Functions에서 Application Insights 라이브러리를 사용할 수 있도록 설정



먼저 Azure Functions에서 Application Insights 라이브러리를 로드할 수 있습니다.
wwwroot 아래에 대상 Function 이름이 있는 폴더가 있습니다. 해당 폴더에 project.json을 만들고 다음과 같은 내용을 씁니다. project.json을 저장하면 라이브러리를 NuGet에서 마음대로 다운로드하여 해당 Function에서 사용할 수 있습니다.
지금은 Azure 포털에서 project.json을 만들 수 없기 때문에 여기에만 Kudu를 사용하거나 Visual Studio를 통해 업로드하는 등 많은 노력이 필요합니다.
{
  "frameworks": {
    "net46": {
      "dependencies": {
        "Microsoft.ApplicationInsights": "2.1.0"
      }
    }
  }
}

Application Insights의 INSTRUMENTATIONKEY를 Functions에서 참조할 수 있도록 한다



Azure Functions의 App Service Settings를 열고 '응용 프로그램 설정' 항목에서 APPINSIGHTS_INSTRUMENTATIONKEY라는 키를 만들고 값에 Application Insights의 INSTRUMENTATIONKEY를 설정합니다.


여기서 설정한 키는 Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY") 라는 코드로 참조할 수 있습니다.

실제로 Functions 코드에서 사용



실제 코드는 다음과 같은 형태입니다.
포인트로서, TelemetryClientContext.Operation.Id 에, 해당 Function 의 InvocationId (호출 ID)를 설정하고 있습니다.
InvocationId 는 Function 가 불려 갈 때마다 독특한 값이 되므로, 어느 호출에 관한 텔레메트리인가를 나중에 추적하기 쉬워집니다. Application Insights도 Operation.Id 마다 텔레메트리를 그룹화해 줍니다.
using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;

public static void Run(TimerInfo myTimer, TraceWriter log, ExecutionContext executionContext)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    var processStartTime = DateTimeOffset.UtcNow;
    var functionSucceed = true;

    var telemetryClient = new TelemetryClient { InstrumentationKey = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY") };
    telemetryClient.Context.Operation.Id = executionContext.InvocationId.ToString();
    telemetryClient.TrackTrace(
                message: "The function has started",
                severityLevel: SeverityLevel.Information,
                properties: new Dictionary<string, string>() {
                    { "somePropertyName", "somePropertyValue"},
                });
    try
    {
        //Functionsで行う処理などを書く
        //適宜telemetryClient.TrackTrace()やtelemetryClient.TrackMetric()などを呼び出してもよい。
    }
    catch (Exception e)
    {
        functionSucceed = false;
        telemetryClient.TrackException(
            exception: e,
            properties: new Dictionary<string, string>() {
                    { "somePropertyName", "somePropertyValue"},
                });
    }
    finally
    {
        stopwatch.Stop();

        telemetryClient.TrackRequest(
            new RequestTelemetry(
                name: "何かわかりやすい名前。このAzureFunctionの名前など設定すること",
                startTime: processStartTime,
                duration: sw.Elapsed,
                responseCode: "",
                success: functionSucceed));
    }
    telemetryClient.Flush();

}

참고로 한 사이트


  • Azure Functions - C#에서 Nuget 패키지를 사용해 보았습니다.
  • Azure Functions에서 런타임 ID 얻기
  • Azure Functions C# developer reference
  • TelemetryContext
  • 좋은 웹페이지 즐겨찾기