다음을 통해 공유


Azure Functions를 사용하여 C# 클래스 라이브러리 함수 개발

이 문서는 .NET 클래스 라이브러리의 C#을 사용하여 Azure Functions를 개발하는 방법을 소개합니다. 이러한 클래스 라이브러리는 Functions 런타임에서 In Process를 실행하는 데 사용됩니다. .NET 함수는 Functions 런타임에서 분리되어 실행할 수 있으며, 이는 몇 가지 이점을 제공합니다. 자세한 내용은 격리된 작업자 모델을 참조하세요. 이러한 두 모델 간의 포괄적인 비교는 In Process 모델과 격리된 작업자 모델 간의 차이점을 참조하세요.

Important

이 문서에서는 런타임과 함께 In Process를 실행하는 .NET 클래스 라이브러리 함수를 지원합니다. C# 함수는 Out-of-process를 실행되고 Functions 런타임에서 격리될 수도 있습니다. 격리된 작업자 프로세스 모델은 현재 버전의 Functions 런타임에서 LTS가 아닌 버전의 .NET 및 .NET Framework 앱을 실행하는 유일한 방법입니다. 자세히 알아보려면 .NET 격리 작업자 프로세스 함수를 참조하세요. 격리 작업자 프로세스와 In Process .NET Functions 간 포괄적 비교는 In Process와 격리 작업자 프로세스 .NET Azure Functions 간의 차이점을 참조하세요.

C# 개발자라면 다음과 같은 문서를 참조할 수도 있습니다.

시작하기 개념 단계별 학습/샘플

Azure Functions는 C# 및 C# 스크립트 프로그래밍 언어를 지원합니다. Azure Portal에서 C#을 사용하는 방법에 대한 지침은 C# 스크립트(.csx) 개발자 참조를 참조하세요.

지원되는 버전

Functions 런타임 버전은 .NET의 특정 버전을 지원합니다. Functions 버전에 대해 자세히 알아보려면 Azure Functions 런타임 버전 개요를 참조하세요. In Process 또는 격리 작업자 프로세스 중 어떤 상태로 함수가 실행되는지에 따라 지원되는 버전이 달라집니다.

참고 항목

함수 앱에서 사용하는 Functions 런타임 버전을 변경하는 방법을 알아보려면 현재 런타임 버전 보기 및 업데이트를 참조하세요.

다음 표에서는 특정 버전의 Functions에서 사용할 수 있는 가장 높은 수준의 .NET 또는 .NET Framework를 보여 줍니다.

Functions 런타임 버전 격리된 작업자 모델 In Process 모델5
Functions 4.x1 .NET 9.0(미리 보기)
.NET 8.0
.NET 6.02
.NET Framework 4.83
.NET 8.0
.NET 6.02
Functions 1.x4 해당 없음 .NET Framework 4.8

1.NET 7은 이전에 격리된 작업자 모델에서 지원되었지만 2024년 5월 14일에 공식 지원이 종료되었습니다.

2 .NET 6은 2024년 11월 12일에 공식 지원이 종료됩니다.

3 빌드 프로세스에는 .NET SDK도 필요합니다.

4 2026년 9월 14일에 Azure Functions 런타임 버전 1.x에 대한 지원이 종료됩니다. 자세한 내용은 이 지원 공지를 참조하세요. 지속적인 전체 지원을 위해 앱을 버전 4.x로 마이그레이션해야 합니다.

5 In Process 모델에 대한 지원은 2026년 11월 10일에 종료됩니다. 자세한 내용은 이 지원 공지를 참조하세요. 계속해서 완전한 지원을 받으려면 앱을 격리된 작업자 모델로 마이그레이션해야 합니다.

특정한 이전 부 버전의 삭제를 비롯하여 Azure Functions 릴리스에 대한 최신 소식을 보려면 Azure App Service 공지를 주기적으로 확인하세요.

대상 .NET 8로 업데이트

