

# Construir funções do Lambda com C\$1
<a name="lambda-csharp"></a>

Você pode executar a aplicação do .NET no Lambda usando o runtime do .NET 8 gerenciado, um runtime personalizado ou uma imagem de contêiner. Depois que o código da aplicação for compilado, você poderá implantá-lo no Lambda como um arquivo .zip ou uma imagem de contêiner. O Lambda fornece os seguintes runtimes para linguagens .NET:


| Nome | Identificador | Sistema operacional | Data da substituição | Bloquear a criação de funções | Bloquear a atualização de funções | 
| --- | --- | --- | --- | --- | --- | 
|  .NET 10  |  `dotnet10`  |  Amazon Linux 2023  |   14 de novembro de 2028   |   14 de dezembro de 2028   |   15 de janeiro de 2029   | 
|  .NET 9 (somente contêiner)  |  `dotnet9`  |  Amazon Linux 2023  |   10 de novembro de 2026   |   Não programado   |   Não programado   | 
|  .NET 8  |  `dotnet8`  |  Amazon Linux 2023  |   10 de novembro de 2026   |   10 de dezembro de 2026   |   11 de janeiro de 2027   | 

## Configurar seu ambiente de desenvolvimento .NET
<a name="csharp-dev-env"></a>

Para desenvolver e compilar funções do Lambda, você pode usar qualquer um dos ambientes de desenvolvimento integrados (IDEs) .NET comumente disponíveis, como Microsoft Visual Studio, Visual Studio Code e JetBrains Rider. Para simplificar sua experiência de desenvolvimento, a AWS fornece um conjunto de modelos de projeto do .NET, bem como a interface de linha de comando (CLI) do `Amazon.Lambda.Tools`.

Execute os seguintes comandos da CLI do .NET para instalar esses modelos de projeto e ferramentas de linha de comando.

### Instalar os modelos de projeto do .NET
<a name="csharp-dev-env-templates"></a>

Para instalar os modelos de projeto, execute o seguinte comando:

```
dotnet new install Amazon.Lambda.Templates
```

### Instalar e atualizar as ferramentas da CLI
<a name="csharp-dev-env-cli-tools"></a>

Execute os comandos a seguir para instalar, atualizar e desinstalar a CLI do `Amazon.Lambda.Tools`.

Para instalar as ferramentas da linha de comando:

```
dotnet tool install -g Amazon.Lambda.Tools
```

Para atualizar as ferramentas da linha de comando:

```
dotnet tool update -g Amazon.Lambda.Tools
```

Para desinstalar as ferramentas da linha de comando:

```
dotnet tool uninstall -g Amazon.Lambda.Tools
```

# Definir o manipulador de função do Lambda em C\$1
<a name="csharp-handler"></a>

O *manipulador* da função do Lambda é o método no código da função que processa eventos. Quando sua função é invocada, o Lambda executa o método do manipulador. A função é executada até que o manipulador retorne uma resposta, seja encerrado ou atinja o tempo limite.

Esta página descreve como trabalhar com manipuladores de função do Lambda em C\$1 para trabalhar com o runtime gerenciado do .NET, incluindo opções para a configuração de projeto, convenções de nomenclatura e práticas recomendadas. Além disso, esta página apresenta um exemplo de uma função do Lambda em C\$1 que aceita informações sobre um pedido, produz um recibo em formato de texto e armazena esse arquivo em um bucket do Amazon Simple Storage Service (S3). Para obter mais informações sobre como implantar a função após gravá-la, consulte [Criar e implantar funções do Lambda em C\$1 com arquivos .zip](csharp-package.md) ou [Implantar funções do Lambda em .NET com imagens de contêiner](csharp-image.md).

