

# 使用 Lambda 上下文对象检索 Go 函数信息
<a name="golang-context"></a>

在 Lambda，此上下文对象提供的方法和属性包含有关调用、函数和执行环境的信息。当 Lambda 运行您的函数时，它会将上下文对象传递到[处理程序](golang-handler.md)。要在处理程序中使用上下文对象，您可以选择将其声明为处理程序的输入参数。如果您想在处理程序中进行以下操作，则上下文对象为必需项：
+ 您需要访问上下文对象提供的任何[全局变量、方法或属性](#golang-context-library)。如 [访问调用上下文信息](#golang-context-access) 中所示，这些方法和属性对于确定调用函数的实体或测量函数调用时间等任务非常有用。
+ 您需要使用 适用于 Go 的 AWS SDK 来调用其他服务。上下文对象是大多数调用的重要输入参数。有关更多信息，请参阅 [在 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 Resource Name (ARN)。表明调用者是否指定了版本号或别名。
+ `AwsRequestID` – 调用请求的标识符。
+ `Identity` –（移动应用程序）有关授权请求的 Amazon Cognito 身份的信息。
+ `ClientContext` –（移动应用程序）客户端应用程序提供给 Lambda 的客户端上下文。

## 访问调用上下文信息
<a name="golang-context-access"></a>

Lambda 函数可以访问有关其环境和调用请求的元数据。这可以在[程序包上下文](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` 是用于使用 context 对象捕获的信息的变量，`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>

如果处理程序需要使用 适用于 Go 的 AWS SDK 来调用其他服务，请将上下文对象作为处理程序的输入包括在内。在 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 调用中传入正确的上下文对象。