

# Lambda 로그 API 사용
<a name="runtimes-logs-api"></a>

**중요**  
Lambda Telemetry API는 Lambda 로그 API를 대체합니다. **로그 API도 계속 정상적으로 작동하지만, 앞으로는 텔레메트리 API만 사용하는 것이 좋습니다.** 텔레메트리 API 또는 로그 API를 사용하여 확장에서 텔레메트리 스트림을 구독할 수 있습니다. 이러한 API 중 하나를 사용하여 구독한 후 다른 API를 사용하여 구독하려고 하면 오류가 반환됩니다.

**Lambda 관리형 인스턴스는 Logs API를 지원하지 않습니다.**  
Lambda 관리형 인스턴스는 Logs API를 지원하지 않습니다. 관리형 인스턴스 함수를 사용하는 경우 대신 [텔레메트리 API](telemetry-api.md)를 사용합니다. 텔레메트리 API는 Lambda 함수에서 텔레메트리 데이터를 수집하고 처리할 수 있도록 향상된 기능을 제공합니다.

Lambda는 런타임 로그를 자동으로 캡처하고 Amazon CloudWatch에 스트리밍합니다. 이 로그 스트림에는 함수 코드 및 익스텐션이 생성하는 로그와 함수 호출의 일부로 Lambda가 생성하는 로그가 포함됩니다.

[Lambda 익스텐션](runtimes-extensions-api.md)은 Lambda Runtime Logs API를 사용하여 Lambda [실행 환경](lambda-runtime-environment.md) 내에서 로그 스트림을 구독할 수 있습니다. Lambda가 로그를 익스텐션에 스트리밍하면 익스텐션은 로그를 처리하고 필터링하여 원하는 모든 대상에 전송할 수 있습니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/logs-api-concept-diagram.png)


Logs API를 사용하면 익스텐션이 세 가지 다른 로그 스트림을 구독할 수 있습니다.
+ Lambda 함수가 생성하고 `stdout` 또는 `stderr`에 쓰는 함수 로그.
+ 익스텐션 코드가 생성하는 익스텐션 로그.
+ Lambda 플랫폼 로그는 호출 및 익스텐션과 관련된 이벤트 및 오류를 기록합니다.

**참고**  
Lambda는 익스텐션이 하나 이상의 로그 스트림을 구독하는 경우에도 모든 로그를 CloudWatch로 전송합니다.

