

# C\$1 Lambda 함수 로그 및 모니터링
<a name="csharp-logging"></a>

AWS Lambda는 자동으로 Lambda 함수를 모니터링하고 로그 항목을 Amazon CloudWatch로 보냅니다. Lambda 함수는 함수의 각 인스턴스에 대한 CloudWatch Logs 로그 그룹 및 로그 스트림과 함께 제공됩니다. Lambda 런타임 환경은 각 간접 호출에 대한 세부 정보와 함수 코드의 기타 출력을 로그 스트림으로 전송합니다. CloudWatch Logs에 대한 자세한 내용은 [CloudWatch Logs로 Lambda 함수 로그 전송](monitoring-cloudwatchlogs.md) 섹션을 참조하세요.

**Topics**
+ [로그를 반환하는 함수 생성](#csharp-logging-output)
+ [.NET에서 Lambda 고급 로깅 제어 사용](#csharp-logging-advanced)
+ [추가 로깅 도구 및 라이브러리](#csharp-tools-libraries)
+ [구조화된 로깅에 Powertools forAWS Lambda(.NET) 및 AWS SAM 사용](#dotnet-logging-sam)
+ [Lambda 콘솔에서 로그 보기](#csharp-logging-console)
+ [CloudWatch 콘솔에서 로그 보기](#csharp-logging-cwconsole)
+ [AWS Command Line Interface(AWS CLI)(을)를 사용하여 로그 보기](#csharp-logging-cli)
+ [로그 삭제](#csharp-logging-delete)

## 로그를 반환하는 함수 생성
<a name="csharp-logging-output"></a>

함수 코드의 로그를 출력하려면 컨텍스트 객체에서 [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs)를 사용하거나 [콘솔 클래스](https://docs.microsoft.com/en-us/dotnet/api/system.console)에서 메서드를 사용하거나 `stdout` 또는 `stderr`에 쓰는 로깅 라이브러리를 사용합니다.

.NET 런타임은 각 호출에 대해 `START`, `END` 및 `REPORT` 줄을 로깅합니다. 보고서 행은 다음과 같은 세부 정보를 제공합니다.

**REPORT 행 데이터 필드**
+ **RequestId** – 호출의 고유한 요청 ID입니다.
+ **지속시간** – 함수의 핸들러 메서드가 이벤트를 처리하는 데 걸린 시간입니다.
+ **청구 기간** – 호출에 대해 청구된 시간입니다.
+ **메모리 크기** - 함수에 할당된 메모리 양입니다.
+ **사용된 최대 메모리** – 함수에서 사용한 메모리 양입니다. 간접 호출이 실행 환경을 공유하는 경우 Lambda는 모든 간접 호출에서 사용된 최대 메모리를 보고합니다. 이 동작으로 인해 보고된 값이 예상보다 높을 수 있습니다.
+ **초기화 기간** – 제공된 첫 번째 요청의 경우 런타임이 핸들러 메서드 외부에서 함수를 로드하고 코드를 실행하는 데 걸린 시간입니다.
+ **XRAY TraceId** – 추적된 요청의 경우 [AWS X-Ray 추적 ID](services-xray.md)입니다.
+ **SegmentId** - 추적된 요청의 경우 X-Ray 세그먼트 ID입니다.
+ **샘플링 완료(Sampled)** – 추적된 요청의 경우 샘플링 결과입니다.

## .NET에서 Lambda 고급 로깅 제어 사용
<a name="csharp-logging-advanced"></a>

함수의 로그를 캡처, 처리 및 사용하는 방법을 더 잘 제어할 수 있도록 지원되는 .NET 런타임에 대한 다음의 로깅 옵션을 구성할 수 있습니다.
+ **로그 형식** - 함수 로그의 경우 일반 텍스트와 구조화된 JSON 형식 중에서 선택
+ **로그 수준** - JSON 형식의 로그의 경우, Lambda가 CloudWatch로 전송하는 로그의 세부 수준(ERROR, DEBUG 또는 INFO 등)을 선택
+ **로그 그룹** - 함수가 로그를 보내는 CloudWatch 로그 그룹을 선택

이러한 로깅 옵션에 대한 자세한 내용과 이를 사용하도록 함수를 구성하는 방법에 대한 지침은 [Lambda 함수에 대한 고급 로깅 제어 구성](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)을 참조하세요.

.NET Lambda 함수에서 로그 형식 및 로그 수준 옵션을 사용하려면 다음 섹션의 지침을 참조하세요.

### .NET에서 구조화된 JSON 로그 형식 사용
<a name="csharp-logging-advanced-JSON"></a>

함수의 로그 형식으로 JSON을 선택하면 Lambda는 [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs)를 사용하여 로그 출력을 구조화된 JSON으로 전송합니다. 각 JSON 로그 객체에는 다음 키가 있는 다섯 개의 키 값 페어가 포함되어 있습니다.
+ `"timestamp"` - 로그 메시지가 생성된 시간
+ `"level"` - 메시지에 할당된 로그 수준
+ `"requestId"` - 함수 간접 호출의 고유한 요청 ID
+ `"traceId"` - `_X_AMZN_TRACE_ID` 환경 변수
+ `"message"` - 로그 메시지의 내용

`ILambdaLogger` 인스턴스는 예를 들어 예외를 로깅할 때 키 값 페어를 추가할 수 있습니다. [고객이 제공하는 로그 파라미터](#csharp-logging-advanced-JSON-user-supplied) 섹션에서 설명한 대로 자체 추가 파라미터를 제공할 수도 있습니다.

**참고**  
코드가 이미 다른 로깅 라이브러리를 사용하여 JSON 형식의 로그를 생성하는 경우 함수의 로그 형식이 일반 텍스트로 설정되었는지 확인합니다. 로그 형식을 JSON으로 설정하면 로그 출력이 이중으로 인코딩됩니다.

다음 로깅 명령 예제에서는 `INFO` 수준의 로그 메시지를 작성하는 방법을 보여줍니다.

**Example .NET 로깅 코드**  

```
context.Logger.LogInformation("Fetching cart from database");
```

다음 예제와 같이 로그 수준을 인수로 사용하는 일반 로그 메서드를 사용할 수도 있습니다.

```
context.Logger.Log(LogLevel.Information, "Fetching cart from database");
```

이 코드 예제의 로그 출력은 다음과 같이 CloudWatch Logs에서 캡처됩니다.

**Example JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Fetching cart from database"
}
```

**참고**  
JSON이 아닌 일반 텍스트를 사용하도록 함수의 로그 형식을 구성하는 경우 메시지에 캡처된 로그 수준은 4자리 레이블을 사용하는 Microsoft 규칙을 따릅니다. 예를 들어 `Debug`의 로그 수준은 메시지에서 `dbug`로 표시됩니다.  
JSON 형식의 로그를 사용하도록 함수를 구성하는 경우 로그에 캡처된 로그 수준은 JSON 로그 레코드 예제에 표시된 대로 전체 레이블을 사용합니다.

로그 출력에 수준을 할당하지 않으면 Lambda는 자동으로 수준 INFO를 할당합니다.

#### JSON에서 예외 로깅
<a name="csharp-logging-advanced-JSON-exceptions"></a>

`ILambdaLogger`를 통해 구조화된 JSON 로깅을 사용하는 경우 다음 예제와 같이 코드에서 예외를 로깅할 수 있습니다.

**Example 예외 로깅 사용**  

```
try
{
    connection.ExecuteQuery(query);
}
catch(Exception e)
{
    context.Logger.LogWarning(e, "Error executing query");
}
```

이 코드에서 생성된 로그 형식 출력은 다음 예제 JSON에 나와 있습니다. JSON의 `message` 속성은 `LogWarning` 직접 호출에서 제공된 메시지 인수를 사용하여 채워지는 반면, `errorMessage` 속성은 예외 자체의 `Message` 속성에서 가져옵니다.

**Example JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Warning",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Error executing query",
    "errorType": "System.Data.SqlClient.SqlException",
    "errorMessage": "Connection closed",
    "stackTrace": ["<call exception.StackTrace>"]
}
```

함수의 로깅 형식이 JSON으로 설정된 경우 Lambda는 코드에서 발견되지 않은 예외가 발생할 때 JSON 형식의 로그 메시지도 출력합니다. 다음 코드 스니펫 및 로그 메시지 예제에서는 발견되지 않은 예외가 로깅되는 방법을 보여줍니다.

**Example 예외 코드**  

```
throw new ApplicationException("Invalid data");
```

**Example JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Error",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Invalid data",
    "errorType": "System.ApplicationException",
    "errorMessage": "Invalid data",
    "stackTrace": ["<call exception.StackTrace>"]
}
```

#### 고객이 제공하는 로그 파라미터
<a name="csharp-logging-advanced-JSON-user-supplied"></a>

JSON 형식의 로그 메시지를 사용하면 추가 로그 파라미터를 제공하고 이를 `message` 로그에 포함할 수 있습니다. 다음 코드 스니펫 예제에서는 `retryAttempt` 및 `uri` 레이블이 지정된 두 개의 사용자 제공 파라미터를 추가하는 명령을 보여줍니다. 예제에서 이러한 파라미터의 값은 로깅 명령으로 전달된 `retryAttempt` 및 `uriDestination` 인수에서 가져옵니다.

**Example 추가 파라미터를 사용하는 JSON 로깅 명령**  

```
context.Logger.LogInformation("Starting retry {retryAttempt} to make GET request to {uri}", retryAttempt, uriDestination);
```

이 명령에서 생성된 로그 메시지 출력은 다음 예제 JSON에 나와 있습니다.

**Example JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Starting retry 1 to make GET request to http://example.com/",
    "retryAttempt": 1,
    "uri": "http://example.com/"
}
```

**작은 정보**  
추가 파라미터를 지정할 때 이름 대신 위치 속성을 사용할 수도 있습니다. 예를 들어 이전 예제의 로깅 명령을 다음과 같이 쓸 수도 있습니다.  

```
context.Logger.LogInformation("Starting retry {0} to make GET request to {1}", retryAttempt, uriDestination);
```

추가 로깅 파라미터를 제공하면 Lambda는 이를 JSON 로그 레코드에서 최상위 속성으로 캡처합니다. 이 접근 방식은 별도의 하위 객체에서 추가 파라미터를 캡처하는 `Serilog`와 같은 일부 널리 사용되는 .NET 로깅 라이브러리와 다릅니다.

추가 파라미터에 대해 제공하는 인수가 복잡한 객체인 경우 기본적으로 Lambda는 `ToString()` 메서드를 사용하여 값을 제공합니다. 인수에 JSON 직렬화를 적용해야 함을 나타내려면 다음 코드 스니펫에 표시된 대로 `@` 접두사를 사용합니다. 이 예제에서 `User`는 `FirstName` 및 `LastName` 속성을 포함하는 객체입니다.

**Example JSON 직렬화가 적용된 객체를 포함하는 JSON 로깅 명령**  

```
context.Logger.LogInformation("User {@user} logged in", User);
```

이 명령에서 생성된 로그 메시지 출력은 다음 예제 JSON에 나와 있습니다.

**Example JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "User {@user} logged in",
    "user": 
    {
        "FirstName": "John",
        "LastName": "Doe"
    }
}
```

추가 파라미터에 대한 인수가 배열이거나 `IList` 또는 `IDictionary`를 구현하는 경우 Lambda는 다음 JSON 로그 레코드 예제와 같이 인수를 JSON 로그 메시지에 배열로 추가합니다. 이 예제에서 `{users}`는 이전 예제와 동일한 형식의 `User` 속성 인스턴스를 포함하는 `IList` 인수를 가져옵니다. Lambda는 이 `IList`를 배열로 변환하며, 이때 각 값은 `ToString` 메서드를 사용하여 생성됩니다.

**Example `IList` 인수를 포함하는 JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "{users} have joined the group",
    "users": 
    [
        "Rosalez, Alejandro",
        "Stiles, John"       
    ] 
}
```

로깅 명령에서 `@` 접두사를 사용하여 목록에 JSON 직렬화를 적용할 수도 있습니다. 다음 JSON 로그 레코드 예제에서는 `users` 속성에 JSON 직렬화가 적용되었습니다.

**Example JSON 직렬화가 적용된된 `IList` 인수를 포함하는 JSON 로그 레코드**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "{@users} have joined the group",
    "users": 
    [
        {
            "FirstName": "Alejandro",
            "LastName": "Rosalez"
        },
        {
            "FirstName": "John",
            "LastName": "Stiles"
        }        
    ] 
}
```

### .NET에서 로그 수준 필터링 사용
<a name="csharp-logging-advanced-levels"></a>

로그 수준 필터링을 구성하면 특정 상세 수준 이하의 로그만 CloudWatch Logs로 전송하도록 선택할 수 있습니다. 함수의 로그 수준 필터링을 구성하는 방법을 알아보려면 [로그 수준 필터링](monitoring-cloudwatchlogs-log-level.md)을 참조하세요.

AWS Lambda에서 로그 메시지를 로그 수준별로 필터링하려면 JSON 형식의 로그를 사용하거나 .NET `Console` 메서드를 사용하여 로그 메시지를 출력할 수 있습니다. JSON 형식의 로그를 생성하려면 [함수의 로그 유형을 JSON으로 구성](monitoring-cloudwatchlogs-logformat.md#monitoring-cloudwatchlogs-set-format)하고 `ILambdaLogger` 인스턴스를 사용합니다.

JSON 형식의 로그를 사용하여 Lambda는 [.NET에서 구조화된 JSON 로그 형식 사용](#csharp-logging-advanced-JSON)에서 설명하는 JSON 객체의 'level' 키 값 페어를 사용하여 로그 출력을 필터링합니다.

.NET `Console` 메서드를 사용하여 CloudWatch Logs에 메시지를 쓰는 경우 Lambda는 다음과 같이 메시지에 로그 수준을 적용합니다.
+ **Console.WriteLine 메서드** - Lambda에서 `INFO`의 로그 수준을 적용함
+ **Console.Error 메서드** - Lambda에서 `ERROR`의 로그 수준을 적용함

로그 수준 필터링을 사용하도록 함수를 구성하는 경우 Lambda가 CloudWatch 로그로 전송하기를 원하는 로그 수준을 다음 옵션 중에서 선택해야 합니다. .NET `ILambdaLogger`에서 사용하는 표준 Microsoft 수준에 대한 Lambda에서 사용하는 로그 수준의 매핑을 기록합니다.


| Lambda 로그 수준 | 동등한 Microsoft 수준 | 표준 사용량 | 
| --- | --- | --- | 
| TRACE(최대 세부 정보) | 추적 | 코드 실행 경로를 추적하는 데 사용되는 가장 세밀한 정보 | 
| DEBUG | 디버그 | 시스템 디버깅에 대한 세부 정보 | 
| INFO | 정보 | 함수의 정상 작동을 기록하는 메시지 | 
| WARN | 경고 | 해결되지 않을 경우 예상치 못한 동작으로 이어질 수 있는 잠재적 오류에 대한 메시지 | 
| 오류 | 오류 | 코드가 예상대로 작동하지 못하게 하는 문제에 대한 메시지 | 
| FATAL(최소 세부 정보) | 심각 | 응용 프로그램 작동을 중지시키는 심각한 오류에 대한 메시지 | 

Lambda는 선택한 상세 수준 이하의 로그만 Cloudwatch로 전송합니다. 예를 들어 로그 수준을 WARN으로 구성하면 Lambda는 WARN, ERROR 및 FATAL에 해당하는 로그를 전송합니다.

## 추가 로깅 도구 및 라이브러리
<a name="csharp-tools-libraries"></a>

[Powertools for AWS Lambda(.NET)](https://docs.aws.amazon.com/powertools/dotnet/)는 서버리스 모범 사례를 구현하고 개발자 속도를 높이기 위한 개발자 도구 키트입니다. [Logging 유틸리티](https://docs.aws.amazon.com/powertools/dotnet/core/logging/)는 JSON으로 구조화된 출력과 함께 모든 함수의 함수 컨텍스트에 대한 추가 정보를 포함하는 Lambda 최적화 로거를 제공합니다. 이 유틸리티를 사용하여 다음을 수행합니다.
+ Lambda 컨텍스트, 콜드 스타트 및 구조 로깅 출력에서 JSON으로 주요 필드 캡처
+ 지시 시 Lambda 호출 이벤트 로깅(기본적으로 비활성화됨)
+ 로그 샘플링을 통해 호출 비율에 대해서만 모든 로그 인쇄(기본적으로 비활성화됨)
+ 언제든지 구조화된 로그에 추가 키 추가
+ 사용자 지정 로그 포맷터(Bring Your Own Formatter)를 사용하여 조직의 로깅 RFC와 호환되는 구조로 로그 출력

## 구조화된 로깅에 Powertools forAWS Lambda(.NET) 및 AWS SAM 사용
<a name="dotnet-logging-sam"></a>

다음 단계를 따라 AWS SAM을 사용하는 통합 [Powertools for AWS Lambda(.NET)](https://docs.powertools.aws.dev/lambda-dotnet) 모듈을 사용하여 샘플 Hello World C\$1 애플리케이션을 다운로드, 빌드 및 배포합니다. 이 애플리케이션은 기본 API 백엔드를 구현하고 Powertools를 사용하여 로그, 지표 및 추적을 내보냅니다. 이 구성에는 Amazon API Gateway 엔드포인트와 Lambda 함수가 포함됩니다. API Gateway 엔드포인트로 GET 요청을 전송하면 Lambda 함수가 간접 호출되고 Embedded Metric Format을 사용하여 로그 및 지표를 CloudWatch로 전송하고 기록을 AWS X-Ray로 전송합니다. 이 함수는 `hello world` 메시지를 반환합니다.

**사전 조건**

이 섹션의 단계를 완료하려면 다음이 필요합니다.
+ .NET 8
+ [AWS CLI 버전 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI 버전 1.75 이상](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). 이전 버전의 AWS SAM CLI가 있는 경우 [AWS SAM CLI 업그레이드](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade)를 참조하세요.

**샘플 AWS SAM 애플리케이션 배포**

1. Hello World TypeScript 템플릿을 사용하여 애플리케이션을 초기화합니다.

   ```
   sam init --app-template hello-world-powertools-dotnet --name sam-app --package-type Zip --runtime dotnet6 --no-tracing
   ```

1. 앱을 빌드합니다.

   ```
   cd sam-app && sam build
   ```

1. 앱을 배포합니다.

   ```
   sam deploy --guided
   ```

1. 화면에 표시되는 프롬프트를 따릅니다. 대화형 환경에서 제공되는 기본 옵션을 수락하려면 `Enter`을 누릅니다.
**참고**  
**HelloWorldFunction에 권한 부여가 정의되어 있지 않을 수 있습니다. 괜찮습니다?**에 대해 `y`를 입력합니다.

1. 배포된 애플리케이션의 URL을 가져옵니다.

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. API 엔드포인트 간접 호출:

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   성공하면 다음과 같은 결과가 응답됩니다.

   ```
   {"message":"hello world"}
   ```

1. 함수에 대한 로그를 가져오려면 [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html)를 실행합니다. 자세한 내용은 *AWS Serverless Application Model 개발자 안내서*에서 [로그 관련 작업](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html)을 참조하세요.

   ```
   sam logs --stack-name sam-app
   ```

   출력은 다음과 같습니다.

   ```
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:27.988000 INIT_START Runtime Version: dotnet:6.v13        Runtime Version ARN: arn:aws:lambda:ap-southeast-2::runtime:699f346a05dae24c58c45790bc4089f252bf17dae3997e79b17d939a288aa1ec
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:28.229000 START RequestId: bed25b38-d012-42e7-ba28-f272535fb80e Version: $LATEST
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:29.259000 2025-09-20T14:15:29.201Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"_aws":{"Timestamp":1676902528962,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ColdStart","Unit":"Count"}],"Dimensions":[["FunctionName"],["Service"]]}]},"FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","Service":"PowertoolsHelloWorld","ColdStart":1}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.479000 2025-09-20T14:15:30.479Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"ColdStart":true,"XrayTraceId":"1-63f3807f-5dbcb9910c96f50742707542","CorrelationId":"d3d4de7f-4ccc-411a-a549-4d67b2fdc015","FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","FunctionVersion":"$LATEST","FunctionMemorySize":256,"FunctionArn":"arn:aws:lambda:ap-southeast-2:123456789012:function:sam-app-HelloWorldFunction-haKIoVeose2p","FunctionRequestId":"bed25b38-d012-42e7-ba28-f272535fb80e","Timestamp":"2025-09-20T14:15:30.4602970Z","Level":"Information","Service":"PowertoolsHelloWorld","Name":"AWS.Lambda.Powertools.Logging.Logger","Message":"Hello world API - HTTP 200"}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.599000 2025-09-20T14:15:30.599Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"_aws":{"Timestamp":1676902528922,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ApiRequestCount","Unit":"Count"}],"Dimensions":[["Service"]]}]},"Service":"PowertoolsHelloWorld","ApiRequestCount":1}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.680000 END RequestId: bed25b38-d012-42e7-ba28-f272535fb80e
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.680000 REPORT RequestId: bed25b38-d012-42e7-ba28-f272535fb80e  Duration: 2450.99 ms   Billed Duration: 2692 ms Memory Size: 256 MB     Max Memory Used: 74 MB  Init Duration: 240.05 ms
   XRAY TraceId: 1-63f3807f-5dbcb9910c96f50742707542       SegmentId: 16b362cd5f52cba0
   ```

1. 이는 인터넷을 통해 액세스할 수 있는 퍼블릭 API 엔드포인트입니다. 테스트 후에는 엔드포인트를 삭제하는 것이 좋습니다.

   ```
   sam delete
   ```

### 로그 보존 관리
<a name="csharp-log-retention"></a>

함수를 삭제해도 로그 그룹이 자동으로 삭제되지 않습니다. 로그를 무기한 저장하지 않으려면 로그 그룹을 삭제하거나 경과 후 CloudWatch가 로그를 자동으로 삭제하는 보존 기간을 구성하세요. 로그 보존을 설정하려면 AWS SAM 템플릿에 다음을 추가합니다.

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}"
      RetentionInDays: 7
```

## Lambda 콘솔에서 로그 보기
<a name="csharp-logging-console"></a>

Lambda 함수를 간접 호출한 후 Lambda 콘솔을 사용하여 로그 출력을 볼 수 있습니다.

포함된 **코드** 편집기에서 코드를 테스트할 수 있는 경우 **실행 결과**에서 로그를 찾을 수 있습니다. 콘솔 테스트 기능을 사용하여 함수를 간접적으로 간접 호출하면 **세부 정보** 섹션에서 **로그 출력**을 찾을 수 있습니다.

## CloudWatch 콘솔에서 로그 보기
<a name="csharp-logging-cwconsole"></a>

Amazon CloudWatch 콘솔을 사용하여 모든 Lambda 함수 호출에 대한 로그를 볼 수 있습니다.

**CloudWatch 콘솔에서 로그를 보려면**

1. CloudWatch 콘솔에서 [로그 그룹 페이지](https://console.aws.amazon.com/cloudwatch/home?#logs:)를 엽니다.

1. 함수(**/aws/lambda/*your-function-name***)에 대한 로그 그룹을 선택합니다.

1. 로그 스트림을 선택합니다.

각 로그 스트림은 [함수의 인스턴스](lambda-runtime-environment.md)에 해당합니다. 로그 스트림은 Lambda 함수를 업데이트할 때, 그리고 동시 호출을 처리하기 위해 추가 인스턴스가 생성될 때 나타납니다. 특정 호출에 대한 로그를 찾으려면 AWS X-Ray로 함수를 계측하는 것이 좋습니다. X-Ray는 요청 및 로그 스트림에 대한 세부 정보를 기록합니다.

## AWS Command Line Interface(AWS CLI)(을)를 사용하여 로그 보기
<a name="csharp-logging-cli"></a>

AWS CLI은(는) 명령줄 셸의 명령을 사용하여 AWS 서비스와 상호 작용할 수 있는 오픈 소스 도구입니다. 이 섹션의 단계를 완료하려면 [AWS CLI 버전 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)가 필요합니다.

[AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)를 사용하면 `--log-type` 명령 옵션을 통해 호출에 대한 로그를 검색할 수 있습니다. 호출에서 base64로 인코딩된 로그를 최대 4KB까지 포함하는 `LogResult` 필드가 응답에 포함됩니다.

**Example 로그 ID 검색**  
다음 예제에서는 `LogResult`이라는 함수의 `my-function` 필드에서 *로그 ID*를 검색하는 방법을 보여줍니다.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
다음 결과가 표시됩니다:  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example decode the logs**  
동일한 명령 프롬프트에서 `base64` 유틸리티를 사용하여 로그를 디코딩합니다. 다음 예제에서는 `my-function`에 대한 base64로 인코딩된 로그를 검색하는 방법을 보여줍니다.  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
**cli-binary-format** 옵션은 AWS CLI 버전 2를 사용할 때 필요합니다. 이 설정을 기본 설정으로 지정하려면 `aws configure set cli-binary-format raw-in-base64-out`을(를) 실행하세요. 자세한 내용은 *AWS Command Line Interface 사용 설명서 버전 2*에서 [AWS CLI 지원 글로벌 명령줄 옵션](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)을 참조하세요.  
다음 결과가 표시됩니다.  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
`base64` 유틸리티는 Linux, macOS 및 [Ubuntu on Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10)에서 사용할 수 있습니다. macOS 사용자는 `base64 -D`를 사용해야 할 수도 있습니다.

**Example get-logs.sh 스크립트**  
동일한 명령 프롬프트에서 다음 스크립트를 사용하여 마지막 5개 로그 이벤트를 다운로드합니다. 이 스크립트는 `sed`를 사용하여 출력 파일에서 따옴표를 제거하고, 로그를 사용할 수 있는 시간을 허용하기 위해 15초 동안 대기합니다. 출력에는 Lambda의 응답과 `get-log-events` 명령의 출력이 포함됩니다.  
다음 코드 샘플의 내용을 복사하고 Lambda 프로젝트 디렉터리에 `get-logs.sh`로 저장합니다.  
**cli-binary-format** 옵션은 AWS CLI 버전 2를 사용할 때 필요합니다. 이 설정을 기본 설정으로 지정하려면 `aws configure set cli-binary-format raw-in-base64-out`을(를) 실행하세요. 자세한 내용은 *AWS Command Line Interface 사용 설명서 버전 2*에서 [AWS CLI 지원 글로벌 명령줄 옵션](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)을 참조하세요.  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example macOS 및 Linux(전용)**  
동일한 명령 프롬프트에서 macOS 및 Linux 사용자는 스크립트가 실행 가능한지 확인하기 위해 다음 명령을 실행해야 할 수 있습니다.  

```
chmod -R 755 get-logs.sh
```

**Example 마지막 5개 로그 이벤트 검색**  
동일한 명령 프롬프트에서 다음 스크립트를 실행하여 마지막 5개 로그 이벤트를 가져옵니다.  

```
./get-logs.sh
```
다음 결과가 표시됩니다:  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## 로그 삭제
<a name="csharp-logging-delete"></a>

함수를 삭제해도 로그 그룹이 자동으로 삭제되지 않습니다. 로그를 무기한 저장하지 않으려면 로그 그룹을 삭제하거나 로그가 자동으로 삭제되는 [보존 기간을 구성](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)하세요.