6 min read

애저 펑션에서 Application Insights로 로그 남기기

Justin Yoo

이 포스트에서는 애저 펑션과 Application Insights를 연동시킬 때 적용시킬 수 있는 몇 가지 방법에 대해 간략하게 알아보기로 한다.

Azure Functions (애저 펑션)는 자체적으로 TraceWriter 인스턴스를 통해 로깅 기능을 제공한다.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, string productId, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
log.Info($"ProductId: {productId}");
...
}

이를 이용하면 애저 펑션의 로그 콘솔에 아래와 같이 정보를 표시할 수 있다.

하지만, 이 콘솔 로그는 최대 1000개의 메시지만 저장할 수 있는 제약이 있어서 간단한 디버깅의 용도로는 좋지만 본격적인 로그 저장 용도로는 썩 좋지 않다. 그래서 최근 Application Insights와 연동을 시키는 프리뷰 기능을 제공하기 시작했다.

Application Insights 연동

이부분은 사실 굉장히 간단하다. 애저 펑션의 AppSettings 섹션에 Application Insights 인스턴스의 Instrumentation Key 값을 APPINSIGHTS_INSTRUMENTATIONKEY 에 추가하면 된다. 이 때 Application Insights 인스턴스는 반드시 General 타입이어야 한다.

이렇게 설정한 후 펑션을 몇 번 실행시켜 보면 아래와 같이 실행 결과 로그가 자동으로 Application Insights에 수집되는 것을 볼 수 있다.

참 쉽죠?

DevOps 엔지니어를 위한 ARM 템플릿 설정

위와 같은 방법으로 Application Insights의 Instrumentation Key를 설정하는 것이 나쁘진 않지만 실제 CI/CD 환경에서 추천할만한 방법은 아니다. DevOps 관점에서는 ARM 템플릿을 이용하는 것이 훨씬 더 효과적이므로 아래 템플릿 샘플과 같이 설정하면 손쉽게 Instrumentation Key를 설정할 수 있다.

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
...
},
"variables": {
...
},
"resources": [
// Application Insights
{
"type": "Microsoft.Insights/components",
"apiVersion": "2014-04-01",
...
// Set the "kind" value to "other", which is "General".
"kind": "other",
...
},
// Function App
{
"type": "Microsoft.Web/sites",
"apiVersion": "2015-08-01",
...
// Set the "kind" value to "functionapp"
"kind": "functionapp",
...
"resources": [
{
"type": "config",
"apiVersion": "2015-08-01",
// Set the "AppSettings" section
"name": "appsettings",
"properties": {
...
// Set the Instrumentation Key directly within ARM template
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.Insights/components', variables('applicationInsightsName')), '2014-04-01').InstrumentationKey]",
...
}
}
],
...
}
],
"outputs": {}
}

위의 ARM 템플릿은 필요한 부분만 남긴 축약 버전이다. 템플릿과 관련한 좀 더 자세한 내용은 이 공식 문서를 참조하면 좋다.

ILogger 연동

ASP.NET Core 라이브러리는 ILogger라는 로깅 관련 인터페이스를 제공한다. 이 인터페이스를 이용하면 Application Insights에서 로그를 보낼 수 있다. 이 부분도 굉장히 간단하다. 기존의 TraceWriter 타입을 ILogger 타입으로 변경하고 로그 메소드 이름을 Info()에서 LogInformation()과 같이 바꿔주면 된다.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, string productId, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
log.LogInformation($"ProductId: {productId}");
...
}

만약 기존의 Info() 메소드 이름을 그대로 사용하고 싶다면 아래와 같이 확장 메서드를 하나 만들어주면 좋다.

public static class LoggerExtensions
{
public static void Info(this ILogger log, string message)
{
...
log.LogInformation(message);
}
}

이 확장 메소드를 이용하면 기존의 log.Info() 메소드를 변경 없이 그대로 사용할 수 있다.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, string productId, ILogger log)
{
log.Info("C# HTTP trigger function processed a request.");
log.Info($"ProductId: {productId}");
...
}

이렇게 바꾼 후 애저 펑션을 실행시켜보면 아래와 같은 결과를 애저 펑션 로그 콘솔에서 확인할 수 있다.

또한 Application Insights에서도 확인이 가능하다.

그렇다면 Application Insights 뿐만 아니라 ILogger 인터페이스를 구현한 써드파티 로깅 라이브러리도 사용할 수 있지 않을까? 안타깝게도 이 포스트를 쓰는 현재 시점에서는 사용할 수 없다. 하지만 이 이슈를 보면 곧 구현될 것 같다.

지금까지 애저 펑션과 Application Insights를 연동시키는 방법에 대해 다양한 관점에서 대략적으로 훑어봤다. 아직까지 프리뷰 기능이어서 제한적이기는 하지만, 그래도 꽤 유용하게 쓰일 수 있을 것처럼 보인다.