**Topics**
+ [수신 로그 구독](#runtimes-logs-api-subscribing)
+ [메모리 사용량](#runtimes-logs-api-memory)
+ [대상 프로토콜](#runtimes-logs-api-dest)
+ [버퍼링 구성](#runtimes-logs-api-buffering)
+ [구독 예](#runtimes-logs-api-subs-example)
+ [Logs API용 샘플 코드](#runtimes-logs-api-samples)
+ [Logs API 참조](#runtimes-logs-api-ref)
+ [로그 메시지](#runtimes-logs-api-msg)

## 수신 로그 구독
<a name="runtimes-logs-api-subscribing"></a>

Lambda 익스텐션은 Logs API에 구독 요청을 전송하여 수신 로그를 구독할 수 있습니다.

수신 로그를 구독하려면 익스텐션 식별자(`Lambda-Extension-Identifier`)가 필요합니다. 먼저 [익스텐션을 등록](runtimes-extensions-api.md#extensions-registration-api-a)하여 익스텐션 식별자를 수신합니다. 그런 다음 [초기화](lambda-runtime-environment.md#runtimes-lifecycle-ib)중에 Logs API를 구독합니다. 초기화 단계가 완료되면 Lambda가 구독 요청을 처리하지 않습니다.

**참고**  
Logs API 구독은 멱등성이 있습니다. 중복 구독 요청으로 인해 구독이 중복되지 않습니다.

## 메모리 사용량
<a name="runtimes-logs-api-memory"></a>

구독자 수가 증가함에 따라 메모리 사용량이 선형적으로 증가합니다. 각 구독은 새 메모리 버퍼를 열어 로그를 저장하기 때문에 메모리 리소스를 사용합니다. 메모리 사용량을 최적화하기 위해 [버퍼링 구성](#runtimes-logs-api-buffering)을 조정할 수 있습니다. 버퍼 메모리 사용량은 실행 환경의 전체 메모리 소비에 포함됩니다.

## 대상 프로토콜
<a name="runtimes-logs-api-dest"></a>

다음 프로토콜 중 하나를 선택하여 로그를 수신할 수 있습니다.

1. **HTTP**(권장) - Lambda가 로그를 로컬 HTTP 엔드포인트(`http://sandbox.localdomain:${PORT}/${PATH}`)에 JSON 형식의 레코드 배열로 전달합니다. `$PATH` 파라미터는 선택 항목입니다. HTTPS가 아닌 HTTP만 지원됩니다. PUT 또는 POST를 통해 로그를 수신하도록 선택할 수 있습니다.

1. **TCP** – Lambda가 로그를 [새 줄 구분 JSON(NDJSON) 형식](https://github.com/ndjson/ndjson-spec)으로 TCP 포트에 전달합니다.

TCP 대신 HTTP를 사용하는 것이 좋습니다. TCP를 사용하면 Lambda 플랫폼에서는 로그를 애플리케이션 계층에 전송할 때 인식할 수 없습니다. 따라서 익스텐션이 충돌하는 경우 로그가 손실될 수 있습니다. HTTP에는 이러한 제한이 없습니다.

또한 수신 로그를 구독하기 전에 로컬 HTTP 수신기 또는 TCP 포트를 설정하는 것이 좋습니다. 설치하는 동안 다음 사항에 유의하세요.
+ Lambda는 실행 환경 내에 있는 대상에만 로그를 보냅니다.
+ Lambda는 리스너가 없거나 POST 또는 PUT 요청으로 인해 오류가 발생하는 경우 로그 전송을 다시 시도합니다(백오프 포함). 로그 구독자가 충돌하면 Lambda가 실행 환경을 다시 시작한 후 로그를 계속 수신합니다.
+ Lambda는 포트 9001을 예약합니다. 다른 포트 번호 제한이나 권장 사항은 없습니다.

## 버퍼링 구성
<a name="runtimes-logs-api-buffering"></a>

Lambda는 로그를 버퍼링하여 구독자에게 전달할 수 있습니다. 다음과 같은 선택적 필드를 지정하여 구독 요청에서 이 동작을 구성할 수 있습니다. Lambda는 지정하지 않은 필드에 기본값을 사용합니다.
+ **timeoutMs** – 배치를 버퍼링할 최대 시간(밀리초)입니다. 기본값: 1,000. 최소: 25 최대값: 30,000.
+ **maxBytes** – 메모리에 버퍼링할 로그의 최대 크기(바이트)입니다. 기본값: 262,144. 최소값: 262,144. 최대값: 1,048,576.
+ **maxItems** – 메모리에 버퍼링할 최대 이벤트 수입니다. 기본값: 10,000. 최소값: 1,000. 최대값: 10,000.

버퍼링 구성 중에 다음 사항에 유의하세요.
+ Lambda는 런타임 충돌 등으로 인해 입력 스트림이 닫히면 로그를 플러시합니다.
+ 각 구독자는 구독 요청에서 다른 버퍼링 구성을 지정할 수 있습니다.
+ 데이터를 읽는 데 필요한 버퍼 크기를 고려하세요. 최대 `2*maxBytes+metadata` 크기의 페이로드를 수신할 수 있도록 준비하세요. 여기서, `maxBytes`는 구독 요청에서 구성됩니다. 예를 들어 Lambda는 각 레코드에 다음 메타데이터 바이트를 추가합니다.

  ```
  {
  "time": "2020-08-20T12:31:32.123Z",
  "type": "function",
  "record": "Hello World"
  }
  ```
+ 구독자가 들어오는 로그를 충분히 빠르게 처리할 수 없는 경우 Lambda는 메모리 사용률을 범위 내로 유지하기 위해 로그를 삭제할 수 있습니다. 삭제된 레코드의 수를 나타내기 위해 Lambda는 `platform.logsDropped` 로그를 전송합니다. 자세한 내용은 [Lambda: 일부 함수 로그가 표시되지 않음](troubleshooting-execution.md#troubleshooting-execution-missinglogs) 섹션을 참조하세요.

## 구독 예
<a name="runtimes-logs-api-subs-example"></a>

다음 예제에서는 플랫폼 및 함수 로그를 구독하는 요청을 보여줍니다.

```
PUT http://${AWS_LAMBDA_RUNTIME_API}/2020-08-15/logs HTTP/1.1
{ "schemaVersion": "2020-08-15",
  "types": [
      "platform",
      "function"
    ],
  "buffering": {
      "maxItems": 1000,
      "maxBytes": 262144,
      "timeoutMs": 100
    },
  "destination": {
    "protocol": "HTTP",
    "URI": "http://sandbox.localdomain:8080/lambda_logs"
  }
}
```

요청이 성공하면 구독자는 HTTP 200 성공 응답을 받습니다.

```
HTTP/1.1 200 OK
"OK"
```

## Logs API용 샘플 코드
<a name="runtimes-logs-api-samples"></a>

로그를 사용자 지정 대상으로 보내는 방법을 보여 주는 샘플 코드는 AWS Lambda 컴퓨팅 블로그의 [AWS 익스텐션을 사용하여 사용자 지정 대상으로 로그 전송](https://aws.amazon.com/blogs/compute/using-aws-lambda-extensions-to-send-logs-to-custom-destinations/)을 참조하세요.

기본 Lambda 익스텐션을 개발하고 Logs API를 구독하는 방법을 보여주는 Python 및 Go 코드 예제는 AWS 샘플 GitHub 리포지토리의 [AWS Lambda 익스텐션](https://github.com/aws-samples/aws-lambda-extensions)을 참조하세요. Lambda 익스텐션 빌드에 대한 자세한 내용은 [Lambda 확장 API를 사용하여 확장 생성](runtimes-extensions-api.md) 단원을 참조하세요.

## Logs API 참조
<a name="runtimes-logs-api-ref"></a>

`AWS_LAMBDA_RUNTIME_API` 환경 변수에서 Logs API 엔드포인트를 검색할 수 있습니다. API 요청을 보내려면 API 경로 앞에 `2020-08-15/` 접두사를 사용합니다. 예:

```
http://${AWS_LAMBDA_RUNTIME_API}/2020-08-15/logs
```

로그 API 버전 **2020-08-15**에 대한 OpenAPI 사양은 여기에서 사용할 수 있습니다. [logs-api-request.zip](samples/logs-api-request.zip)

### Subscribe
<a name="runtimes-logs-api-ref-a"></a>

Lambda 실행 환경에서 사용할 수 있는 하나 이상의 로그 스트림을 구독하기 위해 익스텐션이 Subscribe API 요청을 전송합니다.

**경로** – `/logs`

**메서드** – **PUT**

**본문 파라미터**

`destination` 단원을 참조하세요.[대상 프로토콜](#runtimes-logs-api-dest) 필수 항목 여부: 예. 유형: 문자열.

`buffering` 단원을 참조하세요.[버퍼링 구성](#runtimes-logs-api-buffering) 필수 항목 여부: 아니요 유형: 문자열.

`types` – 수신할 로그 유형의 배열입니다. 필수 항목 여부: 예. 유형: 문자열 배열 유효한 값: "platform", "function", "extension".

`schemaVersion` – 필수 항목 여부: 아니요 기본값: "2020-08-15". 익스텐션에서 [`platform.runtimeDone`](#runtimes-logs-api-ref-done) 메시지를 수신하려면 ‘2021-03-18’으로 설정합니다.

****응답 파라미터****

구독 응답에 대한 OpenAPI 사양(버전 **2020-08-15**)은 HTTP 및 TCP 프로토콜에 사용할 수 있습니다.
+ HTTP: [logs-api-http-response.zip](samples/logs-api-http-response.zip)
+ TCP: [logs-api-tcp-response.zip](samples/logs-api-tcp-response.zip)

****응답 코드****
+ 200 - 요청이 성공적으로 완료되었습니다.
+ 202 - 요청이 수락되었습니다. 로컬 테스트 중 구독 요청에 대한 응답입니다.
+ 4XX - 잘못된 요청
+ 500 - 서비스 오류

요청이 성공하면 구독자는 HTTP 200 성공 응답을 받습니다.

```
HTTP/1.1 200 OK
"OK"
```

요청이 실패하면 구독자는 오류 응답을 받습니다. 예:

```
HTTP/1.1 400 OK
{
    "errorType": "Logs.ValidationError",
    "errorMessage": URI port is not provided; types should not be empty"
}
```

## 로그 메시지
<a name="runtimes-logs-api-msg"></a>

Logs API를 사용하면 익스텐션이 세 가지 다른 로그 스트림을 구독할 수 있습니다.
+ Function – Lambda 함수가 생성하고 `stdout` 또는 `stderr`에 쓰는 함수 로그.
+ 익스텐션 - 익스텐션 코드가 생성하는 로그.
+ 플랫폼 - 런타임 플랫폼이 생성하는 로그로 호출 및 익스텐션과 관련된 이벤트 및 오류 기록.

**Topics**
+ [함수 로그](#runtimes-logs-api-msg-function)
+ [익스텐션 로그](#runtimes-logs-api-msg-extension)
+ [플랫폼 로그](#runtimes-logs-api-msg-platform)

### 함수 로그
<a name="runtimes-logs-api-msg-function"></a>

Lambda 함수 및 내부 익스텐션은 함수 로그를 생성하여 `stdout` 또는 `stderr`에 작성합니다.

다음 예에서는 함수 로그 메시지의 형식을 보여 줍니다.\$1 "time": "2020-08-20T12:31:32.123Z", "type": "function", "record": "ERROR encountered. Stack trace:\$1n\$1my-function (line 10)\$1n" \$1 

### 익스텐션 로그
<a name="runtimes-logs-api-msg-extension"></a>

익스텐션은 익스텐션 로그를 생성할 수 있습니다. 로그 형식은 함수 로그와 같습니다.

### 플랫폼 로그
<a name="runtimes-logs-api-msg-platform"></a>

Lambda는 `platform.start`, `platform.end`, `platform.fault`와 같은 플랫폼 이벤트에 대한 로그 메시지를 생성합니다

또는 `platform.runtimeDone` 로그 메시지를 포함하는 로그 API 스키마의 **2021-03-18** 버전을 구독할 수 있습니다.

#### 플랫폼 로그 메시지 예
<a name="runtimes-logs-api-examples"></a>

다음 예에서는 플랫폼 시작 로그와 플랫폼 종료 로그를 보여 줍니다. 이러한 로그는 requestID가 지정하는 호출에 대한 호출 시작 시간 및 호출 종료 시간을 나타냅니다.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.start",
    "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56"}   
}
{
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.end",
    "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56"}   
}
```

**platform.initRuntimeDone** 로그 메시지는 [Init 수명 주기 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib)의 일부인 `Runtime init` 하위 단계의 상태를 보여줍니다. `Runtime init`가 성공하면 런타임이 `/next` 런타임 API 요청(`on-demand` 및 `provisioned-concurrency` 초기화 유형의 경우) 또는 `restore/next`(`snap-start` 초기화 유형의 경우)를 전송합니다. 다음 예에서는 `snap-start` 초기화 유형에 대한 성공적인 **platform.initRuntimeDone** 로그 메시지를 보여줍니다.

```
{
  "time":"2022-07-17T18:41:57.083Z",
  "type":"platform.initRuntimeDone",
  "record":{
      "initializationType":"snap-start",
      "status":"success"
  }
}
```

**platform.initReport** 로그 메시지에는 `Init` 단계가 지속된 시간과 이 단계에서 청구된 시간(밀리초)이 표시됩니다. 초기화 유형이 `provisioned-concurrency`인 경우 Lambda는 호출 중에 이 메시지를 보냅니다. 초기화 유형이 `snap-start`인 경우 Lambda는 스냅샷을 복원한 후에 이 메시지를 보냅니다. 다음 예에서는 `snap-start` 초기화 유형에 대한 **platform.initReport** 로그 메시지를 보여줍니다.

```
{
  "time":"2022-07-17T18:41:57.083Z",
  "type":"platform.initReport",
  "record":{
      "initializationType":"snap-start",
      "metrics":{
          "durationMs":731.79,
          "billedDurationMs":732
          }
  }
}
```

플랫폼 보고서 로그에는 requestId가 지정하는 호출에 대한 지표가 포함됩니다. 이 `initDurationMs` 필드는 호출에 콜드 스타트가 포함된 경우에만 로그에 포함됩니다. AWS X-Ray 추적이 활성 상태인 경우 로그에 X-Ray 메타데이터가 포함됩니다. 다음 예에서는 콜드 스타트를 포함한 호출에 대한 플랫폼 보고서 로그를 보여 줍니다.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.report",
    "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56",
        "metrics": {"durationMs": 101.51,
            "billedDurationMs": 300,
            "memorySizeMB": 512,
            "maxMemoryUsedMB": 33,
            "initDurationMs": 116.67
        }
    }
}
```

플랫폼 오류 로그는 런타임 또는 실행 환경 오류를 캡처합니다. 다음 예제에서는 플랫폼 장애 로그 메시지를 보여줍니다.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.fault",
    "record": "RequestId: d783b35e-a91d-4251-af17-035953428a2c Process exited before completing request"
}
```

**참고**  
AWS는 현재 Lambda 서비스에 대한 변경 사항을 구현하고 있습니다. 이러한 변경으로 인해, AWS 계정의 여러 Lambda 함수에서 내보내는 시스템 로그 메시지와 추적 세그먼트의 구조와 내용 간에 약간의 차이가 있을 수 있습니다.  
이 변경의 영향을 받는 로그 출력 중 하나는 플랫폼 장애 로그 `"record"` 필드입니다. 다음 예는 이전 형식과 새 형식의 `"record"` 필드를 보여줍니다. 새 스타일의 장애 로그에는 더 간결한 메시지가 포함됩니다.  
이러한 변경 사항은 앞으로 몇 주 동안 구현되며, 중국 및 GovCloud 리전을 제외한 모든 AWS 리전의 모든 기능은 새로운 형식의 로그 메시지 및 추적 세그먼트를 사용하도록 전환됩니다.



**Example 플랫폼 장애 로그 레코드(이전 스타일)**  

```
"record":"RequestId: ...\tError: Runtime exited with error: exit status 255\nRuntime.ExitError"
```

**Example 플랫폼 장애 로그 레코드(새 스타일)**  

```
"record":"RequestId: ... Status: error\tErrorType: Runtime.ExitError"
```

Lambda는 익스텐션이 익스텐션 API에 등록할 때 플랫폼 익스텐션 로그를 생성합니다. 다음 예에서는 플랫폼 익스텐션 메시지를 보여줍니다.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.extension",
    "record": {"name": "Foo.bar",
        "state": "Ready",
        "events": ["INVOKE", "SHUTDOWN"]
     }
}
```

Lambda는 익스텐션이 로그 API를 구독할 때 플랫폼 로그 구독 로그를 생성합니다. 다음 예는 로그 구독 로그 메시지를 보여줍니다.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.logsSubscription",
    "record": {"name": "Foo.bar",
        "state": "Subscribed",
        "types": ["function", "platform"],
    }
}
```

Lambda는 익스텐션이 수신 중인 로그 수를 처리할 수 없는 경우 플랫폼 로그 삭제 로그를 생성합니다. 다음 예제에서는 `platform.logsDropped` 로그 메시지를 보여줍니다.

```
{     
    "time": "2020-08-20T12:31:32.123Z",
    "type": "platform.logsDropped",
    "record": {"reason": "Consumer seems to have fallen behind as it has not acknowledged receipt of logs.",
        "droppedRecords": 123,
        "droppedBytes" 12345
    }
}
```

**platform.restoreStart** 로그 메시지에는 `Restore` 단계가 시작된 시간이 표시됩니다(`snap-start` 초기화 유형만 해당). 예제:

```
{ 
  "time":"2022-07-17T18:43:44.782Z", 
  "type":"platform.restoreStart", 
  "record":{} 
}
```

**platform.restoreReport** 로그 메시지에는 `Restore` 단계가 지속된 시간과 이 단계에서 청구된 시간(밀리초)이 표시됩니다(`snap-start` 초기화 유형만 해당). 예제:

```
{
  "time":"2022-07-17T18:43:45.936Z",
  "type":"platform.restoreReport",
  "record":{
      "metrics":{
          "durationMs":70.87,
          "billedDurationMs":13
      }
  }
}
```

#### 플랫폼 `runtimeDone` 메시지
<a name="runtimes-logs-api-ref-done"></a>

구독 요청에서 스키마 버전을 ‘2021-03-18’로 설정하면 Lambda는 함수 호출이 성공적으로 완료되거나 오류가 발생한 경우 `platform.runtimeDone` 메시지를 보냅니다. 익스텐션은 이 메시지를 사용하여 이 함수 호출에 대한 모든 원격 분석 수집을 중지할 수 있습니다.

스키마 버전 **2021-03-18**의 로그 이벤트 유형에 대한 OpenAPI 사양은 [schema-2021-03-18.zip](samples/schema-2021-03-18.zip)에서 사용할 수 있습니다.

Lambda는 런타임에서 `Next` 또는 `Error` 런타임 API 요청을 보낼 때 `platform.runtimeDone` 로그 메시지를 생성합니다. `platform.runtimeDone` 로그는 함수 호출이 완료되었음을 로그 API 사용자에게 알립니다. 익스텐션은 이 정보를 사용하여 해당 호출 중에 수집된 모든 원격 분석을 보낼 시간을 결정할 수 있습니다.

##### 예제
<a name="runtimes-logs-api-examples"></a>

Lambda는 함수 호출이 완료되면 런타임에서 NEXT 요청을 보낸 후 `platform.runtimeDone` 메시지를 전송합니다. 다음 예에서는 각 상태 값에 대한 메시지(성공, 실패 및 시간 초과)를 보여줍니다.

**Example 성공 메시지 예**  

```
{
    "time": "2021-02-04T20:00:05.123Z",
    "type": "platform.runtimeDone",
    "record": {
       "requestId":"6f7f0961f83442118a7af6fe80b88",
       "status": "success"
    }
}
```

**Example 오류 메시지 예**  

```
{
   "time": "2021-02-04T20:00:05.123Z",
   "type": "platform.runtimeDone",
   "record": {
      "requestId":"6f7f0961f83442118a7af6fe80b88",
      "status": "failure"
   }
}
```

**Example 시간 초과 메시지 예**  

```
{
   "time": "2021-02-04T20:00:05.123Z",
   "type": "platform.runtimeDone",
   "record": {
      "requestId":"6f7f0961f83442118a7af6fe80b88",
      "status": "timeout"
  }
}
```

**Example platform.restoreRuntimeDone 메시지의 예(`snap-start` 초기화 유형만 해당)**  
**platform.restoreRuntimeDone** 로그 메시지는 `Restore` 단계의 성공 여부를 표시합니다. Lambda는 런타임이 `restore/next` 런타임 API 요청을 보낼 때 이 로그 메시지를 보냅니다. 가능한 상태로는 성공, 실패 및 시간 초과가 있습니다. 다음 예는 성공적인 **platform.restoreRuntimeDone** 로그 메시지를 보여줍니다.  

```
{
  "time":"2022-07-17T18:43:45.936Z",
  "type":"platform.restoreRuntimeDone",
  "record":{
      "status":"success"
  }
}
```