In-process 모델을 사용하는 앱은 이 섹션에 설명된 단계에 따라 .NET 8을 대상으로 할 수 있습니다. 그러나 이 옵션을 실행하도록 선택하는 경우 2026년 11월 10일에 In-process 모델에 대한 지원이 종료되기 전에 격리된 작업자 모델로 마이그레이션 계획을 시작해야 합니다.

많은 앱은 코드 또는 재배포를 업데이트하지 않고 Azure에서 함수 앱의 구성을 변경할 수 있습니다. In-process 모델을 사용하여 .NET 8을 실행하려면 다음 세 가지 구성이 필요합니다.

  • 애플리케이션 설정 FUNCTIONS_WORKER_RUNTIME은 "dotnet" 값으로 설정해야 합니다.
  • 애플리케이션 설정 FUNCTIONS_EXTENSION_VERSION은(는) "~4" 값으로 설정해야 합니다.
  • 애플리케이션 설정 FUNCTIONS_INPROC_NET8_ENABLED은(는) 값 "1"로 설정해야 합니다.
  • .NET 8을 참조하도록 스택 구성을 업데이트해야 합니다.

.NET 8에 대한 지원은 여전히 Functions 런타임 버전 4.x를 사용하며 구성된 런타임 버전을 변경할 필요가 없습니다.

로컬 프로젝트를 업데이트하려면 먼저 최신 버전의 로컬 도구를 사용하고 있는지 확인합니다. 그런 다음 프로젝트가 Microsoft.NET.Sdk.Functions 버전 4.4.0 이상을 참조하는지 확인합니다. 그런 다음, TargetFramework을(를) "net8.0"으로 변경할 수 있습니다. 또한 "dotnet"으로 설정된 FUNCTIONS_WORKER_RUNTIME "1"로 설정된 FUNCTIONS_INPROC_NET8_ENABLED 모두 포함하도록 local.settings.json을(를) 업데이트해야 합니다.

다음은 이러한 변경 내용이 포함된 최소 project 파일의 예입니다.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

다음은 이러한 변경 내용이 포함된 최소 local.settings.json 파일의 예입니다.

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_INPROC_NET8_ENABLED": "1",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet"
    }
}

앱에서 Microsoft.Azure.DurableTask.Netherite.AzureFunctions를 사용하는 경우 버전 1.5.3 이상을 대상으로 하는지 확인합니다. .NET 8의 동작 변경으로 인해 이전 버전의 패키지가 있는 앱은 모호한 생성자 예외를 throw합니다.

다른 종속성의 버전 지원에 따라 앱에 다른 변경 사항을 적용해야 할 수도 있습니다.

Functions 런타임의 버전 4.x는 .NET 6 및 .NET 8에 동등한 기능을 제공합니다. In Process 모델에는 새로운 .NET 8 기능과 통합되는 추가 기능 또는 업데이트가 포함되어 있지 않습니다. 예를 들어 런타임이 키 지정 서비스를 지원하지 않습니다. 최신 .NET 8 기능 및 향상된 기능을 최대한 활용하려면 격리된 작업자 모델로 마이그레이션해야 합니다.

Functions 클래스 라이브러리 프로젝트

Visual Studio에서 Azure Functions 프로젝트 템플릿은 다음 파일이 포함된 C# 클래스 라이브러리 프로젝트를 만듭니다.

  • host.json -로컬로 또는 Azure에서 실행될 경우 프로젝트의 모든 함수에 영향을 주는 구성 설정을 저장합니다.
  • local.settings.json - 로컬로 실행될 때 사용되는 앱 설정 및 연결 문자열을 저장합니다. 이 파일은 암호를 포함하며 Azure의 함수 앱에 게시되지 않습니다. 대신 앱 설정을 함수 앱에 추가합니다.

프로젝트를 빌드할 때 빌드 출력 디렉터리에 다음 예제와 같은 폴더 구조가 생성됩니다.

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

