Lambda Logs API 사용하기

Lambda Logs API 사용하기

중요 Lambda Telemetry API가 Lambda Logs API를 대체해요. Logs API는 완전히 작동하지만 앞으로는 Telemetry API만 사용할 것을 권장합니다. Telemetry API 또는 Logs API 중 하나를 사용해서 확장 프로그램을 텔레메트리 스트림에 구독시킬 수 있어요. 이 API 중 하나를 사용해 구독한 후 다른 API를 사용해 구독하려고 하면 오류가 반환돼요.

Lambda Managed Instances는 Logs API를 지원하지 않음 Lambda Managed Instances는 Logs API를 지원하지 않아요. Managed Instance 함수를 사용 중이라면 대신 Telemetry API를 사용하세요. Telemetry API는 Lambda 함수에서 텔레메트리 데이터를 수집·처리하는 향상된 기능을 제공해요.

Lambda는 런타임 로그를 자동으로 캡처해서 Amazon CloudWatch로 스트리밍해요. 이 로그 스트림에는 함수 코드와 확장 프로그램이 생성하는 로그와 Lambda가 함수 호출의 일부로 생성하는 로그가 포함돼요.

Lambda 확장 프로그램은 Lambda Runtime Logs API를 사용해서 Lambda 실행 환경 내부에서 직접 로그 스트림을 구독할 수 있어요. Lambda는 확장 프로그램에 로그를 스트리밍하고, 확장 프로그램은 로그를 처리·필터링해서 선호하는 대상으로 보낼 수 있어요.

Logs API를 사용하면 확장 프로그램이 세 가지 서로 다른 로그 스트림을 구독할 수 있어요:

  • Lambda 함수가 생성해서 stdout 또는 stderr에 쓰는 함수 로그
  • 확장 프로그램 코드가 생성하는 확장 프로그램 로그
  • 호출 및 확장 프로그램과 관련된 이벤트·오류를 기록하는 Lambda 플랫폼 로그

참고 확장 프로그램이 하나 이상의 로그 스트림을 구독하더라도 Lambda는 모든 로그를 CloudWatch로 보내요.

주제

출처: AWS Lambda 개발자 안내서

본문

로그 수신 구독

Lambda 확장 프로그램은 Logs API에 구독 요청을 보내 로그 수신을 구독할 수 있어요.

로그 수신을 구독하려면 확장 프로그램 식별자(Lambda-Extension-Identifier)가 필요해요. 먼저 확장 프로그램 식별자를 받으려면 확장 프로그램을 등록하세요. 그런 다음 초기화 중에 Logs API를 구독하세요. 초기화 단계가 완료되면 Lambda는 구독 요청을 처리하지 않아요.

참고 Logs API 구독은 멱등적이에요. 중복된 구독 요청으로 인해 중복 구독이 발생하지 않아요.

메모리 사용

구독자 수가 증가함에 따라 메모리 사용량이 선형적으로 증가해요. 각 구독은 로그를 저장할 새 메모리 버퍼를 열기 때문에 구독이 메모리 리소스를 소비해요. 메모리 사용을 최적화하려면 버퍼링 구성을 조정할 수 있어요. 버퍼 메모리 사용량은 실행 환경의 전체 메모리 소비에 포함돼요.

대상 프로토콜