**Topics**
+ [

## Configurar o projeto de manipulador em C\$1
](#csharp-handler-setup)
+ [

## Exemplo de código de função do Lambda em C\$1
](#csharp-example-code)
+ [

## Manipuladores de bibliotecas de classes
](#csharp-class-library-handlers)
+ [

## Manipuladores de assembly executáveis
](#csharp-executable-assembly-handlers)
+ [

## Assinaturas de manipulador válidas para funções em C\$1
](#csharp-handler-signatures)
+ [

## Convenções de nomenclatura para manipuladores
](#csharp-handler-naming)
+ [

## Serialização em funções do Lambda em C\$1
](#csharp-handler-serializer)
+ [

## Funções baseadas em arquivos
](#csharp-file-based-functions)
+ [

## Acesso e uso do objeto de contexto do Lambda
](#csharp-example-context)
+ [

## Uso do SDK para .NET v3 em seu manipulador
](#csharp-example-sdk-usage)
+ [

## Acesso a variáveis de ambiente
](#csharp-example-envvars)
+ [

## Usar o estado global
](#csharp-handler-state)
+ [

## Simplificar o código da função com a estrutura Lambda Annotations
](#csharp-handler-annotations)
+ [

## Práticas recomendadas de código para as funções do Lambda em C\$1
](#csharp-best-practices)

## Configurar o projeto de manipulador em C\$1
<a name="csharp-handler-setup"></a>

Ao trabalhar com funções do Lambda em C\$1, o processo envolve escrever seu código e, em seguida, implantá-lo no Lambda. Há dois modelos de execução diferentes para implantar funções do Lambda no .NET: a abordagem de biblioteca de classes e a abordagem de assembly executável.

Na abordagem de biblioteca de classes, você empacota seu código de função como um assembly .NET (`.dll`) e o implanta no Lambda com o runtime gerenciado do .NET (`dotnet8`). Para o nome do manipulador, o Lambda espera uma string no formato `AssemblyName::Namespace.Classname::Methodname`. Durante a fase de inicialização da função, a classe da função é inicializada e qualquer código no construtor é executado.

Na abordagem de assembly executável, você usa o [recurso de instruções de nível superior](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/top-level-statements) que foi introduzido pela primeira vez no C\$1 9. Essa abordagem gera um assembly executável que o Lambda executa sempre que recebe um comando invocar para a função. Nessa abordagem, você também usa o runtime gerenciado do .NET (`dotnet8`). Para o nome do manipulador, você fornece ao Lambda o nome do assembly executável a ser executado.

O principal exemplo desta página ilustra a abordagem de biblioteca de classes. É possível inicializar seu projeto do Lambda em C\$1 de várias formas, mas a maneira mais fácil é usar a CLI do .NET com a CLI do `Amazon.Lambda.Tools`. Configure a CLI do `Amazon.Lambda.Tools` seguindo as etapas em [Configurar seu ambiente de desenvolvimento .NET](lambda-csharp.md#csharp-dev-env). Em seguida, inicialize o projeto com o comando:

```
dotnet new lambda.EmptyFunction --name ExampleCS
```

Esse comando gera a seguinte estrutura de arquivos:

```
/project-root 
    └ src
        └ ExampleCS
            └ Function.cs (contains main handler)
            └ Readme.md
            └ aws-lambda-tools-defaults.json
            └ ExampleCS.csproj          
    └ test
         └ ExampleCS.Tests
            └ FunctionTest.cs (contains main handler)
            └ ExampleCS.Tests.csproj
```

Nessa estrutura de arquivos, a lógica do manipulador principal da sua função reside no arquivo `Function.cs`.

## Exemplo de código de função do Lambda em C\$1
<a name="csharp-example-code"></a>

O exemplo de código apresentado a seguir para uma função do Lambda em C\$1 aceita informações sobre um pedido, produz um recibo em formato de texto e armazena esse arquivo em um bucket do Amazon S3.

**Example `Function.cs`Função do Lambda em**  

```
using System;
using System.Text;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;

// Assembly attribute to enable Lambda function logging
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace ExampleLambda;

public class Order
{
    public string OrderId { get; set; } = string.Empty;
    public double Amount { get; set; }
    public string Item { get; set; } = string.Empty;
}

public class OrderHandler
{
    private static readonly AmazonS3Client s3Client = new();

    public async Task<string> HandleRequest(Order order, ILambdaContext context)
    {
        try
        {
            string? bucketName = Environment.GetEnvironmentVariable("RECEIPT_BUCKET");
            if (string.IsNullOrWhiteSpace(bucketName))
            {
                throw new ArgumentException("RECEIPT_BUCKET environment variable is not set");
            }

            string receiptContent = $"OrderID: {order.OrderId}\nAmount: ${order.Amount:F2}\nItem: {order.Item}";
            string key = $"receipts/{order.OrderId}.txt";

            await UploadReceiptToS3(bucketName, key, receiptContent);

            context.Logger.LogInformation($"Successfully processed order {order.OrderId} and stored receipt in S3 bucket {bucketName}");
            return "Success";
        }
        catch (Exception ex)
        {
            context.Logger.LogError($"Failed to process order: {ex.Message}");
            throw;
        }
    }

    private async Task UploadReceiptToS3(string bucketName, string key, string receiptContent)
    {
        try
        {
            var putRequest = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = key,
                ContentBody = receiptContent,
                ContentType = "text/plain"
            };

            await s3Client.PutObjectAsync(putRequest);
        }
        catch (AmazonS3Exception ex)
        {
            throw new Exception($"Failed to upload receipt to S3: {ex.Message}", ex);
        }
    }
}
```

Este arquivo `Function.cs` contém as seguintes seções de código:
+ Declarações de `using`: use-as para importar as classes C\$1 exigidas por sua função do Lambda.
+ `[assembly: LambdaSerializer(...)]`: `LambdaSerializer` é um atributo de assembly que informa ao Lambda para converter automaticamente as cargas úteis de eventos JSON em objetos C\$1 antes de passá-las para sua função.
+ `namespace ExampleLambda`: define o namespace. Em C\$1, o nome do namespace não precisa corresponder ao nome do arquivo.
+ `public class Order {...}`: define o formato do evento de entrada esperado.
+ `public class OrderHandler {...}`: define sua classe C\$1. Aqui você definirá o método principal do manipulador e quaisquer outros métodos auxiliares.
+ `private static readonly AmazonS3Client s3Client = new();`: inicializa um cliente do Amazon S3 com a cadeia de provedores de credenciais padrão, fora do método do manipulador principal. Isso faz com que o Lambda execute esse código durante a fase de [inicialização](lambda-runtime-environment.md#runtimes-lifecycle-ib).
+ `public async ... HandleRequest (Order order, ILambdaContext context)`: este é o **método principal do manipulador**, que contém a lógica principal da sua aplicação.
+ `private async Task UploadReceiptToS3(...) {}`: este é um método auxiliar que é referenciado pelo método principal do manipulador `handleRequest`.

Como essa função requer um cliente do Amazon S3 SDK, você deve adicioná-lo às dependências do seu projeto. Você pode fazer isso navegando até `src/ExampleCS` e executando o seguinte comando:

```
dotnet add package AWSSDK.S3
```

### Adicione informações de metadados a aws-lambda-tools-defaults.json
<a name="csharp-metadata-example"></a>

Por padrão, o arquivo `aws-lambda-tools-defaults.json` gerado não contém informações `profile` ou `region` para sua função. Além disso, atualize a string `function-handler` com o valor correto (`ExampleCS::ExampleLambda.OrderHandler::HandleRequest`). Você pode fazer essa atualização manualmente e adicionar os metadados necessários para usar um perfil de credenciais e uma região específicos para sua função. Por exemplo, seu arquivo `aws-lambda-tools-defaults.json` deve ser semelhante a este:

```
{
  "Information": [
    "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
    "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
    "dotnet lambda help",
    "All the command line options for the Lambda command can be specified in this file."
  ],
  "profile": "default",
  "region": "us-east-1",
  "configuration": "Release",
  "function-architecture": "x86_64",
  "function-runtime": "dotnet8",
  "function-memory-size": 512,
  "function-timeout": 30,
  "function-handler": "ExampleCS::ExampleLambda.OrderHandler::HandleRequest"
}
```

Para que esta função funcione corretamente, seu [ perfil de execução](lambda-intro-execution-role.md) deve permitir a ação `s3:PutObject`. Além disso, certifique-se de definir a variável de ambiente `RECEIPT_BUCKET`. Após uma invocação com êxito, o bucket do Amazon S3 deve conter um arquivo de recibo.

## Manipuladores de bibliotecas de classes
<a name="csharp-class-library-handlers"></a>

O principal [exemplo de código](#csharp-example-code) desta página ilustra um manipulador de biblioteca de classes. Os manipuladores de biblioteca de classes têm a seguinte estrutura:

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace NAMESPACE;

...

public class CLASSNAME {
    public async Task<string> METHODNAME (...) {
    ...
    }
}
```

Ao criar uma função do Lambda, você precisa fornecer ao Lambda informações sobre o manipulador da função na forma de uma string no campo [Manipulador](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler). Isso informa ao Lambda qual método do código deve ser executado quando sua função é invocada. Em C\$1, para manipuladores de bibliotecas de classes, o formato da string do manipulador é `ASSEMBLY::TYPE::METHOD`, onde:
+ `ASSEMBLY` é o nome do arquivo de assembly do .NET para a aplicação. Se você usar a CLI do `Amazon.Lambda.Tools` para criar a aplicação e não definir o nome do assembly usando a propriedade `AssemblyName` no arquivo `.csproj`, `ASSEMBLY` será simplesmente o nome do arquivo `.csproj`.
+ `TYPE` é o nome completo do tipo do manipulador, ou seja, `NAMESPACE.CLASSNAME`.
+ `METHOD` é o nome do método do manipulador principal no código, ou seja, `METHODNAME`.

Para o código de exemplo principal nesta página, se o assembly for denominado `ExampleCS`, a string completa do manipulador será `ExampleCS::ExampleLambda.OrderHandler::HandleRequest`.

## Manipuladores de assembly executáveis
<a name="csharp-executable-assembly-handlers"></a>

Também é possível definir funções do Lambda em C\$1 como um assembly executável. Os manipuladores de assembly executáveis utilizam o recurso de instruções de nível superior do C\$1, no qual o compilador gera o método `Main()` e coloca o código da sua função dentro dele. Ao usar assemblies executáveis, o runtime do Lambda deve ser inicializado. Para fazer isso, use o método `LambdaBootstrapBuilder.Create` no código. As entradas para este método são a função do manipulador principal, bem como o serializador do Lambda a ser usado. O seguinte exemplo mostra um manipulador de assembly executável em C\$1:

```
namespace GetProductHandler;

IDatabaseRepository repo = new DatabaseRepository();

await LambdaBootstrapBuilder.Create<APIGatewayProxyRequest>(Handler, new DefaultLambdaJsonSerializer())
    .Build()
    .RunAsync();

async Task<APIGatewayProxyResponse> Handler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
    var id = apigProxyEvent.PathParameters["id"];
    var databaseRecord = await this.repo.GetById(id);
    
    return new APIGatewayProxyResponse 
    {
        StatusCode = (int)HttpStatusCode.OK,
        Body = JsonSerializer.Serialize(databaseRecord)
    };
};
```

No campo [Manipulador](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler) para manipuladores de assemblies executáveis, a string do manipulador que diz ao Lambda como executar seu código é o nome do assembly. Nesse exemplo, é `GetProductHandler`.

## Assinaturas de manipulador válidas para funções em C\$1
<a name="csharp-handler-signatures"></a>

Em C\$1, as assinaturas de manipulador do Lambda válidas aceitam entre 0 e 2 argumentos. Normalmente, sua assinatura de manipulador tem dois argumentos, conforme mostrado no exemplo principal:

```
public async Task<string> HandleRequest(Order order, ILambdaContext context)
```

Ao fornecer dois argumentos, o primeiro argumento deve ser a entrada do evento e o segundo argumento deve ser o objeto de contexto do Lambda. Ambos os argumentos são opcionais. Por exemplo, as seguintes também são assinaturas válidas do manipulador do Lambda em C\$1:
+ `public async Task<string> HandleRequest()`
+ `public async Task<string> HandleRequest(Order order)`
+ `public async Task<string> HandleRequest(ILambdaContext context)`

Além da sintaxe básica da assinatura do manipulador, há algumas restrições adicionais:
+ Não é possível usar a palavra-chave `unsafe` na assinatura do manipulador. No entanto, é possível usar o contexto `unsafe` dentro do método manipulador e suas dependências. Para obter mais informações, consulte [unsafe (referência de C\$1)](https://msdn.microsoft.com/en-us/library/chfa2zb8.aspx) no site de documentação da Microsoft.
+ O manipulador não pode usar a palavra-chave `params` nem usar `ArgIterator` como parâmetro de entrada ou retorno. Essas palavras-chave oferecem suporte a um número variável de parâmetros. O número máximo de argumentos que seu manipulador pode aceitar é dois.
+ O manipulador não pode ser um método genérico. Em outras palavras, ele não pode usar parâmetros de tipo genérico, como `<T>`.
+ O Lambda não oferece suporte a manipuladores assíncronos com `async void` na assinatura.

## Convenções de nomenclatura para manipuladores
<a name="csharp-handler-naming"></a>

Os manipuladores do Lambda em C\$1 não têm restrições estritas de nomenclatura. No entanto, é necessário garantir que você forneça a string correta do manipulador ao Lambda ao implantar a função. A string correta do manipulador depende se você está implantando um manipulador de [biblioteca de classes](#csharp-class-library-handlers) ou um [manipulador de montagem executável](#csharp-executable-assembly-handlers).

Apesar de ser possível usar um nome qualquer para o manipulador, os nomes das funções em C\$1 geralmente estão em PascalCase. Além disso, embora o nome do arquivo não precise corresponder ao nome da classe ou do manipulador, geralmente é prática recomendada usar um nome de arquivo como `OrderHandler.cs` se o nome da classe for `OrderHandler`. Por exemplo, é possível modificar o nome do arquivo neste exemplo de `Function.cs` para `OrderHandler.cs`.

## Serialização em funções do Lambda em C\$1
<a name="csharp-handler-serializer"></a>

O formato de entrada JSON é o mais comum e padrão para funções do Lambda. Neste exemplo, a função espera uma entrada semelhante à seguinte:

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

Em C\$1, é possível definir o formato do evento de entrada esperado em uma classe. Neste exemplo, definimos a classe `Order` para modelar essa entrada:

```
public class Order
{
    public string OrderId { get; set; } = string.Empty;
    public double Amount { get; set; }
    public string Item { get; set; } = string.Empty;
}
```

Se a função do Lambda usar tipos de entrada ou de saída diferentes de objeto `Stream`, você deverá adicionar uma biblioteca de serialização à aplicação. Isso permite converter a entrada JSON em uma instância da classe que você definiu. Há dois métodos de serialização para funções em C\$1 no Lambda: serialização baseada em reflexão e serialização gerada por código-fonte.

### Serialização baseada em reflexão
<a name="csharp-reflection-based-serialization"></a>

A AWS fornece bibliotecas pré-criadas que você pode adicionar rapidamente à aplicação. Essas bibliotecas implementam a serialização usando [reflexão](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/reflection-and-attributes/). Use um dos pacotes a seguir para implementar a serialização baseada em reflexão:
+ `Amazon.Lambda.Serialization.SystemTextJson`: no backend, esse pacote usa `System.Text.Json` para realizar tarefas de serialização.
+ `Amazon.Lambda.Serialization.Json`: no backend, esse pacote usa `Newtonsoft.Json` para realizar tarefas de serialização.

Você pode criar sua própria biblioteca de serialização implementando a interface `ILambdaSerializer`, que está disponível como parte da biblioteca `Amazon.Lambda.Core`. Essa interface define dois métodos:
+ `T Deserialize<T>(Stream requestStream);`

  Você implementa esse método para desserializar a carga útil da solicitação da API `Invoke` no objeto que é passado para o manipulador da função do Lambda.
+ `T Serialize<T>(T response, Stream responseStream);`

  Você implementa esse método para serializar o resultado retornado pelo manipulador da função do Lambda na carga útil da resposta retornada pela operação da API `Invoke`.

O exemplo principal nesta página usa serialização baseada em reflexão. A serialização baseada em reflexão funciona imediatamente com o AWS Lambda e não requer configuração adicional, o que a torna uma boa opção para simplificação. No entanto, ela requer mais uso da memória funcional. Você também pode ver latências de função mais altas devido à reflexão do runtime.

### Serialização gerada por código-fonte
<a name="csharp-source-generated-serialization"></a>

Com a serialização gerada por código-fonte, o código de serialização é gerado em tempo de compilação. Isso elimina a necessidade de reflexão e pode melhorar a performance da função. Para usar a serialização gerada por código-fonte na função, é necessário fazer o seguinte:
+ Crie uma nova classe parcial herdada de `JsonSerializerContext`, adicionando atributos `JsonSerializable` para todos os tipos que exigem serialização ou desserialização.
+ Configure o `LambdaSerializer` para usar um `SourceGeneratorLambdaJsonSerializer<T>`.
+ Atualize qualquer serialização ou desserialização manual no código da aplicação para usar a classe recém-criada.

O exemplo a seguir mostra como você pode modificar o exemplo principal nesta página, que usa serialização baseada em reflexão, para usar a serialização gerada por código-fonte.

```
using System.Text.Json;
using System.Text.Json.Serialization;

...

public class Order
{
    public string OrderId { get; set; } = string.Empty;
    public double Amount { get; set; }
    public string Item { get; set; } = string.Empty;
}

[JsonSerializable(typeof(Order))]
public partial class OrderJsonContext : JsonSerializerContext {}

public class OrderHandler
{

    ...

    public async Task<string> HandleRequest(string input, ILambdaContext context)
    {
    
    var order = JsonSerializer.Deserialize(input, OrderJsonContext.Default.Order);
    
    ...
    
    }

}
```

A serialização gerada por código-fonte requer mais configuração do que a serialização baseada em reflexão. No entanto, as funções que usam a serialização gerada por código-fonte tendem a usar menos memória e apresentar maior performance devido à geração de código em tempo de compilação. Para ajudar a eliminar as [inicializações a frio](lambda-runtime-environment.md#cold-start-latency) de funções, considere migrar para a serialização gerada por código-fonte.

**nota**  
Caso deseje usar a [compilação antecipada (AOT)](dotnet-native-aot.md) nativa com o Lambda, será necessário usar a serialização gerada por código-fonte.

## Funções baseadas em arquivos
<a name="csharp-file-based-functions"></a>

Introduzidos no .NET 10, os aplicativos baseados em arquivos permitem que você crie aplicações .NET a partir de um único arquivo `.cs`, sem uma estrutura de arquivos ou diretórios `.csproj`. O Lambda oferece suporte a funções baseadas em arquivos, começando com o .NET 10. Eles oferecem uma maneira simplificada e leve de criar funções do Lambda em C\$1.

A maneira mais rápida de começar a criar uma função do Lambda baseada em arquivos C\$1 é usar o pacote `Amazon.Lambda.Templates`. Para instalar esse pacote, execute o seguinte comando:

```
dotnet new install Amazon.Lambda.Templates
```

Em seguida, crie uma função de exemplo do Lambda baseada em arquivo C\$1:

```
dotnet new lambda.FileBased -n MyLambdaFunction
```

As funções baseadas em arquivos usam [manipuladores de assembly executáveis](#csharp-executable-assembly-handlers). Portanto, você deve incluir o pacote NuGet `Amazon.Lambda.RuntimeSupport` e usar o método `LambdaBootstrapBuilder.Create` para registrar a função do manipulador .NET para o tipo de evento e iniciar o cliente de runtime do .NET Lambda.

As funções baseadas em arquivo usam o a AOT nativa .NET por padrão, o que requer serialização gerada pela origem. Você pode desativar a AOT nativa especificando `#:property PublishAot=false` em seu arquivo de origem. Para obter mais informações sobre como usar a AOT nativa no Lambda, consulte [Compilar o código .NET da função do Lambda em um formato de runtime nativo](dotnet-native-aot.md).

## Acesso e uso do objeto de contexto do Lambda
<a name="csharp-example-context"></a>

O [objeto de contexto](csharp-context.md) do Lambda contém informações sobre a invocação, a função e o ambiente de execução. Neste exemplo, o objeto de contexto é do tipo `Amazon.Lambda.Core.ILambdaContext` e é o segundo argumento da função principal do manipulador.

```
public async Task<string> HandleRequest(Order order, ILambdaContext context) {
    ...
}
```

O objeto de contexto é uma entrada opcional. Para obter mais informações sobre as assinaturas de manipulador válidas e aceitas, consulte [Assinaturas de manipulador válidas para funções em C\$1](#csharp-handler-signatures).

O objeto de contexto é útil para produzir logs de funções para o Amazon CloudWatch. É possível usar o método `context.getLogger()` para obter um objeto `LambdaLogger` para registro. Neste exemplo, podemos usar o logger para registrar uma mensagem de erro se o processamento falhar por qualquer motivo:

```
context.Logger.LogError($"Failed to process order: {ex.Message}");
```

Fora do registro em log, é possível usar o objeto de contexto para realizar o monitoramento da função. Para obter mais informações sobre o objeto de contexto, consulte [Usar o objeto de contexto do Lambda para recuperar informações das funções em C\$1](csharp-context.md).

## Uso do SDK para .NET v3 em seu manipulador
<a name="csharp-example-sdk-usage"></a>

Frequentemente, você usará as funções do Lambda para interagir com ou fazer atualizações em outros recursos da AWS. A maneira mais simples de interagir com esses recursos é usar o SDK para .NET v3.

**nota**  
O SDK para .NET (v2) está obsoleto. Recomendamos usar somente o SDK para .NET v3 daqui em diante.

Você pode adicionar dependências do SDK ao seu projeto usando o seguinte comando do `Amazon.Lambda.Tools`:

```
dotnet add package <package_name>
```

Por exemplo, no exemplo principal nesta página, precisamos usar a API do Amazon S3 para fazer upload de um recibo no S3. Podemos importar o cliente do Amazon S3 SDK com o seguinte comando:

```
dotnet add package AWSSDK.S3
```

Esse comando adiciona a dependência ao seu projeto. Você também deve ver uma linha semelhante à seguinte no arquivo `.csproj` do seu projeto:

```
<PackageReference Include="AWSSDK.S3" Version="3.7.2.18" />
```

Em seguida, importe as dependências diretamente em seu código C\$1:

```
using Amazon.S3;
using Amazon.S3.Model;
```

O código de exemplo então inicializa um cliente do Amazon S3 (usando a [cadeia de fornecedores de credenciais padrão](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html)) da seguinte forma:

```
private static readonly AmazonS3Client s3Client = new();
```

Neste exemplo, inicializamos nosso cliente do Amazon S3 fora da função do manipulador principal para evitar a necessidade que inicializá-lo a cada vez que nossa função é invocada. Após inicializar o cliente do SDK, você pode usá-lo para interagir com outros serviços da AWS. O código de exemplo chama a API `PutObject` do Amazon S3 da seguinte forma:

```
var putRequest = new PutObjectRequest
{
    BucketName = bucketName,
    Key = key,
    ContentBody = receiptContent,
    ContentType = "text/plain"
};

await s3Client.PutObjectAsync(putRequest);
```

## Acesso a variáveis de ambiente
<a name="csharp-example-envvars"></a>

No código do manipulador, você pode fazer referência a qualquer [variável de ambiente](configuration-envvars.md) ao usar o método `System.Environment.GetEnvironmentVariable`. Neste exemplo, referenciamos a variável de ambiente `RECEIPT_BUCKET` definida usando as seguintes linhas de código:

```
string? bucketName = Environment.GetEnvironmentVariable("RECEIPT_BUCKET");
if (string.IsNullOrWhiteSpace(bucketName))
{
    throw new ArgumentException("RECEIPT_BUCKET environment variable is not set");
}
```

## Usar o estado global
<a name="csharp-handler-state"></a>

O Lambda executa seu código estático e o construtor de classe durante a [fase de inicialização](lambda-runtime-environment.md#runtimes-lifecycle-ib) antes de invocar a função pela primeira vez. Os recursos criados durante a inicialização permanecem na memória entre as invocações, para que você possa evitar ter que criá-los toda vez que invocar sua função.

No código de exemplo, o código de inicialização do cliente do S3 está fora do método do manipulador principal. O runtime inicializa o cliente antes que a função manipule seu primeiro evento, o que pode levar a tempos de processamento mais longos. Os eventos subsequentes são muito mais rápidos porque o Lambda não precisa inicializar o cliente novamente.

## Simplificar o código da função com a estrutura Lambda Annotations
<a name="csharp-handler-annotations"></a>

O [Lambda Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) é uma estrutura para o .NET 8 que simplifica a escrita de funções do Lambda usando o C\$1. A estrutura do Annotations usa [geradores de código-fonte](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) para gerar código que é traduzido do modelo de programação do Lambda para código simplificado. Com a estrutura Annotations, você pode substituir grande parte do código em uma função Lambda escrita usando o modelo de programação regular. O código escrito usando a estrutura usa expressões mais simples que permitem que você se concentre em sua lógica de negócios. Consulte [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) na documentação do nuget para ver exemplos.

Para ver um exemplo de uma aplicação completa que utiliza o Lambda Annotations, consulte o exemplo [PhotoAssetManager](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/cross-service/PhotoAssetManager) no repositório `awsdocs/aws-doc-sdk-examples` do GitHub. O arquivo `Function.cs` principal no diretório `PamApiAnnotations` usa o Lambda Annotations. Para comparação, o diretório `PamApi` tem arquivos equivalentes escritos usando o modelo de programação do Lambda normal.

### Injeção de dependência com a estrutura Lambda Annotations
<a name="csharp-handler-annotations-injection"></a>

Você também pode usar a estrutura do Lambda Annotations para adicionar injeção de dependência nas funções do Lambda usando a sintaxe com a qual você está familiarizado. Quando você adiciona um atributo `[LambdaStartup]` a um arquivo `Startup.cs`, a estrutura do Lambda Annotations gera o código necessário durante a compilação.

```
[LambdaStartup]
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IDatabaseRepository, DatabaseRepository>();
    }
}
```

A função Lambda pode injetar serviços usando injeção de construtor ou injetando em métodos individuais usando o atributo `[FromServices]`.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function(IDatabaseRepository repo)
    {
        this._repo = repo;
    }
    
    [LambdaFunction]
    [HttpApi(LambdaHttpMethod.Get, "/product/{id}")]
    public async Task<Product> FunctionHandler([FromServices] IDatabaseRepository repository, string id)
    {
        return await this._repo.GetById(id);
    }
}
```

## Práticas recomendadas de código para as funções do Lambda em C\$1
<a name="csharp-best-practices"></a>

Adote as diretrizes da lista a seguir para usar as práticas recomendadas de codificação ao compilar suas funções do Lambda:
+ **Separe o manipulador do Lambda da lógica central.** Isso permite que você crie uma função mais fácil para teste de unidade.
+ **Controle as dependências no pacote de implantação da função. ** O ambiente de execução do AWS Lambda contém várias bibliotecas. Para habilitar o conjunto de recursos e atualizações de segurança mais recente, o Lambda atualizará periodicamente essas bibliotecas. Essas atualizações podem introduzir alterações sutis ao comportamento de sua função do Lambda. Para ter controle total das dependências usadas por sua função, empacote todas as dependências em seu pacote de implantação. 
+ **Minimize a complexidade de suas dependências.** Prefira frameworks mais simples que sejam carregados rapidamente no startup do [ambiente de execução](lambda-runtime-environment.md).
+ **Minimize o tamanho do pacote de implantação para conter somente o necessário para o runtime. ** Isso reduzirá a quantidade de tempo necessária para que seu pacote de implantação seja obtido por download e desempacotado antes da invocação. Para funções criadas em .NET Core, evite carregar toda a biblioteca do AWS SDK como parte do pacote de implantação. Em vez disso, dependa seletivamente dos módulos que coletam os componentes do SDK necessários (por exemplo, DynamoDB, módulos do SDK do Amazon S3 e bibliotecas principais do Lambda). 

**Aproveite a reutilização do ambiente de execução para melhorar a performance da função.** Inicialize clientes SDK e conexões de banco de dados fora do manipulador de funções e armazene em cache os ativos estáticos localmente no diretório `/tmp`. As invocações subsequentes processadas pela mesma instância da função podem reutilizar esses recursos. Isso economiza custos reduzindo o runtime da função.

Para evitar possíveis vazamentos de dados entre invocações, não use o ambiente de execução para armazenar dados do usuário, eventos ou outras informações com implicações de segurança. Se sua função depende de um estado mutável que não pode ser armazenado na memória dentro do manipulador, considere criar uma função separada ou versões separadas de uma função para cada usuário.

**Use uma diretiva de keep-alive para manter conexões persistentes.** O Lambda limpa conexões ociosas ao longo do tempo. A tentativa de reutilizar uma conexão ociosa ao invocar uma função resultará em um erro de conexão. Para manter sua conexão persistente, use a diretiva keep-alive associada ao runtime. Para obter um exemplo, consulte [Reutilizar conexões com keep-alive em Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Use [variáveis de ambiente](configuration-envvars.md) para passar parâmetros operacionais para sua função.** Por exemplo, se estiver gravando em um bucket do Amazon S3, em vez fixar no código o nome do bucket em que você está gravando, configure o nome do bucket como uma variável de ambiente.

**Evite usar invocações recursivas** em sua função do Lambda, em que a função invoca a si mesma ou inicia um processo que pode invocar a função novamente. Isso pode levar a um volume não intencional de invocações da função e a custos elevados. Se você observar um volume não intencional de invocações, defina a simultaneidade reservada da função como `0` imediatamente para limitar todas as invocações da função enquanto atualiza o código.

**Não use APIs não documentadas e não públicas** no código da função do Lambda. Para os tempos de execução gerenciados pelo AWS Lambda, o Lambda aplica periodicamente atualizações funcionais e de segurança às APIs internas do Lambda. Essas atualizações internas da API podem ser incompatíveis com versões anteriores, gerando consequências não intencionais, como falhas de invocação, caso sua função tenha dependência nessas APIs não públicas. Consulte [a referência da API](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) para obter uma lista de APIs disponíveis publicamente.

**Escreva um código idempotente.** Escrever um código idempotente para suas funções garante que eventos duplicados sejam tratados da mesma maneira. Seu código deve validar eventos adequadamente e lidar corretamente com eventos duplicados. Para obter mais informações, consulte [Como torno minha função do Lambda idempotente?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Criar e implantar funções do Lambda em C\$1 com arquivos .zip
<a name="csharp-package"></a>

Um pacote de implantação do .NET (arquivo .zip) contém o assembly compilado da função junto com todas as suas dependências de assembly. O pacote também contém um arquivo `proj.deps.json`. Isso sinaliza para o runtime do .NET todas as dependências da função e um arquivo `proj.runtimeconfig.json`, que é usado para configurar o runtime.

Para implantar funções do Lambda individuais, você pode usar a CLI do .NET Lambda Global `Amazon.Lambda.Tools`. O uso do comando `dotnet lambda deploy-function` cria automaticamente um pacote de implantação .zip e o implanta no Lambda. Porém, recomendamos que você use estruturas como o AWS Serverless Application Model (AWS SAM) ou o AWS Cloud Development Kit (AWS CDK) para implantar as aplicações do .NET na AWS.

As aplicações com tecnologia sem servidor geralmente incluem uma combinação de funções do Lambda e outros Serviços da AWS gerenciados trabalhando juntos para realizar uma tarefa de negócios específica. O AWS SAM e o AWS CDK simplificam a criação e implantação de funções do Lambda com outros Serviços da AWS em escala. A [especificação do modelo do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html) fornece uma sintaxe simples e clara para descrever as funções, APIs, permissões, configurações e outros recursos do da AWS que compõem sua aplicação com tecnologia sem servidor. Com o [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html), você define a infraestrutura de nuvem como código para ajudar a criar aplicações confiáveis, escaláveis e econômicas na nuvem, usando linguagens e estruturas de programação modernas, como o .NET. Tanto o AWS CDK quanto o AWS SAM usam a CLI do .NET Lambda Global para empacotar as funções.

Embora seja possível usar as [Camadas do Lambda](chapter-layers.md) com funções em C\$1 [usando a CLI do .NET Core](csharp-package-cli.md#csharp-layers), não recomendamos. Funções em C\$1 que usam camadas carregam manualmente os conjuntos compartilhados na memória durante o [Fase de inicialização](lambda-runtime-environment.md#runtimes-lifecycle-ib), o que pode aumentar o tempo de início a frio. Em vez disso, inclua todo o código compartilhado no momento da compilação para evitar o impacto no desempenho do carregamento de assemblies em runtime.

Você pode encontrar instruções para criar e implantar as funções do Lambda do .NET usando o AWS SAM o AWS CDK e a CLI do .NET Lambda Global nas seções a seguir.

**Topics**
+ [

# Usando a CLI do .NET Lambda Global
](csharp-package-cli.md)
+ [

# Implantar funções do Lambda em C\$1 usando o AWS SAM
](csharp-package-sam.md)
+ [

# Implantar funções do Lambda em C\$1 usando o AWS CDK
](csharp-package-cdk.md)
+ [

# Implementar aplicações ASP.NET
](csharp-package-asp.md)

# Usando a CLI do .NET Lambda Global
<a name="csharp-package-cli"></a>

A CLI do .NET e a extensão .NET Lambda Global Tools (`Amazon.Lambda.Tools`) oferecem uma maneira multiplataforma de criar aplicações do Lambda baseadas no .NET, empacotá-las e implantá-las no Lambda. Nesta seção, você aprenderá a criar novos projetos do Lambda do .NET usando a CLI do .NET e os modelos do Amazon Lambda e a empacotá-los e implantá-los usando o `Amazon.Lambda.Tools`

**Topics**
+ [

## Pré-requisitos
](#csharp-package-cli-prerequisites)
+ [

## Criar projetos do .NET usando a CLI do .NET
](#csharp-package-cli-create)
+ [

## Implantar projetos do .NET usando a CLI do .NET
](#csharp-package-cli-deploy)
+ [

## Usar camadas Lambda com a CLI do .NET
](#csharp-layers)

## Pré-requisitos
<a name="csharp-package-cli-prerequisites"></a>

**SDK do .NET 8**  
Se você ainda não o fez, instale o SDK e o runtime do [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

**Modelos de projetos do AWS Amazon.Lambda.Templates do .NET**  
Para gerar o código da função do Lambda, use o Pacote do NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates). Para instalar esse pacote de modelo, execute o comando a seguir:  

```
dotnet new install Amazon.Lambda.Templates
```

**Ferramentas AWS Amazon.Lambda.Tools da CLI Global do .NET**  
Para criar as funções do Lambda, você usa a [extensão .NET Global Tools](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) do [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Para instalar Amazon.Lambda.Tools, execute o comando a seguir:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Para obter mais informações sobre a extensão Amazon.Lambda.Tools da CLI do .NET, consulte o repositório [AWS Extensions for .NET CLI](https://github.com/aws/aws-extensions-for-dotnet-cli) no GitHub.

## Criar projetos do .NET usando a CLI do .NET
<a name="csharp-package-cli-create"></a>

Na CLI do .NET, você usa o comando `dotnet new` para criar projetos do .NET em uma linha de comando. O Lambda oferece modelos adicionais usando o pacote NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates).

Depois de instalar o pacote, execute o comando a seguir para ver uma lista dos modelos disponíveis.

```
dotnet new list
```

Para examinar detalhes sobre um modelo, use a opção `help`. Por exemplo, para ver detalhes sobre o modelo de `lambda.EmptyFunction`, execute o comando a seguir.

```
dotnet new lambda.EmptyFunction --help
```

Para criar um modelo básico para uma função do .NET Lambda, use o modelo `lambda.EmptyFunction`. Isso cria uma função simples que pega uma string como entrada e a converte em maiúsculas usando o método `ToUpper`. O modelo é compatível com as opções a seguir: 
+ `--name`: o nome da função.
+ `--region`: a região da AWS na qual criar a função.
+ `--profile`: o nome de um perfil no arquivo de credenciais do AWS SDK para .NET. Para saber mais sobre perfis de credenciais no .NET, consulte [Configure AWS credentials](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) no *AWS SDK for .NET Developer Guide*.

Neste exemplo, criamos uma nova função vazia denominada `myDotnetFunction` usando o perfil e as configurações do Região da AWS padrão:

```
dotnet new lambda.EmptyFunction --name myDotnetFunction
```

Esse comando cria os seguintes arquivos e diretórios no diretório do seu projeto.

```
└── myDotnetFunction
    ├── src
    │   └── myDotnetFunction
    │       ├── Function.cs
    │       ├── Readme.md
    │       ├── aws-lambda-tools-defaults.json
    │       └── myDotnetFunction.csproj
    └── test
        └── myDotnetFunction.Tests
            ├── FunctionTest.cs
            └── myDotnetFunction.Tests.csproj
```

No diretório `src/myDotnetFunction`, examine os seguintes arquivos:
+ **aws-lambda-tools-defaults.json**: este é o local em que você especifica as opções de linha de comando ao implantar sua função do Lambda. Por exemplo:

  ```
    "profile" : "default",
    "region" : "us-east-2",
    "configuration" : "Release",
    "function-architecture": "x86_64",
    "function-runtime":"dotnet8",
    "function-memory-size" : 256,
    "function-timeout" : 30,
    "function-handler" : "myDotnetFunction::myDotnetFunction.Function::FunctionHandler"
  ```
+ **Function.cs**: o código da função do manipulador do Lambda. É um modelo C \$1 que inclui a biblioteca `Amazon.Lambda.Core` padrão e um atributo `LambdaSerializer` padrão. Para obter mais informações sobre os requisitos e as opções de serialização, consulte [Serialização em funções do Lambda em C\$1](csharp-handler.md#csharp-handler-serializer). Isso também inclui uma função de exemplo que você pode editar para aplicar o código de sua função do Lambda.

  ```
  using Amazon.Lambda.Core;
  
  // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
  [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
  
  namespace myDotnetFunction;
  
  public class Function
  {
  
      /// <summary>
      /// A simple function that takes a string and does a ToUpper
      /// </summary≫
      /// <param name="input"></param>
      /// <param name="context"></param>
      /// <returns></returns>
      public string FunctionHandler(string input, ILambdaContext context)
      {
          return input.ToUpper();
      }
  }
  ```
+ **myDotnetFunction.csproj**: um arquivo [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx) que lista os arquivos e assemblies que compõem a aplicação.

  ```
  <Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
      <TargetFramework>net8.0</TargetFramework>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
      <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
      <AWSProjectType>Lambda</AWSProjectType>
      <!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
      <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
      <!-- Generate ready to run images during publishing to improve cold start time. -->
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    <ItemGroup>
      <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />
      <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.0" />
    </ItemGroup>
  </Project>
  ```
+ **Readme**: use este arquivo para documentar sua função do Lambda.

No diretório `myfunction/test`, examine os seguintes arquivos:
+ **myDotnetFunction.Tests.csproj**: conforme observado anteriormente, este é um arquivo [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx) que lista os arquivos e assemblies que compõem seu projeto de teste. Observe também que ele inclui a biblioteca `Amazon.Lambda.Core`, portanto, é possível integrar perfeitamente qualquer modelo do Lambda necessário para testar sua função.

  ```
  <Project Sdk="Microsoft.NET.Sdk">
     ... 
  
      <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0 " />
     ...
  ```
+ **FunctionTest.cs**: o mesmo arquivo de modelo de código C \$1 que é incluído no diretório `src`. Edite esse arquivo para espelhar o código de produção de sua função e testá-lo antes de carregar sua função do Lambda em um ambiente de produção.

  ```
  using Xunit;
  using Amazon.Lambda.Core;
  using Amazon.Lambda.TestUtilities;
  
  using MyFunction;
  
  namespace MyFunction.Tests
  {
      public class FunctionTest
      {
          [Fact]
          public void TestToUpperFunction()
          {
  
              // Invoke the lambda function and confirm the string was upper cased.
              var function = new Function();
              var context = new TestLambdaContext();
              var upperCase = function.FunctionHandler("hello world", context);
  
              Assert.Equal("HELLO WORLD", upperCase);
          }
      }
  }
  ```

## Implantar projetos do .NET usando a CLI do .NET
<a name="csharp-package-cli-deploy"></a>

Para criar o pacote de implantação e implantá-lo no Lambda, você usa as ferramentas da CLI de `Amazon.Lambda.Tools`. Para implantar a função usando os arquivos que você criou nas etapas anteriores, primeiro navegue até a pasta que contém o arquivo `.csproj` da função.

```
cd myDotnetFunction/src/myDotnetFunction
```

Para implantar o código no Lambda como um pacote de implantação .zip, execute o comando a seguir. Escolha o nome da sua função.

```
dotnet lambda deploy-function myDotnetFunction
```

Durante a implantação, o assistente solicita que você selecione um [Definir permissões de uma função do Lambda com um perfil de execução](lambda-intro-execution-role.md). Para esse exemplo, selecione `lambda_basic_role`.

Depois de implantar a função, você poderá testá-la na nuvem usando o comando `dotnet lambda invoke-function`. Para o código de exemplo no modelo da `lambda.EmptyFunction`, você pode testar a função passando uma string usando a opção `--payload`.

```
dotnet lambda invoke-function myDotnetFunction --payload "Just checking if everything is OK"
```

Se a função foi implantada com sucesso, você deverá ver um resultado semelhante ao apresentado a seguir.

```
dotnet lambda invoke-function myDotnetFunction --payload "Just checking if everything is OK"
Amazon Lambda Tools for .NET Core applications (5.8.0)
Project Home: https://github.com/aws/aws-extensions-for-dotnet-cli, https://github.com/aws/aws-lambda-dotnet

Payload:
"JUST CHECKING IF EVERYTHING IS OK"

Log Tail:
START RequestId: id Version: $LATEST
END RequestId: id
REPORT RequestId: id  Duration: 0.99 ms       Billed Duration: 1 ms         Memory Size: 256 MB     Max Memory Used: 12 MB
```

## Usar camadas Lambda com a CLI do .NET
<a name="csharp-layers"></a>

**nota**  
Embora seja possível usar as [camadas](chapter-layers.md) com funções em .NET, não recomendamos essa prática. Funções em .NET que usam camadas carregam manualmente os assemblies compartilhados na memória durante a fase de `Init`, o que pode aumentar o tempo de início a frio. Em vez disso, inclua todo o código compartilhado no momento da compilação para aproveitar as otimizações integradas do compilador .NET.

A CLI do .NET é compatível com comandos que ajudam a publicar camadas e implantar funções C\$1 que consomem camadas. Para publicar uma camada em um bucket específico do Amazon S3, execute o seguinte comando no mesmo diretório do seu arquivo `.csproj`:

```
dotnet lambda publish-layer <layer_name> --layer-type runtime-package-store --s3-bucket <s3_bucket_name>
```

Em seguida, ao implantar sua função usando a CLI do .NET, especifique o ARN da camada a ser consumida no comando a seguir:

```
dotnet lambda deploy-function <function_name> --function-layers arn:aws:lambda:us-east-1:123456789012:layer:layer-name:1
```

Para obter um exemplo completo de uma função Hello World, consulte a amostra [blank-csharp-com-layer](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-csharp-with-layer).

# Implantar funções do Lambda em C\$1 usando o AWS SAM
<a name="csharp-package-sam"></a>

O AWS Serverless Application Model (AWS SAM) é um kit de ferramentas que ajuda a simplificar o processo de criação e execução de aplicações com tecnologia sem servidor na AWS. Você define os recursos para a aplicação em um modelo YAML ou JSON e usa a interface da linha de comando do AWS SAM (CLI do AWS SAM) para criar, empacotar e implantar aplicações. Quando você cria uma função do Lambda com base em um modelo do AWS SAM, o AWS SAM cria automaticamente um pacote de implantação .zip ou uma imagem de contêiner com o código da função e todas as dependências que você especificar. O AWS SAM então implanta a função usando uma [pilha do CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html) Para saber mais sobre como usar o AWS SAM para criar e implantar funções do Lambda, consulte [Conceitos básicos do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html) no *Guia do desenvolvedor do AWS Serverless Application Model*.

As etapas a seguir mostram como baixar, criar e implantar um exemplo de aplicação Hello World do .NET usando o AWS SAM. Essa aplicação de exemplo usa uma função do Lambda e um endpoint do Amazon API Gateway para implementar um back-end básico de API. Quando você envia uma solicitação HTTP GET ao endpoint do API Gateway, o API Gateway invoca a sua função do Lambda. A função retorna uma mensagem "Hello world, juntamente com o endereço IP da instância da função do Lambda que processa a solicitação.

Quando você criar e implanta a aplicação usando o AWS SAM, nos bastidores, a CLI do AWS SAM usa o comando `dotnet lambda package` para empacotar os pacotes individuais de códigos de função do Lambda.

## Pré-requisitos
<a name="csharp-package-sam-prerequisites"></a>

**SDK do .NET 8**  
Instale o SDK e o runtime do [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

**CLI do AWS SAM versão 1.39 ou posterior**  
Para saber como instalar a versão mais recente da CLI do AWS SAM, consulte [Instalar a CLI do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).

## Implantar uma aplicação de exemplo do AWS SAM
<a name="csharp-package-sam-deploy"></a>

1. Inicialize a aplicação usando o modelo de Hello world do .NET com o comando a seguir.

   ```
   sam init --app-template hello-world --name sam-app \
   --package-type Zip --runtime dotnet8
   ```

   Esse comando cria os seguintes arquivos e diretórios no diretório do seu projeto.

   ```
   └── sam-app
       ├── README.md
       ├── events
       │   └── event.json
       ├── omnisharp.json
       ├── samconfig.toml
       ├── src
       │   └── HelloWorld
       │       ├── Function.cs
       │       ├── HelloWorld.csproj
       │       └── aws-lambda-tools-defaults.json
       ├── template.yaml
       └── test
           └── HelloWorld.Test
               ├── FunctionTest.cs
               └── HelloWorld.Tests.csproj
   ```

1. Navegue até o diretório que contém o `template.yaml file`. Esse arquivo é um modelo que define os recursos da AWS da sua aplicação, incluindo a função do Lambda e uma API do API Gateway.

   ```
   cd sam-app
   ```

1. Para criar o código-fonte da aplicação, execute o comando a seguir.

   ```
   sam build
   ```

1. Para implantar a aplicação no AWS, execute o comando a seguir.

   ```
   sam deploy --guided
   ```

   Esse comando empacota e implanta a aplicação com a série de prompts a seguir. Para aceitar as opções padrão, pressione Enter.
**nota**  
Para **HelloWorldFunction pode não ter autorização definida, tudo bem?**, certifique-se de inserir `y`.
   + **Nome da pilha**: o nome da pilha a implantar para CloudFormation. Esse nome deve ser exclusivo para a sua Conta da AWS e a Região da AWS.
   + **Região da AWS**: a Região da AWS em que você deseja implantar a aplicação.
   + **Confirmar as alterações antes da implantação**: selecione Sim para revisar manualmente qualquer conjunto de alterações antes do AWS SAM implantar as alterações da aplicação. Se você selecionar Não, a CLI do AWS SAM implantará automaticamente as alterações da aplicação.
   + **Permitir a criação de perfil do IAM do SAM CLI**: muitos modelos do AWS SAM, incluindo o Hello world neste exemplo, criam perfis do AWS Identity and Access Management (IAM) para dar permissão às suas funções do Lambda para acessar outras Serviços da AWS. Selecione Sim para fornecer permissão para implantar uma pilha CloudFormation que cria ou modifica os perfis do IAM.
   + **Desativar a reversão**: por padrão, se o AWS SAM encontrar um erro durante a criação ou implantação da pilha, ela reverte a pilha para a versão anterior. Selecione Não para aceitar esse padrão.
   + **HelloWorldFunction pode não ter autorização definida, tudo bem?**: insira `y`.
   + **Salvar argumentos em samconfig.toml**: selecione Sim para salvar suas opções de configuração. No futuro, você poderá executar o `sam deploy` novamente sem parâmetros para implantar alterações na aplicação.

1. Quando a implantação da aplicação estiver concluída, a CLI retornará o nome do recurso da Amazon (ARN) da função do Lambda Hello World e o perfil do IAM criado para ela. Ela também exibe o endpoint da API do API Gateway. Para testar a aplicação, abra o endpoint em um navegador. Você verá uma resposta semelhante a que se segue.

   ```
   {"message":"hello world","location":"34.244.135.203"}
   ```

1. Para excluir os seus recursos, execute o comando a seguir. Observe que o endpoint da API que você criou é um endpoint público acessível pela Internet. Recomendamos excluir este endpoint após o teste.

   ```
   sam delete
   ```

## Próximas etapas
<a name="csharp-package-sam-next"></a>

Para saber mais sobre o uso do AWS SAM para criar e implantar funções do Lambda usando o .NET, consulte os seguintes recursos:
+ O [https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)
+ [Criar aplicações do .NET com tecnologia sem servidor com o AWS Lambda e com a CLI do SAM](https://aws.amazon.com/blogs/dotnet/building-serverless-net-applications-with-aws-lambda-and-the-sam-cli/)

# Implantar funções do Lambda em C\$1 usando o AWS CDK
<a name="csharp-package-cdk"></a>

O AWS Cloud Development Kit (AWS CDK) é uma estrutura de desenvolvimento de software de código aberto para definição da infraestrutura em nuvem como código com linguagens de programação e estruturas modernas, como o .NET. Os projetos do AWS CDK são executados para gerar modelos do CloudFormation que são usados para implantar o código.

Para criar e implantar um exemplo de aplicação Hello world do .NET usando o AWS CDK, siga as instruções nas seções a seguir. A aplicação de amostra implementa um back-end de API básica que consiste em um endpoint do API Gateway e uma função do Lambda. O API Gateway invoca a função do Lambda quando você envia uma solicitação HTTP GET ao endpoint. A função retorna uma mensagem Hello world, juntamente com o endereço IP da instância do Lambda que processa a sua solicitação.

## Pré-requisitos
<a name="csharp-package-cdk-prereqs"></a>

**SDK do .NET 8**  
Instale o SDK e o runtime do [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

**AWS CDK versão 2**  
Para saber como instalar a versão mais recente do AWS CDK, consulte [Conceitos básicos do AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) no *Guia do desenvolvedor do AWS Cloud Development Kit (AWS CDK) v2*.

## Implantar uma aplicação de exemplo do AWS CDK
<a name="csharp-package-cdk-deploy"></a>

1. Crie um diretório de projeto para a aplicação de amostra e navegue até ele.

   ```
   mkdir hello-world
   cd hello-world
   ```

1. Inicialize uma nova aplicação do AWS CDK executando o comando a seguir.

   ```
   cdk init app --language csharp
   ```

   O comando cria os seguintes arquivos e diretórios no diretório do projeto.

   ```
   ├── README.md
   ├── cdk.json
   └── src
       ├── HelloWorld
       │   ├── GlobalSuppressions.cs
       │   ├── HelloWorld.csproj
       │   ├── HelloWorldStack.cs
       │   └── Program.cs
       └── HelloWorld.sln
   ```

1. Abra o diretório `src` e crie uma nova função do Lambda usando a CLI do .NET. Essa é a função que você implantará usando o AWS CDK. Neste exemplo, você cria uma função Hello world denominada `HelloWorldLambda` usando o modelo `lambda.EmptyFunction`.

   ```
   cd src
   dotnet new lambda.EmptyFunction -n HelloWorldLambda
   ```

   Após esta etapa, a estrutura de diretórios dentro do projeto deve ser semelhante à apresentada a seguir.

   ```
   ├── README.md
   ├── cdk.json
   └── src
       ├── HelloWorld
       │   ├── GlobalSuppressions.cs
       │   ├── HelloWorld.csproj
       │   ├── HelloWorldStack.cs
       │   └── Program.cs
       ├── HelloWorld.sln
       └── HelloWorldLambda
           ├── src
           │   └── HelloWorldLambda
           │       ├── Function.cs
           │       ├── HelloWorldLambda.csproj
           │       ├── Readme.md
           │       └── aws-lambda-tools-defaults.json
           └── test
               └── HelloWorldLambda.Tests
                   ├── FunctionTest.cs
                   └── HelloWorldLambda.Tests.csproj
   ```

1. Abra o arquivo `HelloWorldStack.cs` do diretório `src/HelloWorld`. Substitua o conteúdo do arquivo pelo código a seguir.

   ```
   using Amazon.CDK;
   using Amazon.CDK.AWS.Lambda;
   using Amazon.CDK.AWS.Logs;
   using Constructs;
   
   namespace CdkTest
   {
       public class HelloWorldStack : Stack
       {
           internal HelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
           {
               var buildOption = new BundlingOptions()
               {
                   Image = Runtime.DOTNET_8.BundlingImage,
                   User = "root",
                   OutputType = BundlingOutput.ARCHIVED,
                   Command = new string[]{
               "/bin/sh",
                   "-c",
                   " dotnet tool install -g Amazon.Lambda.Tools"+
                   " && dotnet build"+
                   " && dotnet lambda package --output-package /asset-output/function.zip"
                   }
               };
   
                var helloWorldLambdaFunction = new Function(this, "HelloWorldFunction", new FunctionProps
               {
                   Runtime = Runtime.DOTNET_8,
                   MemorySize = 1024,
                   LogRetention = RetentionDays.ONE_DAY,
                   Handler = "HelloWorldLambda::HelloWorldLambda.Function::FunctionHandler",
                   Code = Code.FromAsset("./src/HelloWorldLambda/src/HelloWorldLambda", new Amazon.CDK.AWS.S3.Assets.AssetOptions
                   {
                       Bundling = buildOption
                   }),
               });
           }
       }
   }
   ```

   Esse é o código para compilar e empacotar o código da aplicação, bem como a definição da própria função do Lambda. O objeto `BundlingOptions` permite que um arquivo zip seja criado, juntamente com um conjunto de comandos usados para gerar o conteúdo do arquivo zip. Nessa instância, o comando `dotnet lambda package` é usado para compilar e gerar o arquivo zip.

1. Para implantar a aplicação, execute o comando a seguir.

   ```
   cdk deploy
   ```

1. Invoque sua função do Lambda implantada usando a CLI do .NET Lambda.

   ```
   dotnet lambda invoke-function HelloWorldFunction -p "hello world"
   ```

1. Depois de finalizados os testes, você poderá excluir os recursos criados, a menos que deseje mantê-los. Execute o comando a seguir para excluir os seus recursos.

   ```
   cdk destroy
   ```

## Próximas etapas
<a name="csharp-package-cdk-next"></a>

Para saber mais sobre o uso do AWS CDK para criar e implantar funções do Lambda usando o .NET, consulte os seguintes recursos:
+ [Trabalhar com o AWS CDK em C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)
+ [Criar, empacotar e publicar funções do Lambda no .NET C\$1 com o CDK do AWS](https://aws.amazon.com/blogs/modernizing-with-aws/build-package-publish-dotnet-csharp-lambda-functions-aws-cdk/)

# Implementar aplicações ASP.NET
<a name="csharp-package-asp"></a>

Além de hospedar funções orientadas por eventos, você também pode usar o .NET com o Lambda para hospedar aplicações leves do ASP.NET. Você pode criar e implantar aplicações ASP.NET usando o pacote NuGet `Amazon.Lambda.AspNetCoreServer`. Nesta seção, você aprenderá a implantar uma API da Web do ASP.NET no Lambda usando as ferramentas CLI do .NET Lambda.

**Topics**
+ [

## Pré-requisitos
](#csharp-package-asp-prerequisites)
+ [

## Implantando uma API Web do ASP.NET no Lambda
](#csharp-package-asp-deploy-api)
+ [

## Implantar APIs mínimas do ASP.NET no Lambda
](#csharp-package-asp-deploy-minimal)

## Pré-requisitos
<a name="csharp-package-asp-prerequisites"></a>

**SDK do .NET 8**  
Instale o SDK do [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) e o Runtime do ASP.NET Core.

**Amazon.Lambda.Tools**  
Para criar as funções do Lambda, você usa a [extensão .NET Global Tools](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) do [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Para instalar Amazon.Lambda.Tools, execute o comando a seguir:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Para obter mais informações sobre a extensão Amazon.Lambda.Tools da CLI do .NET, consulte o repositório [AWS Extensions for .NET CLI](https://github.com/aws/aws-extensions-for-dotnet-cli) no GitHub.

**Amazon.Lambda.Templates**  
Para gerar o código da função do Lambda, use o Pacote do NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates). Para instalar esse pacote de modelo, execute o comando a seguir:  

```
dotnet new --install Amazon.Lambda.Templates
```

## Implantando uma API Web do ASP.NET no Lambda
<a name="csharp-package-asp-deploy-api"></a>

Para implantar uma API da Web usando o ASP.NET, você pode usar os modelos do .NET Lambda para criar um novo projeto de API da Web. Use o comando a seguir para inicializar um novo projeto de API da Web do ASP.NET. No comando de exemplo, denominamos o projeto `AspNetOnLambda`.

```
dotnet new serverless.AspNetCoreWebAPI -n AspNetOnLambda
```

Esse comando cria os seguintes arquivos e diretórios no diretório do seu projeto.

```
.
└── AspNetOnLambda
    ├── src
    │   └── AspNetOnLambda
    │       ├── AspNetOnLambda.csproj
    │       ├── Controllers
    │       │   └── ValuesController.cs
    │       ├── LambdaEntryPoint.cs
    │       ├── LocalEntryPoint.cs
    │       ├── Readme.md
    │       ├── Startup.cs
    │       ├── appsettings.Development.json
    │       ├── appsettings.json
    │       ├── aws-lambda-tools-defaults.json
    │       └── serverless.template
    └── test
        └── AspNetOnLambda.Tests
            ├── AspNetOnLambda.Tests.csproj
            ├── SampleRequests
            │   └── ValuesController-Get.json
            ├── ValuesControllerTests.cs
            └── appsettings.json
```

Quando o Lambda invoca sua função, o ponto de entrada usado é o arquivo `LambdaEntryPoint.cs`. O arquivo criado pelo modelo do .NET Lambda contém o seguinte código de função.

```
namespace AspNetOnLambda;

public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
{
    protected override void Init(IWebHostBuilder builder)
    {
        builder
            .UseStartup≪Startup≫();
    }

    protected override void Init(IHostBuilder builder)
    {
    }
}
```

O ponto de entrada usado pelo Lambda deve herdar de uma das três classes básicas do pacote `Amazon.Lambda.AspNetCoreServer`. Essas três classes básicas são:
+ `APIGatewayProxyFunction`
+ `APIGatewayHttpApiV2ProxyFunction`
+ `ApplicationLoadBalancerFunction`

A classe padrão usada quando você cria o arquivo `LambdaEntryPoint.cs` usando o modelo do .NET Lambda fornecido é `APIGatewayProxyFunction`. A classe básica que você usa na função depende de qual camada de API está na frente da função do Lambda.

Cada uma das três classes básicas contém um método público denominado `FunctionHandlerAsync`. O nome desse método fará parte da [string do manipulador](csharp-handler.md#csharp-class-library-handlers) que o Lambda usa para invocar a função. O método `FunctionHandlerAsync` transforma a carga útil do evento de entrada no formato ASP.NET correto e a resposta do ASP.NET em uma carga útil de resposta do Lambda. Para o projeto de exemplo `AspNetOnLambda` mostrado, a string do manipulador seria como a que se segue.

```
AspNetOnLambda::AspNetOnLambda.LambdaEntryPoint::FunctionHandlerAsync
```

Para implantar a API no Lambda, execute os comandos a seguir para navegar até o diretório que contém o arquivo de código-fonte e implantar a função usando o CloudFormation.

```
cd AspNetOnLambda/src/AspNetOnLambda
dotnet lambda deploy-serverless
```

**dica**  
Quando você implanta uma API usando o comando `dotnet lambda deploy-serverless`, o CloudFormation atribui um nome à função do Lambda com base no nome da pilha que você especificou durante a implantação. Para dar um nome personalizado à função do Lambda, edite o arquivo `serverless.template` para adicionar uma propriedade `FunctionName` ao recurso `AWS::Serverless::Function`. Para saber mais, consulte [Tipo de nome](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html) no *Guia do usuário do CloudFormation*.

## Implantar APIs mínimas do ASP.NET no Lambda
<a name="csharp-package-asp-deploy-minimal"></a>

Para implantar uma API mínima do ASP.NET no Lambda, você pode usar os modelos do .NET Lambda para criar um novo projeto de API mínimo. Use o comando a seguir para inicializar um novo projeto de API mínima. Neste exemplo, denominamos o projeto `MinimalApiOnLambda`.

```
dotnet new serverless.AspNetCoreMinimalAPI -n MinimalApiOnLambda
```

O comando cria os arquivos e diretórios a seguir no diretório do seu projeto.

```
└── MinimalApiOnLambda
    └── src
        └── MinimalApiOnLambda
            ├── Controllers
            │   └── CalculatorController.cs
            ├── MinimalApiOnLambda.csproj
            ├── Program.cs
            ├── Readme.md
            ├── appsettings.Development.json
            ├── appsettings.json
            ├── aws-lambda-tools-defaults.json
            └── serverless.template
```

O arquivo `Program.cs` contém o código a seguir.

```
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

// Add AWS Lambda support. When application is run in Lambda Kestrel is swapped out as the web server with Amazon.Lambda.AspNetCoreServer. This
// package will act as the webserver translating request and responses between the Lambda event source and ASP.NET Core.
builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);

var app = builder.Build();


app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.MapGet("/", () => "Welcome to running ASP.NET Core Minimal API on AWS Lambda");

app.Run();
```

Para configurar a API mínima para ser executada no Lambda, pode ser necessário editar esse código para que as solicitações e respostas entre o Lambda e o ASP.NET Core sejam traduzidas adequadamente. Por padrão, a função é configurada para uma fonte de eventos API REST. Para uma API HTTP ou um Application Load Balancer, substitua `(LambdaEventSource.RestApi)` por uma das seguintes opções:
+ `(LambdaEventSource.HttpAPi)`
+ `(LambdaEventSource.ApplicationLoadBalancer)`

Para implantar a API mínima no Lambda, execute os comandos a seguir para navegar até o diretório que contém o arquivo de código-fonte e implantar a função usando o CloudFormation.

```
cd MinimalApiOnLambda/src/MinimalApiOnLambda
dotnet lambda deploy-serverless
```

# Como trabalhar com camadas para funções do Lambda em .NET
<a name="dotnet-layers"></a>

Não recomendamos usar [camadas](chapter-layers.md) para gerenciar dependências de funções do Lambda escritas em .NET. Como o .NET é uma linguagem compilada, suas funções ainda precisam carregar manualmente quaisquer montagens compartilhadas na memória durante a fase [inicial](lambda-runtime-environment.md#runtimes-lifecycle-ib), o que pode aumentar os tempos de inicialização a frio. O uso de camadas não apenas complica o processo de implantação, mas também impede que você aproveite as otimizações integradas do compilador.

Para usar dependências externas com manipuladores .NET, inclua-as diretamente no pacote de implantação no momento da compilação. Fazendo isso, você simplifica o processo de implantação e também aproveita as otimizações integradas do compilador .NET. Para ver um exemplo de como importar e usar dependências como os pacotes NuGet em sua função, consulte [Definir o manipulador de função do Lambda em C\$1](csharp-handler.md).

# Implantar funções do Lambda em .NET com imagens de contêiner
<a name="csharp-image"></a>

Existem três maneiras de criar uma imagem de contêiner para uma função do Lambda em .NET:
+ [Usar uma imagem base da AWS para .NET](#csharp-image-instructions)

  As [imagens base da AWS](images-create.md#runtimes-images-lp) são pré-carregadas com um  runtime de linguagem, um cliente de interface de runtime para gerenciar a interação entre o Lambda e o código da sua função e um emulador de interface de runtime para testes locais.
+ [Usar uma imagem base somente para sistema operacional da AWS](images-create.md#runtimes-images-provided)

  [As imagens base somente para sistema operacional da AWS](https://gallery.ecr.aws/lambda/provided) contêm uma distribuição do Amazon Linux e o [emulador de interface de runtime](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Essas imagens são comumente usadas para criar imagens de contêiner para linguagens compiladas, como [Go](go-image.md#go-image-provided) e [Rust](lambda-rust.md) e para uma linguagem ou versão de linguagem para a qual o Lambda não fornece uma imagem base, como Node.js 19. Você também pode usar imagens base somente para sistema operacional para implementar um [runtime personalizado](runtimes-custom.md). Para tornar a imagem compatível com o Lambda, você deve incluir [o cliente de interface de runtime do .NET](#csharp-image-clients) na imagem.
+ [Usar uma imagem base que não é da AWS](#csharp-image-clients)

  Você também pode usar uma imagem base alternativa de outro registro de contêiner, como Alpine Linux ou Debian. Você também pode usar uma imagem personalizada criada por sua organização. Para tornar a imagem compatível com o Lambda, você deve incluir [o cliente de interface de runtime do .NET](#csharp-image-clients) na imagem.

**dica**  
Para reduzir o tempo necessário para que as funções do contêiner do Lambda se tornem ativas, consulte [Use multi-stage builds](https://docs.docker.com/build/building/multi-stage/) na documentação do Docker. Para criar imagens de contêiner eficientes, siga as [Melhores práticas para gravar Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

Esta página explica como criar, testar e implantar imagens de contêiner para o Lambda.

**Topics**
+ [

## Imagens base da AWS para .NET
](#csharp-image-base)
+ [

## Usar uma imagem base da AWS para .NET
](#csharp-image-instructions)
+ [

## Usar uma imagem base alternativa com o cliente da interface de runtime
](#csharp-image-clients)

## Imagens base da AWS para .NET
<a name="csharp-image-base"></a>

A AWS oferece as seguintes imagens base para .NET:


| Tags | Runtime | Sistema operacional | Dockerfile | Desaprovação | 
| --- | --- | --- | --- | --- | 
| 10 | .NET 10 | Amazon Linux 2023 | [Dockerfile para .NET 10 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet10/Dockerfile.dotnet10) |   14 de novembro de 2028   | 
| 9 | .NET 9 | Amazon Linux 2023 | [Dockerfile para .NET 9 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet9/Dockerfile.dotnet9) |   10 de novembro de 2026   | 
| 8 | .NET 8 | Amazon Linux 2023 | [Dockerfile para .NET 8 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet8/Dockerfile.dotnet8) |   10 de novembro de 2026   | 

Repositório do Amazon ECR: [gallery.ecr.aws/lambda/dotnet](https://gallery.ecr.aws/lambda/dotnet)

## Usar uma imagem base da AWS para .NET
<a name="csharp-image-instructions"></a>

### Pré-requisitos
<a name="dotnet-csharp-image-prerequisites"></a>

Para executar as etapas desta seção, você deve ter o seguinte:
+ [.NET SDK](https://dotnet.microsoft.com/download): as etapas a seguir usam a imagem base do .NET 8. Certifique-se de que sua versão do .NET corresponda à versão da [imagem base](https://gallery.ecr.aws/lambda/dotnet) que você especifica em seu Dockerfile.
+ [Docker](https://docs.docker.com/get-docker) (versão mínima 25.0.0)
+ O plug-in [buildx](https://github.com/docker/buildx/blob/master/README.md) do Docker.

### Criação e implantação de uma imagem usando uma imagem base
<a name="dotnet-image-create"></a>

Nas etapas a seguir, você usará [Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) e [Amazon.Lambda.Tools](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) para criar um projeto.NET. Em seguida, você construirá uma imagem do Docker, fará upload da imagem no Amazon ECR e a implantará em uma função do Lambda.

1. Instale o pacote [NuGet Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates).

   ```
   dotnet new install Amazon.Lambda.Templates
   ```

1. Crie um projeto .NET usando o modelo `lambda.image.EmptyFunction`.

   ```
   dotnet new lambda.image.EmptyFunction --name MyFunction --region us-east-1
   ```

   Os arquivos do projeto são armazenados no diretório `MyFunction/src/MyFunction`:
   + **aws-lambda-tools-defaults.json**: especifica as opções de linha de comando para implantar a função do Lambda.
   + **Function.cs**: o código da função do manipulador do Lambda. Ele é um modelo em C\$1 que inclui a biblioteca `Amazon.Lambda.Core` padrão e um atributo `LambdaSerializer` padrão. Para obter mais informações sobre os requisitos e as opções de serialização, consulte [Serialização em funções do Lambda em C\$1](csharp-handler.md#csharp-handler-serializer). É possível usar o código fornecido para testes ou substituí-lo pelo seu.
   + **MyFunction.csproj**: um [arquivo de projeto](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) .NET que lista os arquivos e conjuntos que compõem a aplicação.
   + **Dockerfile**: é possível usar o Dockerfile fornecido para testes ou substituí-lo pelo seu próprio. Se você usar o seu próprio, certifique-se de:
     + Definir a propriedade `FROM` como o [URI da imagem base](https://gallery.ecr.aws/lambda/dotnet). A imagem de base e a `TargetFramework` no arquivo `MyFunction.csproj` devem usar a mesma versão do .NET. Por exemplo, para usar o .NET 9:
       + Dockerfile: `FROM public.ecr.aws/lambda/dotnet:9`
       + MyFunction.csproj: `<TargetFramework>net9.0</TargetFramework>`
     + Definir o argumento `CMD` para o manipulador de funções do Lambda. Isso deve corresponder ao `image-command` em `aws-lambda-tools-defaults.json`.

1. Instale a [.NET Global Tool](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) do Amazon.Lambda.Tools.

   ```
   dotnet tool install -g Amazon.Lambda.Tools
   ```

   Se o Amazon.Lambda.Tools já estiver instalado, certifique-se de ter a versão mais recente.

   ```
   dotnet tool update -g Amazon.Lambda.Tools
   ```

1. Altere o diretório para `MyFunction/src/MyFunction`, caso você ainda não esteja lá.

   ```
   cd src/MyFunction
   ```

1. Use o Amazon.Lambda.Tools para construir a imagem do Docker, enviá-la para um novo repositório do Amazon ECR e implantar a função do Lambda.

   Em `--function-role`, especifique o nome do perfil, não o nome do recurso da Amazon (ARN), do [perfil de execução](lambda-intro-execution-role.md) da função. Por exemplo, `lambda-role`.

   ```
   dotnet lambda deploy-function MyFunction --function-role lambda-role
   ```

   Para obter mais informações sobre a ferramenta do Amazon.Lambda.Tools do .NET Global, consulte o repositório [AWS Extensions for .NET CLI](https://github.com/aws/aws-extensions-for-dotnet-cli) no GitHub.

1. Invoque a função.

   ```
   dotnet lambda invoke-function MyFunction --payload "Testing the function"
   ```

   Se tudo estiver certo, você verá uma resposta como a seguinte:

   ```
   Payload:
   {"Lower":"testing the function","Upper":"TESTING THE FUNCTION"}
   
   Log Tail:
   INIT_REPORT Init Duration: 9999.81 ms   Phase: init     Status: timeout
   START RequestId: 12378346-f302-419b-b1f2-deaa1e8423ed Version: $LATEST
   END RequestId: 12378346-f302-419b-b1f2-deaa1e8423ed
   REPORT RequestId: 12378346-f302-419b-b1f2-deaa1e8423ed  Duration: 3173.06 ms    Billed Duration: 3174 ms        Memory Size: 512 MB     Max Memory Used: 24 MB
   ```

1. Exclua a função do Lambda.

   ```
   dotnet lambda delete-function MyFunction
   ```

## Usar uma imagem base alternativa com o cliente da interface de runtime
<a name="csharp-image-clients"></a>

Se você usar uma [imagem base somente para sistema operacional](images-create.md#runtimes-images-provided) ou uma imagem base alternativa, deverá incluir o cliente de interface de runtime na imagem. O cliente de interface de runtime estende [API de runtime](runtimes-api.md), que gerencia a interação entre o Lambda e o código da sua função.

O exemplo a seguir demonstra como criar uma imagem de contêiner para .NET usando uma imagem base que não é da AWS e como adicionar o [pacote Amazon.Lambda.RuntimeSupport](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library), que é o cliente da interface de runtime do Lambda para .NET. O Dockerfile do exemplo usa a imagem base do Microsoft .NET 8.

### Pré-requisitos
<a name="dotnet-csharp-alt-prerequisites"></a>

Para executar as etapas desta seção, você deve ter o seguinte:
+ [.NET SDK](https://dotnet.microsoft.com/download): as etapas a seguir usam uma imagem de base do .NET 9. Certifique-se de que sua versão do .NET corresponda à versão da imagem base que você especifica em seu Dockerfile.
+ [Docker](https://docs.docker.com/get-docker) (versão mínima 25.0.0)
+ O plug-in [buildx](https://github.com/docker/buildx/blob/master/README.md) do Docker.

### Criar e implantar uma imagem usando uma imagem base alternativa
<a name="dotnet-alt-create"></a>

1. Instale o pacote [NuGet Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates).

   ```
   dotnet new install Amazon.Lambda.Templates
   ```

1. Crie um projeto .NET usando o modelo `lambda.CustomRuntimeFunction`. Esse modelo inclui o pacote [Amazon.Lambda.RuntimeSupport](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library).

   ```
   dotnet new lambda.CustomRuntimeFunction --name MyFunction --region us-east-1
   ```

1. Navegue até o diretório `MyFunction/src/MyFunction`. É aqui o local em que os arquivos do projeto são armazenados. Examine os seguintes arquivos:
   + **aws-lambda-tools-defaults.json**: este arquivo é onde você especifica as opções de linha de comando ao implantar sua função do Lambda.
   + **Function.cs**: o código contém uma classe com um método `Main` que inicializa a biblioteca `Amazon.Lambda.RuntimeSupport` como bootstrap. O método `Main` é o ponto de entrada para o processo da função. O método `Main` ajusta o manipulador da função em um wrappper com o qual o bootstrap pode trabalhar. Para obter mais informações, consulte [Usar Amazon.Lambda.RuntimeSupport como uma biblioteca de classes](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library) no repositório do GitHub.
   + **MyFunction.csproj**: um [arquivo de projeto](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) .NET que lista os arquivos e conjuntos que compõem sua aplicação.
   + **Readme.md**: este arquivo contém mais informações sobre a função do Lambda de exemplo.

1. Abra o arquivo `aws-lambda-tools-defaults.json` e adicione as seguintes linhas:

   ```
     "package-type": "image",
     "docker-host-build-output-dir": "./bin/Release/lambda-publish"
   ```
   + **package-type**: define o pacote de implantação como uma imagem de contêiner.
   + **docker-host-build-output-dir**: define o diretório de saída para o processo de compilação.  
**Example aws-lambda-tools-defaults.json**  

   ```
   {
     "Information": [
       "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
       "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
       "dotnet lambda help",
       "All the command line options for the Lambda command can be specified in this file."
     ],
     "profile": "",
     "region": "us-east-1",
     "configuration": "Release",
     "function-runtime": "provided.al2023",
     "function-memory-size": 256,
     "function-timeout": 30,
     "function-handler": "bootstrap",
     "msbuild-parameters": "--self-contained true",
     "package-type": "image",
     "docker-host-build-output-dir": "./bin/Release/lambda-publish"
   }
   ```

1. Crie um Dockerfile no diretório `MyFunction/src/MyFunction`. O Dockerfile de exemplo a seguir usa uma imagem base do Microsoft.NET em vez de uma [imagem base da AWS](#csharp-image-base).
   + Defina a propriedade `FROM` como o identificador da imagem base. A imagem de base e a `TargetFramework` no arquivo `MyFunction.csproj` devem usar a mesma versão do .NET.
   + Use o comando `COPY` para copiar a função para o diretório `/var/task`.
   + Defina o `ENTRYPOINT` como o módulo em que você deseja que o contêiner do Docker seja executado quando for iniciado. Nesse caso, o módulo é o bootstrap, que inicializa a biblioteca `Amazon.Lambda.RuntimeSupport`.

   Observe que o Dockerfile de exemplo não inclui uma [instrução USER](https://docs.docker.com/reference/dockerfile/#user). Quando você implanta uma imagem de contêiner no Lambda, o Lambda define automaticamente um usuário padrão do Linux com permissões de privilégio mínimo. Isso é diferente do comportamento padrão do Docker, que adota o usuário `root` como padrão quando nenhuma instrução `USER` é fornecida.  
**Example Dockerfile**  

   ```
   # You can also pull these images from DockerHub amazon/aws-lambda-dotnet:8
   FROM mcr.microsoft.com/dotnet/runtime:9.0
   
   # Set the image's internal work directory
   WORKDIR /var/task
     
   # Copy function code to Lambda-defined environment variable
   COPY "bin/Release/net9.0/linux-x64"  .
     
   # Set the entrypoint to the bootstrap
   ENTRYPOINT ["/usr/bin/dotnet", "exec", "/var/task/bootstrap.dll"]
   ```

1. Instale a [extensão .NET Global Tools](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) Amazon.Lambda.Tools.

   ```
   dotnet tool install -g Amazon.Lambda.Tools
   ```

   Se o Amazon.Lambda.Tools já estiver instalado, certifique-se de ter a versão mais recente.

   ```
   dotnet tool update -g Amazon.Lambda.Tools
   ```

1. Use o Amazon.Lambda.Tools para criar a imagem do Docker, enviá-la para um novo repositório do Amazon ECR e implantar a função do Lambda.

   Em `--function-role`, especifique o nome do perfil, não o nome do recurso da Amazon (ARN), do [perfil de execução](lambda-intro-execution-role.md) da função. Por exemplo, `lambda-role`.

   ```
   dotnet lambda deploy-function MyFunction --function-role lambda-role
   ```

   Para obter mais informações sobre a extensão da CLi Amazon.Lambda.Tools .NET, consulte o repositório [AWS Extensions for .NET CLI](https://github.com/aws/aws-extensions-for-dotnet-cli) no GitHub.

1. Invoque a função.

   ```
   dotnet lambda invoke-function MyFunction --payload "Testing the function"
   ```

   Se tudo for bem-sucedido, você verá o seguinte:

   ```
   Payload:
   "TESTING THE FUNCTION"
   
   Log Tail:
   START RequestId: id Version: $LATEST
   END RequestId: id
   REPORT RequestId: id  Duration: 0.99 ms       Billed Duration: 1 ms         Memory Size: 256 MB     Max Memory Used: 12 MB
   ```

1. Exclua a função do Lambda.

   ```
   dotnet lambda delete-function MyFunction
   ```

# Compilar o código .NET da função do Lambda em um formato de runtime nativo
<a name="dotnet-native-aot"></a>

O .NET 8 oferece suporte à compilação Ahead Of Time (AOT) nativa. Com a AOT nativa, é possível compilar o código da função do Lambda para um formato de runtime nativo, o que elimina a necessidade de compilar o código .NET em runtime. A compilação AOT nativa pode reduzir o tempo de inicialização a frio para funções do Lambda gravadas em .NET. Para obter mais informações, consulte [Introdução ao runtime do .NET 8 para AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-net-8-runtime-for-aws-lambda/) no Blog AWS Compute.

**Topics**
+ [

## Runtime do Lambda
](#dotnet-native-aot-runtime)
+ [

## Pré-requisitos
](#dotnet-native-aot-prerequisites)
+ [

## Conceitos básicos
](#dotnet-native-aot-getting-started)
+ [

## Serialização
](#dotnet-native-aot-serialization)
+ [

## Remoção
](#dotnet-native-aot-trimming)
+ [

## Solução de problemas
](#dotnet-native-aot-troubleshooting)

## Runtime do Lambda
<a name="dotnet-native-aot-runtime"></a>

Para implantar uma função do Lambda criada com compilação AOT nativa, use o runtime do Lambda do .NET 8 gerenciado. Esse runtime oferece suporte a arquiteturas x86\$164 e arm64.

Quando uma função do Lambda .NET é implantada, sua aplicação é compilada em código de linguagem intermediária (IL). Em tempo de execução o compilador just-in-time (JIT) no runtime do Lambda assume o código IL e o compila em código de máquina conforme necessário. Com uma função do Lambda que é compilada antecipadamente com AOT nativa, você compila seu código em código de máquina ao implantar sua função. Assim, você se torna independente do runtime do .NET ou do SDK no runtime do Lambda para compilar seu código antes que ele seja executado.

Uma limitação da AOT é que o código da aplicação deve ser compilado em um ambiente com o mesmo sistema operacional Amazon Linux 2023 (AL2023) usado pelo runtime do .NET 8. A CLI do Lambda .NET fornece funcionalidade para compilar a aplicação em um contêiner do Docker usando uma imagem do AL2023.

Para evitar possíveis problemas de compatibilidade entre arquiteturas, é altamente recomendável compilar o código em um ambiente com a mesma arquitetura de processador configurada para sua função. Para saber mais sobre as limitações da compilação entre arquiteturas, consulte [Compilação cruzada](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile) na documentação do Microsoft.NET.

## Pré-requisitos
<a name="dotnet-native-aot-prerequisites"></a>

**Docker**  
Para usar a AOT nativa, o código da função deve ser compilado em um ambiente com o mesmo sistema operacional AL2023 que o runtime do .NET 8. Os comandos da CLI do .NET nas seções a seguir usam o Docker para desenvolver e compilar funções do Lambda em um ambiente do AL2023.

**SDK do .NET 8**  
A compilação AOT nativa é um recurso do .NET 8. É necessário instalar o [SDK do .NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) no computador de compilação, e não somente o runtime.

**Amazon.Lambda.Tools**  
Para criar as funções do Lambda, você usa a [extensão .NET Global Tools](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) do [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Para instalar Amazon.Lambda.Tools, execute o comando a seguir:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Para obter mais informações sobre a extensão Amazon.Lambda.Tools da CLI do .NET, consulte o repositório [AWS Extensions for .NET CLI](https://github.com/aws/aws-extensions-for-dotnet-cli) no GitHub.

**Amazon.Lambda.Templates**  
Para gerar o código da função do Lambda, use o Pacote do NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates). Para instalar esse pacote de modelo, execute o comando a seguir:  

```
dotnet new install Amazon.Lambda.Templates
```

## Conceitos básicos
<a name="dotnet-native-aot-getting-started"></a>

Tanto a CLI Global do .NET quanto o AWS Serverless Application Model (AWS SAM) fornecem modelos de introdução para criar aplicações usando a AOT nativa. Para criar sua primeira função do Lambda da AOT nativa, execute as etapas nas seguintes instruções.

**Para inicializar e implantar uma função do Lambda compilada na AOT nativa**

1. Inicialize um novo projeto usando o modelo da AOT nativa e, em seguida, navegue até o diretório que contém os arquivos `.cs` e `.csproj` criados. Neste exemplo, nossa função tem o nome `NativeAotSample`.

   ```
   dotnet new lambda.NativeAOT -n NativeAotSample
   cd ./NativeAotSample/src/NativeAotSample
   ```

   O arquivo `Function.cs` criado pelo modelo de AOT nativa contém o seguinte código de função.

   ```
   using Amazon.Lambda.Core;
   using Amazon.Lambda.RuntimeSupport;
   using Amazon.Lambda.Serialization.SystemTextJson;
   using System.Text.Json.Serialization;
   
   namespace NativeAotSample;
   
   public class Function
   {
       /// <summary>
       /// The main entry point for the Lambda function. The main function is called once during the Lambda init phase. It
       /// initializes the .NET Lambda runtime client passing in the function handler to invoke for each Lambda event and
       /// the JSON serializer to use for converting Lambda JSON format to the .NET types.
       /// </summary>
       private static async Task Main()
       {
           Func<string, ILambdaContext, string> handler = FunctionHandler;
           await LambdaBootstrapBuilder.Create(handler, new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>())
               .Build()
               .RunAsync();
       }
   
       /// <summary>
       /// A simple function that takes a string and does a ToUpper.
       ///
       /// To use this handler to respond to an AWS event, reference the appropriate package from
       /// https://github.com/aws/aws-lambda-dotnet#events
       /// and change the string input parameter to the desired event type. When the event type
       /// is changed, the handler type registered in the main method needs to be updated and the LambdaFunctionJsonSerializerContext
       /// defined below will need the JsonSerializable updated. If the return type and event type are different then the
       /// LambdaFunctionJsonSerializerContext must have two JsonSerializable attributes, one for each type.
       ///
       // When using Native AOT extra testing with the deployed Lambda functions is required to ensure
       // the libraries used in the Lambda function work correctly with Native AOT. If a runtime
       // error occurs about missing types or methods the most likely solution will be to remove references to trim-unsafe
       // code or configure trimming options. This sample defaults to partial TrimMode because currently the AWS
       // SDK for .NET does not support trimming. This will result in a larger executable size, and still does not
       // guarantee runtime trimming errors won't be hit.
       /// </summary>
       /// <param name="input"></param>
       /// <param name="context"></param>
       /// <returns></returns>
       public static string FunctionHandler(string input, ILambdaContext context)
       {
           return input.ToUpper();
       }
   }
   
   /// <summary>
   /// This class is used to register the input event and return type for the FunctionHandler method with the System.Text.Json source generator.
   /// There must be a JsonSerializable attribute for each type used as the input and return type or a runtime error will occur
   /// from the JSON serializer unable to find the serialization information for unknown types.
   /// </summary>
   [JsonSerializable(typeof(string))]
   public partial class LambdaFunctionJsonSerializerContext : JsonSerializerContext
   {
       // By using this partial class derived from JsonSerializerContext, we can generate reflection free JSON Serializer code at compile time
       // which can deserialize our class and properties. However, we must attribute this class to tell it what types to generate serialization code for.
       // See https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation
   ```

   A AOT nativa compila a aplicaçãp em um único binário nativo. O ponto de entrada desse binário é o método `static Main`. No `static Main`, o runtime do Lambda é inicializado e o método `FunctionHandler` é configurado. Como parte da inicialização do runtime, um serializador gerado pela fonte é configurado usando `new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>()`

1. Para implantar a aplicação no Lambda, certifique-se de que o Docker esteja sendo executado em seu ambiente local e execute o comando a seguir.

   ```
   dotnet lambda deploy-function
   ```

   Nos bastidores, a CLI global do .NET baixa uma imagem do Docker do AL2023 e compila o código da aplicação em um contêiner em execução. O binário compilado é enviado de volta para o sistema de arquivos local antes de ser implantado no Lambda.

1. Teste a função executando o comando a seguir. Substitua `<FUNCTION_NAME>` pelo nome que você escolheu para a função no assistente de implantação.

   ```
   dotnet lambda invoke-function <FUNCTION_NAME> --payload "hello world"
   ```

   A resposta da CLI inclui detalhes de desempenho da inicialização a frio (duração da inicialização) e do tempo total de execução da invocação da função.

1. Para excluir os recursos do AWS que você criou seguindo as etapas anteriores, execute o comando a seguir. Substitua `<FUNCTION_NAME>` pelo nome que você escolheu para a função no assistente de implantação. Excluindo os recursos da AWS que não está mais usando, você evita que encargos desnecessários sejam cobrados em sua Conta da AWS.

   ```
   dotnet lambda delete-function <FUNCTION_NAME>
   ```

## Serialização
<a name="dotnet-native-aot-serialization"></a>

Para implantar funções no Lambda usando a AOT nativa, seu código de função deve usar [serialização gerada pela fonte](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation-modes?pivots=dotnet-8-0). Em vez de usar a reflexão de runtime para reunir os metadados necessários para acessar as propriedades do objeto para serialização, os geradores de fonte geram arquivos fonte em C\$1 que são compilados quando você cria a aplicação. Para configurar corretamente o serializador gerado pela fonte, certifique-se de incluir todos os objetos de entrada e saída que a função usa, bem como todo os tipos personalizados. Por exemplo, uma função do Lambda que recebe eventos de uma API REST do API Gateway e retorna um tipo de `Product` personalizado incluiria um serializador definido da seguinte forma.

```
[JsonSerializable(typeof(APIGatewayProxyRequest))]
[JsonSerializable(typeof(APIGatewayProxyResponse))]
[JsonSerializable(typeof(Product))]
public partial class CustomSerializer : JsonSerializerContext
{
}
```

## Remoção
<a name="dotnet-native-aot-trimming"></a>

A AOT nativa remove o código da aplicação como parte da compilação para garantir que o binário seja o menor possível. O.NET 8 para Lambda fornece suporte aprimorado à remoção em comparação com as versões anteriores do .NET. Suporte foi adicionado às [bibliotecas de runtime do Lambda](https://github.com/aws/aws-lambda-dotnet/pull/1596), ao [AWS SDK para .NET](https://github.com/aws/aws-sdk-net/pulls?q=is%3Apr+trimming), ao [.NET Lambda Annotations](https://github.com/aws/aws-lambda-dotnet/pull/1610) e ao próprio .NET 8.

Essas melhorias oferecem o potencial de eliminar os avisos de remoção em tempo de compilação, mas nunca será totalmente seguro remover o .NET. Isso significa que partes das bibliotecas das quais a função depende podem ser removidas como parte da etapa de compilação. É possível gerenciar isso definindo `TrimmerRootAssemblies` como parte do seu arquivo `.csproj`, conforme mostrado no exemplo a seguir. 

```
<ItemGroup>
    <TrimmerRootAssembly Include="AWSSDK.Core" />
    <TrimmerRootAssembly Include="AWSXRayRecorder.Core" />
    <TrimmerRootAssembly Include="AWSXRayRecorder.Handlers.AwsSdk" />
    <TrimmerRootAssembly Include="Amazon.Lambda.APIGatewayEvents" />
    <TrimmerRootAssembly Include="bootstrap" />
    <TrimmerRootAssembly Include="Shared" />
</ItemGroup>
```

Observe que, quando você recebe um aviso de remoção, adicionar a classe que gera o aviso a `TrimmerRootAssembly` pode não resolver o problema. Um aviso de remoção indica que a classe está tentando acessar alguma outra classe que não pode ser determinada até o tempo de execução. Para evitar erros de tempo de execução, adicione essa segunda classe a `TrimmerRootAssembly`.

Para saber mais sobre como gerenciar avisos de remoção, consulte [Introdução aos avisos de remoção](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/fixing-warnings) na documentação do Microsoft .NET.

## Solução de problemas
<a name="dotnet-native-aot-troubleshooting"></a>

**Erro: não há suporte para a compilação nativa entre sistemas operacionais.**  
Sua versão da ferramenta global do NET Core para Amazon.Lambda.Tools está desatualizada. Atualize para a versão mais recente e tente novamente.

**Docker: o sistema operacional de imagem “linux” não pode ser usado nesta plataforma.**  
O Docker está configurado para usar contêineres do Windows em seu sistema. Alterne para contêineres do Linux para executar o ambiente de compilação AOT nativo.

Para obter mais informações sobre erros comuns, consulte o repositório [AWS NativeAOT para .NET](https://github.com/awslabs/dotnet-nativeaot-labs#common-errors) no GitHub.

# Usar o objeto de contexto do Lambda para recuperar informações das funções em C\$1
<a name="csharp-context"></a>

Quando o Lambda executa a função, ele transmite um objeto de contexto para o [handler](csharp-handler.md). Esse objeto fornece propriedades com informações sobre a invocação, a função e o ambiente de execução.

**Propriedades de contexto**
+ `FunctionName`: o nome da função do Lambda.
+ `FunctionVersion`: a [versão](configuration-versions.md) da função.
+ `InvokedFunctionArn`: o nome do recurso da Amazon (ARN) usado para invocar a função. Indica se o invocador especificou um alias ou número de versão.
+ `MemoryLimitInMB`: a quantidade de memória alocada para a função.
+ `AwsRequestId`: o identificador da solicitação de invocação.
+ `LogGroupName`: o grupo de logs da função.
+ `LogStreamName`: a transmissão de log para a instância da função.
+ `RemainingTime` (`TimeSpan`): o número de milissegundos restantes antes do tempo limite da execução.
+ `Identity`: (aplicativos móveis) informações sobre a identidade do Amazon Cognito que autorizou a solicitação.
+ `ClientContext`: (aplicativos móveis) contexto do cliente fornecido ao Lambda pela aplicação cliente.
+ `Logger` O [objeto logger](csharp-logging.md) para a função.

Você pode usar a informação no objeto do `ILambdaContext` para gerar informações sobre a invocação da função para fins de monitoramento. O código a seguir fornece um exemplo de como adicionar informações de contexto a uma estrutura de log estruturada. Neste exemplo, a função adiciona `AwsRequestId` às saídas do log. A função também usa a propriedade `RemainingTime` para cancelar uma tarefa em execução se o tempo limite da função do Lambda estiver prestes a ser atingido.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function()
    {
        this._repo = new DatabaseRepository();
    }
    
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        Logger.AppendKey("AwsRequestId", context.AwsRequestId);
        
        var id = request.PathParameters["id"];

        using var cts = new CancellationTokenSource();
        
        try
        {
            cts.CancelAfter(context.RemainingTime.Add(TimeSpan.FromSeconds(-1)));
            
            var databaseRecord = await this._repo.GetById(id, cts.Token);
            
            return new APIGatewayProxyResponse 
            {
                StatusCode = (int)HttpStatusCode.OK,
                Body = JsonSerializer.Serialize(databaseRecord)
            };
        }
        catch (Exception ex)
        {
            return new APIGatewayProxyResponse 
            {
                StatusCode = (int)HttpStatusCode.InternalServerError,
                Body = JsonSerializer.Serialize(new { error = ex.Message })
            };
        }
        finally
        {
            cts.Cancel();
        }
    }
}
```

# Registrar em log e monitorar funções do Lambda em C\$1
<a name="csharp-logging"></a>

O AWS Lambda monitora automaticamente as funções do Lambda e envia entradas de logs para o Amazon CloudWatch. Sua função do Lambda vem com um grupo de logs do CloudWatch Logs e uma transmissão de logs para cada instância de sua função. O ambiente de runtime do Lambda envia detalhes sobre cada invocação e outras saídas do código da função para o fluxo de logs. Para obter mais informações sobre o CloudWatch Logs, consulte [Enviar logs de função do Lambda para o CloudWatch Logs](monitoring-cloudwatchlogs.md).

**Topics**
+ [

## Criar uma função que retorna logs
](#csharp-logging-output)
+ [

## Uso de controles avançados de registro em log do Lambda com .NET
](#csharp-logging-advanced)
+ [

## Outras ferramentas de geração de log e bibliotecas
](#csharp-tools-libraries)
+ [

## Uso do Powertools para AWS Lambda (.NET) e do AWS SAM para registro em log estruturado
](#dotnet-logging-sam)
+ [

## Visualizar logs no console do Lambda
](#csharp-logging-console)
+ [

## Visualização de logs no console do CloudWatch
](#csharp-logging-cwconsole)
+ [

## Visualizar logs usando a AWS Command Line Interface (AWS CLI)
](#csharp-logging-cli)
+ [

## Excluir logs
](#csharp-logging-delete)

## Criar uma função que retorna logs
<a name="csharp-logging-output"></a>

Para gerar os logs do código de função, você pode usar o [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) no objeto de contexto, os métodos na [classe Console](https://docs.microsoft.com/en-us/dotnet/api/system.console) ou qualquer biblioteca de logs que grave no `stdout` ou no `stderr`.

O runtime do .NET registra em log as linhas `START`, `END` e `REPORT` para cada invocação. A linha do relatório fornece os detalhes a seguir.

**RELATAR campos de dados de linha**
+ **RequestId**: o ID de solicitação exclusivo para a invocação.
+ **Duração**: a quantidade de tempo que o método de manipulador da função gastou processando o evento.
+ **Duração faturada**: a quantia de tempo faturada para a invocação.
+ **Tamanho da memória**: a quantidade de memória alocada para a função.
+ **Memória máxima utilizada**: a quantidade de memória utilizada pela função. Quando as invocações compartilham um ambiente de execução, o Lambda relata a memória máxima usada em todas as invocações. Esse comportamento pode resultar em um valor relatado maior do que o esperado.
+ **Duração inicial**: para a primeira solicitação atendida, a quantidade de tempo que o runtime levou para carregar a função e executar o código fora do método do handler.
+ **XRAY TraceId**: para solicitações rastreadas, o [ID de rastreamento do AWS X-Ray](services-xray.md).
+ **SegmentId**: para solicitações rastreadas, o ID do segmento do X-Ray.
+ **Amostragem**: para solicitações rastreadas, o resultado da amostragem.

## Uso de controles avançados de registro em log do Lambda com .NET
<a name="csharp-logging-advanced"></a>

Para dar mais controle sobre como os logs das funções são capturados, processados e consumidos, você pode configurar as seguintes opções de log para runtimes compatíveis do .NET:
+ **Formato do log**: selecione entre texto simples e formato JSON estruturado para os logs da sua função.
+ **Nível de log**: para logs no formato JSON, escolha o nível de detalhe dos logs enviados pelo Lambda para o CloudWatch, como ERROR, DEBUG ou INFO.
+ **Grupo de logs**: escolha o grupo de logs do CloudWatch para o qual sua função envia logs.

Para obter mais informações sobre essas opções de registro em log e instruções sobre como configurar a função para usá-las, consulte [Configurar controles avançados de registro em log para funções do Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

Para usar as opções de formato de log e nível de log com as funções do Lambda para .NET, consulte as orientações nas seções a seguir.

### Uso de logs em formato JSON estruturado com .NET
<a name="csharp-logging-advanced-JSON"></a>

Se você selecionar JSON para o formato de log da função, o Lambda enviará a saída de logs usando [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) como JSON estruturado. Cada objeto de log JSON contém pelo menos cinco pares de valores-chave com as seguintes chaves:
+ `"timestamp"`: o horário em que a mensagem de log foi gerada.
+ `"level"`: o nível de log atribuído à mensagem.
+ `"requestId"`: o ID de solicitação exclusivo para invocar a função.
+ `"traceId"`: a variável de ambiente `_X_AMZN_TRACE_ID`
+ `"message"`: o conteúdo da mensagem de log.

A instância `ILambdaLogger` pode adicionar mais pares de valores-chave, por exemplo, ao gerar logs de exceções. Também é possível fornecer seus próprios parâmetros adicionais, conforme descrito na seção [Parâmetros de log fornecidos pelo cliente](#csharp-logging-advanced-JSON-user-supplied).

**nota**  
Se o código já usa outra biblioteca de logs para produzir logs em formato JSON, confira se o formato de log da função está definido como texto sem formatação. Definir o formato de log como JSON resultará na codificação dupla das saídas de log.

O exemplo de comando de geração de log a seguir mostra como escrever uma mensagem de log com o nível `INFO`.

**Example Código de log do .NET**  

```
context.Logger.LogInformation("Fetching cart from database");
```

Também é possível usar um método de log genérico que usa o nível de log como argumento, conforme mostrado no exemplo a seguir.

```
context.Logger.Log(LogLevel.Information, "Fetching cart from database");
```

A saída de log desse exemplo de trechos de código seria capturada no CloudWatch Logs da seguinte forma:

**Example Registro em log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Fetching cart from database"
}
```

**nota**  
Se você configurar o formato de log da sua função para usar texto sem formatação, em vez de JSON, o nível de log capturado na mensagem seguirá a convenção da Microsoft de usar um rótulo de quatro caracteres. Por exemplo, um nível de log de `Debug` é representado na mensagem como `dbug`.  
Quando você configura sua função para usar logs no formato JSON, o nível de log capturado no log usa o rótulo completo, conforme mostrado no exemplo de registro de log JSON.

Se você não atribuir um nível à saída de log, o Lambda atribuirá automaticamente o nível INFO a ele.

#### Exceções de log em JSON
<a name="csharp-logging-advanced-JSON-exceptions"></a>

Ao usar a geração estruturada de logs JSON com `ILambdaLogger`, você pode registrar exceções em seu código, conforme mostrado no exemplo a seguir.

**Example uso de logs de exceções**  

```
try
{
    connection.ExecuteQuery(query);
}
catch(Exception e)
{
    context.Logger.LogWarning(e, "Error executing query");
}
```

A saída do formato de log por esse código é mostrada no JSON de exemplo a seguir. Observe que a propriedade `message` no JSON é preenchida usando o argumento de mensagem fornecido na chamada `LogWarning`, enquanto a propriedade `errorMessage` vem da propriedade `Message` da própria exceção.

**Example Registro em log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Warning",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Error executing query",
    "errorType": "System.Data.SqlClient.SqlException",
    "errorMessage": "Connection closed",
    "stackTrace": ["<call exception.StackTrace>"]
}
```

Se o formato de log da sua função estiver definido como JSON, o Lambda também mostrará mensagens de log formatadas em JSON quando seu código gerar uma exceção não detectada. O exemplo de trecho de código e mensagem de log a seguir mostra como as exceções não detectadas são registradas em log.

**Example código de exceção**  

```
throw new ApplicationException("Invalid data");
```

**Example Registro em log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Error",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Invalid data",
    "errorType": "System.ApplicationException",
    "errorMessage": "Invalid data",
    "stackTrace": ["<call exception.StackTrace>"]
}
```

#### Parâmetros de log fornecidos pelo cliente
<a name="csharp-logging-advanced-JSON-user-supplied"></a>

Com mensagens de log formatadas em JSON, você pode fornecer parâmetros adicionais de log e incluí-los no log `message`. O exemplo de trecho de código a seguir mostra um comando para adicionar dois parâmetros fornecidos pelo usuário com os rótulos `retryAttempt` e `uri`. No exemplo, o valor desses parâmetros vem dos argumentos `retryAttempt` e `uriDestination` passados para o comando de geração e log.

**Example Comando de geração de log JSON com parâmetros adicionais**  

```
context.Logger.LogInformation("Starting retry {retryAttempt} to make GET request to {uri}", retryAttempt, uriDestination);
```

A saída da mensagem de log desse comando é mostrada no JSON de exemplo a seguir.

**Example Registro em log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Starting retry 1 to make GET request to http://example.com/",
    "retryAttempt": 1,
    "uri": "http://example.com/"
}
```

**dica**  
Também é possível usar propriedades posicionais, em vez de nomes, ao especificar parâmetros adicionais. O comando de geração de log do exemplo anterior também poderia ser escrito da seguinte forma:  

```
context.Logger.LogInformation("Starting retry {0} to make GET request to {1}", retryAttempt, uriDestination);
```

Observe que, quando você fornece parâmetros adicionais de log, o Lambda os captura como propriedades de nível superior no registro de log JSON. Essa abordagem difere de algumas bibliotecas populares de logs .NET, como `Serilog`, que captura parâmetros adicionais em um objeto filho separado.

Se o argumento que você fornece para um parâmetro adicional for um objeto complexo, por padrão, o Lambda usa o método `ToString()` para fornecer o valor. Para indicar que um argumento deve ser um objeto serializado JSON, use o prefixo `@` conforme mostrado no trecho de código a seguir. Neste exemplo, `User` é um objeto com as propriedades `FirstName` e `LastName`.

**Example Comando de geração de log JSON com objeto serializado JSON**  

```
context.Logger.LogInformation("User {@user} logged in", User);
```

A saída da mensagem de log desse comando é mostrada no JSON de exemplo a seguir.

**Example Registro em log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "User {@user} logged in",
    "user": 
    {
        "FirstName": "John",
        "LastName": "Doe"
    }
}
```

Se o argumento para um parâmetro adicional for uma matriz ou implementar `IList` ou `IDictionary`, o Lambda acrescentará o argumento à mensagem de log JSON como uma matriz, conforme mostrado no exemplo de registro de log JSON a seguir. Neste exemplo, `{users}` usa um argumento `IList` que contém instâncias da propriedade `User` com o mesmo formato do exemplo anterior. O Lambda converte `IList` em uma matriz, com cada valor sendo criado usando o método `ToString`.

**Example Registro de log JSON com um argumento `IList`**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "{users} have joined the group",
    "users": 
    [
        "Rosalez, Alejandro",
        "Stiles, John"       
    ] 
}
```

Também é possível serializar a lista com JSON usando o prefixo `@` em seu comando de geração de log. No exemplo de registro de log JSON a seguir, a propriedade `users` é serializada em JSON.

**Example Registro de log JSON com um argumento `IList` serializado JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "{@users} have joined the group",
    "users": 
    [
        {
            "FirstName": "Alejandro",
            "LastName": "Rosalez"
        },
        {
            "FirstName": "John",
            "LastName": "Stiles"
        }        
    ] 
}
```

### Uso de filtragem em nível de log com .NET
<a name="csharp-logging-advanced-levels"></a>

Ao configurar a filtragem em nível de log, você pode optar por enviar somente logs de um determinado nível de detalhe, ou inferior, para o CloudWatch Logs. Para saber como configurar a filtragem em nível de log para a função, consulte [Filtragem em nível de log](monitoring-cloudwatchlogs-log-level.md).

Para o AWS Lambda filtrar suas mensagens de log por nível de log, você pode usar logs formatados em JSON ou usar os métodos .NET `Console` para gerar mensagens de log. Para criar logs no formato JSON, [configure o tipo de log da sua função como JSON](monitoring-cloudwatchlogs-logformat.md#monitoring-cloudwatchlogs-set-format) e use a instância `ILambdaLogger`.

Com logs formatados em JSON, o Lambda filtrará as saídas de log usando o par de valores-chave “nível” no objeto JSON descrito em [Uso de logs em formato JSON estruturado com .NET](#csharp-logging-advanced-JSON).

Se você usa os métodos .NET `Console` para gravar mensagens no CloudWatch Logs, o Lambda aplica níveis de log às suas mensagens da seguinte forma:
+ **Método Console.WriteLine**: o Lambda aplica um nível de log `INFO`
+ **Método Console.Error**: o Lambda aplica um nível de log `ERROR`

Ao configurar sua função para usar a filtragem em nível de log, você precisa selecionar entre as seguintes opções para o nível de logs enviados pelo Lambda para o CloudWatch Logs. Observe o mapeamento dos níveis de log usados pelo Lambda com os níveis padrão da Microsoft usados pelo `ILambdaLogger` .NET.


| Nível de log do Lambda | Nível equivalente da Microsoft | Uso padrão | 
| --- | --- | --- | 
| TRACE (mais detalhes) | Rastreamento | As informações mais detalhadas usadas para rastrear o caminho da execução do código | 
| DEBUG | Depure | Informações detalhadas para depuração do sistema | 
| INFORMAÇÕES | Informações | Mensagens que registram a operação normal da função | 
| WARN | Aviso | Mensagens sobre possíveis erros que podem levar a um comportamento inesperado se não forem corrigidos | 
| ERRO | Erro | Mensagens sobre problemas que impedem que o código funcione conforme o esperado | 
| FATAL (menos detalhes) | Crítico | Mensagens sobre erros graves que fazem a aplicação parar de funcionar | 

O Lambda envia logs do nível de detalhe selecionado, e dos níveis inferiores, para o CloudWatch. Por exemplo, se você configurar um nível de log de WARN, o Lambda enviará logs correspondentes aos níveis WARN, ERROR e FATAL.

## Outras ferramentas de geração de log e bibliotecas
<a name="csharp-tools-libraries"></a>

O [Powertools para AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) é um kit de ferramentas para desenvolvedores para implementar práticas recomendadas de tecnologia sem servidor e aumentar a velocidade do desenvolvedor. O [utilitário de logs](https://docs.aws.amazon.com/powertools/dotnet/core/logging/) fornece um registrador de logs otimizado para Lambda que inclui informações adicionais sobre o contexto da função em todas as suas funções, com saída estruturada como JSON. Use esse utilitário para fazer o seguinte:
+ Capturar campos-chave do contexto do Lambda, inicialização a frio e estruturas registrando em log a saída como JSON
+ Registrar em log eventos de invocação do Lambda quando instruído (desativado por padrão)
+ Imprimir todos os logs somente para uma porcentagem das invocações por meio da amostragem de logs (desativado por padrão)
+ Anexar chaves adicionais ao log estruturado a qualquer momento
+ Use um formatador de log personalizado (Bring Your Own Formatter) para gerar logs em uma estrutura compatível com o RFC de logs da sua organização

## Uso do Powertools para AWS Lambda (.NET) e do AWS SAM para registro em log estruturado
<a name="dotnet-logging-sam"></a>

Siga as etapas abaixo para baixar, criar e implantar um exemplo de aplicação C\$1 Hello World com os módulos integrados do [Powertools para AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) usando o AWS SAM. Esta aplicação implementa um backend de API básico e usa o Powertools para emitir logs, métricas e rastreamentos. Consiste em um endpoint do Amazon API Gateway e uma função do Lambda. Quando você envia uma solicitação GET ao endpoint do API Gateway, a função do Lambda invoca, envia logs e métricas usando o formato de métricas incorporadas ao CloudWatch e envia rastreamentos ao AWS X-Ray. A função retorna uma mensagem `hello world`.

**Pré-requisitos**

Para executar as etapas desta seção, você deve ter o seguinte:
+ .NET 8
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI versão 1.75 ou posterior](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Se você tiver uma versão mais antiga da CLI do AWS SAM, consulte [Atualizando a CLI do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implantar uma aplicação de exemplo do AWS SAM**

1. Inicialize a aplicação usando o modelo Hello World TypeScript.

   ```
   sam init --app-template hello-world-powertools-dotnet --name sam-app --package-type Zip --runtime dotnet6 --no-tracing
   ```

1. Crie a aplicação.

   ```
   cd sam-app && sam build
   ```

1. Implante o aplicativo.

   ```
   sam deploy --guided
   ```

1. Siga as instruções na tela. Para aceitar as opções padrão fornecidas na experiência interativa, pressione `Enter`.
**nota**  
Em **HelloWorldFunction pode não ter autorização definida, tudo bem?**, certifique-se de inserir `y`.

1. Obtenha o URL da aplicação implantada:

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. Invoque o endpoint da API:

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   Se tiver êxito, você verá esta resposta:

   ```
   {"message":"hello world"}
   ```

1. Para obter os logs da função, execute [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html). Para obter mais informações, consulte [Trabalhar com logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html) no *Guia do desenvolvedor do AWS Serverless Application Model*.

   ```
   sam logs --stack-name sam-app
   ```

   O resultado de saída do log se parece com:

   ```
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:27.988000 INIT_START Runtime Version: dotnet:6.v13        Runtime Version ARN: arn:aws:lambda:ap-southeast-2::runtime:699f346a05dae24c58c45790bc4089f252bf17dae3997e79b17d939a288aa1ec
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:28.229000 START RequestId: bed25b38-d012-42e7-ba28-f272535fb80e Version: $LATEST
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:29.259000 2025-09-20T14:15:29.201Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"_aws":{"Timestamp":1676902528962,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ColdStart","Unit":"Count"}],"Dimensions":[["FunctionName"],["Service"]]}]},"FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","Service":"PowertoolsHelloWorld","ColdStart":1}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.479000 2025-09-20T14:15:30.479Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"ColdStart":true,"XrayTraceId":"1-63f3807f-5dbcb9910c96f50742707542","CorrelationId":"d3d4de7f-4ccc-411a-a549-4d67b2fdc015","FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","FunctionVersion":"$LATEST","FunctionMemorySize":256,"FunctionArn":"arn:aws:lambda:ap-southeast-2:123456789012:function:sam-app-HelloWorldFunction-haKIoVeose2p","FunctionRequestId":"bed25b38-d012-42e7-ba28-f272535fb80e","Timestamp":"2025-09-20T14:15:30.4602970Z","Level":"Information","Service":"PowertoolsHelloWorld","Name":"AWS.Lambda.Powertools.Logging.Logger","Message":"Hello world API - HTTP 200"}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.599000 2025-09-20T14:15:30.599Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"_aws":{"Timestamp":1676902528922,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ApiRequestCount","Unit":"Count"}],"Dimensions":[["Service"]]}]},"Service":"PowertoolsHelloWorld","ApiRequestCount":1}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.680000 END RequestId: bed25b38-d012-42e7-ba28-f272535fb80e
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.680000 REPORT RequestId: bed25b38-d012-42e7-ba28-f272535fb80e  Duration: 2450.99 ms   Billed Duration: 2692 ms Memory Size: 256 MB     Max Memory Used: 74 MB  Init Duration: 240.05 ms
   XRAY TraceId: 1-63f3807f-5dbcb9910c96f50742707542       SegmentId: 16b362cd5f52cba0
   ```

1. Este é um endpoint de API pública que é acessado pela Internet. Recomendamos excluir o endpoint após o teste.

   ```
   sam delete
   ```

### Gerenciar a retenção de logs
<a name="csharp-log-retention"></a>

Os grupos de logs não são excluídos automaticamente excluídos quando você exclui uma função. Para evitar armazenar logs por tempo indeterminado, exclua o grupo de logs ou configure um período de retenção após o qual o CloudWatch excluirá os logs automaticamente. Para configurar a retenção de logs, adicione o seguinte ao seu modelo do AWS SAM:

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}"
      RetentionInDays: 7
```

## Visualizar logs no console do Lambda
<a name="csharp-logging-console"></a>

É possível usar o console do Lambda para exibir a saída do log depois de invocar uma função do Lambda.

Se seu código puder ser testado no editor de **Código** incorporado, você encontrará logs nos **resultados de execução**. Ao usar o recurso de teste do console para invocar uma função, você encontrará **Saída de log** na seção **Detalhes**.

## Visualização de logs no console do CloudWatch
<a name="csharp-logging-cwconsole"></a>

É possível usar o console do Amazon CloudWatch para exibir logs de todas as invocações da função do Lambda.

**Para visualizar logs no console do CloudWatch**

1. No console do Amazon CloudWatch, abra a [página Log groups](https://console.aws.amazon.com/cloudwatch/home?#logs:) (Grupos de log).

1. Escolha o grupo de logs de sua função (**/aws/lambda/*nome-de-sua-função***).

1. Escolha um stream de logs.

Cada fluxo de log corresponde a uma [instância da sua função](lambda-runtime-environment.md). Um fluxo de logs é exibido quando você atualiza sua função do Lambda e quando mais instâncias são criadas para lidar com invocações simultâneas. Para localizar logs de uma invocação específica, recomendamos intrumentar sua função com AWS X-Ray. O X-Ray registra detalhes sobre a solicitação e o stream de logs no rastreamento.

## Visualizar logs usando a AWS Command Line Interface (AWS CLI)
<a name="csharp-logging-cli"></a>

O AWS CLI é uma ferramenta de código aberto que permite interagir com os serviços do AWS usando comandos no shell da linha de comando. Para concluir as etapas desta seção, você deve ter a [versão 2 da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

É possível usar a [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) para recuperar logs de uma invocação usando a opção de comando `--log-type`. A resposta contém um campo `LogResult` com até 4 KB de logs codificados em base64 obtidos da invocação.

**Example recuperar um ID de log**  
O exemplo a seguir mostra como recuperar um *ID de log* do campo `LogResult` para uma função chamada `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
A seguinte saída deverá ser mostrada:  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example decodificar os logs**  
No mesmo prompt de comando, use o utilitário `base64` para decodificar os logs. O exemplo a seguir mostra como recuperar logs codificados em base64 de `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.  
A seguinte saída deverá ser mostrada:  

```
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
```
O utilitário `base64` está disponível no Linux, macOS e [Ubuntu no Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Os usuários do macOS precisam usar `base64 -D`.

**Example get-logs.sh script**  
No mesmo prompt de comando, use o script a seguir para fazer download dos últimos cinco eventos de log. O script usa `sed` para remover as aspas do arquivo de saída e fica inativo por 15 segundos para que os logs tenham tempo de ficar disponíveis. A saída inclui a resposta do Lambda, e a saída do comando `get-log-events`.   
Copie o conteúdo do exemplo de código a seguir e salve no diretório de seu projeto do Lambda como `get-logs.sh`.  
A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.  

```
#!/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 e Linux (somente)**  
No mesmo prompt de comando, os usuários do macOS e do Linux podem precisar executar o comando a seguir para garantir que o script seja executável.  

```
chmod -R 755 get-logs.sh
```

**Example recuperar os últimos cinco eventos de log**  
No mesmo prompt de comando, execute o script a seguir para obter os últimos cinco eventos de log.  

```
./get-logs.sh
```
A seguinte saída deverá ser mostrada:  

```
{
    "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"
}
```

## Excluir logs
<a name="csharp-logging-delete"></a>

Os grupos de logs não são excluídos automaticamente excluídos quando você exclui uma função. Para evitar armazenar logs indefinidamente, exclua o grupo de logs ou[Configurar um período de retenção](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)após o qual os logs são excluídos automaticamente.

# Instrumentar o código C \$1 no AWS Lambda
<a name="csharp-tracing"></a>

O Lambda se integra ao AWS X-Ray para ajudar você a rastrear, depurar e otimizar aplicações do Lambda. É possível usar o X-Ray para rastrear uma solicitação enquanto ela atravessa recursos na aplicação, o que pode incluir funções Lambda e outros produtos da AWS.

Para enviar dados de rastreamento ao X-Ray, é possível usar uma das três bibliotecas SDK:
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel): uma distribuição segura, pronta para produção e com suporte na AWS do SDK OpenTelemetry (OTel).
+ [AWS X-Ray SDK for .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) – um SDK para geração e envio de dados de rastreamento ao X-Ray.
+ [Powertools para AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/): um kit de ferramentas para desenvolvedores para implementar práticas recomendadas de tecnologia sem servidor e aumentar a velocidade do desenvolvedor.

Cada um dos SDKs oferece maneiras de enviar dados de telemetria ao serviço do X-Ray. Em seguida, é possível usar o X-Ray para visualizar, filtrar e obter insights sobre as métricas de performance da aplicação para identificar problemas e oportunidades de otimização.

**Importante**  
Os SDKs do X-Ray e do Powertools para AWS Lambda fazem parte de uma solução de instrumentação totalmente integrada oferecida pela AWS. As camadas do Lambda para ADOT fazem parte de um padrão em todo o setor para instrumentação de rastreamento que coleta mais dados em geral, mas pode não ser adequado para todos os casos de uso. É possível implementar o rastreamento de ponta a ponta no X-Ray usando ambas as soluções. Para saber mais sobre como escolher entre elas, consulte [Como escolher entre os SDKs do AWS Distro para OpenTelemetry e do X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing).

**Topics**
+ [

## Uso do Powertools para AWS Lambda (.NET) e do AWS SAM para rastreamento
](#dotnet-tracing-sam)
+ [

## Uso do SDK do X-Ray para instrumentar suas funções do .NET
](#dotnet-xray-sdk)
+ [

## Ativar o rastreamento com o console do Lambda
](#dotnet-tracing-console)
+ [

## Ativar o rastreamento com a API do Lambda
](#dotnet-tracing-api)
+ [

## Ativar o rastreamento com o CloudFormation
](#dotnet-tracing-cloudformation)
+ [

## Interpretar um rastreamento do X-Ray
](#dotnet-tracing-interpretation)

## Uso do Powertools para AWS Lambda (.NET) e do AWS SAM para rastreamento
<a name="dotnet-tracing-sam"></a>

Siga as etapas abaixo para baixar, criar e implantar um exemplo de aplicação C\$1 Hello World com os módulos integrados do [Powertools para AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) usando o AWS SAM. Esta aplicação implementa um backend de API básico e usa o Powertools para emitir logs, métricas e rastreamentos. Consiste em um endpoint do Amazon API Gateway e uma função do Lambda. Quando você envia uma solicitação GET ao endpoint do API Gateway, a função do Lambda invoca, envia logs e métricas usando o formato de métricas incorporadas ao CloudWatch e envia rastreamentos ao AWS X-Ray. A função retorna uma mensagem de hello world.

**Pré-requisitos**

Para executar as etapas desta seção, você deve ter o seguinte:
+ .NET 8
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI versão 1.75 ou posterior](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Se você tiver uma versão mais antiga da CLI do AWS SAM, consulte [Atualizando a CLI do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implantar uma aplicação de exemplo do AWS SAM**

1. Inicialize a aplicação usando o modelo Hello World TypeScript.

   ```
   sam init --app-template hello-world-powertools-dotnet --name sam-app --package-type Zip --runtime dotnet6 --no-tracing
   ```

1. Crie a aplicação.

   ```
   cd sam-app && sam build
   ```

1. Implante o aplicativo.

   ```
   sam deploy --guided
   ```

1. Siga as instruções na tela. Para aceitar as opções padrão fornecidas na experiência interativa, pressione `Enter`.
**nota**  
Em **HelloWorldFunction pode não ter autorização definida, tudo bem?**, certifique-se de inserir `y`.

1. Obtenha o URL da aplicação implantada:

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. Invoque o endpoint da API:

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   Se tiver êxito, você verá esta resposta:

   ```
   {"message":"hello world"}
   ```

1. Para obter os rastreamentos da função, execute [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   A saída de rastreamento se parece com:

   ```
   New XRay Service Graph
     Start time: 2023-02-20 23:05:16+08:00
     End time: 2023-02-20 23:05:16+08:00
     Reference Id: 0 - AWS::Lambda - sam-app-HelloWorldFunction-pNjujb7mEoew - Edges: [1]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 2.814
     Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-pNjujb7mEoew - Edges: []
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 2.429
     Reference Id: 2 - (Root) AWS::ApiGateway::Stage - sam-app/Prod - Edges: [0]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 2.839
     Reference Id: 3 - client - sam-app/Prod - Edges: [2]
      Summary_statistics:
        - total requests: 0
        - ok count(2XX): 0
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0
   
   XRay Event [revision 3] at (2023-02-20T23:05:16.521000) with id (1-63f38c2c-270200bf1d292a442c8e8a00) and duration (2.877s)
    - 2.839s - sam-app/Prod [HTTP: 200]
      - 2.836s - Lambda [HTTP: 200]
    - 2.814s - sam-app-HelloWorldFunction-pNjujb7mEoew [HTTP: 200]
    - 2.429s - sam-app-HelloWorldFunction-pNjujb7mEoew
      - 0.230s - Initialization
      - 2.389s - Invocation
        - 0.600s - ## FunctionHandler
          - 0.517s - Get Calling IP
      - 0.039s - Overhead
   ```

1. Este é um endpoint de API pública que é acessado pela Internet. Recomendamos excluir o endpoint após o teste.

   ```
   sam delete
   ```

O X-Ray não rastreia todas as solicitações para sua aplicação. O X-Ray aplica um algoritmo de amostragem para garantir que o rastreamento seja eficiente, enquanto ainda fornece uma amostra representativa das solicitações. A taxa de amostragem é uma solicitação por segundo e 5% de solicitações adicionais. Você não pode configurar a taxa de amostragem do X-Ray para suas funções.

## Uso do SDK do X-Ray para instrumentar suas funções do .NET
<a name="dotnet-xray-sdk"></a>

É possível instrumentar seu código de função para gravar metadados e rastrear chamadas downstream. Para registrar detalhes sobre as chamadas que a função faz para outros recursos e serviços, use o AWS X-Ray SDK for .NET. Para obter o SDK, adicione os pacotes `AWSXRayRecorder` ao arquivo do projeto.

```
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <AWSProjectType>Lambda</AWSProjectType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" />
    <PackageReference Include="Amazon.Lambda.SQSEvents" Version="2.1.0" />
    <PackageReference Include="Amazon.Lambda.Serialization.Json" Version="2.1.0" />
    <PackageReference Include="AWSSDK.Core" Version="3.7.103.24" />
    <PackageReference Include="AWSSDK.Lambda" Version="3.7.104.3" />
    <PackageReference Include="AWSXRayRecorder.Core" Version="2.13.0" />
    <PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.11.0" />
  </ItemGroup>
</Project>
```

Há uma variedade de pacotes Nuget que fornecem auto-instrumentação automática para os SDKs da AWS, Entity Framework e solicitações HTTP. Para ver o conjunto completo de opções de configuração, consulte [AWS X-Ray SDK for .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) no *AWS X-Ray Developer Guide*.

Depois de adicionar os pacotes Nuget desejados, configure a instrumentação automática. A prática recomendada é realizar essa configuração fora da função de manipulador da função. Isso permite que você aproveite a reutilização do ambiente de execução para melhorar o desempenho da função. No exemplo de código a seguir, o método `RegisterXRayForAllServices` é chamado no construtor da função para adicionar instrumentação a todas as chamadas do SDK da AWS.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function()
    {
        // Add auto instrumentation for all AWS SDK calls
        // It is important to call this method before initializing any SDK clients
        AWSSDKHandler.RegisterXRayForAllServices();
        this._repo = new DatabaseRepository();
    }
    
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request)
    {
        var id = request.PathParameters["id"];
        
        var databaseRecord = await this._repo.GetById(id);
        
        return new APIGatewayProxyResponse 
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = JsonSerializer.Serialize(databaseRecord)
        };
    }
}
```

## Ativar o rastreamento com o console do Lambda
<a name="dotnet-tracing-console"></a>

Para alternar o rastreamento ativo na sua função do Lambda usando o console, siga as etapas abaixo:

**Para ativar o rastreamento ativo**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha uma função.

1. Escolha **Configuration** (Configuração) e depois **Monitoring and operations tools** (Ferramentas de monitoramento e operações).

1. Em **Ferramentas de monitoramento adicionais**, selecione **Editar**.

1. Em **CloudWatch Application Signals e AWS X-Ray**, escolha **Habilitar** para **Rastreamentos do serviço Lambda**.

1. Escolha **Salvar**.

## Ativar o rastreamento com a API do Lambda
<a name="dotnet-tracing-api"></a>

Configure o rastreamento na sua função do Lambda com a AWS CLI ou o AWS SDK, usando as seguintes operações de 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)

O exemplo de comando da AWS CLI a seguir habilita o rastreamento ativo em uma função chamada **my-function**.

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

O modo de rastreamento faz parte da configuração específica da versão quando você publica uma versão da função. Não é possível alterar o modo de rastreamento em uma versão publicada.

## Ativar o rastreamento com o CloudFormation
<a name="dotnet-tracing-cloudformation"></a>

Para ativar o rastreamento ativo em um recurso `AWS::Lambda::Function` em um modelo do CloudFormation, use a propriedade `TracingConfig`.

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml): configuração de rastreamento**  

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

Para um recurso do AWS Serverless Application Model (AWS SAM) `AWS::Serverless::Function`, use a propriedade `Tracing`.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml): configuração de rastreamento**  

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

## Interpretar um rastreamento do X-Ray
<a name="dotnet-tracing-interpretation"></a>

Sua função precisa de permissão para carregar dados de rastreamento no X-Ray. Quando você ativa o rastreamento ativo no console do Lambda, o Lambda adiciona as permissões necessárias à [função de execução](lambda-intro-execution-role.md) da função. Caso contrário, adicione a política [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) à função de execução.

Após configurar o rastreamento ativo, você pode observar solicitações específicas por meio da aplicação. O [grafo de serviço do X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) exibe informações sobre sua aplicação e todos os componentes. O exemplo a seguir mostra uma aplicação com duas funções. A função principal processa eventos e, às vezes, retorna erros. A segunda função de cima para baixo processa erros que aparecem no primeiro grupo de logs e usa o AWS SDK para chamar o X-Ray, o Amazon Simple Storage Service (Amazon S3) e o Amazon CloudWatch Logs.

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


O X-Ray não rastreia todas as solicitações para sua aplicação. O X-Ray aplica um algoritmo de amostragem para garantir que o rastreamento seja eficiente, enquanto ainda fornece uma amostra representativa das solicitações. A taxa de amostragem é uma solicitação por segundo e 5% de solicitações adicionais. Você não pode configurar a taxa de amostragem do X-Ray para suas funções.

No X-Ray, um *rastreamento* registra informações sobre uma solicitação que é processada por um ou mais *serviços*. O Lambda registra dois segmentos por rastreamento, o que cria dois nós no gráfico de serviços. A imagem a seguir destaca esses dois nós:

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


O primeiro nó à esquerda representa o serviço do Lambda, que recebe a solicitação de invocação. O segundo nó representa a sua função do Lambda específica. O exemplo a seguir mostra um rastreamento com esses dois segmentos. Ambos têm o nome **my-function**, mas um tem a origem `AWS::Lambda` e o outro, a origem `AWS::Lambda::Function`. Se o segmento `AWS::Lambda` mostrar um erro, o serviço Lambda teve um problema. Se o segmento `AWS::Lambda::Function` mostrar um erro, sua função teve um problema.

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


Este exemplo expande o segmento `AWS::Lambda::Function` para mostrar seus três subsegmentos.

**nota**  
A AWS atualmente está implementando alterações no serviço Lambda. Devido a essas alterações, você pode ver pequenas diferenças entre a estrutura e o conteúdo das mensagens de log do sistema e os segmentos de rastreamento emitidos por diferentes funções do Lambda na sua Conta da AWS.  
O exemplo de rastreamento mostrado aqui ilustra o segmento de função no estilo antigo. As diferenças entre os segmentos no estilo antigo e no estilo novo são descritas nos próximos parágrafos.  
Essas alterações serão implementadas durante as próximas semanas, e todas as funções em todas as Regiões da AWS, exceto nas regiões China e GovCloud, passarão a usar o novo formato de mensagens de log e segmentos de rastreamento.

O segmento de função no estilo antigo contém os seguintes subsegmentos:
+ **Inicialização**: representa o tempo gasto carregando a função e executando o [código de inicialização](foundation-progmodel.md). Esse subsegmento aparece somente para o primeiro evento que cada instância da função processa.
+ **Invocação**: representa o tempo gasto na execução do código do manipulador.
+ **Sobrecarga**: representa o tempo gasto pelo runtime do Lambda preparando-se para lidar com o próximo evento.

O segmento de função no estilo novo não contém um subsegmento `Invocation`. Em vez disso, os subsegmentos dos clientes são anexados diretamente ao segmento da função. Para obter mais informações sobre a estrutura dos segmentos de função no estilo antigo e no estilo novo, consulte [Noções básicas sobre rastreamentos do X-Ray](services-xray.md#services-xray-traces).

Você também pode instrumentar clientes HTTP, registrar consultas SQL e criar subsegmentos personalizados com anotações e metadados. Para obter mais informações, consulte [AWS X-Ray SDK for .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) no *Guia do desenvolvedor do AWS X-Ray*.

**Preços**  
Você pode usar o rastreamento do X-Ray gratuitamente todos os meses até determinado limite como parte do nível gratuito da AWS. Além do limite, o X-Ray cobra por armazenamento e recuperação de rastreamento. Para obter mais informações, consulte [Definição de preçoAWS X-Ray](https://aws.amazon.com/xray/pricing/).

# Teste da função do AWS Lambda em C\$1
<a name="dotnet-csharp-testing"></a>

**nota**  
Consulte o capítulo [Testar funções](testing-guide.md) para obter uma introdução completa às técnicas e melhores práticas para testar soluções com tecnologia sem servidor. 

 Os testes de funções com tecnologia sem servidor usam tipos e técnicas de teste tradicionais, mas você também deve considerar testar aplicações com tecnologia sem servidor como um todo. Os testes baseados em nuvem fornecerão a medida **mais precisa** da qualidade das suas funções e aplicações com tecnologia sem servidor. 

 Uma arquitetura de aplicações com tecnologia sem servidor inclui serviços gerenciados que fornecem funcionalidade de aplicações  críticas por meio de chamadas de API. Por esse motivo, seu ciclo de desenvolvimento deve incluir testes automatizados que verifiquem a funcionalidade quando sua função e seus serviços interagem. 

 Se você não criar testes baseados em nuvem, poderá encontrar problemas devido às diferenças entre o ambiente local e o ambiente implantado. Seu processo de integração contínua deve executar testes em comparação com um conjunto de recursos provisionados na nuvem antes de promover seu código para o próximo ambiente de implantação, como GQ, Preparação ou Produção. 

 Continue lendo este breve guia para aprender sobre estratégias de testes para aplicações com tecnologia sem servidor ou acesse o [repositório de exemplos de testes com tecnologia sem servidor](https://github.com/aws-samples/serverless-test-samples) para conhecer exemplos práticos, específicos da linguagem e do runtime escolhidos. 

 ![\[illustration showing the relationship between types of tests\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/test-type-illustration2.png) 

 Para testes com tecnologia sem servidor, você ainda escreverá testes *unitários*, de *integração* e de *ponta a ponta*. 
+ **Testes unitários**: testes executados em comparação com um bloco de código isolado. Por exemplo, verificar a lógica de negócios para calcular a taxa de entrega de acordo com um item e um destino determinado.
+ **Testes de integração**: testes envolvendo dois ou mais componentes ou serviços que interagem, normalmente em um ambiente de nuvem. Por exemplo, a verificação de eventos de processos de uma função em uma fila.
+ **Testes de ponta a ponta**: testes que verificam o comportamento em toda a aplicação. Por exemplo, garantir que a infraestrutura seja configurada corretamente e que os eventos fluam entre os serviços conforme o esperado para registrar o pedido de um cliente.

## Testar suas aplicações com tecnologia sem servidor
<a name="dotnet-csharp-testing-techniques-for-serverless-applications"></a>

 Geralmente, você usará uma combinação de abordagens para testar o código da aplicação com tecnologia sem servidor, incluindo testes na nuvem, testes com simulações e, ocasionalmente, testes com emuladores. 

### Testes na nuvem
<a name="dotnet-csharp-testing-in-the-cloud"></a>

 Os testes na nuvem são valiosos para todas as fases dos testes, incluindo testes unitários, testes de integração e testes de ponta a ponta. Você executa testes com o código implantado na nuvem e interagindo com serviços baseados na nuvem. Essa abordagem fornece a medida **mais precisa** da qualidade do código. 

 Uma maneira conveniente de depurar a função do Lambda na nuvem é com o uso de um evento de teste no console. Um *evento de teste* é uma entrada JSON para sua função. Se a função não necessitar de entrada, o evento poderá ser um documento JSON vazio `({})`. O console fornece eventos de exemplo para uma variedade de integrações de serviços. Depois de criar um evento no console, você pode compartilhá-lo com sua equipe para tornar os testes mais fáceis e consistentes. 

**nota**  
[Testar uma função no console](testing-functions.md) é uma maneira rápida de começar a usar, mas automatizar os ciclos de teste garante a qualidade da aplicação e a velocidade de desenvolvimento. 

### Ferramentas de teste
<a name="dotnet-csharp-testing-tools"></a>

Para acelerar seu ciclo de desenvolvimento, há várias ferramentas e técnicas que você pode usar ao testar as funções. Por exemplo, o [AWS SAM Accelerate](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-sync.html) e o [modo de observação do AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-deploy-watch) diminuem o tempo necessário para atualizar os ambientes de nuvem.

A maneira como você define o código da função do Lambda simplifica a adição de testes de unidade. O Lambda exige um construtor público sem parâmetros para inicializar a classe. A introdução de um segundo construtor interno dá a você controle das dependências que a aplicação usa.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function(): this(null)
    {
    }
    
    internal Function(IDatabaseRepository repo)
    {
        this._repo = repo ?? new DatabaseRepository();
    }
    
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request)
    {
        var id = request.PathParameters["id"];
        
        var databaseRecord = await this._repo.GetById(id);
        
        return new APIGatewayProxyResponse 
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = JsonSerializer.Serialize(databaseRecord)
        };
    }
}
```

Para escrever um teste para essa função, você pode inicializar uma nova instância da classe da `Function` e passar por uma implementação simulada do `IDatabaseRepository`. Os exemplos abaixo usam `XUnit`, `Moq` e `FluentAssertions` para escrever um teste simples, garantindo que o `FunctionHandler` retorne de um código de status 200.

```
using Xunit;
using Moq;
using FluentAssertions;

public class FunctionTests
{
    [Fact]
    public async Task TestLambdaHandler_WhenInputIsValid_ShouldReturn200StatusCode()
    {
        // Arrange
        var mockDatabaseRepository = new Mock<IDatabaseRepository>();
        
        var functionUnderTest = new Function(mockDatabaseRepository.Object);
        
        // Act
        var response = await functionUnderTest.FunctionHandler(new APIGatewayProxyRequest());
        
        // Assert
        response.StatusCode.Should().Be(200);
    }
}
```

Para exemplos mais detalhados, incluindo exemplos de testes assíncronos, consulte o [repositório de amostras de testes do .NET](https://github.com/aws-samples/serverless-test-samples/tree/main/dotnet-test-samples) no GitHub.