

# Go를 사용하여 Lambda 함수 빌드
<a name="lambda-golang"></a>

Go는 다른 관리형 런타임과 다른 방법으로 구현됩니다. Go는 기본적으로 실행 가능한 바이너리로 컴파일되므로 전용 언어 런타임이 필요하지 않습니다. [OS 전용 런타임](runtimes-provided.md)(`provided` 런타임 패밀리)을 사용하여 Lambda에 Go 함수를 배포합니다.

**Topics**
+ [Go 런타임 지원](#golang-al1)
+ [도구 및 라이브러리](#golang-libraries)
+ [Go에서 Lambda 함수 핸들러 정의](golang-handler.md)
+ [Lambda 컨텍스트 객체를 사용하여 Go 함수 정보 검색](golang-context.md)
+ [.zip 파일 아카이브를 사용하여 Go Lambda 함수 배포](golang-package.md)
+ [컨테이너 이미지로 Go Lambda 함수 배포](go-image.md)
+ [Go Lambda 함수를 위한 계층 작업](golang-layers.md)
+ [Go Lambda 함수 로깅 및 모니터링](golang-logging.md)
+ [AWS Lambda에서 Go 코드 계측](golang-tracing.md)

## Go 런타임 지원
<a name="golang-al1"></a>

Lambda용 Go 1.x 관리형 런타임은 [더 이상 사용되지 않습니다](lambda-runtimes.md#runtime-support-policy). Go 1.x 런타임을 사용하는 함수가 있는 경우 `provided.al2023` 또는 `provided.al2`로 마이그레이션해야 합니다. `provided.al2023` 및 `provided.al2` 런타임은 `go1.x`보다 뛰어난 몇 가지 이점을 제공하며, 여기에는 arm64 아키텍처(AWS Graviton2 프로세서), 더 작은 바이너리 및 약간 더 빠른 간접 호출 시간에 대한 지원이 해당됩니다.

이 마이그레이션에는 코드 변경이 필요 없습니다. 유일한 필수 변경 사항은 배포 패키지를 빌드하는 방법과 함수를 생성하는 데 사용하는 런타임과 관련이 있습니다. 자세한 내용은 *AWS 컴퓨팅 블로그*에서 [ Migrating AWS Lambda functions from the Go1.x runtime to the custom runtime on Amazon Linux 2](https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/)를 참조하세요.


| 이름 | 식별자 | 운영 체제 | 사용 중단 날짜 | 블록 함수 생성 | 블록 함수 업데이트 | 
| --- | --- | --- | --- | --- | --- | 
|  OS 전용 런타임  |  `provided.al2023`  |  Amazon Linux 2023  |   2029년 6월 30일   |   2029년 7월 31일   |   2029년 8월 31일   | 
|  OS 전용 런타임  |  `provided.al2`  |  Amazon Linux 2  |   2026년 7월 31일   |   2026년 8월 31일   |   2026년 9월 30일   | 

## 도구 및 라이브러리
<a name="golang-libraries"></a>

Lambda에서는 다음과 같은 Go 런타임용 도구 및 라이브러리를 제공합니다.
+ [AWS SDK for Go v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2): Go 프로그래밍 언어용 공식 AWS SDK입니다.
+ [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda): Go용 Lambda 프로그래밍 모델을 구현한 것입니다. 이 패키지는 AWS Lambda에서 [핸들러](golang-handler.md)를 간접 호출하기 위해 사용됩니다.
+ [github.com/aws/aws-lambda-go/lambdacontext](https://github.com/aws/aws-lambda-go/tree/master/lambdacontext): [컨텍스트 객체](golang-context.md)에서 컨텍스트 정보에 액세스하기 위한 헬퍼입니다.
+ [github.com/aws/aws-lambda-go/events](https://github.com/aws/aws-lambda-go/tree/master/events): 이 라이브러리는 일반적인 이벤트 소스 통합을 위한 유형 정의를 제공합니다.
+ [github.com/aws/aws-lambda-go/cmd/build-lambda-zip](https://github.com/aws/aws-lambda-go/tree/master/cmd/build-lambda-zip): 이 도구를 사용하여 Windows에서 .zip 파일 아카이브를 생성할 수 있습니다.

자세한 내용은 GitHub의 [aws-lambda-go](https://github.com/aws/aws-lambda-go)를 참조하세요.

Lambda에서는 다음과 같은 Go 런타임용 샘플 애플리케이션을 제공합니다.

**Go의 샘플 Lambda 애플리케이션**
+ [go-al2](https://github.com/aws-samples/sessions-with-aws-sam/tree/master/go-al2) – 퍼블릭 IP 주소를 반환하는 hello world 함수입니다. 이 앱은 `provided.al2` 사용자 지정 런타임을 사용합니다.
+ [blank-go](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-go) – Lambda의 Go 라이브러리, 로깅, 환경 변수 및 AWS SDK를 사용하는 방법을 보여주는 Go 함수입니다. 이 앱은 `go1.x` 런타임을 사용합니다.

# Go에서 Lambda 함수 핸들러 정의
<a name="golang-handler"></a>

Lambda 함수의 *핸들러*는 이벤트를 처리하는 함수 코드의 메서드입니다. 함수가 간접 호출되면 Lambda는 핸들러 메서드를 실행합니다. 함수는 핸들러가 응답을 반환하거나 종료하거나 제한 시간이 초과될 때까지 실행됩니다.

이 페이지에서는 프로젝트 설정, 이름 지정 규칙, 모범 사례를 포함하여 Go에서 Lambda 함수 핸들러를 사용하는 방법을 설명합니다. 이 페이지에는 주문에 대한 정보를 가져와서 텍스트 파일 영수증을 생성하고 해당 파일을 Amazon Simple Storage Service(Amazon S3) 버킷에 넣는 Go Lambda 함수의 예제도 포함되어 있습니다. 함수를 작성한 후 배포하는 방법에 대한 자세한 내용은 [.zip 파일 아카이브를 사용하여 Go Lambda 함수 배포](golang-package.md) 또는 [컨테이너 이미지로 Go Lambda 함수 배포](go-image.md) 섹션을 참조하세요.

**Topics**
+ [Go 핸들러 프로젝트 설정](#golang-handler-setup)
+ [예제 Go Lambda 함수 코드](#golang-example-code)
+ [핸들러 이름 지정 규칙](#golang-handler-naming)
+ [입력 이벤트 객체 정의 및 액세스](#golang-example-input)
+ [Lambda 컨텍스트 객체 액세스 및 사용](#golang-example-context)
+ [Go 핸들러에 대해 유효한 핸들러 서명](#golang-handler-signatures)
+ [핸들러에서 AWS SDK for Go v2 사용](#golang-example-sdk-usage)
+ [환경 변수에 액세스](#golang-example-envvars)
+ [전역 상태 사용](#golang-handler-state)
+ [Go Lambda 함수의 코드 모범 사례](#go-best-practices)

## Go 핸들러 프로젝트 설정
<a name="golang-handler-setup"></a>

[Go](https://golang.org/)에서 작성된 Lambda 함수는 Go 실행 파일로 작성됩니다. 다음 `go mod init` 명령을 사용하여 다른 Go 프로젝트를 초기화하는 것과 동일한 방식으로 Go Lambda 함수 프로젝트를 초기화할 수 있습니다.

```
go mod init example-go
```

여기에서 `example-go`는 모듈 이름입니다. 이를 다른 것으로 대체할 수 있습니다. 이 명령은 프로젝트를 초기화하고 프로젝트의 종속성을 나열하는 `go.mod` 파일을 생성합니다.

`go get` 명령을 사용하여 프로젝트에 외부 종속성을 추가합니다. 예를 들어 Go의 모든 Lambda 함수에 대해서는 Go용 Lambda 프로그래밍 모델을 구현하는 [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 패키지를 포함해야 합니다. 다음 `go get` 명령을 사용하여 이 패키지를 포함합니다.

```
go get github.com/aws/aws-lambda-go
```

함수 코드는 Go 파일에 있어야 합니다. 다음 예제에서는 이 파일의 이름을 `main.go`로 지정합니다. 이 파일에서는 핸들러 메서드에 핵심 함수 논리와 이 핸들러를 호출하는 `main()` 함수를 구현합니다.

## 예제 Go Lambda 함수 코드
<a name="golang-example-code"></a>

다음 예제 Go Lambda 함수 코드는 주문에 대한 정보를 입력으로 가져와서 텍스트 파일 영수증을 생성하고 해당 파일을 Amazon S3 버킷에 넣습니다.

**Example `main.go` Lambda 함수**  

```
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

type Order struct {
	OrderID string  `json:"order_id"`
	Amount  float64 `json:"amount"`
	Item    string  `json:"item"`
}

var (
	s3Client *s3.Client
)

func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatalf("unable to load SDK config, %v", err)
	}

	s3Client = s3.NewFromConfig(cfg)
}

func uploadReceiptToS3(ctx context.Context, bucketName, key, receiptContent string) error {
	_, err := s3Client.PutObject(ctx, &s3.PutObjectInput{
		Bucket: &bucketName,
		Key:    &key,
		Body:   strings.NewReader(receiptContent),
	})
	if err != nil {
		log.Printf("Failed to upload receipt to S3: %v", err)
		return err
	}
	return nil
}

func handleRequest(ctx context.Context, event json.RawMessage) error {
	// Parse the input event
	var order Order
	if err := json.Unmarshal(event, &order); err != nil {
		log.Printf("Failed to unmarshal event: %v", err)
		return err
	}

	// Access environment variables
	bucketName := os.Getenv("RECEIPT_BUCKET")
	if bucketName == "" {
		log.Printf("RECEIPT_BUCKET environment variable is not set")
		return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
	}

	// Create the receipt content and key destination
	receiptContent := fmt.Sprintf("OrderID: %s\nAmount: $%.2f\nItem: %s",
		order.OrderID, order.Amount, order.Item)
	key := "receipts/" + order.OrderID + ".txt"

	// Upload the receipt to S3 using the helper method
	if err := uploadReceiptToS3(ctx, bucketName, key, receiptContent); err != nil {
		return err
	}

	log.Printf("Successfully processed order %s and stored receipt in S3 bucket %s", order.OrderID, bucketName)
	return nil
}

func main() {
	lambda.Start(handleRequest)
}
```

`main.go` 파일은 다음 코드 섹션을 포함하고 있습니다.
+ `package main`: Go에서 `func main()` 함수를 포함하는 패키지의 이름은 항상 `main`이어야 합니다.
+ `import` 블록: 이 블록을 사용하여 Lambda 함수에 필요한 라이브러리를 포함합니다.
+ `type Order struct {}` 블록: 이 Go 구조체에서 예상 입력 이벤트의 형태를 정의합니다.
+ `var ()` 블록: 이 블록을 사용하여 Lambda 함수에 사용할 전역 변수를 정의합니다.
+ `func init() {}`: 이 `init()` 메서드의 [초기화 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib)에서 Lambda가 실행하기를 원하는 모든 코드를 포함합니다.
+ `func uploadReceiptToS3(...) {}`: 기본 `handleRequest` 핸들러 메서드에서 참조하는 도우미 메서드입니다.
+ `func handleRequest(ctx context.Context, event json.RawMessage) error {}`: 기본 애플리케이션 논리를 포함한 **기본 핸들러 메서드**입니다.
+ `func main() {}`: Lambda 핸들러에 필요한 진입점입니다. `lambda.Start()` 메서드에 대한 인수는 기본 핸들러 메서드입니다.

이 함수가 제대로 작동하려면 [실행 역할](lambda-intro-execution-role.md)이 `s3:PutObject` 작업을 허용해야 합니다. 또한 `RECEIPT_BUCKET` 환경 변수를 정의해야 합니다. 성공적으로 호출되면 Amazon S3 버킷은 영수증 파일을 포함합니다.

## 핸들러 이름 지정 규칙
<a name="golang-handler-naming"></a>

Go의 Lambda 함수의 경우에는 핸들러에 어떤 이름이라도 사용할 수 있습니다. 이 예제의 핸들러 메서드 이름은 `handleRequest`입니다. 코드에서 핸들러 값을 참조하려면 `_HANDLER` 환경 변수를 사용합니다.

[.zip 배포 패키지](golang-package.md)를 사용하여 배포된 Go 함수의 경우 함수 코드가 포함된 실행 파일의 이름은 `bootstrap`이어야 합니다. 또한 `bootstrap` 파일은 .zip 파일의 루트에 있어야 합니다. [컨테이너 이미지](go-image.md#go-image-provided)를 사용하여 배포된 Go 함수의 경우 실행 파일에 어떤 이름이라도 사용할 수 있습니다.

## 입력 이벤트 객체 정의 및 액세스
<a name="golang-example-input"></a>

JSON은 Lambda 함수의 가장 일반적인 표준 입력 형식입니다. 이 예제에서 함수는 다음과 유사한 입력을 예상합니다.

```
{
    "order_id": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

Go에서 Lambda 함수로 작업할 때 예상되는 입력 이벤트의 형태를 Go 구조체로 정의할 수 있습니다. 이 예제에서는 `Order`를 나타내는 구조체를 정의합니다.

```
type Order struct {
    OrderID string  `json:"order_id"`
    Amount  float64 `json:"amount"`
    Item    string  `json:"item"`
}
```

이 구조체는 예상 입력 형태와 일치합니다. 구조체를 정의한 후에는 [encoding/json 표준 라이브러리](https://pkg.go.dev/encoding/json)와 호환되는 일반 JSON 유형을 받아들이는 핸들러 서명을 작성할 수 있습니다. 그런 다음 [func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal) 함수를 사용하여 이를 구조체로 역직렬화할 수 있습니다. 이는 핸들러의 처음 몇 줄에 설명되어 있습니다.

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    // Parse the input event
    var order Order
    if err := json.Unmarshal(event, &order); err != nil {
        log.Printf("Failed to unmarshal event: %v", err)
        return err
    ...
}
```

역직렬화 후에는 `order` 변수의 필드에 액세스할 수 있습니다. 예를 들어 `order.OrderID`는 원래 입력에서 `"order_id"`의 값을 검색합니다.

**참고**  
`encoding/json` 패키지는 내보낸 필드에만 액세스할 수 있습니다. 내보내기를 위해서는 이벤트 구문의 필드 이름이 대문자로 표시되어야 합니다.

## Lambda 컨텍스트 객체 액세스 및 사용
<a name="golang-example-context"></a>

Lambda [컨텍스트 객체](golang-context.md)에는 호출, 함수, 실행 환경에 관한 정보가 포함되어 있습니다. 이 예제에서는 핸들러 서명에서 이 변수를 `ctx`로 선언했습니다.

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    ...
}
```

`ctx context.Context` 입력은 함수 핸들러의 선택적 인수입니다. 허용되는 핸들러 서명에 대한 자세한 내용은 [Go 핸들러에 대해 유효한 핸들러 서명](#golang-handler-signatures) 섹션을 참조하세요.

AWS SDK를 사용하여 다른 서비스를 직접적으로 호출하는 경우 몇 가지 주요 영역에서 컨텍스트 객체가 필요합니다. 예를 들어 SDK 클라이언트를 올바르게 초기화하려면 다음과 같이 컨텍스트 객체를 사용하여 올바른 AWS SDK 구성을 로드할 수 있습니다.

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
```

SDK 호출 자체에 컨텍스트 객체가 입력으로 필요할 수 있습니다. 예를 들어 `s3Client.PutObject` 호출은 컨텍스트 객체를 첫 번째 인수로 수락합니다.

```
// Upload the receipt to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

AWS SDK 요청 외에도 함수 모니터링에 컨텍스트 객체를 사용할 수 있습니다. 컨텍스트 객체에 대한 자세한 내용은 [Lambda 컨텍스트 객체를 사용하여 Go 함수 정보 검색](golang-context.md) 섹션을 참조하세요.

## Go 핸들러에 대해 유효한 핸들러 서명
<a name="golang-handler-signatures"></a>

Go에서 Lambda 함수 핸들러를 빌드할 때 몇 가지 옵션들이 있으며 다만 다음과 같은 규칙들을 반드시 준수해야 합니다.
+ 핸들러는 하나의 함수여야 합니다.
+ 핸들러는 0\$12개의 인수를 취할 수 있습니다. 인수가 2개일 경우, 첫 번째 인수는 `context.Context`를 구현해야 합니다.
+ 핸들러는 0\$12개의 인수를 반환할 수 있습니다. 반환 값이 1개일 경우, 이 값은 `error`를 구현해야 합니다. 반환 값이 2개일 경우, 두 번째 값은 `error`를 구현해야 합니다.

다음 목록은 유효한 핸들러 서명을 열거합니다. `TIn` 및 `TOut`은 *encoding/json* 표준 라이브러리와 호환 가능한 유형을 나타냅니다. 이러한 유형들이 역직렬화되는 방식에 관한 자세한 내용은 [func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal)을 참조하시기 바랍니다.
+ 

  ```
  func ()
  ```
+ 

  ```
  func () error
  ```
+ 

  ```
  func () (TOut, error)
  ```
+ 

  ```
  func (TIn) error
  ```
+ 

  ```
  func (TIn) (TOut, error)
  ```
+ 

  ```
  func (context.Context) error
  ```
+ 

  ```
  func (context.Context) (TOut, error)
  ```
+ 

  ```
  func (context.Context, TIn) error
  ```
+ 

  ```
  func (context.Context, TIn) (TOut, error)
  ```

## 핸들러에서 AWS SDK for Go v2 사용
<a name="golang-example-sdk-usage"></a>

종종 Lambda 함수를 사용하여 다른 AWS 리소스와 상호 작용하거나 업데이트하는 경우가 있습니다. 이러한 리소스와 상호 작용하는 가장 간단한 방법은 [AWS SDK for Go v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2)를 사용하는 것입니다.

**참고**  
AWS SDK for Go(v1)는 유지 관리 모드이며 2025년 7월 31일에 지원이 종료됩니다. 앞으로는 AWS SDK for Go v2만 사용하는 것을 권장합니다.

함수에 SDK 종속성을 추가하려면 필요한 특정 SDK 클라이언트에 `go get` 명령을 사용하세요. 이전의 예제 코드에서는 `config` 라이브러리와 `s3` 라이브러리를 사용했습니다. `go.mod` 및 `main.go ` 파일이 포함된 디렉터리에서 다음 명령을 실행하여 이러한 종속성을 추가합니다.

```
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3
```

그런 다음 함수의 가져오기 블록에서 그에 따른 종속성을 가져옵니다.

```
import (
    ...
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)
```

핸들러에서 SDK를 사용하는 경우에는 클라이언트를 올바른 설정으로 구성하세요. 가장 간단한 방법은 [기본 자격 증명 제공업체 체인](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain)을 사용하는 것입니다. 이 예제에서는 이러한 구성을 로드하는 한 가지 방법을 보여줍니다.

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        log.Printf("Failed to load AWS SDK config: %v", err)
        return err
    }
```

이러한 구성을 `cfg` 변수에 로드한 후에 해당 변수를 클라이언트 인스턴스에 전달할 수 있습니다. 예제 코드는 다음과 같이 Amazon S3 클라이언트를 인스턴스화합니다.

```
// Create an S3 client
    s3Client := s3.NewFromConfig(cfg)
```

이 예제에서는 `init()` 함수를 간접적으로 간접 호출할 때마다 초기화할 필요가 없도록 함수에서 Amazon S3 클라이언트를 초기화했습니다. 문제는 `init()` 함수에서 Lambda가 컨텍스트 객체에 액세스할 수 없다는 점입니다. 이 문제를 해결하려면 초기화 단계에서 `context.TODO()`와 같은 자리 표시자를 전달할 수 있습니다. 나중에 클라이언트를 사용하여 직접적으로 호출할 때 전체 컨텍스트 객체를 전달합니다. 이 해결 방법은 [AWS SDK 클라이언트 초기화 및 호출에서 컨텍스트 사용](golang-context.md#golang-context-sdk)에도 설명되어 있습니다.

SDK 클라이언트를 구성하고 초기화한 후에는 이를 사용하여 다른 AWS 서비스와 상호 작용할 수 있습니다. 예제 코드는 다음과 같이 Amazon S3 `PutObject` API를 직접적으로 호출합니다.

```
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucketName,
    Key:    &key,
    Body:   strings.NewReader(receiptContent),
})
```

## 환경 변수에 액세스
<a name="golang-example-envvars"></a>

핸들러 코드에서 `os.Getenv()` 메서드를 사용하여 모든 [환경 변수](configuration-envvars.md)를 참조할 수 있습니다. 이 예제에서는 다음 코드 줄을 사용하여 정의된 `RECEIPT_BUCKET` 환경 변수를 참조합니다.

```
// Access environment variables
    bucketName := os.Getenv("RECEIPT_BUCKET")
    if bucketName == "" {
        log.Printf("RECEIPT_BUCKET environment variable is not set")
        return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
    }
```

## 전역 상태 사용
<a name="golang-handler-state"></a>

함수를 간접 호출할 때마다 새 리소스가 생성되지 않도록 하려면 Lambda 함수의 핸들러 코드 외부에서 전역 변수를 선언하고 수정할 수 있습니다. `var` 블록 또는 문에서 이러한 전역 변수를 정의합니다. 또한 핸들러는 [초기화 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib) 동안 실행되는 `init()` 함수를 선언할 수 있습니다. `init` 메서드는 표준 Go 프로그램에서와 마찬가지로 AWS Lambda에서도 동일하게 동작합니다.

## Go Lambda 함수의 코드 모범 사례
<a name="go-best-practices"></a>

Lambda 함수를 구축할 때 코딩 모범 사례를 사용하려면 다음 목록의 지침을 준수하세요.
+ **핵심 로직에서 Lambda 핸들러를 분리합니다.** 이를 통해 단위 테스트를 수행할 수 있는 더 많은 함수를 만들 수 있습니다.
+ **종속성의 복잡성을 최소화합니다.** [실행 환경](lambda-runtime-environment.md) 시작 시 빠르게 로드되는 더 단순한 프레임워크가 권장됩니다.
+ **배포 패키지 크기를 런타임 필요에 따라 최소화합니다.** 이렇게 하면 호출 전에 배포 패키지를 다운로드하고 압축을 풀 때 걸리는 시간이 단축됩니다.

**실행 환경 재사용을 활용하여 함수 성능을 향상시킵니다.** 함수 핸들러 외부에서 SDK 클라이언트 및 데이터베이스 연결을 초기화하고 정적 자산을 `/tmp` 디렉토리에 로컬로 캐시합니다. 동일한 함수 인스턴스에서 처리하는 후속 간접 호출은 이러한 리소스를 재사용할 수 있습니다. 이를 통해 함수 실행 시간을 줄여 비용을 절감합니다.

호출에서 발생할 수 있는 데이터 유출을 방지하려면 실행 환경을 사용하여 사용자 데이터, 이벤트 또는 보안과 관련된 기타 정보를 저장하지 마세요. 함수가 핸들러 내부 메모리에 저장할 수 없는 변경 가능한 상태에 의존하는 경우 각 사용자에 대해 별도의 함수 또는 별도의 함수 버전을 생성하는 것이 좋습니다.

**연결 유지 지시문을 사용하여 지속적인 연결을 유지하세요.** Lambda는 시간이 지남에 따라 유휴 연결을 제거합니다. 함수를 호출할 때 유휴 연결을 재사용하려고 하면 연결 오류가 발생합니다. 지속적인 연결을 유지하려면 런타임과 관련된 연결 유지 지시문을 사용하세요. 예를 들어, [Node.js에서 연결 유지를 이용해 연결 재사용](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)을 참조하세요.

** [환경 변수](configuration-envvars.md)를 사용하여 함수에 운영 파라미터를 전달합니다.** 예를 들어, Amazon S3 버킷에 기록하는 경우 기록하고 있는 버킷 이름을 하드 코딩하는 대신 환경 변수로 구성합니다.

Lambda 함수에서 함수가 자기 자신을 간접적으로 간접 호출하거나 함수를 다시 간접적으로 간접 호출할 수 있는 프로세스를 시작하는 **재귀적 간접 호출을 사용하지 마세요**. 리커시브 코드를 사용할 경우, 의도하지 않은 함수 호출이 증가하고 비용이 상승할 수 있습니다. 의도치 않게 간접 호출이 대량으로 발생하는 경우 함수의 예약된 동시성을 즉시 `0`으로 설정하여 코드를 업데이트하는 동안 해당 함수에 대한 모든 간접 호출을 제한합니다.

Lambda 함수 코드에는 **문서화되지 않은 비공개 API를 사용하지 마세요.** AWS Lambda 관리형 런타임의 경우, Lambda는 주기적으로 보안 및 기능 업데이트를 Lambda의 내부 API에 적용합니다. 이러한 내부 API 업데이트는 이전 버전과 호환되지 않으므로 함수가 이러한 비공개 API에 종속성을 갖는 경우 호출 실패와 같은 의도하지 않은 결과를 초래할 수 있습니다. 공개적으로 사용 가능한 API의 목록은 [API 레퍼런스](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)를 참조하세요.

**멱등성 코드를 작성합니다.** 함수에 멱등성 코드를 작성하면 중복 이벤트가 동일한 방식으로 처리됩니다. 코드는 이벤트를 올바르게 검증하고 중복 이벤트를 정상적으로 처리해야 합니다. 자세한 내용은 [멱등성 Lambda 함수를 만들려면 어떻게 해야 합니까?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/) 단원을 참조하십시오.

# Lambda 컨텍스트 객체를 사용하여 Go 함수 정보 검색
<a name="golang-context"></a>

Lambda에서 컨텍스트 객체는 호출, 함수, 실행 환경에 대한 정보를 메서드와 속성에 제공합니다. Lambda는 함수를 실행할 때 컨텍스트 객체를 [핸들러](golang-handler.md)에 전달합니다. 핸들러에서 컨텍스트 객체를 사용하려면 이를 핸들러에 대한 입력 파라미터로 선언할 수 있습니다(선택 사항). 핸들러에서 다음을 수행하려면 컨텍스트 객체가 필요합니다.
+ 컨텍스트 객체가 제공하는 [전역 변수, 메서드 또는 속성](#golang-context-library)에 액세스해야 합니다. 이러한 메서드와 속성은 [호출 컨텍스트 정보 액세스](#golang-context-access)에 설명된 것처럼 함수를 호출한 엔터티를 확인하거나 함수의 호출 시간을 측정하는 등의 태스크에 유용합니다.
+ AWS SDK for Go를 사용하여 다른 서비스를 직접적으로 호출해야 합니다. 컨텍스트 객체는 이러한 호출 대부분에 대한 중요한 입력 파라미터입니다. 자세한 내용은 [AWS SDK 클라이언트 초기화 및 호출에서 컨텍스트 사용](#golang-context-sdk) 단원을 참조하십시오.

**Topics**
+ [컨텍스트 객체에서 지원되는 변수, 메서드, 속성](#golang-context-library)
+ [호출 컨텍스트 정보 액세스](#golang-context-access)
+ [AWS SDK 클라이언트 초기화 및 호출에서 컨텍스트 사용](#golang-context-sdk)

## 컨텍스트 객체에서 지원되는 변수, 메서드, 속성
<a name="golang-context-library"></a>

Lambda 컨텍스트 라이브러리는 다음과 같은 전역 변수, 메서드 및 속성들을 제공합니다.

**전역 변수**
+ `FunctionName` – Lambda 함수의 이름입니다.
+ `FunctionVersion` – 함수의 [버전](configuration-versions.md)입니다.
+ `MemoryLimitInMB` – 함수에 할당된 메모리의 양입니다.
+ `LogGroupName` – 함수에 대한 로그 그룹입니다.
+ `LogStreamName` – 함수 인스턴스에 대한 로그 스트림입니다.

**컨텍스트 메서드**
+ `Deadline` – 실행 시간이 초과된 날짜를 Unix 시간 형식에 따른 밀리초 단위로 반환합니다.

**컨텍스트 속성**
+ `InvokedFunctionArn` – 함수를 호출할 때 사용하는 Amazon 리소스 이름(ARN)입니다. 호출자가 버전 번호 또는 별칭을 지정했는지 여부를 나타냅니다.
+ `AwsRequestID` – 호출 요청의 식별자입니다.
+ `Identity` – (모바일 앱) 요청을 승인한 Amazon Cognito 자격 증명에 대한 정보입니다.
+ `ClientContext` – (모바일 앱) 클라이언트 애플리케이션이 Lambda에게 제공한 클라이언트 컨텍스트입니다.

## 호출 컨텍스트 정보 액세스
<a name="golang-context-access"></a>

Lambda 함수들은 자신의 환경과 호출 요청에 관한 메타데이터에 액세스할 수 있습니다. 이는 [Package context](https://golang.org/pkg/context/)에서 액세스할 수 있습니다. 핸들러가 `context.Context`를 하나의 파라미터로 포함할 경우, Lambda는 함수에 관한 정보를 컨텍스트의 `Value` 속성에 삽입합니다. `lambdacontext` 객체의 콘텐츠에 액세스하려면 `context.Context` 라이브러리를 가져와야 합니다.

```
package main
 
import (
        "context"
        "log"
        "github.com/aws/aws-lambda-go/lambda"
        "github.com/aws/aws-lambda-go/lambdacontext"
)
 
func CognitoHandler(ctx context.Context) {
        lc, _ := lambdacontext.FromContext(ctx)
        log.Print(lc.Identity.CognitoIdentityPoolID)
}
 
func main() {
        lambda.Start(CognitoHandler)
}
```

위 예제에서 `lc`는 콘텍스트 객체가 수집한 해당 정보를 소비하는 데 사용되는 변수이며, `log.Print(lc.Identity.CognitoIdentityPoolID)`는 그 정보(이 경우에는 CognitoIdentityPoolID)를 출력합니다.

다음 예제는 컨텍스트 객체를 사용하여 Lambda 함수가 완료되는 데 걸리는 시간을 모니터링하는 방법을 소개합니다. 이 방법을 활용하면 기대 성능을 분석할 수 있으며 필요에 따라 함수 코드를 조정할 수 있습니다.

```
package main

import (
        "context"
        "log"
        "time"
        "github.com/aws/aws-lambda-go/lambda"
)

func LongRunningHandler(ctx context.Context) (string, error) {

        deadline, _ := ctx.Deadline()
        deadline = deadline.Add(-100 * time.Millisecond)
        timeoutChannel := time.After(time.Until(deadline))

        for {

                select {

                case <- timeoutChannel:
                        return "Finished before timing out.", nil

                default:
                        log.Print("hello!")
                        time.Sleep(50 * time.Millisecond)
                }
        }
}

func main() {
        lambda.Start(LongRunningHandler)
}
```

## AWS SDK 클라이언트 초기화 및 호출에서 컨텍스트 사용
<a name="golang-context-sdk"></a>

핸들러가 AWS SDK for Go를 사용하여 다른 서비스를 직접적으로 호출하는 경우 컨텍스트 객체를 핸들러에 대한 입력으로 포함합니다. AWS에서는 대부분의 AWS SDK 호출에서 컨텍스트 객체를 전달하는 것이 가장 좋습니다. 예를 들어 Amazon S3 `PutObject` 호출은 컨텍스트 객체(`ctx`)를 첫 번째 인수로 수락합니다.

```
// Upload an object to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

SDK 클라이언트를 올바르게 초기화하려면 컨텍스트 객체를 사용하여 올바른 구성을 로드한 후 해당 구성 객체를 클라이언트에 전달할 수도 있습니다.

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    ...
    s3Client = s3.NewFromConfig(cfg)
```

기본 핸들러 외부, 즉 초기화 단계 중에 SDK 클라이언트를 초기화하려는 경우 자리 표시자 컨텍스트 객체를 전달할 수 있습니다.

```
func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	...
	s3Client = s3.NewFromConfig(cfg)
}
```

이런 방식으로 클라이언트를 초기화하는 경우 기본 핸들러에서 SDK 호출로 올바른 컨텍스트 객체를 전달해야 합니다.

# .zip 파일 아카이브를 사용하여 Go Lambda 함수 배포
<a name="golang-package"></a>

AWS Lambda 함수의 코드는 스크립트 또는 컴파일된 프로그램과 해당 종속 항목으로 구성됩니다. 함수 코드는 *배포 패키지*를 사용하여 Lambda에 배포합니다. Lambda는 컨테이너 이미지 및 .zip 파일 아카이브의 두 가지 배포 패키지를 지원합니다.

이 페이지에서는 Go 런타임의 배포 패키지로 .zip 파일을 생성한 다음 .zip 파일을 사용하여 AWS Management Console, AWS Command Line Interface(AWS CLI) 및 AWS Serverless Application Model(AWS SAM)에서 AWS Lambda에 함수 코드를 배포하는 방법을 설명합니다.

Lambda는 POSIX 파일 권한을 사용하므로 .zip 파일 아카이브를 생성하기 전에 [배포 패키지 폴더에 대한 권한을 설정](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/)해야 할 수 있습니다.

**Topics**
+ [macOS 및 Linux에서 .zip 파일 만들기](#golang-package-mac-linux)
+ [Windows에서 .zip 파일 만들기](#golang-package-windows)
+ [.zip 파일을 사용하여 Go Lambda 함수 생성 및 업데이트](#golang-package-create-function)

## macOS 및 Linux에서 .zip 파일 만들기
<a name="golang-package-mac-linux"></a>

다음 단계에서는 `go build` 명령을 사용하여 실행 파일을 컴파일하고 Lambda용 .zip 파일 배포 패키지를 생성하는 방법을 보여줍니다. 코드를 컴파일하기 전에 GitHub에서 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 패키지를 설치했는지 확인하세요. 이 모듈은 Lambda와 함수 코드 간의 상호 작용을 관리하는 런타임 인터페이스의 구현을 제공합니다. 이 라이브러리를 다운로드하려면 다음 명령을 실행합니다.

```
go get github.com/aws/aws-lambda-go/lambda
```

함수에서 AWS SDK for Go를 사용하는 경우 애플리케이션에 필요한 AWS 서비스 API 클라이언트와 함께 표준 SDK 모듈 세트를 다운로드하세요. SDK for Go를 설치하는 방법을 알아보려면 [Getting Started with the AWS SDK for Go V2](https://github.com/aws/aws-sdk-go-v2?tab=readme-ov-file#getting-started)를 참조하세요.

### 제공된 런타임 패밀리 사용
<a name="golang-package-mac-linux-al2"></a>

Go는 다른 관리형 런타임과 다른 방법으로 구현됩니다. Go는 기본적으로 실행 가능한 바이너리로 컴파일되므로 전용 언어 런타임이 필요하지 않습니다. [OS 전용 런타임](runtimes-provided.md)(`provided` 런타임 패밀리)을 사용하여 Lambda에 Go 함수를 배포합니다.

**.zip 배포 패키지 생성(macOS/Linux)**

1. 애플리케이션의 `main.go` 파일이 들어 있는 프로젝트 디렉터리에서 실행 파일을 컴파일합니다. 다음 사항에 유의하세요.
   + 실행 파일의 이름은 `bootstrap`이어야 합니다. 자세한 내용은 [핸들러 이름 지정 규칙](golang-handler.md#golang-handler-naming) 섹션을 참조하세요.
   + 대상 [명령 세트 아키텍처](foundation-arch.md)를 설정합니다. OS 전용 런타임은 arm64와 x86\$164를 모두 지원합니다.
   + 선택 사항인 `lambda.norpc` 태그를 사용하여 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 라이브러리의 원격 절차 호출(RPC) 구성 요소를 제외할 수 있습니다. RPC 구성 요소는 지원 중단된 Go 1.x 런타임을 사용할 경우에만 필요합니다. RPC를 제외하면 배포 패키지의 크기가 줄어듭니다.

   arm64 아키텍처의 경우:

   ```
   GOOS=linux GOARCH=arm64 go build -tags lambda.norpc -o bootstrap main.go
   ```

   x86\$164 아키텍처의 경우:

   ```
   GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o bootstrap main.go
   ```

1. (선택 사항) Linux에서 `CGO_ENABLED=0` 세트를 사용하여 패키지를 컴파일해야 할 수도 있습니다.

   ```
   GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o bootstrap -tags lambda.norpc main.go
   ```

   이 명령은 표준 C 라이브러리(`libc`) 버전에 대해 안정적인 바이너리 패키지를 만듭니다. 이 패키지는 다른 Lambda 및 다른 장치에서 다를 수 있습니다.

1. 실행 파일을 .zip 파일로 패키지하여 배포 패키지를 만듭니다.

   ```
   zip myFunction.zip bootstrap
   ```
**참고**  
`bootstrap` 파일은 .zip 파일의 루트에 있어야 합니다.

1.  함수를 생성합니다. 다음 사항에 유의하세요.
   + 바이너리의 이름은 `bootstrap`이어야 하지만 핸들러 이름은 무엇이든 지정할 수 있습니다. 자세한 내용은 [핸들러 이름 지정 규칙](golang-handler.md#golang-handler-naming) 섹션을 참조하세요.
   + `--architectures` 옵션은 arm64를 사용할 때만 필요합니다. 기본값은 x86\$164입니다.
   + `--role`에 [실행 역할](lambda-intro-execution-role.md)의 Amazon 리소스 이름(ARN)을 지정합니다.

   ```
   aws lambda create-function --function-name myFunction \
   --runtime provided.al2023 --handler bootstrap \
   --architectures arm64 \
   --role arn:aws:iam::111122223333:role/lambda-ex \
   --zip-file fileb://myFunction.zip
   ```

## Windows에서 .zip 파일 만들기
<a name="golang-package-windows"></a>

다음 단계에서는 GitHub에서 Windows용 [build-lambda-zip](https://github.com/aws/aws-lambda-go/tree/main/cmd/build-lambda-zip) 도구를 다운로드하고, 실행 파일을 컴파일하고, .zip 배포 패키지를 생성하는 방법을 보여줍니다.

**참고**  
설치를 아직 수행하지 않았다면 [git](https://git-scm.com/)를 설치한 후 `git` 실행 파일을 Windows `%PATH%` 환경 변수에 추가해야 합니다.

코드를 컴파일하기 전에 GitHub에서 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 라이브러리를 설치했는지 확인하세요. 이 라이브러리를 다운로드하려면 다음 명령을 실행합니다.

```
go get github.com/aws/aws-lambda-go/lambda
```

함수에서 AWS SDK for Go를 사용하는 경우 애플리케이션에 필요한 AWS 서비스 API 클라이언트와 함께 표준 SDK 모듈 세트를 다운로드하세요. SDK for Go를 설치하는 방법을 알아보려면 [Getting Started with the AWS SDK for Go V2](https://aws.github.io/aws-sdk-go-v2/docs/getting-started/)를 참조하세요.

### 제공된 런타임 패밀리 사용
<a name="golang-package-windows-al2"></a>

Go는 다른 관리형 런타임과 다른 방법으로 구현됩니다. Go는 기본적으로 실행 가능한 바이너리로 컴파일되므로 전용 언어 런타임이 필요하지 않습니다. [OS 전용 런타임](runtimes-provided.md)(`provided` 런타임 패밀리)을 사용하여 Lambda에 Go 함수를 배포합니다.

**.zip 배포 패키지 생성(Windows)**

1. GitHub에서 **build-lambda-zip** 도구를 다운로드합니다.

   ```
   go install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest
   ```

1. `GOPATH`의 도구를 사용하여 .zip 파일을 만듭니다. Go가 기본적으로 설치되어 있다면 도구는 보통 `%USERPROFILE%\Go\bin`에 있습니다. 그렇지 않다면 Go 런타임을 설치한 위치로 이동해 다음 중 하나를 수행합니다.

------
#### [ cmd.exe ]

   cmd.exe에서 대상 [명령 세트 아키텍처](foundation-arch.md)에 따라 다음 중 하나를 실행합니다. OS 전용 런타임은 arm64와 x86\$164를 모두 지원합니다.

   선택 사항인 `lambda.norpc` 태그를 사용하여 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 라이브러리의 원격 절차 호출(RPC) 구성 요소를 제외할 수 있습니다. RPC 구성 요소는 지원 중단된 Go 1.x 런타임을 사용할 경우에만 필요합니다. RPC를 제외하면 배포 패키지의 크기가 줄어듭니다.

**Example - x86\$164 아키텍처의 경우**  

   ```
   set GOOS=linux
   set GOARCH=amd64
   set CGO_ENABLED=0
   go build -tags lambda.norpc -o bootstrap main.go
   %USERPROFILE%\Go\bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

**Example - arm64 아키텍처의 경우**  

   ```
   set GOOS=linux
   set GOARCH=arm64
   set CGO_ENABLED=0
   go build -tags lambda.norpc -o bootstrap main.go
   %USERPROFILE%\Go\bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

------
#### [ PowerShell ]

   PowerShell에서 대상 [명령 세트 아키텍처](foundation-arch.md)에 따라 다음 중 하나를 실행합니다. OS 전용 런타임은 arm64와 x86\$164를 모두 지원합니다.

   선택 사항인 `lambda.norpc` 태그를 사용하여 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 라이브러리의 원격 절차 호출(RPC) 구성 요소를 제외할 수 있습니다. RPC 구성 요소는 지원 중단된 Go 1.x 런타임을 사용할 경우에만 필요합니다. RPC를 제외하면 배포 패키지의 크기가 줄어듭니다.

   x86\$164 아키텍처의 경우:

   ```
   $env:GOOS = "linux"
   $env:GOARCH = "amd64"
   $env:CGO_ENABLED = "0"
   go build -tags lambda.norpc -o bootstrap main.go
   ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

   arm64 아키텍처의 경우:

   ```
   $env:GOOS = "linux"
   $env:GOARCH = "arm64"
   $env:CGO_ENABLED = "0"
   go build -tags lambda.norpc -o bootstrap main.go
   ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap
   ```

------

1.  함수를 생성합니다. 다음 사항에 유의하세요.
   + 바이너리의 이름은 `bootstrap`이어야 하지만 핸들러 이름은 무엇이든 지정할 수 있습니다. 자세한 내용은 [핸들러 이름 지정 규칙](golang-handler.md#golang-handler-naming) 섹션을 참조하세요.
   + `--architectures` 옵션은 arm64를 사용할 때만 필요합니다. 기본값은 x86\$164입니다.
   + `--role`에 [실행 역할](lambda-intro-execution-role.md)의 Amazon 리소스 이름(ARN)을 지정합니다.

   ```
   aws lambda create-function --function-name myFunction \
   --runtime provided.al2023 --handler bootstrap \
   --architectures arm64 \
   --role arn:aws:iam::111122223333:role/lambda-ex \
   --zip-file fileb://myFunction.zip
   ```

## .zip 파일을 사용하여 Go Lambda 함수 생성 및 업데이트
<a name="golang-package-create-function"></a>

 .zip 배포 패키지를 생성한 후 이를 사용하여 새 Lambda 함수를 생성하거나 기존 함수를 업데이트할 수 있습니다. Lambda 콘솔, AWS Command Line Interface 및 Lambda API를 사용하여 .zip 패키지를 배포할 수 있습니다. AWS Serverless Application Model(AWS SAM) 및 CloudFormation을 사용하여 Lambda 함수를 생성하고 업데이트할 수도 있습니다.

Lambda용 .zip 배포 패키지의 최대 크기는 250MB(압축 해제됨)입니다. 이 제한은 Lambda 계층을 포함하여 업로드하는 모든 파일의 합산 크기에 적용됩니다.

Lambda 런타임은 배포 패키지의 파일을 읽을 수 있는 권한이 필요합니다. Linux 권한 8진수 표기법에서는 Lambda에 실행 불가능한 파일(rw-r--r--)에 대한 644개의 권한과 디렉터리 및 실행 파일에 대한 755개의 권한(rwxr-xr-x)이 필요합니다.

Linux 및 MacOS에서는 `chmod` 명령을 사용하여 배포 패키지의 파일 및 디렉터리에 대한 파일 권한을 변경합니다. 예를 들어 실행 불가능한 파일에 올바른 권한을 부여하려면 다음 명령을 실행합니다.

```
chmod 644 <filepath>
```

Windows에서 파일 권한을 변경하려면 Microsoft Windows 설명서의 [Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10))를 참조하세요.

**참고**  
배포 패키지의 디렉터리에 액세스하는 데 필요한 권한을 Lambda에 부여하지 않으면 Lambda는 해당 디렉터리에 대한 권한을 755(rwxr-xr-x)로 설정합니다.

### 콘솔을 사용하여.zip 파일로 함수 생성 및 업데이트
<a name="golang-package-create-console"></a>

 새 함수를 생성하려면 먼저 콘솔에서 함수를 생성한 다음.zip 아카이브를 업로드해야 합니다. 기존 함수를 업데이트하려면 함수에 대한 페이지를 연 다음 동일한 절차에 따라 업데이트된 .zip 파일을 추가합니다.

 .zip 파일이 50MB 미만인 경우 로컬 컴퓨터에서 직접 파일을 업로드하여 함수를 생성하거나 업데이트할 수 있습니다. 50MB보다 큰 .zip 파일의 경우 먼저 패키지를 Amazon S3 버킷에 업로드해야 합니다. AWS Management Console을 사용하여 Amazon S3 버킷에 파일을 업로드하는 방법에 대한 지침은 [Amazon S3 시작하기](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)를 참조하세요. AWS CLI를 사용하여 파일을 업로드하려면 **AWS CLI 사용 설명서의 [객체 이동](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)을 참조하세요.

**참고**  
.zip 아카이브를 사용하도록 기존 컨테이너 이미지 함수를 변환할 수는 없습니다. 새로운 함수를 생성해야 합니다.

**새 함수 생성(콘솔)**

1. Lambda 콘솔의 [함수 페이지](https://console.aws.amazon.com/lambda/home#/functions)를 열고 **함수 생성**을 선택합니다.

1. **새로 작성**을 선택합니다.

1. **기본 정보**에서 다음과 같이 합니다.

   1. **함수 이름**에 함수 이름을 입력합니다.

   1. **런타임**에서 `provided.al2023`를 선택합니다.

1. (선택 사항) **권한(Permissions)**에서 **기본 실행 역할 변경(Change default execution role)**을 확장합니다. 새로운 **실행 역할**을 생성하거나 기존 실행 역할을 사용할 수 있습니다.

1. **함수 생성**을 선택합니다. Lambda에서 선택한 런타임을 사용하여 기본 'Hello World' 함수를 생성합니다.

**로컬 시스템에서 .zip 아카이브 업로드(콘솔)**

1. Lambda 콘솔의 [함수 페이지](https://console.aws.amazon.com/lambda/home#/functions)에서.zip 파일을 업로드할 함수를 선택합니다.

1. **코드** 탭을 선택합니다.

1. **코드 소스** 창에서 **에서 업로드**를 선택합니다.

1. **.zip 파일**을 선택합니다.

1. .zip 파일을 업로드하려면 다음을 수행합니다.

   1. **업로드**를 선택한 다음 파일 선택기에서.zip 파일을 선택합니다.

   1. **Open**을 선택합니다.

   1. **저장**을 선택합니다.

**Amazon S3 버킷에서.zip 아카이브 업로드(콘솔)**

1. Lambda 콘솔의 [함수 페이지](https://console.aws.amazon.com/lambda/home#/functions)에서 새 .zip 파일을 업로드할 함수를 선택합니다.

1. **코드** 탭을 선택합니다.

1. **코드 소스** 창에서 **에서 업로드**를 선택합니다.

1. **Amazon S3 위치**를 선택합니다.

1. .zip 파일의 Amazon S3 링크 URL을 붙여 넣고 **저장**을 선택합니다.

### AWS CLI를 사용하여.zip 파일로 함수 생성 및 업데이트
<a name="golang-package-create-cli"></a>

 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)를 사용하여 새 함수를 생성하거나.zip 파일로 기존 함수를 업데이트할 수 있습니다. [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 및 [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 명령을 사용하여 .zip 패키지를 배포합니다. .zip 파일이 50MB보다 작은 경우 로컬 빌드 시스템의 파일 위치에서 .zip 패키지를 업로드할 수 있습니다. 더 큰 파일의 경우 Amazon S3 버킷에서 .zip 패키지를 업로드해야 합니다. AWS CLI를 사용하여 Amazon S3 버킷에 파일을 업로드하는 방법에 대한 지침은 **AWS CLI 사용 설명서의 [객체 이동](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)을 참조하세요.

**참고**  
AWS CLI를 사용하여 Amazon S3 버킷에서 .zip 파일을 업로드하는 경우 버킷은 함수와 동일한 AWS 리전에 있어야 합니다.

 AWS CLI에서 .zip 파일을 사용하여 새 함수를 생성하려면 다음을 지정해야 합니다.
+ 함수의 이름(`--function-name`)
+ 함수의 런타임(`--runtime`)
+ 함수의 [실행 역할](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)(`--role`)의 Amazon 리소스 이름(ARN)
+ 함수 코드에 있는 핸들러 메서드의 이름(`--handler`)

 .zip 파일의 위치도 지정해야 합니다. .zip 파일이 로컬 빌드 시스템의 폴더에 있는 경우 다음 예제 명령과 같이 `--zip-file` 옵션을 사용하여 파일 경로를 지정합니다.

```
aws lambda create-function --function-name myFunction \
--runtime provided.al2023 --handler bootstrap \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 Amazon S3 버킷에서 .zip 파일의 위치를 지정하려면 다음 예제 명령과 같이 `--code` 옵션을 사용합니다. 버전이 지정된 객체에만 `S3ObjectVersion` 파라미터를 사용해야 합니다.

```
aws lambda create-function --function-name myFunction \
--runtime provided.al2023 --handler bootstrap \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 CLI를 사용하여 기존 함수를 업데이트하려면 `--function-name` 파라미터를 사용하여 함수 이름을 지정합니다. 함수 코드를 업데이트하는 데 사용할.zip 파일의 위치도 지정해야 합니다. .zip 파일이 로컬 빌드 시스템의 폴더에 있는 경우 다음 예제 명령과 같이 `--zip-file` 옵션을 사용하여 파일 경로를 지정합니다.

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 Amazon S3 버킷에서 .zip 파일의 위치를 지정하려면 다음 예제 명령과 같이 `--s3-bucket` 및 `--s3-key` 옵션을 사용합니다. 버전이 지정된 객체에만 `--s3-object-version` 파라미터를 사용해야 합니다.

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

### Lambda API를 사용하여.zip 파일로 함수 생성 및 업데이트
<a name="golang-package-create-api"></a>

 .zip 파일 아카이브를 사용하여 함수를 생성하고 업데이트하려면 다음 API 작업을 사용합니다.
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)

### AWS SAM을 사용하여.zip 파일로 함수 생성 및 업데이트
<a name="golang-package-create-sam"></a>

 AWS Serverless Application Model(AWS SAM)은 AWS에서 서버리스 애플리케이션을 빌드하고 실행하는 프로세스를 간소화하는 데 도움이 되는 도구 키트입니다. YAML 또는 JSON 템플릿에서 애플리케이션의 리소스를 정의하고 AWS SAM Command Line Interface(AWS SAM CLI)를 사용하여 애플리케이션을 빌드, 패키징 및 배포합니다. AWS SAM 템플릿에서 Lambda 함수를 빌드하면 AWS SAM은 함수 코드와 사용자가 지정하는 종속 항목을 사용하여 .zip 배포 패키지 또는 컨테이너 이미지를 자동으로 생성합니다. AWS SAM을 사용하여 Lambda 함수를 빌드하고 배포하는 방법에 대해 자세히 알아보려면 **AWS Serverless Application Model 개발자 안내서의 [Getting started with AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)을 참조하세요.

AWS SAM을 사용하여 기존 .zip 파일 아카이브로 Lambda 함수를 생성할 수도 있습니다. AWS SAM을 사용하여 Lambda 함수를 생성하려면 Amazon S3 버킷 또는 빌드 시스템의 로컬 폴더에 .zip 파일을 저장할 수 있습니다. AWS CLI를 사용하여 Amazon S3 버킷에 파일을 업로드하는 방법에 대한 지침은 **AWS CLI 사용 설명서의 [객체 이동](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)을 참조하세요.

 AWS SAM 템플릿에서 `AWS::Serverless::Function` 리소스는 Lambda 함수를 지정합니다. 이 리소스에서 다음 속성을 설정하여 .zip 파일 아카이브로 함수를 생성합니다.
+ `PackageType` - `Zip`으로 설정됨
+ `CodeUri` - 함수 코드의 Amazon S3 URI, 로컬 폴더 경로 또는 [FunctionCode](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functioncode.html) 객체로 설정됨
+ `Runtime` - 선택한 런타임으로 설정됨

 AWS SAM을 사용하면 .zip 파일이 50MB보다 큰 경우 Amazon S3 버킷에 먼저 파일을 업로드할 필요가 없습니다. AWS SAM은 로컬 빌드 시스템의 위치에서 허용되는 최대 크기 250MB(압축 해제)까지 .zip 패키지를 업로드할 수 있습니다.

 AWS SAM에서 .zip 파일을 사용하여 함수를 배포하는 방법에 대해 자세히 알아보려면 **AWS SAM 개발자 안내서의 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)을 참조하세요.

**예제: AWS SAM을 사용하여 provided.al2023로 Go 함수 구축**

1. 다음 속성을 사용하여 AWS SAM 템플릿을 생성합니다.
   + **BuildMethod**: 애플리케이션의 컴파일러를 지정합니다. `go1.x`를 사용합니다.
   + **Runtime**: `provided.al2023`를 사용합니다.
   + **CodeUri**: 코드 경로를 입력합니다.
   + **Architectures**: arm64 아키텍처의 경우 `[arm64]`를 사용하고, x86\$164 명령 세트 아키텍처의 경우 `[amd64]`를 사용하거나 `Architectures` 속성을 제거합니다.  
**Example template.yaml**  

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: 'AWS::Serverless-2016-10-31'
   Resources:
     HelloWorldFunction:
       Type: AWS::Serverless::Function
       Metadata:
         BuildMethod: go1.x
       Properties:
         CodeUri: hello-world/ # folder where your main program resides
         Handler: bootstrap
         Runtime: provided.al2023
         Architectures: [arm64]
   ```

1. [sam build](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) 명령을 사용하여 실행 파일을 컴파일합니다.

   ```
   sam build
   ```

1. [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html) 명령을 사용하여 함수를 Lambda에 배포합니다.

   ```
   sam deploy --guided
   ```

### CloudFormation을 사용하여.zip 파일로 함수 생성 및 업데이트
<a name="golang-package-create-cfn"></a>

 CloudFormation을 사용하여 .zip 파일 아카이브로 Lambda 함수를 생성할 수 있습니다. .zip 파일에서 Lambda 함수를 생성하려면 먼저 Amazon S3 버킷에 파일을 업로드해야 합니다. AWS CLI를 사용하여 Amazon S3 버킷에 파일을 업로드하는 방법에 대한 지침은 **AWS CLI 사용 설명서의 [객체 이동](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)을 참조하세요.

CloudFormation 템플릿에서 `AWS::Lambda::Function` 리소스는 Lambda 함수를 지정합니다. 이 리소스에서 다음 속성을 설정하여 .zip 파일 아카이브로 함수를 생성합니다.
+ `PackageType` - `Zip`으로 설정됨
+ `Code` - `S3Bucket` 및 `S3Key` 필드에 Amazon S3 버킷 이름과 .zip 파일 이름을 입력합니다.
+ `Runtime` - 선택한 런타임으로 설정됨

 CloudFormation에서 생성하는 .zip 파일은 4MB를 초과할 수 없습니다. CloudFormation에서 .zip 파일을 사용하여 함수를 배포하는 방법에 대해 자세히 알아보려면 **CloudFormation 사용 설명서의 [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)을 참조하세요.

# 컨테이너 이미지로 Go Lambda 함수 배포
<a name="go-image"></a>

Go Lambda 함수의 컨테이너 이미지를 빌드하는 두 가지 방법이 있습니다.
+ [AWS OS 전용 기본 이미지 사용](#go-image-provided)

  Go는 다른 관리형 런타임과 다른 방법으로 구현됩니다. Go는 기본적으로 실행 가능한 바이너리로 컴파일되므로 전용 언어 런타임이 필요하지 않습니다. [OS 전용 기본 이미지](images-create.md#runtimes-images-provided)를 사용하여 Lambda용 Go 이미지를 빌드합니다. 이미지가 Lambda와 호환되도록 하려면 이미지에 `aws-lambda-go/lambda` 패키지를 포함해야 합니다.
+ [비AWS 기본 이미지 사용](#go-image-other)

  Alpine Linux, Debian 등의 다른 컨테이너 레지스트리의 대체 기본 이미지를 사용할 수 있습니다. 조직에서 생성한 사용자 지정 이미지를 사용할 수도 있습니다. 이미지가 Lambda와 호환되도록 하려면 이미지에 `aws-lambda-go/lambda` 패키지를 포함해야 합니다.

**작은 정보**  
Lambda 컨테이너 함수가 활성 상태가 되는 데 걸리는 시간을 줄이려면 Docker 설명서의 [다단계 빌드 사용](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)을 참조하세요. 효율적인 컨테이너 이미지를 빌드하려면 [Dockerfile 작성 모범 사례](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)를 따르세요.

이 페이지에서는 Lambda용 컨테이너 이미지를 빌드, 테스트 및 배포하는 방법을 설명합니다.

## Go 함수 배포를 위한 AWS 기본 이미지
<a name="go-image-base"></a>

Go는 다른 관리형 런타임과 다른 방법으로 구현됩니다. Go는 기본적으로 실행 가능한 바이너리로 컴파일되므로 전용 언어 런타임이 필요하지 않습니다. [OS 전용 기본 이미지](images-create.md#runtimes-images-provided)를 사용하여 Lambda에 Go 함수를 배포합니다.


| 이름 | 식별자 | 운영 체제 | 사용 중단 날짜 | 블록 함수 생성 | 블록 함수 업데이트 | 
| --- | --- | --- | --- | --- | --- | 
|  OS 전용 런타임  |  `provided.al2023`  |  Amazon Linux 2023  |   2029년 6월 30일   |   2029년 7월 31일   |   2029년 8월 31일   | 
|  OS 전용 런타임  |  `provided.al2`  |  Amazon Linux 2  |   2026년 7월 31일   |   2026년 8월 31일   |   2026년 9월 30일   | 

Amazon Elastic Container Registry 퍼블릭 갤러리: [gallery.ecr.aws/lambda/provided](https://gallery.ecr.aws/lambda/provided)

## Go 런타임 인터페이스 클라이언트
<a name="go-image-clients"></a>

`aws-lambda-go/lambda` 패키지에는 런타임 인터페이스의 구현이 포함되어 있습니다. 이미지에 `aws-lambda-go/lambda`를 사용하는 방법의 예는 [AWS OS 전용 기본 이미지 사용](#go-image-provided) 또는 [비AWS 기본 이미지 사용](#go-image-other) 섹션을 참조하세요.

## AWS OS 전용 기본 이미지 사용
<a name="go-image-provided"></a>

Go는 다른 관리형 런타임과 다른 방법으로 구현됩니다. Go는 기본적으로 실행 가능한 바이너리로 컴파일되므로 전용 언어 런타임이 필요하지 않습니다. [OS 전용 기본 이미지](images-create.md#runtimes-images-provided)를 사용하여 Go 함수용 컨테이너 이미지를 빌드합니다.


| Tags | 런타임 | 운영 체제 | Dockerfile | 사용 중단 | 
| --- | --- | --- | --- | --- | 
| al2023 | OS 전용 런타임 | Amazon Linux 2023 | [GitHub의 OS 전용 런타임용 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2023/Dockerfile.provided.al2023) |   2029년 6월 30일   | 
| al2 | OS 전용 런타임 | Amazon Linux 2 | [GitHub의 OS 전용 런타임용 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/provided.al2/Dockerfile.provided.al2) |   2026년 7월 31일   | 

이러한 기본 이미지에 대한 자세한 내용은 Amazon ECR 퍼블릭 갤러리의 [provided](https://gallery.ecr.aws/lambda/provided)를 참조하세요.

Go 핸들러에 [aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go) 패키지를 포함해야 합니다. 이 패키지는 런타임 인터페이스를 포함하여 Go용 프로그래밍 모델을 구현합니다.

### 사전 조건
<a name="go-custom-prerequisites"></a>

이 섹션의 단계를 완료하려면 다음이 필요합니다.
+ [AWS CLI 버전 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker)(최소 버전 25.0.0)
+ Docker [buildx 플러그인](https://github.com/docker/buildx/blob/master/README.md)
+ Go

### provided.al2023 기본 이미지에서 이미지 생성
<a name="go-custom-create"></a>

**`provided.al2023` 기본 이미지로 Go 함수를 빌드하고 배포합니다.**

1. 프로젝트에 대한 디렉터리를 생성하고 해당 디렉터리로 전환합니다.

   ```
   mkdir hello
   cd hello
   ```

1. 새 Go 모듈을 초기화합니다.

   ```
   go mod init example.com/hello-world
   ```

1. **lambda** 라이브러리를 새 모듈의 종속 구성 요소로 추가합니다.

   ```
   go get github.com/aws/aws-lambda-go/lambda
   ```

1. 이름이 `main.go`인 파일을 생성하여 텍스트 편집기에서 엽니다. Lambda 함수에 대한 코드입니다. 다음 샘플 코드를 테스트에 사용하거나 사용자 고유의 코드로 바꿀 수 있습니다.

   ```
   package main
   
   import (
   	"context"
   	"github.com/aws/aws-lambda-go/events"
   	"github.com/aws/aws-lambda-go/lambda"
   )
   
   func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
   	response := events.APIGatewayProxyResponse{
   		StatusCode: 200,
   		Body:       "\"Hello from Lambda!\"",
   	}
   	return response, nil
   }
   
   func main() {
   	lambda.Start(handler)
   }
   ```

1. 텍스트 편집기를 사용하여 프로젝트 디렉터리에 Dockerfile을 생성합니다.
   + 다음 예제 Dockerfile은 [다단계 빌드](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)를 사용합니다. 이렇게 하면 각 단계에서 다른 기본 이미지를 사용할 수 있습니다. [Go 기본 이미지](https://hub.docker.com/_/golang)와 같은 하나의 이미지를 사용하여 코드를 컴파일하고 실행 가능한 바이너리를 빌드할 수 있습니다. 그런 다음 최종 `FROM` 문에서 `provided.al2023` 등의 다른 이미지를 사용하여 Lambda에 배포할 이미지를 정의할 수 있습니다. 빌드 프로세스는 최종 배포 이미지와 분리되어 있으므로 최종 이미지에는 애플리케이션을 실행하는 데 필요한 파일만 포함됩니다.
   + 선택 사항인 `lambda.norpc` 태그를 사용하여 [lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) 라이브러리의 원격 절차 호출(RPC) 구성 요소를 제외할 수 있습니다. RPC 구성 요소는 지원 중단된 Go 1.x 런타임을 사용할 경우에만 필요합니다. RPC를 제외하면 배포 패키지의 크기가 줄어듭니다.
   + 참고로 Dockerfile 예제에는 [USER 지침](https://docs.docker.com/reference/dockerfile/#user)이 포함되어 있지 않습니다. Lambda에 컨테이너 이미지를 배포할 때 Lambda는 권한이 최소 권한인 기본 Linux 사용자를 자동으로 정의합니다. 이는 `USER` 지침이 제공되지 않을 때 `root` 사용자에게 기본 설정이 적용되는 표준 Docker 동작과는 다릅니다.  
**Example - 다단계 빌드 Dockerfile**  
**참고**  
Dockerfile에서 지정한 Go 버전(예: `golang:1.20`)이 애플리케이션을 생성하는 데 사용한 Go 버전과 동일한지 확인합니다.

   ```
   FROM golang:1.20 as build
   WORKDIR /helloworld
   # Copy dependencies list
   COPY go.mod go.sum ./
   # Build with optional lambda.norpc tag
   COPY main.go .
   RUN go build -tags lambda.norpc -o main main.go
   # Copy artifacts to a clean image
   FROM public.ecr.aws/lambda/provided:al2023
   COPY --from=build /helloworld/main ./main
   ENTRYPOINT [ "./main" ]
   ```

1. [docker build](https://docs.docker.com/engine/reference/commandline/build/) 명령으로 도커 이미지를 빌드합니다. 다음 예제에서는 이미지 이름을 `docker-image`로 지정하고 `test` [태그](https://docs.docker.com/engine/reference/commandline/build/#tag)를 지정합니다. 이미지를 Lambda와 호환되게 만들려면 `--provenance=false` 옵션을 사용해야 합니다.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**참고**  
이 명령은 빌드 머신의 아키텍처에 관계없이 컨테이너가 Lambda 실행 환경과 호환되는지 확인하기 위해 `--platform linux/amd64` 옵션을 지정합니다. ARM64 명령 세트 아키텍처를 사용하여 Lambda 함수를 생성하려는 경우 `--platform linux/arm64` 옵션을 대신 사용하도록 명령을 변경해야 합니다.

### (선택 사항) 로컬에서 이미지 테스트
<a name="go-custom-test"></a>

[런타임 인터페이스 에뮬레이터](https://github.com/aws/aws-lambda-runtime-interface-emulator/)를 사용하여 이미지를 로컬로 테스트합니다. `provided.al2023` 기본 이미지에는 런타임 인터페이스 에뮬레이터가 포함됩니다.

**로컬 시스템에 런타임 인터페이스 에뮬레이터 실행**

1. **docker run** 명령을 사용하여 Docker 이미지를 시작합니다. 다음 사항에 유의하세요.
   + `docker-image`는 이미지 이름이고 `test`는 태그입니다.
   + `./main`은 Dockerfile의 `ENTRYPOINT`입니다.

   ```
   docker run -d -p 9000:8080 \
   --entrypoint /usr/local/bin/aws-lambda-rie \
   docker-image:test ./main
   ```

   이 명령은 이미지를 컨테이너로 실행하고 `localhost:9000/2015-03-31/functions/function/invocations`에 로컬 엔드포인트를 생성합니다.

1. 새 터미널 창에서 **curl** 명령을 사용하여 다음 엔드포인트에 이벤트를 게시합니다.

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   이 명령은 빈 이벤트와 함께 함수를 간접 호출하고 응답을 반환합니다. 일부 함수에는 JSON 페이로드가 필요할 수 있습니다. 예제:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

1. 컨테이너 ID를 가져옵니다.

   ```
   docker ps
   ```

1. [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) 명령을 사용하여 컨테이너를 중지합니다. 이 명령에서 `3766c4ab331c`를 이전 단계의 컨테이너 ID로 바꿉니다.

   ```
   docker kill 3766c4ab331c
   ```

### 이미지 배포
<a name="go-custom-deploy"></a>

**Amazon ECR에 이미지 배포 및 Lambda 함수 생성**

1. [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) 명령을 실행하여 Amazon ECR 레지스트리에 대해 Docker CLI를 인증합니다.
   + `--region` 값을 Amazon ECR 리포지토리를 생성하려는 AWS 리전으로 설정합니다.
   + `111122223333`를 사용자의 AWS 계정 ID로 바꿉니다.

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html) 명령을 사용하여 Amazon ECR에 리포지토리를 생성합니다.

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**참고**  
Amazon ECR 리포지토리는 Lambda 함수와 동일한 AWS 리전 내에 있어야 합니다.

   성공하면 다음과 같은 응답이 표시됩니다.

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 이전 단계의 출력에서 `repositoryUri`를 복사합니다.

1. [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) 명령을 실행하여 로컬 이미지를 Amazon ECR 리포지토리에 최신 버전으로 태깅합니다. 이 명령에서:
   + `docker-image:test`는 Docker 이미지의 이름과 [태그](https://docs.docker.com/engine/reference/commandline/build/#tag)입니다. `docker build` 명령에서 지정한 이미지 이름 및 태그입니다.
   + `<ECRrepositoryUri>`를 복사한 `repositoryUri`로 바꿉니다. URI 끝에 `:latest`를 포함해야 합니다.

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   예제:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [docker push](https://docs.docker.com/engine/reference/commandline/push/) 명령을 실행하여 Amazon ECR 리포지토리에 로컬 이미지를 배포합니다. 리포지토리 URI 끝에 `:latest`를 포함해야 합니다.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 함수에 대한 실행 역할이 아직 없는 경우 하나 [생성](lambda-intro-execution-role.md#permissions-executionrole-api)합니다. 다음 단계에서는 역할의 Amazon 리소스 이름(ARN)이 필요합니다.

1. Lambda 함수를 생성합니다. `ImageUri`의 경우 이전의 리포지토리 URI를 지정합니다. URI 끝에 `:latest`를 포함해야 합니다.

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**참고**  
이미지가 Lambda 함수와 동일한 리전에 있는 한 다른 AWS 계정의 이미지를 사용하여 함수를 생성할 수 있습니다. 자세한 내용은 [Amazon ECR 교차 계정 권한](images-create.md#configuration-images-xaccount-permissions) 섹션을 참조하세요.

1. 함수를 간접 호출합니다.

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   다음과 같은 응답이 표시되어야 합니다.

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 함수의 출력을 보려면 `response.json` 파일을 확인합니다.

함수 코드를 업데이트하려면 이미지를 다시 빌드하고 Amazon ECR 리포지토리에 새 이미지를 업로드한 다음 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 명령을 사용하여 이미지를 Lambda 함수에 배포해야 합니다.

Lambda는 이미지 태그를 특정 이미지 다이제스트로 확인합니다. 즉, 함수를 배포하는 데 사용된 이미지 태그가 Amazon ECR의 새 이미지로 가리키는 경우 Lambda는 새 이미지를 사용하도록 함수를 자동으로 업데이트하지 않습니다.

새 이미지를 동일한 Lambda 함수에 배포하려면 Amazon ECR의 이미지 태그가 동일하게 유지되더라도 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 명령을 사용해야 합니다. 다음 예제에서 `--publish` 옵션은 업데이트된 컨테이너 이미지를 사용하여 새 버전의 함수를 생성합니다.

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## 비AWS 기본 이미지 사용
<a name="go-image-other"></a>

비 AWS 기본 이미지에서 Go용 컨테이너 이미지를 빌드할 수 있습니다. 다음 단계의 예제 Dockerfile에서는 [Alpine 기본 이미지](https://hub.docker.com/_/golang/)를 사용합니다.

Go 핸들러에 [aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go) 패키지를 포함해야 합니다. 이 패키지는 런타임 인터페이스를 포함하여 Go용 프로그래밍 모델을 구현합니다.

### 사전 조건
<a name="go-alt-prerequisites"></a>

이 섹션의 단계를 완료하려면 다음이 필요합니다.
+ [AWS CLI 버전 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker)(최소 버전 25.0.0)
+ Docker [buildx 플러그인](https://github.com/docker/buildx/blob/master/README.md)
+ Go

### 대체 기본 이미지에서 이미지 생성
<a name="go-alt-create"></a>

**Alpine 기본 이미지로 Go 함수 빌드 및 배포**

1. 프로젝트에 대한 디렉터리를 생성하고 해당 디렉터리로 전환합니다.

   ```
   mkdir hello
   cd hello
   ```

1. 새 Go 모듈을 초기화합니다.

   ```
   go mod init example.com/hello-world
   ```

1. **lambda** 라이브러리를 새 모듈의 종속 구성 요소로 추가합니다.

   ```
   go get github.com/aws/aws-lambda-go/lambda
   ```

1. 이름이 `main.go`인 파일을 생성하여 텍스트 편집기에서 엽니다. Lambda 함수에 대한 코드입니다. 다음 샘플 코드를 테스트에 사용하거나 사용자 고유의 코드로 바꿀 수 있습니다.

   ```
   package main
   
   import (
   	"context"
   	"github.com/aws/aws-lambda-go/events"
   	"github.com/aws/aws-lambda-go/lambda"
   )
   
   func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
   	response := events.APIGatewayProxyResponse{
   		StatusCode: 200,
   		Body:       "\"Hello from Lambda!\"",
   	}
   	return response, nil
   }
   
   func main() {
   	lambda.Start(handler)
   }
   ```

1. 텍스트 편집기를 사용하여 프로젝트 디렉터리에 Dockerfile을 생성합니다. 다음 예제 Dockerfile에서는 [Alpine 기본 이미지](https://hub.docker.com/_/golang/)를 사용합니다. 참고로 Dockerfile 예제에는 [USER 지침](https://docs.docker.com/reference/dockerfile/#user)이 포함되어 있지 않습니다. Lambda에 컨테이너 이미지를 배포할 때 Lambda는 권한이 최소 권한인 기본 Linux 사용자를 자동으로 정의합니다. 이는 `USER` 지침이 제공되지 않을 때 `root` 사용자에게 기본 설정이 적용되는 표준 Docker 동작과는 다릅니다.  
**Example Dockerfile**  
**참고**  
Dockerfile에서 지정한 Go 버전(예: `golang:1.20`)이 애플리케이션을 생성하는 데 사용한 Go 버전과 동일한지 확인합니다.

   ```
   FROM golang:1.20.2-alpine3.16 as build
   WORKDIR /helloworld
   # Copy dependencies list
   COPY go.mod go.sum ./
   # Build
   COPY main.go .
   RUN go build -o main main.go
   # Copy artifacts to a clean image
   FROM alpine:3.16
   COPY --from=build /helloworld/main /main
   ENTRYPOINT [ "/main" ]
   ```

1. [docker build](https://docs.docker.com/engine/reference/commandline/build/) 명령으로 도커 이미지를 빌드합니다. 다음 예제에서는 이미지 이름을 `docker-image`로 지정하고 `test` [태그](https://docs.docker.com/engine/reference/commandline/build/#tag)를 지정합니다. 이미지를 Lambda와 호환되게 만들려면 `--provenance=false` 옵션을 사용해야 합니다.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**참고**  
이 명령은 빌드 머신의 아키텍처에 관계없이 컨테이너가 Lambda 실행 환경과 호환되는지 확인하기 위해 `--platform linux/amd64` 옵션을 지정합니다. ARM64 명령 세트 아키텍처를 사용하여 Lambda 함수를 생성하려는 경우 `--platform linux/arm64` 옵션을 대신 사용하도록 명령을 변경해야 합니다.

### (선택 사항) 로컬에서 이미지 테스트
<a name="go-alt-test"></a>

[런타임 인터페이스 에뮬레이터](https://github.com/aws/aws-lambda-runtime-interface-emulator/)를 사용하여 이미지를 로컬로 테스트합니다. [에뮬레이터를 이미지에 빌드](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image)하거나 다음 절차를 사용하여 로컬 시스템에 설치할 수 있습니다.

**로컬 시스템에 런타임 인터페이스 에뮬레이터 설치 및 실행**

1. 프로젝트 디렉터리에서 다음 명령을 실행하여 GitHub에서 런타임 인터페이스 에뮬레이터(x86-64 아키텍처)를 다운로드하고 로컬 시스템에 설치합니다.

------
#### [ Linux/macOS ]

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   arm64 에뮬레이터를 설치하려면 이전 명령의 GitHub 리포지토리 URL을 다음과 같이 바꿉니다.

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------
#### [ PowerShell ]

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   arm64 에뮬레이터를 설치하려면 `$downloadLink`을(를) 다음과 같이 바꿉니다.

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. **docker run** 명령을 사용하여 Docker 이미지를 시작합니다. 다음 사항에 유의하세요.
   + `docker-image`는 이미지 이름이고 `test`는 태그입니다.
   + `/main`은 Dockerfile의 `ENTRYPOINT`입니다.

------
#### [ Linux/macOS ]

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /main
   ```

------
#### [ PowerShell ]

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /main
   ```

------

   이 명령은 이미지를 컨테이너로 실행하고 `localhost:9000/2015-03-31/functions/function/invocations`에 로컬 엔드포인트를 생성합니다.
**참고**  
ARM64 명령 세트 아키텍처를 위한 도커 이미지를 빌드한 경우 `--platform linux/arm64` 옵션을 `--platform linux/amd64` 대신 사용해야 합니다.

1. 로컬 엔드포인트에 이벤트를 게시합니다.

------
#### [ Linux/macOS ]

   Linux 및 macOS에서 다음 `curl` 명령을 실행합니다.

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   이 명령은 빈 이벤트와 함께 함수를 간접 호출하고 응답을 반환합니다. 샘플 함수 코드가 아닌 자체 함수 코드를 사용하는 경우 JSON 페이로드로 함수를 간접 호출할 수 있습니다. 예제:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   PowerShell에서 다음 `Invoke-WebRequest` 명령을 실행합니다.

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   이 명령은 빈 이벤트와 함께 함수를 간접 호출하고 응답을 반환합니다. 샘플 함수 코드가 아닌 자체 함수 코드를 사용하는 경우 JSON 페이로드로 함수를 간접 호출할 수 있습니다. 예제:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. 컨테이너 ID를 가져옵니다.

   ```
   docker ps
   ```

1. [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) 명령을 사용하여 컨테이너를 중지합니다. 이 명령에서 `3766c4ab331c`를 이전 단계의 컨테이너 ID로 바꿉니다.

   ```
   docker kill 3766c4ab331c
   ```

### 이미지 배포
<a name="go-alt-deploy"></a>

**Amazon ECR에 이미지 배포 및 Lambda 함수 생성**

1. [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) 명령을 실행하여 Amazon ECR 레지스트리에 대해 Docker CLI를 인증합니다.
   + `--region` 값을 Amazon ECR 리포지토리를 생성하려는 AWS 리전으로 설정합니다.
   + `111122223333`를 사용자의 AWS 계정 ID로 바꿉니다.

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html) 명령을 사용하여 Amazon ECR에 리포지토리를 생성합니다.

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**참고**  
Amazon ECR 리포지토리는 Lambda 함수와 동일한 AWS 리전 내에 있어야 합니다.

   성공하면 다음과 같은 응답이 표시됩니다.

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 이전 단계의 출력에서 `repositoryUri`를 복사합니다.

1. [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) 명령을 실행하여 로컬 이미지를 Amazon ECR 리포지토리에 최신 버전으로 태깅합니다. 이 명령에서:
   + `docker-image:test`는 Docker 이미지의 이름과 [태그](https://docs.docker.com/engine/reference/commandline/build/#tag)입니다. `docker build` 명령에서 지정한 이미지 이름 및 태그입니다.
   + `<ECRrepositoryUri>`를 복사한 `repositoryUri`로 바꿉니다. URI 끝에 `:latest`를 포함해야 합니다.

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   예제:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [docker push](https://docs.docker.com/engine/reference/commandline/push/) 명령을 실행하여 Amazon ECR 리포지토리에 로컬 이미지를 배포합니다. 리포지토리 URI 끝에 `:latest`를 포함해야 합니다.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 함수에 대한 실행 역할이 아직 없는 경우 하나 [생성](lambda-intro-execution-role.md#permissions-executionrole-api)합니다. 다음 단계에서는 역할의 Amazon 리소스 이름(ARN)이 필요합니다.

1. Lambda 함수를 생성합니다. `ImageUri`의 경우 이전의 리포지토리 URI를 지정합니다. URI 끝에 `:latest`를 포함해야 합니다.

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**참고**  
이미지가 Lambda 함수와 동일한 리전에 있는 한 다른 AWS 계정의 이미지를 사용하여 함수를 생성할 수 있습니다. 자세한 내용은 [Amazon ECR 교차 계정 권한](images-create.md#configuration-images-xaccount-permissions) 섹션을 참조하세요.

1. 함수를 간접 호출합니다.

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   다음과 같은 응답이 표시되어야 합니다.

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 함수의 출력을 보려면 `response.json` 파일을 확인합니다.

함수 코드를 업데이트하려면 이미지를 다시 빌드하고 Amazon ECR 리포지토리에 새 이미지를 업로드한 다음 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 명령을 사용하여 이미지를 Lambda 함수에 배포해야 합니다.

Lambda는 이미지 태그를 특정 이미지 다이제스트로 확인합니다. 즉, 함수를 배포하는 데 사용된 이미지 태그가 Amazon ECR의 새 이미지로 가리키는 경우 Lambda는 새 이미지를 사용하도록 함수를 자동으로 업데이트하지 않습니다.

새 이미지를 동일한 Lambda 함수에 배포하려면 Amazon ECR의 이미지 태그가 동일하게 유지되더라도 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 명령을 사용해야 합니다. 다음 예제에서 `--publish` 옵션은 업데이트된 컨테이너 이미지를 사용하여 새 버전의 함수를 생성합니다.

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

# Go Lambda 함수를 위한 계층 작업
<a name="golang-layers"></a>

Go로 작성된 Lambda 함수의 종속성을 관리하는 데는 [계층](chapter-layers.md)을 사용하지 않는 것이 좋습니다. 이는 Go의 Lambda 함수가 단일 실행 파일로 컴파일되어 함수를 배포할 때 Lambda에 제공하기 때문입니다. 이 실행 파일에는 컴파일된 함수 코드와 모든 종속성이 포함되어 있습니다. 계층을 사용하면 이 프로세스가 복잡해질 뿐만 아니라 함수가 초기화 단계에서 추가 어셈블리를 메모리에 수동으로 로드해야 하기 때문에 콜드 스타트 시간이 늘어납니다.

Go 핸들러와 함께 외부 종속성을 사용하려면 배포 패키지에 외부 종속성을 직접 포함하세요. 이렇게 하면 배포 프로세스를 간소화하고 내장된 Go 컴파일러 최적화를 활용할 수 있습니다. 함수에서 AWS SDK for Go와 같은 종속 항목을 가져와서 사용하는 방법에 대한 예제는 [Go에서 Lambda 함수 핸들러 정의](golang-handler.md) 섹션을 참조하세요.

# Go Lambda 함수 로깅 및 모니터링
<a name="golang-logging"></a>

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

이 페이지에서는 AWS Command Line Interface, Lambda 콘솔 또는 CloudWatch 콘솔을 사용하여 Lambda 함수 코드의 로그 출력하고 액세스 로그를 생성하는 방법에 대해 설명합니다.

**Topics**
+ [로그를 반환하는 함수 생성](#golang-logging-output)
+ [Lambda 콘솔에서 로그 보기](#golang-logging-console)
+ [CloudWatch 콘솔에서 로그 보기](#golang-logging-cwconsole)
+ [AWS Command Line Interface(AWS CLI)(을)를 사용하여 로그 보기](#golang-logging-cli)
+ [로그 삭제](#golang-logging-delete)

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

함수 코드의 로그를 출력하려면, [fmt 패키지](https://golang.org/pkg/fmt/)에서 메서드를 사용하거나 `stdout` 또는 `stderr`에 쓰는 로깅 라이브러리를 사용합니다. 다음 예제에서는 [로그 패키지](https://golang.org/pkg/log/)를 사용합니다.

**Example [main.go](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-go/function/main.go) – 로깅**  

```
func handleRequest(ctx context.Context, event events.SQSEvent) (string, error) {
  // event
  eventJson, _ := json.MarshalIndent(event, "", "  ")
  log.Printf("EVENT: %s", eventJson)
  // environment variables
  log.Printf("REGION: %s", os.Getenv("AWS_REGION"))
  log.Println("ALL ENV VARS:")
  for _, element := range os.Environ() {
    log.Println(element)
  }
```

**Example 로그 형식**  

```
START RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71 Version: $LATEST
2020/03/27 03:40:05 EVENT: {
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "Hello from SQS!",
      "md5OfBody": "7b27xmplb47ff90a553787216d55d91d",
      "md5OfMessageAttributes": "",
      "attributes": {
        "ApproximateFirstReceiveTimestamp": "1523232000001",
        "ApproximateReceiveCount": "1",
        "SenderId": "123456789012",
        "SentTimestamp": "1523232000000"
      },
      ...
2020/03/27 03:40:05 AWS_LAMBDA_LOG_STREAM_NAME=2020/03/27/[$LATEST]569cxmplc3c34c7489e6a97ad08b4419
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_NAME=blank-go-function-9DV3XMPL6XBC
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128
2020/03/27 03:40:05 AWS_LAMBDA_FUNCTION_VERSION=$LATEST
2020/03/27 03:40:05 AWS_EXECUTION_ENV=AWS_Lambda_go1.x
END RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71
REPORT RequestId: dbda340c-xmpl-4031-8810-11bb609b4c71	Duration: 38.66 ms	Billed Duration: 243 ms	Memory Size: 128 MB	Max Memory Used: 54 MB	Init Duration: 203.69 ms	
XRAY TraceId: 1-5e7d7595-212fxmpl9ee07c4884191322	SegmentId: 42ffxmpl0645f474	Sampled: true
```

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

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

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

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

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

## CloudWatch 콘솔에서 로그 보기
<a name="golang-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="golang-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="golang-logging-delete"></a>

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

# AWS Lambda에서 Go 코드 계측
<a name="golang-tracing"></a>

Lambda는 AWS X-Ray와 통합되어 Lambda 애플리케이션을 추적, 디버깅 및 최적화할 수 있습니다. Lambda 함수와 기타 AWS 서비스를 포함할 수 있는 애플리케이션의 리소스를 탐색할 때 X-Ray를 사용하여 요청을 추적할 수 있습니다.

추적 데이터를 X-Ray로 전송하려면 다음 두 SDK 라이브러리 중 하나를 사용할 수 있습니다.
+ [AWS Distro for OpenTelemetry(ADOT)](https://aws.amazon.com/otel) - 안전하게 프로덕션 준비가 된 AWS에서 지원하는 OpenTelemetry(OTEL) SDK의 배포입니다.
+ [AWS Go용 X-Ray SDK](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go.html) – 추적 데이터를 생성하고 X-Ray에 전송하는 SDK입니다.

각 SDK는 텔레메트리 데이터를 X-Ray 서비스로 전송하는 방법을 제공합니다. X-Ray를 사용하여 애플리케이션의 성능 지표를 확인하고, 필터링하고, 인사이트를 얻어 문제와 최적화 기회를 식별할 수 있습니다.

**중요**  
X-Ray와 Powertools for AWS Lambda SDK는 AWS에서 제공하는 긴밀하게 통합된 계측 솔루션의 일부입니다. ADOT Lambda Layer는 일반적으로 더 많은 데이터를 수집하는 추적 계측기에 대한 전체 업계 표준의 일부이지만 모든 사용 사례에 적합하지는 않을 수 있습니다. 어떤 솔루션을 사용하든 X-Ray에서 엔드 투 엔드 추적 기능을 구현할 수 있습니다. 둘 중 하나를 선택하는 방법에 대해 자세히 알아보려면 [AWS Distro for Open Telemetry와 X-Ray SDK 중에서 선택하기](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)를 참조하세요.

**Topics**
+ [ADOT를 사용하여 Go 함수 계측](#golang-adot)
+ [X-Ray Go를 사용하여 Java 함수 계측](#golang-xray-sdk)
+ [Lambda 콘솔을 사용하여 추적 활성화](#golang-tracing-console)
+ [Lambda API를 사용하여 추적 활성화](#golang-tracing-api)
+ [CloudFormation을 사용하여 추적 활성화](#golang-tracing-cloudformation)
+ [X-Ray 추적 해석](#golang-tracing-interpretation)

## ADOT를 사용하여 Go 함수 계측
<a name="golang-adot"></a>

ADOT는 OTel SDK를 사용하여 원격 측정 데이터를 수집하는 데 필요한 모든 것을 패키징할 수 있는 완전 관리형 Lambda [계층](chapter-layers.md)을 제공합니다. 이 계층을 사용하면 모든 함수 코드를 수정하지 않고도 Lambda 함수를 계측할 수 있습니다. 계층을 구성하여 OTel의 사용자 지정 초기화를 수행할 수도 있습니다. 자세한 내용은 ADOT 설명서의 [Lambda에서 ADOT 컬렉터에 대한 사용자 지정 구성](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda)을 참조하세요.

Go 런타임의 경우 **ADOT Go용 AWS 관리형 Lambda 계층**을 추가하여 함수를 자동으로 계측할 수 있습니다. 이 계층을 추가하는 방법에 대한 자세한 지침은 ADOT 설명서의 [AWS Distro for OpenTelemetry Lambda Support for Go](https://aws-otel.github.io/docs/getting-started/lambda/lambda-go)를 참조하세요.

## X-Ray Go를 사용하여 Java 함수 계측
<a name="golang-xray-sdk"></a>

Lambda 함수가 애플리케이션의 다른 리소스에 대해 수행하는 호출에 대한 세부 정보를 기록하려면 AWS X-Ray Go용 SDK를 사용할 수도 있습니다. SDK를 가져오려면 `go get`을 사용하여 해당 [GitHub 리포지토리](https://github.com/aws/aws-xray-sdk-go)에서 SDK를 다운로드합니다.

```
go get github.com/aws/aws-xray-sdk-go
```

AWS SDK 클라이언트를 계측하려면 클라이언트를 `xray.AWS()` 메서드에 전달합니다. 그런 다음 메서드의 `WithContext` 버전을 사용하여 호출을 추적할 수 있습니다.

```
svc := s3.New(session.New())
xray.AWS(svc.Client)
...
svc.ListBucketsWithContext(ctx aws.Context, input *ListBucketsInput)
```

올바른 종속성을 추가하고 필요한 코드를 변경한 후 Lambda 콘솔 또는 API를 통해 함수의 구성에서 추적을 활성화합니다.

## Lambda 콘솔을 사용하여 추적 활성화
<a name="golang-tracing-console"></a>

콘솔을 사용하여 Lambda 함수에 대한 활성 추적을 전환하려면 다음 단계를 따르십시오.

**활성 추적 켜기**

1. Lambda 콘솔의 [함수 페이지](https://console.aws.amazon.com/lambda/home#/functions)를 엽니다.

1. 함수를 선택합니다.

1. **구성(Configuration)**을 선택한 다음 **모니터링 및 운영 도구(Monitoring and operations tools)**를 선택합니다.

1. **추가 모니터링 도구**에서 **편집**을 선택합니다.

1. **CloudWatch 애플리케이션 신호 및 AWS X-Ray**에서 **Lambda 서비스 트레이스**에 대해 **활성화**를 선택합니다.

1. **저장**을 선택합니다.

## Lambda API를 사용하여 추적 활성화
<a name="golang-tracing-api"></a>

AWS CLI 또는 AWS SDK를 사용하여 Lambda 함수에 대한 추적을 구성하고 다음 API 작업을 사용합니다.
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

다음 예제 AWS CLI 명령은 **my-function**이라는 함수에 대한 활성 추적을 사용 설정합니다.

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

추적 모드는 함수 버전을 게시할 때 버전별 구성의 일부입니다. 게시된 버전에 대한 추적 모드는 변경할 수 없습니다.

## CloudFormation을 사용하여 추적 활성화
<a name="golang-tracing-cloudformation"></a>

CloudFormation 템플릿에서 `AWS::Lambda::Function` 리소스에 대한 추적을 활성화하려면 `TracingConfig` 속성을 사용합니다.

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml) – 추적 구성**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

AWS Serverless Application Model(AWS SAM) `AWS::Serverless::Function` 리소스의 경우 `Tracing` 속성을 사용합니다.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) – 추적 구성**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## X-Ray 추적 해석
<a name="golang-tracing-interpretation"></a>

함수에 추적 데이터를 X-Ray로 업로드할 권한이 있어야 합니다. Lambda 콘솔에서 추적을 활성화하면 Lambda가 필요한 권한을 함수의 [실행 역할](lambda-intro-execution-role.md)에 추가합니다. 그렇지 않으면 실행 역할에 [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) 정책을 추가합니다.

활성 추적을 구성하면 애플리케이션을 통해 특정 요청을 관찰할 수 있습니다. [ X-Ray 서비스 그래프](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph)는 애플리케이션 및 모든 구성 요소에 대한 정보를 보여줍니다. 다음 예제에서는 2개의 함수가 있는 애플리케이션을 보여줍니다. 기본 함수는 이벤트를 처리하고 때로는 오류를 반환합니다. 맨 위의 두 번째 함수는 첫 번째의 로그 그룹에 나타나는 오류를 처리하고 AWS SDK를 사용하여 X-Ray, Amazon Simple Storage Service(Amazon S3), Amazon CloudWatch Logs를 호출합니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


X-Ray는 애플리케이션에 대한 모든 요청을 추적하지 않습니다. X-Ray는 모든 요청의 대표 샘플을 여전히 제공하면서 추적이 효율적으로 수행되도록 샘플링 알고리즘을 적용합니다. 샘플링 요율은 초당 요청이 1개이며 추가 요청의 5퍼센트입니다. 함수에 대해 X-Ray 샘플링 요율을 구성할 수 없습니다.

X-Ray에서 *추적*은 하나 이상의 *서비스*에서 처리되는 요청에 대한 정보를 기록합니다. Lambda는 각 추적에 대해 2개의 세그먼트를 기록하고, 이에 따라 서비스 그래프에 2개의 노드가 생성됩니다. 다음 이미지에서는 이 두 노드를 강조 표시합니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/xray-servicemap-function.png)


왼쪽의 첫 번째 노드는 호출 요청을 수신하는 Lambda 서비스를 나타냅니다. 두 번째 노드는 특정 Lambda 함수를 나타냅니다. 다음 예에서는 이러한 2개의 세그먼트가 있는 추적을 보여줍니다. 둘 다 이름이 **my-function** 이지만 하나는 오리진이 `AWS::Lambda`이고 다른 하나는 오리진이 `AWS::Lambda::Function`입니다. `AWS::Lambda` 세그먼트에 오류가 표시되면 Lambda 서비스에 문제가 있는 것입니다. `AWS::Lambda::Function` 세그먼트에 오류가 표시되면 함수에 문제가 있는 것입니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


이 예제에서는 3개의 하위 세그먼트를 표시하도록 `AWS::Lambda::Function` 세그먼트를 확장합니다.

**참고**  
AWS는 현재 Lambda 서비스에 대한 변경 사항을 구현하고 있습니다. 이러한 변경으로 인해, AWS 계정의 여러 Lambda 함수에서 내보내는 시스템 로그 메시지와 추적 세그먼트의 구조와 내용 간에 약간의 차이가 있을 수 있습니다.  
여기에 표시된 예제 트레이스는 이전 스타일의 함수 세그먼트를 보여줍니다. 이전 스타일 세그먼트와 새로운 스타일 세그먼트의 차이점은 다음 단락들에 설명되어 있습니다.  
이러한 변경 사항은 앞으로 몇 주 동안 구현되며, 중국 및 GovCloud 리전을 제외한 모든 AWS 리전의 모든 기능은 새로운 형식의 로그 메시지 및 추적 세그먼트를 사용하도록 전환됩니다.

이전 스타일의 함수 세그먼트에는 다음과 같은 하위 세그먼트가 포함됩니다.
+ **초기화** – 함수를 로드하고 [초기화 코드](foundation-progmodel.md)를 실행하는 데 소요된 시간을 나타냅니다. 이 하위 세그먼트는 함수의 각 인스턴스에서 처리하는 첫 번째 이벤트에 대해서만 표시됩니다.
+ **호출**— 핸들러 코드를 실행하는 데 소요된 시간을 나타냅니다.
+ **오버헤드** – Lambda 런타임이 다음 이벤트를 처리하기 위해 준비하는 데 소비하는 시간을 나타냅니다.

새로운 스타일의 함수 세그먼트에는 `Invocation` 하위 세그먼트가 포함되지 않습니다. 대신, 고객 하위 세그먼트는 함수 세그먼트에 직접 연결됩니다. 이전 스타일과 새로운 스타일의 함수 세그먼트의 구조에 대한 자세한 내용은 [X-Ray 추적 이해](services-xray.md#services-xray-traces)를 참조하세요.

HTTP 클라이언트를 계측하고, SQL 쿼리를 기록하고, 주석 및 메타데이터가 있는 사용자 지정 하위 세그먼트를 생성할 수도 있습니다. 자세한 내용은 *AWS X-Ray 개발자 안내서*의 [AWS X-Ray SDK for Go](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-python.html)를 참조하세요.

**가격 책정**  
X-Ray 추적을 AWS 프리 티어의 일부로서 특정 한도까지 매월 무료로 사용할 수 있습니다. 해당 한도를 초과하면 추적 저장 및 검색에 대한 X-Ray 요금이 부과됩니다. 자세한 내용은 [AWS X-Ray 요금](https://aws.amazon.com/xray/pricing/)을 참조하십시오.