이 디렉터리는 Azure의 함수 앱에 배포되는 디렉터리입니다. Functions 런타임의 버전 2.x에 필요한 바인딩 확장은 NuGet 패키지로 프로젝트에 추가됩니다.

Important

빌드 프로세스는 각 함수에 대해 function.json 파일을 만듭니다. 이 function.json 파일은 직접 편집할 수 없습니다. 이 파일을 편집하여 바인딩 구성을 변경하거나 함수를 사용하지 않도록 설정할 수 없습니다. 함수를 사용하지 않도록 설정하는 방법을 알아보려면 함수를 사용하지 않도록 설정하는 방법을 참조하세요.

함수로 인식되는 메서드

클래스 라이브러리에서 함수는 다음 예제와 같이 FunctionName 및 트리거 특성을 포함하는 메서드입니다.

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

FunctionName 특성은 메서드를 함수 진입점으로 표시합니다. 이름은 프로젝트 내에서 고유해야 하고, 문자로 시작해야 하고, 문자, 숫자, _, -만 포함해야 하며 허용되는 최대 길이는 127자입니다. 프로젝트 템플릿에서 Run 메서드를 자주 만들지만, 유효한 C# 이름은 모두 메서드 이름이 될 수 있습니다. 위의 예제에서는 사용 중인 정적 메서드를 보여 주지만 함수가 정적일 필요는 없습니다.

트리거 특성은 트리거 유형을 지정하고, 입력 데이터를 메서드 매개 변수에 바인딩합니다. 예제 함수는 큐 메시지에 의해 트리거되며, 큐 메시지는 myQueueItem 매개 변수의 메서드에 전달됩니다.

메서드 서명 매개 변수

트리거 특성에 사용되는 매개 변수 이외의 매개 변수가 메서드 서명에 포함될 수 있습니다. 다음은 포함할 수 있는 기타 매개 변수 중 일부입니다.

함수 시그니처에서 매개 변수의 순서는 중요하지 않습니다. 예를 들어, 다른 바인딩 전후에 트리거 매개 변수를 추가하고, 트리거 또는 바인딩 매개 변수 전후에 로거 매개 변수를 추가할 수 있습니다.

출력 바인딩

함수는 출력 매개 변수를 사용하여 정의된 0개 또는 여러 개의 출력 바인딩을 가질 수 있습니다.

다음 예제에서는 myQueueItemCopy라는 이름의 출력 큐 바인딩을 추가하여 이전 예제를 수정합니다. 이 함수는 함수를 다른 큐의 새 메시지로 트리거하는 메시지 콘텐츠를 씁니다.

public static class SimpleExampleWithOutput
{
    [FunctionName("CopyQueueMessage")]
    public static void Run(
        [QueueTrigger("myqueue-items-source")] string myQueueItem, 
        [Queue("myqueue-items-destination")] out string myQueueItemCopy,
        ILogger log)
    {
        log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
        myQueueItemCopy = myQueueItem;
    }
}

출력 바인딩에 할당된 값은 함수가 종료될 때 쓰입니다. 여러 출력 매개 변수에 값을 할당하기만 하면 함수에서 둘 이상의 출력 바인딩을 사용할 수 있습니다.

바인딩 참조 문서(예: 스토리지 큐)는 트리거, 입력 또는 출력 바인딩 특성에 사용할 수 있는 매개 변수 형식을 설명합니다.

바인딩 식 예제

다음 코드는 앱 설정에서 모니터링할 큐의 이름을 가져오고, insertionTime 매개 변수에서 큐 메시지 작성 시간을 가져옵니다.

public static class BindingExpressionsExample
{
    [FunctionName("LogQueueMessage")]
    public static void Run(
        [QueueTrigger("%queueappsetting%")] string myQueueItem,
        DateTimeOffset insertionTime,
        ILogger log)
    {
        log.LogInformation($"Message content: {myQueueItem}");
        log.LogInformation($"Created at: {insertionTime}");
    }
}