로그를 수신하기 위해 다음 프로토콜 중 하나를 선택할 수 있어요:

  1. HTTP(권장) – Lambda가 로컬 HTTP 엔드포인트(http://sandbox.localdomain:${PORT}/${PATH})에 JSON 형식의 레코드 배열로 로그를 전달해요. $PATH 매개변수는 선택 사항이에요. HTTPS가 아닌 HTTP만 지원된다는 점에 유의하세요. PUT 또는 POST를 통해 로그를 수신하도록 선택할 수 있어요.

  2. TCP – Lambda가 Newline delimited JSON(NDJSON) 형식으로 TCP 포트에 로그를 전달해요.

TCP보다는 HTTP를 사용하는 것을 권장해요. TCP를 사용하면 Lambda 플랫폼이 언제 로그를 애플리케이션 계층에 전달하는지 확인할 수 없어요. 따라서 확장 프로그램이 충돌하면 로그를 잃을 수 있어요. HTTP에는 이러한 제한이 없어요.

또한 로그 수신 구독 전에 로컬 HTTP 리스너나 TCP 포트를 설정하는 것을 권장해요. 설정 중 다음 사항에 유의하세요:

  • Lambda는 실행 환경 내부의 대상에만 로그를 보내요.
  • 리스너가 없거나 POST 또는 PUT 요청이 오류를 일으키면 Lambda가(백오프와 함께) 로그 전송을 재시도해요. 로그 구독자가 충돌하면 Lambda가 실행 환경을 재시작한 후에도 계속 로그를 수신해요.
  • Lambda는 포트 9001을 예약해요. 다른 포트 번호 제한이나 권장 사항은 없어요.

버퍼링 구성

Lambda는 로그를 버퍼링해서 구독자에게 전달할 수 있어요. 구독 요청에서 다음 선택적 필드를 지정해 이 동작을 구성할 수 있어요. 지정하지 않은 필드에는 Lambda가 기본값을 사용해요.

  • timeoutMs – 한 배치를 버퍼링할 최대 시간(밀리초)입니다. 기본값: 1,000. 최소: 25. 최대: 30,000.
  • maxBytes – 메모리에 버퍼링할 로그의 최대 크기(바이트)입니다. 기본값: 262,144. 최소: 262,144. 최대: 1,048,576.
  • maxItems – 메모리에 버퍼링할 최대 이벤트 수입니다. 기본값: 10,000. 최소: 1,000. 최대: 10,000.

버퍼링 구성 중 다음 사항에 유의하세요:

  • 입력 스트림 중 하나가 닫히면(예: 런타임 충돌) Lambda가 로그를 플러시해요.

  • 각 구독자는 구독 요청에서 서로 다른 버퍼링 구성을 지정할 수 있어요.

  • 데이터를 읽는 데 필요한 버퍼 크기를 고려하세요. maxBytes가 구독 요청에 구성된 값일 때 2*maxBytes+metadata만큼 큰 페이로드를 받을 것으로 예상하세요. 예를 들어 Lambda는 각 레코드에 다음 메타데이터 바이트를 추가해요:

    {
    "time": "2020-08-20T12:31:32.123Z",
    "type": "function",
    "record": "Hello World"
    }
    
  • 구독자가 들어오는 로그를 충분히 빠르게 처리하지 못하면 Lambda는 메모리 사용량을 제한하기 위해 로그를 버릴 수 있어요. 버려진 레코드 수를 나타내기 위해 Lambda는 platform.logsDropped 로그를 보내요. 자세한 내용은 Lambda: 함수 로그가 모두 표시되지 않음을 참고하세요.

구독 예시

다음 예시는 플랫폼 및 함수 로그를 구독하는 요청을 보여줘요.

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 샘플 코드

로그를 사용자 지정 대상으로 보내는 방법을 보여주는 샘플 코드는 AWS Compute Blog의 AWS Lambda 확장 프로그램을 사용해 사용자 지정 대상으로 로그 보내기를 참고하세요.

기본 Lambda 확장 프로그램을 개발하고 Logs API를 구독하는 방법을 보여주는 Python 및 Go 코드 예시는 AWS Samples GitHub 저장소의 AWS Lambda Extensions를 참고하세요. Lambda 확장 프로그램 빌드에 대한 자세한 내용은 Lambda Extensions API를 사용해 확장 프로그램 만들기를 참고하세요.

Logs API 참조

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

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

Logs API 버전 2020-08-15의 OpenAPI 사양은 여기에서 확인할 수 있어요: logs-api-request.zip

구독

Lambda 실행 환경에서 사용 가능한 로그 스트림 중 하나 이상을 구독하기 위해 확장 프로그램은 Subscribe API 요청을 보내요.

경로 – /logs

메서드 – PUT

본문 매개변수

destination – 대상 프로토콜을 참고하세요. 필수: 예. 유형: 문자열.

buffering – 버퍼링 구성을 참고하세요. 필수: 아니요. 유형: 문자열.

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

schemaVersion – 필수: 아니요. 기본값: "2020-08-15". 확장 프로그램이 platform.runtimeDone 메시지를 받으려면 "2021-03-18"로 설정하세요.

응답 매개변수

버전 2020-08-15 구독 응답의 OpenAPI 사양은 HTTP 및 TCP 프로토콜 모두 제공되요:

응답 코드

  • 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"
}

