텔레메트리 API를 사용하여 확장의 실시간 텔레메트리 데이터에 액세스
텔레메트리 API를 사용하면 확장에서 Lambda로부터 텔레메트리 데이터를 직접 수신할 수 있습니다. 함수 초기화 및 간접 호출 중에 Lambda는 로그, 플랫폼 지표, 플랫폼 트레이스와 같은 텔레메트리를 자동으로 캡처합니다. 텔레메트리 API를 사용하면 확장에서 Lambda로부터 거의 실시간으로 이 텔레메트리 데이터에 직접 액세스할 수 있습니다.
Lambda 실행 환경 내에서 텔레메트리 스트림에 대한 Lambda 확장을 구독할 수 있습니다. 구독 후 Lambda는 모든 텔레메트리 데이터를 확장으로 자동 전송합니다. 그런 다음 유연하게 데이터를 처리 및 필터링하고 Amazon Simple Storage Service(S3) 버킷 또는 타사 관찰성 도구 제공업체와 같은 원하는 대상으로 전송할 수 있습니다.
다음 다이어그램은 확장 API와 텔레메트리 API가 실행 환경 내에서 확장을 Lambda에 연결하는 방법을 보여줍니다. 또한 런타임 API는 런타임 및 함수를 Lambda에 연결합니다.
중요
Lambda 텔레메트리 API는 Lambda 로그 API를 대체합니다. 로그 API도 계속 정상적으로 작동하지만, 앞으로는 텔레메트리 API만 사용하는 것이 좋습니다. 텔레메트리 API 또는 로그 API를 사용하여 확장에서 텔레메트리 스트림을 구독할 수 있습니다. 이러한 API 중 하나를 사용하여 구독한 후 다른 API를 사용하여 구독하려고 하면 오류가 반환됩니다.
확장은 텔레메트리 API를 사용하여 세 가지 텔레메트리 스트림을 구독할 수 있습니다.
-
플랫폼 텔레메트리 - 실행 환경 런타임 수명 주기, 확장 수명 주기 및 함수 호출과 관련한 이벤트와 오류를 설명하는 로그, 지표 및 트레이스입니다.
-
함수 로그 - Lambda 함수 코드가 생성하는 사용자 지정 로그입니다.
-
확장 로그 - Lambda 확장 코드가 생성하는 사용자 지정 로그입니다.
참고
확장이 텔레메트리 스트림을 구독하는 경우에도 Lambda는 CloudWatch로 로그와 지표를 전송하고 X-Ray로 트레이스를 전송합니다(추적을 활성화한 경우).
Sections
텔레메트리 API를 사용하여 확장 생성
Lambda 확장은 실행 환경에서 독립 프로세스로 실행됩니다. 함수 간접 호출이 완료된 후에도 확장을 계속 실행할 수 있습니다. 화장은 별도의 프로세스로 실행되므로 함수 코드와 다른 언어로 작성할 수 있습니다. Golang 또는 Rust와 같은 컴파일된 언어를 사용하여 확장을 작성하는 것이 좋습니다. 이 경우 확장은 지원되는 모든 런타임과 호환되는 독립형 바이너리입니다.
다음 다이어그램은 텔레메트리 API를 사용하여 텔레메트리 데이터를 수신하고 처리하는 확장을 생성하는 4단계 프로세스를 보여줍니다.
다음은 각 단계에 대한 자세한 내용입니다.
-
Lambda 확장 API를 사용하여 확장 생성를 사용하여 확장을 등록합니다. 이렇게 하면 다음 단계에서 필요한
Lambda-Extension-Identifier
가 제공됩니다. 확장을 등록하는 자세한 방법은 확장 등록 섹션을 참조하세요. -
텔레메트리 리스너를 생성합니다. 기본 HTTP 또는 TCP 서버일 수 있습니다. Lambda는 텔레메트리 리스너의 URI를 사용하여 텔레메트리 데이터를 확장에 전송합니다. 자세한 내용은 텔레메트리 리스너 생성 단원을 참조하십시오.
-
텔레메트리 API에서 구독 API를 사용하여 원하는 텔레메트리 스트림에 대한 확장을 구독합니다. 이 단계에는 텔레메트리 리스너의 URI가 필요합니다. 자세한 내용은 텔레메트리 API에 구독 요청 전송 단원을 참조하십시오.
-
텔레메트리 리스너를 통해 Lambda에서 텔레메트리 데이터를 가져옵니다. Amazon S3나 외부 관측성 서비스로 데이터를 디스패치하는 등 이 데이터에 대한 모든 사용자 지정 처리 작업을 수행할 수 있습니다.
참고
Lambda 함수의 실행 환경은 수명 주기의 일부로 여러 번 시작 및 중지할 수 있습니다. 일반적으로 확장 코드는 함수 호출 중에 실행되며 종료 단계에서도 최대 2초간 실행됩니다. 텔레메트리가 리스너에 도착하면 일괄 처리하는 것이 좋습니다. 그런 다음, Invoke
및 Shutdown
수명 주기 이벤트를 사용하여 각 배치를 원하는 대상으로 전송합니다.
확장 등록
텔레메트리 데이터를 구독하려면 먼저 Lambda 확장을 등록해야 합니다. 등록은 확장 초기화 단계에서 이루어집니다. 다음 예제에서는 확장을 등록하는 HTTP 요청을 보여줍니다.
POST http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register Lambda-Extension-Name: lambda_extension_name { 'events': [ 'INVOKE', 'SHUTDOWN'] }
요청이 성공하면 구독자는 HTTP 200 성공 응답을 받습니다. 응답 헤더에는 Lambda-Extension-Identifier
가 포함되어 있습니다. 응답 본문에는 함수의 다른 속성이 포함되어 있습니다.
HTTP/1.1 200 OK Lambda-Extension-Identifier: a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 { "functionName": "lambda_function", "functionVersion": "$LATEST", "handler": "lambda_handler", "accountId": "123456789012" }
자세한 내용은 익스텐션 API 참조을 참조하세요.
텔레메트리 리스너 생성
Lambda 확장에는 텔레메트리 API로부터 수신되는 요청을 처리하는 리스너가 있어야 합니다. 다음 코드는 Golang의 텔레메트리 리스너 구현 예제를 보여줍니다.
// Starts the server in a goroutine where the log events will be sent func (s *TelemetryApiListener) Start() (string, error) { address := listenOnAddress() l.Info("[listener:Start] Starting on address", address) s.httpServer = &http.Server{Addr: address} http.HandleFunc("/", s.http_handler) go func() { err := s.httpServer.ListenAndServe() if err != http.ErrServerClosed { l.Error("[listener:goroutine] Unexpected stop on Http Server:", err) s.Shutdown() } else { l.Info("[listener:goroutine] Http Server closed:", err) } }() return fmt.Sprintf("http://%s/", address), nil } // http_handler handles the requests coming from the Telemetry API. // Everytime Telemetry API sends log events, this function will read them from the response body // and put into a synchronous queue to be dispatched later. // Logging or printing besides the error cases below is not recommended if you have subscribed to // receive extension logs. Otherwise, logging here will cause Telemetry API to send new logs for // the printed lines which may create an infinite loop. func (s *TelemetryApiListener) http_handler(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { l.Error("[listener:http_handler] Error reading body:", err) return } // Parse and put the log messages into the queue var slice []interface{} _ = json.Unmarshal(body, &slice) for _, el := range slice { s.LogEventsQueue.Put(el) } l.Info("[listener:http_handler] logEvents received:", len(slice), " LogEventsQueue length:", s.LogEventsQueue.Len()) slice = nil }
대상 프로토콜 지정
텔레메트리를 수신하기 위해 텔레메트리 API를 사용하여 구독하는 경우, 대상 URI 외에 대상 프로토콜도 지정할 수 있습니다.
{ "destination": { "protocol": "HTTP", "URI": "http://sandbox.localdomain:8080" } }
Lambda는 텔레메트리를 수신하는 데 두 가지 프로토콜을 허용합니다.
-
HTTP(권장) – Lambda가 텔레메트리를 로컬 HTTP 엔드포인트(
http://sandbox.localdomain:${PORT}/${PATH}
)에 JSON 형식의 레코드 배열로 전달합니다.$PATH
파라미터는 선택 항목입니다. Lambda는 HTTP만 지원하고 HTTPS는 지원하지 않습니다. Lambda는 POST 요청을 통해 텔레메트리를 제공합니다. -
TCP – Lambda가 텔레메트리를 새 줄 구분 JSON(NDJSON) 형식
으로 TCP 포트에 전달합니다.
참고
TCP 대신 HTTP를 사용하는 것이 좋습니다. TCP를 사용하면 Lambda 플랫폼에서는 텔레메트리를 애플리케이션 계층에 전송할 때 인식할 수 없습니다. 따라서 확장이 작동 중지될 경우 텔레메트리가 손실될 수 있습니다. HTTP에는 이러한 제한이 없습니다.
텔레메트리 수신을 위해 구독하기 전에 로컬 HTTP 리스너 또는 TCP 포트를 설정합니다. 설치하는 동안 다음 사항에 유의하세요.
-
Lambda는 실행 환경 내에 있는 대상에만 텔레메트리를 보냅니다.
-
Lambda는 리스너가 없거나 POST 요청에서 오류가 발생하는 경우 텔레메트리 전송을 다시 시도합니다(백오프 포함). 텔레메트리 리스너에서 충돌이 발생하는 경우 Lambda가 실행 환경을 다시 시작한 후 텔레메트리를 계속 수신합니다.
-
Lambda는 포트 9001을 예약합니다. 다른 포트 번호 제한이나 권장 사항은 없습니다.
메모리 사용량 및 버퍼링 구성
실행 환경에서 메모리 사용량은 구독자 수에 따라 선형적으로 증가합니다. 각 구독은 새 메모리 버퍼를 열어 텔레메트리 데이터를 저장하기 때문에 메모리 리소스를 사용합니다. 버퍼 메모리 사용량은 실행 환경의 전체 메모리 소비에 포함됩니다.
텔레메트리 API를 사용하여 텔레메트리를 수신하기 위해 구독하면 텔레메트리 데이터를 버퍼링하여 구독자에게 배치로 전달하는 옵션이 제공됩니다. 메모리 사용량을 최적화하기 위해 버퍼링 구성을 지정할 수 있습니다.
{ "buffering": { "maxBytes": 256*1024, "maxItems": 1000, "timeoutMs": 100 } }
파라미터 | 설명 | 기본값 및 한도 |
---|---|---|
|
메모리에 버퍼링할 텔레메트리의 최대 볼륨(바이트)입니다. |
기본값: 26만 2,144 최소: 26만 2,144 최대: 1,04만 8,576 |
|
메모리에 버퍼링할 최대 이벤트 수입니다. |
기본값: 1만 최소: 1,000 최대값: 10,000 |
|
배치를 버퍼링할 최대 시간(밀리초)입니다. |
기본값: 1,000 최소: 25 최대: 3만 |
버퍼링을 설정할 때 다음 사항을 고려합니다.
-
입력 스트림이 닫히면 Lambda가 로그를 플러시합니다. 예를 들어 런타임에서 충돌이 발생한 경우 이 상황이 나타날 수 있습니다.
-
각 구독자는 구독 요청에서 버퍼링 구성을 사용자 지정할 수 있습니다.
-
데이터를 읽기 위한 버퍼 크기를 결정할 때 수신 페이로드를 최대
2 * maxBytes + metadataBytes
로 예상합니다. 여기서,maxBytes
는 버퍼링 설정의 구성 요소입니다. 고려할metadataBytes
의 크기를 측정하려면 다음 메타데이터를 검토합니다. Lambda는 다음과 유사한 메타데이터를 각 레코드에 추가합니다.{ "time": "2022-08-20T12:31:32.123Z", "type": "function", "record": "Hello World" }
-
구독자가 들어오는 텔레메트리를 충분히 빠르게 처리할 수 없거나 함수 코드가 매우 높은 로그 볼륨을 생성하는 경우 Lambda는 메모리 사용률을 범위 내로 유지하기 위해 레코드를 삭제할 수 있습니다. 이 경우 Lambda는
platform.logsDropped
이벤트를 전송합니다.
텔레메트리 API에 구독 요청 전송
Lambda 확장은 텔레메트리 API에 구독 요청을 전송하여 텔레메트리 데이터를 수신하도록 구독할 수 있습니다. 이 구독 요청에는 확장이 구독하도록 하려는 이벤트 유형에 대한 정보가 포함되어야 합니다. 또한 이 요청에는 전송 대상 정보와 버퍼링 구성이 포함될 수 있습니다.
구독 요청을 전송하려면 먼저 확장 ID(Lambda-Extension-Identifier
)가 있어야 합니다. 확장 API를 사용하여 확장을 등록할 때 API 응답에서 확장 ID를 얻습니다.
구독은 확장 초기화 단계에서 이루어집니다. 다음 예에서는 플랫폼 텔레메트리, 함수 로그, 확장 로그의 세 가지 텔레메트리 스트림을 모두 구독하는 HTTP 요청을 보여줍니다.
PUT http://${AWS_LAMBDA_RUNTIME_API}/2022-07-01/telemetry HTTP/1.1 { "schemaVersion": "2022-12-13", "types": [ "platform", "function", "extension" ], "buffering": { "maxItems": 1000, "maxBytes": 256*1024, "timeoutMs": 100 }, "destination": { "protocol": "HTTP", "URI": "http://sandbox.localdomain:8080" } }
요청이 성공하면 구독자는 HTTP 200 성공 응답을 받습니다.
HTTP/1.1 200 OK "OK"
인바운드 텔레메트리 API 메시지
텔레메트리 API를 사용하여 구독하고 나면 확장이 POST 요청을 통해 Lambda로부터 텔레메트리를 자동으로 수신하기 시작합니다. 각 POST 요청 본문에는 Event
객체 배열이 포함되어 있습니다. 각 Event
에는 다음 스키마가 있습니다.
{ time: String, type: String, record: Object }
-
time
속성은 Lambda 플랫폼에서 이벤트를 생성한 시점을 정의합니다. 이벤트가 실제로 발생한 시점과는 다릅니다.time
의 문자열 값은 ISO 8601 형식의 타임스탬프입니다. -
type
속성은 이벤트 유형을 정의합니다. 다음 표에서는 모든 가능한 값을 설명합니다. -
record
속성은 텔레메트리 데이터가 포함된 JSON 객체를 정의합니다. 이 JSON 객체의 스키마는type
에 따라 달라집니다.
다음 표에는 모든 유형의 Event
객체가 요약되어 있으며 각 이벤트 유형의 텔레메트리 APIEvent 스키마 참조에 대한 링크가 나와 있습니다.
범주 | 이벤트 유형 | 설명 | 이벤트 레코드 스키마 |
---|---|---|---|
플랫폼 이벤트 |
|
함수 초기화가 시작되었습니다. |
|
플랫폼 이벤트 |
|
함수 초기화가 완료되었습니다. |
|
플랫폼 이벤트 |
|
함수 초기화 보고서입니다. |
|
플랫폼 이벤트 |
|
함수 호출이 시작되었습니다. |
platform.start 스키마 |
플랫폼 이벤트 |
|
런타임이 이벤트 처리를 성공 또는 실패로 완료했습니다. |
|
플랫폼 이벤트 |
|
함수 호출 보고서입니다. |
platform.report 스키마 |
플랫폼 이벤트 |
|
런타임 복원이 시작되었습니다. |
|
플랫폼 이벤트 |
|
런타임 복원이 완료되었습니다. |
|
플랫폼 이벤트 |
|
런타임 복원 보고서. |
|
플랫폼 이벤트 |
|
텔레메트리 API를 구독하는 확장입니다. |
|
플랫폼 이벤트 |
|
Lambda가 로그 항목을 삭제했습니다. |
|
함수 로그 |
|
함수 코드의 로그 줄입니다. |
function 스키마 |
익스텐션 로그 |
|
확장 코드의 로그 줄입니다. |
extension 스키마 |