자동 생성된 function.json

빌드 프로세스는 build 폴더의 function 폴더에 function.json 파일을 만듭니다. 앞에서 설명한 대로 이 파일은 직접 편집할 수 없습니다. 이 파일을 편집하여 바인딩 구성을 변경하거나 함수를 사용하지 않도록 설정할 수 없습니다.

이 파일은 사용 플랜에 대한 크기 결정에 사용하기 위해 크기 조정 컨트롤러에 정보를 제공하는 데 필요합니다. 이와 같은 이유로 이 파일에는 트리거 정보만 있고 입출력 바인딩은 없습니다.

생성된 function.json 파일에는 바인딩에 function.json 구성 대신 .NET 특성을 사용하도록 런타임에 지시하는 configurationSource 속성이 포함되어 있습니다. 예를 들면 다음과 같습니다.

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

Microsoft.NET.Sdk.Functions

function.json 파일 세대는 NuGet 패키지 Microsoft.NET.Sdk.Functions에 의해 수행됩니다.

다음 예제에서는 동일한 Sdk 패키지의 서로 다른 대상 프레임워크가 있는 .csproj 파일의 관련 부분을 보여 줍니다.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.5.0" />
</ItemGroup>

Important

Core Tools 버전 4.0.6517부터 In-process 모델 프로젝트는 버전 4.5.0 이상을 Microsoft.NET.Sdk.Functions참조해야 합니다. 이전 버전을 사용하는 func start 경우 명령에 오류가 발생합니다.

Sdk 패키지 종속성에는 트리거 및 바인딩이 있습니다. 해당 트리거 및 바인딩은 .NET Framework를 대상으로 하므로 1.x 프로젝트는 1.x 트리거 및 바인딩을 참조하지만, 4.x 트리거 및 바인딩을 .NET Core를 대상으로 합니다.

Sdk 패키지는 Newtonsoft.Json에도 종속되며, WindowsAzure.Storage에는 간접적으로 종속됩니다. 이러한 종속성 때문에 프로젝트는 대상이 되는 Functions 런타임 버전에서 작동하는 패키지 버전을 사용하게 됩니다. 예를 들어, Newtonsoft.Json에는 .NET Framework 4.6.1용 버전 11이 있지만, .NET Framework 4.6.1을 대상으로 하는 Functions 런타임은 Newtonsoft.Json 9.0.1과만 호환됩니다. 따라서 해당 프로젝트의 함수 코드도 Newtonsoft.Json 9.0.1을 사용해야 합니다.

Microsoft.NET.Sdk.Functions의 소스 코드는 GitHub 리포지토리 azure-functions-vs-build-sdk에서 사용할 수 있습니다.

로컬 런타임 버전

Visual Studio는 Azure Functions 핵심 도구를 사용하여 로컬 컴퓨터에서 Functions 프로젝트를 실행합니다. 핵심 도구는 Function 런타임에 대한 명령줄 인터페이스입니다.

Windows 설치 프로그램(MSI) 패키지를 사용하거나 npm을 사용하여 핵심 도구를 설치하는 경우 Visual Studio에서 사용하는 핵심 도구 버전에는 영향을 미치지 않습니다. Functions 런타임 버전 1.x의 경우, Visual Studio는 %USERPROFILE%\AppData\Local\Azure.Functions.Cli에 핵심 도구 버전을 저장하고 해당 위치에 저장된 최신 버전을 사용합니다. Functions 4.x의 경우, 핵심 도구는 Azure Functions 및 Web Jobs Tools 확장에 포함되어 있습니다. Functions 1.x의 경우 Functions 프로젝트를 실행할 때 콘솔 출력에 사용되는 버전을 확인할 수 있습니다.

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRun

함수 앱을 ReadyToRun 이진 파일로 컴파일할 수 있습니다. ReadyToRun은 사용 플랜에서 실행할 때 콜드 부팅의 영향을 줄이는 데 도움이 되도록 시작 성능을 개선할 수 있는 사전 컴파일 형식입니다.

ReadyToRun은 .NET 6 이상 버전에서 사용할 수 있으며 Azure Functions 런타임 버전 4.0이 필요합니다.

프로젝트를 ReadyToRun으로 컴파일하려면 <PublishReadyToRun><RuntimeIdentifier> 요소를 추가하여 프로젝트 파일을 업데이트합니다. 다음은 Windows 32비트 함수 앱에 게시하기 위한 구성입니다.

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

Important

.NET 6부터 복합 ReadyToRun 컴파일에 대한 지원이 추가되었습니다. ReadyToRun 크로스 플랫폼 및 아키텍처 제한을 확인하세요.

명령줄에서 ReadyToRun을 사용하여 앱을 빌드할 수도 있습니다. 자세한 내용은 dotnet publish-p:PublishReadyToRun=true 옵션을 참조하세요.

바인딩에 대해 지원되는 형식

각 바인딩에는 자체적인 지원 형식이 있습니다. 예를들 어, Blob 트리거 특성은 문자열 매개 변수, POCO 매개 변수, CloudBlockBlob 매개 변수 또는 지원되는 기타 몇 가지 형식에 적용될 수 있습니다. Blob 바인딩에 대한 바인딩 참조 문서에는 지원되는 모든 매개 변수 형식이 나와 있습니다. 자세한 내용은 트리거 및 바인딩각 바인딩 형식에 대한 바인딩 참조 문서를 참조하세요.

HTTP 또는 WebHook를 사용할 계획인 경우 HttpClient의 부적절한 인스턴스화로 인해 발생할 수 있는 포트 소모를 피하도록 계획합니다. 자세한 내용은 Azure Functions에서 연결을 관리하는 방법을 참조하세요.

메서드 반환 값에 바인딩

메서드 반환 값에 특성을 적용하여 출력 바인딩에 대한 메서드 반환 값을 사용할 수 있습니다. 예제를 보려면 트리거 및 바인딩을 참조하세요.

성공적인 함수 실행이 항상 출력 바인딩으로 전달할 반환 값을 생성하는 경우에만 반환 값을 사용합니다. 그렇지 않으면 다음 섹션에 나와 있는 것처럼 ICollector 또는 IAsyncCollector를 사용합니다.

여러 출력 값 쓰기

출력 바인딩에 여러 값을 쓰거나 성공적인 함수 호출이 출력 바인딩에 전달할 값을 생성하지 않는 경우 ICollector 또는 IAsyncCollector 형식을 사용합니다. 이러한 형식은 메서드가 완료될 때 출력 바인딩에 기록되는 쓰기 전용 컬렉션입니다.

이 예제에서는 ICollector를 사용하여 동일한 큐에 여러 큐 메시지를 씁니다.

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
        myDestinationQueue.Add($"Copy 1: {myQueueItem}");
        myDestinationQueue.Add($"Copy 2: {myQueueItem}");
    }
}

Async