로그 메시지

Logs API를 사용하면 확장 프로그램이 세 가지 서로 다른 로그 스트림을 구독할 수 있어요:

  • 함수(Function) – Lambda 함수가 생성해서 stdout 또는 stderr에 쓰는 로그
  • 확장 프로그램(Extension) – 확장 프로그램 코드가 생성하는 로그
  • 플랫폼(Platform) – 런타임 플랫폼이 생성하며 호출 및 확장 프로그램과 관련된 이벤트·오류를 기록하는 로그

주제

함수 로그

Lambda 함수와 내부 확장 프로그램은 함수 로그를 생성해서 stdout 또는 stderr에 써요.

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

확장 프로그램 로그

확장 프로그램은 확장 프로그램 로그를 생성할 수 있어요. 로그 형식은 함수 로그와 동일해요.

플랫폼 로그

Lambda는 platform.start, platform.end, platform.fault 같은 플랫폼 이벤트에 대한 로그 메시지를 생성해요.

선택적으로 platform.runtimeDone 로그 메시지를 포함하는 Logs API 스키마 2021-03-18 버전을 구독할 수 있어요.

플랫폼 로그 메시지 예시

다음 예시는 플랫폼 시작 및 플랫폼 종료 로그를 보여줘요. 이 로그는 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 수명주기 단계의 일부인 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 리전의 모든 함수가 새 형식의 로그 메시지와 트레이스 세그먼트로 전환될 거예요.

예시 플랫폼 결함 로그 레코드(이전 스타일)

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

예시 플랫폼 결함 로그 레코드(새 스타일)

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

확장 프로그램이 확장 API에 등록하면 Lambda가 플랫폼 확장 프로그램 로그를 생성해요. 다음 예시는 플랫폼 확장 프로그램 메시지를 보여줘요.

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

확장 프로그램이 로그 API를 구독하면 Lambda가 플랫폼 로그 구독 로그를 생성해요. 다음 예시는 로그 구독 메시지를 보여줘요.

{
    "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 메시지

구독 요청에서 스키마 버전을 "2021-03-18"로 설정하면 Lambda가 함수 호출이 성공 또는 오류로 완료된 후 platform.runtimeDone 메시지를 보내요. 확장 프로그램은 이 메시지를 사용해서 이 함수 호출에 대한 모든 텔레메트리 수집을 중지할 수 있어요.

스키마 버전 2021-03-18의 로그 이벤트 유형에 대한 OpenAPI 사양은 여기에서 확인할 수 있어요: schema-2021-03-18.zip

Lambda는 런타임이 Next 또는 Error 런타임 API 요청을 보낼 때 platform.runtimeDone 로그 메시지를 생성해요. platform.runtimeDone 로그는 함수 호출이 완료되었음을 Logs API 소비자에게 알려줘요. 확장 프로그램은 이 정보를 사용해서 해당 호출 중 수집된 모든 텔레메트리를 언제 보낼지 결정할 수 있어요.

예시

함수 호출이 완료되면 런타임이 NEXT 요청을 보낸 후 Lambda가 platform.runtimeDone 메시지를 보내요. 다음 예시는 성공, 실패, 시간 초과의 각 상태 값에 대한 메시지를 보여줘요.

예시 성공 메시지

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

예시 실패 메시지

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

예시 시간 초과 메시지

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

예시 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"
  }
}

더 알아보기 (Learn more)

이 주제는 Lambda Logs API를 사용해 로그 스트림을 구독하는 방법을 설명해요. 확장 프로그램과 텔레메트리 수집에 대한 자세한 내용은 Lambda 개발자 안내서의 Telemetry API 및 Extensions API 관련 주제를 참고하세요.