비동기화 함수를 만들려면 async 키워드를 사용하고 Task 개체를 반환합니다.

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        ILogger log)
    {
        log.LogInformation($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

out 매개 변수는 비동기 함수에 사용할 수 없습니다. 출력 바인딩에는 함수 반환 값 또는 수집기 개체를 대신 사용합니다.

취소 토큰

함수는 함수가 종료될 때 운영 체제가 코드에 알릴 수 있게 해주는 CancellationToken 매개 변수를 사용할 수 있습니다. 이 알림을 통해 함수가 예기치 않게 종료되어 데이터가 일관되지 않은 상태가 되는 것을 방지할 수 있습니다.

메시지를 일괄 처리로 처리하는 함수가 있는 경우를 고려합니다. 다음 Azure Service Bus 트리거 함수는 특정 함수 호출에 의해 처리될 수신 메시지의 일괄 처리를 나타내는 ServiceBusReceivedMessage 개체의 배열을 처리합니다.

using Azure.Messaging.ServiceBus;
using System.Threading;

namespace ServiceBusCancellationToken
{
    public static class servicebus
    {
        [FunctionName("servicebus")]
        public static void Run([ServiceBusTrigger("csharpguitar", Connection = "SB_CONN")]
               ServiceBusReceivedMessage[] messages, CancellationToken cancellationToken, ILogger log)
        {
            try
            { 
                foreach (var message in messages)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        log.LogInformation("A cancellation token was received. Taking precautionary actions.");
                        //Take precautions like noting how far along you are with processing the batch
                        log.LogInformation("Precautionary activities --complete--.");
                        break;
                    }
                    else
                    {
                        //business logic as usual
                        log.LogInformation($"Message: {message} was processed.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogInformation($"Something unexpected happened: {ex.Message}");
            }
        }
    }
}

로깅

함수 코드로 Application Insights에서 traces로 표시되는 로그에 출력을 작성할 수 있습니다. 로그에 작성하는 경우 일반적으로 이름이 logILogger형식의 매개 변수를 포함하는 것이 좋습니다. Functions 런타임의 버전 1.x는 TraceWriter를 사용하며, 이는 Application Insights에도 작성하지만 구조적 로깅은 지원하지 않습니다. 해당 데이터는 Application Insights에 의해 캡처되지 않으므로 Console.Write를 사용하여 로그를 작성하지 마세요.

ILogger

함수 정의에서 구조적 로깅을 지원하는 ILogger 매개 변수를 포함합니다.

ILogger 개체를 사용하여 로그를 생성하는 Log<level>ILogger의 확장 메서드를 호출합니다. 다음 코드는 범주가 Function.<YOUR_FUNCTION_NAME>.User.Information 로그를 작성합니다.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

Functions 구현 방법에 대한 자세한 ILogger 내용은 원격 분석 데이터 수집을 참조하세요. Function 접두사가 붙은 범주는 ILogger 인스턴스를 사용하고 있다고 가정합니다. 대신 ILogger<T>를 사용하도록 선택하는 경우 범주 이름은 대신 T를 기반으로 할 수 있습니다.

구조적 로깅

이름이 아닌 자리 표시자는 로그 메시지에 사용되는 매개 변수를 결정합니다. 다음과 같은 코드가 있다고 가정하겠습니다.

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

메시지 문자열을 동일하게 유지하고 매개 변수의 순서를 반대로 바꾸면 그 결과 메시지 텍스트가 잘못된 위치에서 값을 갖습니다.

구조적 로깅을 수행할 수 있도록 자리 표시자는 이러한 방식으로 처리됩니다. Application Insights는 매개 변수 이름-값 쌍과 메시지 문자열을 저장합니다. 그 결과로 메시지 인수는 사용자가 쿼리할 수 있는 필드가 됩니다.

로거 메서드 호출이 이전 예제와 같은 경우 customDimensions.prop__rowKey 필드를 쿼리할 수 있습니다. 런타임에서 추가하는 필드와 함수 코드에서 추가하는 필드가 서로 충돌하지 않도록 prop__ 접두사가 추가됩니다.

customDimensions.prop__{OriginalFormat} 필드를 참조하여 원래 메시지 문자열을 쿼리할 수도 있습니다.

다음은 customDimensions 데이터의 샘플 JSON 표현입니다.

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

로그 사용자 지정 원격 분석

함수에서 Application Insights로 사용자 지정 원격 분석 데이터를 전송하는 데 사용할 수 있는 Application Insights SDK의 Functions 관련 버전 Microsoft.Azure.WebJobs.Logging.ApplicationInsights가 있습니다. 명령 프롬프트에서 다음 명령을 사용하여 이 패키지를 설치합니다.

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

이 명령에서 <VERSION>을 설치된 Microsoft.Azure.WebJobs를 지원하는 이 패키지의 버전으로 바꿉니다.

다음 C# 예제에서는 사용자 지정 원격 분석 API를 사용합니다. 이 예제는 .NET 클래스 라이브러리용이지만 Application Insights 코드는 C# 스크립트와 동일합니다.

런타임 2.x 이상 버전에서는 원격 분석 데이터와 현재 작업 간의 상관 관계를 자동으로 지정하는 Application Insights의 새 기능이 사용됩니다. 작업 Id, ParentId 또는 Name 필드를 수동으로 설정할 필요가 없습니다.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;

namespace functionapp0915
{
    public class HttpTrigger2
    {
        private readonly TelemetryClient telemetryClient;

        /// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
        public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
        {
            this.telemetryClient = new TelemetryClient(telemetryConfiguration);
        }

        [FunctionName("HttpTrigger2")]
        public Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ExecutionContext context, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            DateTime start = DateTime.UtcNow;

            // Parse query parameter
            string name = req.Query
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            // Write an event to the customEvents table.
            var evt = new EventTelemetry("Function called");
            evt.Context.User.Id = name;
            this.telemetryClient.TrackEvent(evt);

            // Generate a custom metric, in this case let's use ContentLength.
            this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);

            // Log a custom dependency in the dependencies table.
            var dependency = new DependencyTelemetry
            {
                Name = "GET api/planets/1/",
                Target = "swapi.co",
                Data = "https://swapi.co/api/planets/1/",
                Timestamp = start,
                Duration = DateTime.UtcNow - start,
                Success = true
            };
            dependency.Context.User.Id = name;
            this.telemetryClient.TrackDependency(dependency);

            return Task.FromResult<IActionResult>(new OkResult());
        }
    }
}

이 예제에서 사용자 지정 메트릭 데이터는 customMetrics 테이블로 전송되기 전에 호스트에 의해 집계됩니다. 자세히 알아보려면 Application Insights의 GetMetric 문서를 참조하세요.

로컬로 실행하는 경우 Application Insights 키를 사용하여 local.settings.json 파일에 APPINSIGHTS_INSTRUMENTATIONKEY 설정을 추가해야 합니다.

TrackRequest 또는 StartOperation<RequestTelemetry>를 호출하지 마세요. 함수 호출에 대한 요청이 중복으로 표시됩니다. Functions 런타임에서 자동으로 요청을 추적합니다.

telemetryClient.Context.Operation.Id를 설정하지 마십시오. 이 전역 설정은 여러 함수가 동시에 실행될 때 잘못된 상관 관계를 유발합니다. 대신 새로운 원격 분석 인스턴스(DependencyTelemetry, EventTelemetry)를 만들고 해당하는 Context 속성을 수정합니다. 그런 다음, 원격 분석 인스턴스를 TelemetryClient의 해당 Track 메서드(TrackDependency(), TrackEvent(), TrackMetric())에 전달합니다. 이 방법을 사용하면 원격 분석 데이터가 현재 함수 호출에 대해 올바른 상관 관계 세부 정보를 가질 수 있습니다.

테스팅 함수

다음 문서에서는 테스트 목적으로 In Process C# 클래스 라이브러리 함수를 로컬로 실행하는 방법을 보여 줍니다.

환경 변수

환경 변수 또는 앱 설정 값을 가져오려면 다음 코드 예제와 같이 System.Environment.GetEnvironmentVariable을 사용합니다.

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    private static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

앱 설정은 로컬로 개발할 때와 Azure에서 실행할 때 환경 변수에서 읽을 수 있습니다. 로컬로 개발할 때 앱 설정은 Valueslocal.settings.json 파일의 컬렉션에서 가져옵니다. 로컬 및 Azure의 두 환경에서 GetEnvironmentVariable("<app setting name>")은 명명된 앱 설정의 값을 검색합니다. 예를 들어 로컬로 실행하는 경우 local.settings.json 파일에 { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }이 포함된 경우 "My Site Name"이 반환됩니다.

System.Configuration.ConfigurationManager.AppSettings 속성은 앱 설정 값을 가져오는 대체 API지만, 다음과 같이 GetEnvironmentVariable을 사용하는 것이 좋습니다.

런타임에 바인딩

C# 및 기타 .NET 언어에서는 특성의 declarative 바인딩과 달리 명령적 바인딩 패턴을 사용할 수 있습니다. 명령적 바인딩은 바인딩 매개 변수를 디자인 타임이 아닌 런타임에 계산해야 할 경우 유용합니다. 이 패턴을 사용하면 함수 코드에서 지원되는 입력 및 출력 바인딩을 즉시 바인딩할 수 있습니다.

다음과 같이 명령적 바인딩을 정의합니다.

  • 원하는 명령적 바인딩에 대한 함수 시그니처에 특성을 포함하지 마세요.

  • 입력 매개 변수 Binder binder 또는 IBinder binder에 전달합니다.

  • 다음 C# 패턴을 사용하여 데이터 바인딩을 수행합니다.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    BindingTypeAttribute는 바인딩을 정의하는 .NET 특성이며, T는 해당 바인딩 형식에서 지원되는 입력 또는 출력 형식입니다. Tout 매개 변수 형식(예: out JObject)일 수 없습니다. 예를 들어, Mobile Apps 테이블 출력 바인딩은 6가지 출력 형식을 지원하지만 명령적 바인딩에는 ICollector<T> 또는 IAsyncCollector<T>만 사용할 수 있습니다.

단일 특성 예제

다음 예제 코드에서는 런타임에서 정의된 Blob경로를 사용하는 Storage Blob 출력 바인딩을 만든 다음, Blob에 문자열을 씁니다.

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        ILogger log)
    {
        log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

BlobAttributeStorage Blob 입력 또는 출력 바인딩을 정의하며, TextWriter는 지원되는 출력 바인딩 형식입니다.

다중 특성 예제

앞의 예제에서는 함수 앱의 주 Storage 계정 연결 문자열(AzureWebJobsStorage)에 대한 앱 설정을 가져옵니다. StorageAccountAttribute를 추가하고 BindAsync<T>()에 특성 배열을 전달하여 스토리지 계정에 사용할 사용자 지정 앱 설정을 지정할 수 있습니다. IBinder가 아닌 Binder 매개 변수를 사용합니다. 예시:

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            ILogger log)
    {
        log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

트리거 및 바인딩

이 표는 Azure Functions 런타임의 주요 버전에서 지원되는 바인딩을 보여 줍니다.

Type 1.x1 2.x 이상2 트리거 입력 출력
Blob Storage
Azure Cosmos DB
Azure Data Explorer
Azure SQL
Dap4
Event Grid
Event Hubs
HTTP 및 웹후크
IoT Hub
Kafka3
Mobile Apps
Notification Hubs
Queue Storage
Redis
RabbitMQ3
SendGrid
Service Bus
SignalR
Table Storage
타이머
Twilio

참고:

  1. 2026년 9월 14일에 Azure Functions 런타임 버전 1.x에 대한 지원이 종료됩니다. 완전한 지원을 받으려면 앱을 버전 4.x로 마이그레이션하는 것이 좋습니다.
  2. 버전 2.x 런타임부터는 HTTP 및 타이머를 제외한 모든 바인딩이 등록되어야 합니다. 바인딩 확장 등록을 참조하세요.
  3. 트리거는 소비 계획에서 지원되지 않습니다. 런타임 기반 트리거가 필요합니다.
  4. Kubernetes, IoT Edge 및 기타 자체 호스팅 모드에서만 지원됩니다.

다음 단계