

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Erstellen von Lambda-Funktionen mit Rust
<a name="lambda-rust"></a>

Da Rust zu nativem Code kompiliert wird, benötigen Sie keine spezielle Laufzeit, um Rust-Code auf Lambda auszuführen. Verwenden Sie stattdessen den [Rust-Runtime-Client](https://github.com/aws/aws-lambda-rust-runtime), um Ihr Projekt lokal zu erstellen, und stellen Sie es dann mithilfe einer [reinen Betriebssystemlaufzeit](runtimes-provided.md) auf Lambda bereit. Wenn Sie eine reine Betriebssystem-Runtime verwenden, hält Lambda das Betriebssystem automatisch mit den neuesten Patches auf dem neuesten Stand.

**Tools und Bibliotheken für Rust**
+ [AWS SDK für Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/getting-started.html): Das AWS SDK für Rust bietet Rust APIs die Möglichkeit, mit den Infrastrukturdiensten von Amazon Web Services zu interagieren.
+  [Rust-Laufzeitclient für Lambda](https://github.com/aws/aws-lambda-rust-runtime): Der Rust-Runtime-Client macht es einfach, in Rust geschriebene Lambda-Funktionen auszuführen.
+ [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html): Dies ist eine Open-Source-Erweiterung eines Drittanbieters für das Cargo-Befehlszeilentool, die das Erstellen und Bereitstellen von Rust Lambda-Funktionen vereinfacht.
+ [Lambda HTTP](https://github.com/aws/aws-lambda-rust-runtime/tree/main/lambda-http): Diese Bibliothek bietet einen Wrapper für die Arbeit mit HTTP-Ereignissen.
+  [Lambda-Erweiterung](https://github.com/aws/aws-lambda-rust-runtime/tree/main/lambda-extension): Diese Bibliothek bietet Unterstützung für das Schreiben von Lambda-Erweiterungen mit Rust. 
+ [AWS Lambda Ereignisse](https://crates.io/crates/aws_lambda_events): Diese Bibliothek bietet Typdefinitionen für gängige Integrationen mit Ereignisquellen.

**Beispiele für Lambda-Anwendungen für Rust**
+ [Grundlegende Lambda-Funktion](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-lambda): Eine Rust-Funktion, die zeigt, wie grundlegende Ereignisse verarbeitet werden.
+ [Lambda-Funktion mit Fehlerbehandlung](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-error-handling): Eine Rust-Funktion, die zeigt, wie benutzerdefinierte Rust-Fehler in Lambda behandelt werden.
+ [Lambda-Funktion mit gemeinsam genutzten Ressourcen](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/basic-shared-resource): Ein Rust-Projekt, das gemeinsam genutzte Ressourcen initialisiert, bevor die Lambda-Funktion erstellt wird.
+ [Lambda-HTTP-Ereignisse](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-basic-lambda): Eine Rust-Funktion, die HTTP-Ereignisse verarbeitet.
+ [Lambda-HTTP-Ereignisse mit CORS-Headern](https://github.com/aws/aws-lambda-rust-runtime/blob/main//examples/http-cors): Eine Rust-Funktion, die Tower verwendet, um CORS-Header zu injizieren.
+ [Lambda-REST-API](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/http-axum-diesel): Eine REST-API, die Axum und Diesel verwendet, um eine Verbindung zu einer PostgreSQL-Datenbank herzustellen.
+ [Serverlose Rust-Demo](https://github.com/aws-samples/serverless-rust-demo/): Ein Rust-Projekt, das die Verwendung der Rust-Bibliotheken, der Protokollierung, der Umgebungsvariablen und des SDK von Lambda zeigt. AWS 
+ [Basic Lambda-Erweiterung](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/extension-basic): Eine Rust-Erweiterung, die zeigt, wie grundlegende Erweiterungsereignisse verarbeitet werden.
+ [Lambda-Protokolle und Erweiterung für Amazon Data Firehose](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/extension-logs-kinesis-firehose): Eine Rust-Erweiterung, die das Senden von Lambda-Protokollierung an Firehose aufzeigt.

**Topics**
+ [

# Definieren von Lambda-Funktionshandlern in Rust
](rust-handler.md)
+ [

# Verwenden des Lambda-Kontextobjekts zum Abrufen von Rust-Funktionsinformationen
](rust-context.md)
+ [

# Verarbeitung von HTTP-Ereignissen mit Rust
](rust-http-events.md)
+ [

# Bereitstellen von Lambda-Rust-Funktionen mit ZIP-Dateiarchiven
](rust-package.md)
+ [

# Arbeiten mit Ebenen für Rust-Lambda-Funktionen
](rust-layers.md)
+ [

# Rust-Lambda-Funktionen protokollieren und überwachen
](rust-logging.md)

# Definieren von Lambda-Funktionshandlern in Rust
<a name="rust-handler"></a>

Der Lambda-Funktions*handler* ist die Methode in Ihrem Funktionscode, die Ereignisse verarbeitet. Wenn Ihre Funktion aufgerufen wird, führt Lambda die Handler-Methode aus. Ihre Funktion wird so lange ausgeführt, bis der Handler eine Antwort zurückgibt, beendet wird oder ein Timeout auftritt.

Auf dieser Seite wird beschrieben, wie Sie mit Lambda-Funktionshandlern in Rust arbeiten, einschließlich der Projektinitialisierung, Benennungskonventionen und Best Practices. Diese Seite enthält auch ein Beispiel für eine Rust-Lambda-Funktion, die Informationen über eine Bestellung aufnimmt, eine Textdatei als Quittung erstellt und diese Datei in einen Amazon Simple Storage Service (S3)-Bucket stellt. Weitere Informationen darüber, wie Sie Ihre Funktion nach dem Schreiben einsetzen können, finden Sie unter [Bereitstellen von Lambda-Rust-Funktionen mit ZIP-Dateiarchiven](rust-package.md).

**Topics**
+ [

## Einrichten Ihres Rust-Handler-Projekts
](#rust-handler-setup)
+ [

## Beispiel für Rust-Lambda-Funktionscode
](#rust-example-code)
+ [

## Gültige Klassendefinitionen für Rust-Handler
](#rust-handler-signatures)
+ [

## Namenskonventionen für Handler
](#rust-example-naming)
+ [

## Definieren Sie das Eingabeereignisobjekt und greifen Sie darauf zu
](#rust-handler-input)
+ [

## Zugreifen auf und Verwenden des Lambda-Kontextobjekts
](#rust-example-context)
+ [

## Verwenden Sie den AWS SDK für Rust in Ihrem Handler
](#rust-example-sdk-usage)
+ [

## Zugriff auf Umgebungsvariablen
](#rust-example-envvars)
+ [

## Geteilten Zustand verwenden
](#rust-shared-state)
+ [

## Bewährte Codemethoden für Rust-Lambda-Funktionen
](#rust-best-practices)

## Einrichten Ihres Rust-Handler-Projekts
<a name="rust-handler-setup"></a>

Wenn Sie mit Lambda-Funktionen in Rust arbeiten, umfasst der Prozess das Schreiben Ihres Codes, das Kompilieren und das Bereitstellen der kompilierten Artefakte in Lambda. Der einfachste Weg, ein Lambda-Handler-Projekt in Rust einzurichten, ist die Verwendung von [AWS Lambda Runtime for Rust](https://github.com/aws/aws-lambda-rust-runtime). Trotz ihres Namens ist AWS Lambda Runtime for Rust keine verwaltete Laufzeit im gleichen Sinne wie Lambda für Python, Java oder Node.js. Stattdessen ist die AWS Lambda Runtime for Rust eine crate (`lambda_runtime`), die das Schreiben von Lambda-Funktionen in Rust und die Anbindung an die Ausführungsumgebung AWS Lambda unterstützt.

Verwenden Sie den folgenden Befehl, um [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html) zu installieren, eine Open-Source-Erweiterung eines Drittanbieters für das Cargo-Befehlszeilentool, die das Erstellen und Bereitstellen von Rust Lambda-Funktionen vereinfacht:

```
cargo install cargo-lambda
```

Verwenden Sie nach der erfolgreichen Installation von `cargo-lambda` den folgenden Befehl, um ein neues Rust-Lambda-Funktions-Handler-Projekt zu initialisieren:

```
cargo lambda new example-rust
```

Wenn Sie diesen Befehl ausführen, stellt Ihnen die Befehlszeilenschnittstelle (CLI) einige Fragen zu Ihrer Lambda-Funktion:
+ **HTTP-Funktion**: Wenn Sie beabsichtigen, Ihre Funktion über [API Gateway](services-apigateway.md) oder eine [Funktions-URL](urls-configuration.md) aufzurufen, antworten Sie mit **Ja**. Andernfalls antworten Sie mit **Nein**. Im Beispielcode auf dieser Seite rufen wir unsere Funktion mit einem benutzerdefinierten JSON-Ereignis auf und wählen daher **Nein**.
+ **Ereignistyp**: Wenn Sie eine vordefinierte Ereignisform verwenden möchten, um Ihre Funktion aufzurufen, wählen Sie den richtigen erwarteten Ereignistyp aus. Andernfalls lassen Sie diese Option leer. Im Beispielcode auf dieser Seite rufen wir unsere Funktion mit einem benutzerdefinierten JSON-Ereignis auf, daher lassen wir diese Option leer.

Nachdem der Befehl erfolgreich ausgeführt wurde, geben Sie das Hauptverzeichnis Ihres Projekts ein:

```
cd example-rust
```

Mit diesem Befehl werden eine `generic_handler.rs`- und eine `main.rs`-Datei im `src`-Verzeichnis generiert. `generic_handler.rs` kann verwendet werden, um einen generischen Ereignis-Handler anzupassen. Die `main.rs`-Datei enthält Ihre Hauptanwendungslogik. Die `Cargo.toml`-Datei enthält Metadaten über Ihr Paket und listet dessen externe Abhängigkeiten auf.

## Beispiel für Rust-Lambda-Funktionscode
<a name="rust-example-code"></a>

Das folgende Beispiel für einen Rust-Lambda-Funktionscode nimmt Informationen über eine Bestellung auf, erstellt eine Textdateiquittung und platziert diese Datei in einem Amazon-S3-Bucket.

**Example `main.rs`-Lambda-Funktion**  

```
use aws_sdk_s3::{Client, primitives::ByteStream};
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::env;

#[derive(Deserialize, Serialize)]
struct Order {
    order_id: String,
    amount: f64,
    item: String,
}

async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> {
    let payload = event.payload;

    // Deserialize the incoming event into Order struct
    let order: Order = serde_json::from_value(payload)?;

    let bucket_name = env::var("RECEIPT_BUCKET")
        .map_err(|_| "RECEIPT_BUCKET environment variable is not set")?;

    let receipt_content = format!(
        "OrderID: {}\nAmount: ${:.2}\nItem: {}",
        order.order_id, order.amount, order.item
    );
    let key = format!("receipts/{}.txt", order.order_id);

    let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
    let s3_client = Client::new(&config);

    upload_receipt_to_s3(&s3_client, &bucket_name, &key, &receipt_content).await?;

    Ok("Success".to_string())
}

async fn upload_receipt_to_s3(
    client: &Client,
    bucket_name: &str,
    key: &str,
    content: &str,
) -> Result<(), Error> {
    client
        .put_object()
        .bucket(bucket_name)
        .key(key)
        .body(ByteStream::from(content.as_bytes().to_vec()))  // Fixed conversion
        .content_type("text/plain")
        .send()
        .await?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(service_fn(function_handler)).await
}
```

Diese `main.rs`-Datei enthält die folgenden Abschnitte des Codes:
+ `use`-Anweisungen: Damit können Sie Rust-Crates und -Methoden importieren, die für Ihre Lambda-Funktion erforderlich sind.
+ `#[derive(Deserialize, Serialize)]`: Definieren Sie die Form des erwarteten Eingabeereignisses in dieser Rust-Struktur.
+ `async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>`: Dies ist die **Haupthandler-Methode**, die Ihre Hauptanwendungslogik enthält.
+ `async fn upload_receipt_to_s3 (...)`: Dies ist eine Hilfsmethode, auf die von der Haupt-`function_handler`-Methode verwiesen wird.
+ `#[tokio::main]`: Dies ist ein Makro, das den Einstiegspunkt eines Rust-Programms markiert. Außerdem wird eine [Tokio-Laufzeit](https://docs.rs/tokio/latest/tokio/runtime/index.html) eingerichtet, die es Ihrer `main()`-Methode ermöglicht, `async`/`await` asynchron zu verwenden und auszuführen.
+ `async fn main() -> Result<(), Error>`: Die `main()`-Funktion ist der Einstiegspunkt Ihres Codes. Darin spezifizieren wir `function_handler` als Haupt-Handler-Methode.

### Beispiel für eine Cargo.toml-Datei
<a name="rust-cargo-toml"></a>

Die folgende `Cargo.toml`-Datei gehört zu dieser Funktion.

```
[package]
name = "example-rust"
version = "0.1.0"
edition = "2024"

[dependencies]
aws-config = "1.5.18"
aws-sdk-s3 = "1.78.0"
lambda_runtime = "0.13.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }
```

Damit diese Funktion ordnungsgemäß funktioniert, muss ihre [Ausführungsrolle](lambda-intro-execution-role.md) die `s3:PutObject`-Aktion zulassen. Stellen Sie außerdem sicher, dass Sie die `RECEIPT_BUCKET`-Umgebungsvariable definieren. Nach einem erfolgreichen Aufruf sollte der Amazon-S3-Bucket eine Empfangsdatei enthalten.

## Gültige Klassendefinitionen für Rust-Handler
<a name="rust-handler-signatures"></a>

In den meisten Fällen haben Lambda-Handler-Signaturen, die Sie in Rust definieren, das folgende Format:

```
async fn function_handler(event: LambdaEvent<T>) -> Result<U, Error>
```

Für diesen Handler:
+ Der Name dieses Handlers ist `function_handler`.
+ Der einzige Eingabewert für den Handler ist „event“ und hat den Typ `LambdaEvent<T>`.
  + `LambdaEvent` ist ein Wrapper, die aus der `lambda_runtime`-Crate stammt. Durch die Verwendung dieses Wrappers erhalten Sie Zugriff auf das Kontextobjekt, das Lambda-spezifische Metadaten wie die Anforderungs-ID des Aufrufs enthält.
  + `T` ist der deserialisierte Ereignistyp. Dies kann beispielsweise `serde_json::Value` sein, wodurch der Handler jede generische JSON-Eingabe entgegennehmen kann. Alternativ kann dies ein Typ wie `ApiGatewayProxyRequest` sein, wenn Ihre Funktion einen bestimmten, vordefinierten Eingabetyp erwartet.
+ Der Rückgabetyp des Handlers ist `Result<U, Error>`.
  + `U` ist der deserialisierte Ausgabetyp. `U` muss das `serde::Serialize`-Merkmal implementieren, damit Lambda den Rückgabewert in JSON konvertieren kann. Beispielsweise kann `U` ein einfacher Typ wie `String`, `serde_json::Value` oder eine benutzerdefinierte Struktur sein, solange es `Serialize` implementiert. Wenn Ihr Code eine Ok(U)-Anweisung erreicht, bedeutet dies, dass die Ausführung erfolgreich war, und Ihre Funktion gibt einen Wert vom Typ `U` zurück.
  + Wenn Ihr Code auf einen Fehler stößt (d. h.`Err(Error)`), protokolliert Ihre Funktion den Fehler in Amazon CloudWatch und gibt eine Fehlerantwort vom Typ zurück`Error`.

In unserem Beispiel sieht die Handler-Signatur wie folgt aus:

```
async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>
```

Andere gültige Handler-Signaturen können Folgendes enthalten:
+ Weglassen des `LambdaEvent`-Wrappers: Wenn Sie `LambdaEvent` weglassen, verlieren Sie den Zugriff auf das Lambda-Kontextobjekt innerhalb Ihrer Funktion. Es folgt ein Beispiel für diese Art von Signatur:

  ```
  async fn handler(event: serde_json::Value) -> Result<String, Error>
  ```
+ Verwendung des Einheitentyps als Eingabe: Bei Rust können Sie den Einheitentyp verwenden, um eine leere Eingabe darzustellen. Dies wird häufig für Funktionen mit periodischen, geplanten Aufrufen verwendet. Es folgt ein Beispiel für diese Art von Signatur:

  ```
  async fn handler(_: ()) -> Result<Value, Error>
  ```

## Namenskonventionen für Handler
<a name="rust-example-naming"></a>

Lambda-Handler in Rust haben keine strengen Benennungsbeschränkungen. Sie können zwar einen beliebigen Namen für Ihren Handler verwenden, Funktionsnamen in Rust werden aber im Allgemeinen in `snake_case` angegeben.

Für kleinere Anwendungen wie in diesem Beispiel können Sie eine einzige `main.rs`-Datei verwenden, die Ihren gesamten Code enthält. Bei größeren Projekten sollte `main.rs` den Einstiegspunkt zu Ihrer Funktion enthalten, aber Sie können zusätzliche Dateien dafür haben, die Ihren Code in logische Module unterteilen. Beispielsweise könnte Ihre Dateistruktur wie folgt aussehen:

```
/example-rust
│── src/
│   ├── main.rs        # Entry point
│   ├── handler.rs     # Contains main handler
│   ├── services.rs    # [Optional] Back-end service calls
│   ├── models.rs      # [Optional] Data models
│── Cargo.toml
```

## Definieren Sie das Eingabeereignisobjekt und greifen Sie darauf zu
<a name="rust-handler-input"></a>

JSON ist das gebräuchlichste und standardmäßigste Eingabeformat für Lambda-Funktionen. In diesem Beispiel erwartet die Funktion eine Eingabe ähnlich der folgenden:

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

In Rust können Sie die Form des erwarteten Eingabeereignisses in einer Struktur definieren. In diesem Beispiel definieren wir die folgende Struktur, die einen `Order` darstellt:

```
#[derive(Deserialize, Serialize)]
struct Order {
    order_id: String,
    amount: f64,
    item: String,
}
```

Diese Struktur entspricht der erwarteten Eingabeform. In diesem Beispiel generiert das `#[derive(Deserialize, Serialize)]`-Makro automatisch Code für die Serialisierung und Deserialisierung. Das bedeutet, dass wir den generischen Eingabe-JSON-Typ mithilfe der `serde_json::from_value()`-Methode in unsere Struktur deserialisieren können. Dies wird in den ersten Zeilen des Handlers veranschaulicht:

```
async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> {
    let payload = event.payload;

    // Deserialize the incoming event into Order struct
    let order: Order = serde_json::from_value(payload)?;
    ...
}
```

Sie können dann auf die Felder des Objekts zugreifen. Zum Beispiel holt `order.order_id` den Wert von `order_id` aus der ursprünglichen Eingabe.

### Vordefinierte Eingabe-Ereignistypen
<a name="rust-input-event-types"></a>

In der `aws_lambda_events`-Crate sind viele vordefinierte Eingabe-Ereignistypen verfügbar. Wenn Sie beispielsweise beabsichtigen, Ihre Funktion mit API Gateway aufzurufen, einschließlich des folgenden Imports:

```
use aws_lambda_events::event::apigw::ApiGatewayProxyRequest;
```

Stellen Sie dann sicher, dass Ihr Haupt-Handler die folgende Signatur verwendet:

```
async fn handler(event: LambdaEvent<ApiGatewayProxyRequest>) -> Result<String, Error> {
    let body = event.payload.body.unwrap_or_default();
    ...
}
```

Weitere Informationen zu anderen vordefinierten Eingabe-Ereignistypen finden Sie in der Crate [aws\$1lambda\$1events](https://crates.io/crates/aws_lambda_events).

## Zugreifen auf und Verwenden des Lambda-Kontextobjekts
<a name="rust-example-context"></a>

Das Lambda-[Kontextobjekt](rust-context.md) enthält Informationen über Aufruf, Funktion und Ausführungsumgebung. In Rust enthält der `LambdaEvent`-Wrapper das Kontextobjekt. Beispielsweise können Sie das Kontextobjekt verwenden, um die Anforderungs-ID des aktuellen Aufrufs mit dem folgenden Code abzurufen:

```
async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> {
    let request_id = event.context.request_id;
    ...
}
```

Weitere Informationen über das Kontextobjekt finden Sie unter [Verwenden des Lambda-Kontextobjekts zum Abrufen von Rust-Funktionsinformationen](rust-context.md).

## Verwenden Sie den AWS SDK für Rust in Ihrem Handler
<a name="rust-example-sdk-usage"></a>

Oft verwenden Sie Lambda-Funktionen, um mit anderen AWS Ressourcen zu interagieren oder diese zu aktualisieren. Die einfachste Art, eine Schnittstelle zu diesen Ressourcen herzustellen, ist die Verwendung von [AWS SDK für Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/welcome.html).

Um SDK-Abhängigkeiten zu Ihrer Funktion hinzuzufügen, fügen Sie diese in Ihrer `Cargo.toml`-Datei hinzu. Wir empfehlen, nur die Bibliotheken hinzuzufügen, die Sie für Ihre Funktion benötigen. Im Beispielcode zuvor haben wir `aws_sdk_s3::Client` verwendet. In der `Cargo.toml`-Datei können Sie diese Abhängigkeit hinzufügen, indem Sie die folgende Zeile unter dem `[dependencies]`-Abschnitt hinzufügen:

```
aws-sdk-s3 = "1.78.0"
```

**Anmerkung**  
Dies ist möglicherweise nicht die neueste Version. Wählen Sie die passende Version für Ihre Anwendung.

Importieren Sie dann die Abhängigkeiten direkt in Ihren Code:

```
use aws_sdk_s3::{Client, primitives::ByteStream};
```

Der Beispielcode initialisiert dann einen Amazon-S3-Client wie folgt:

```
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let s3_client = Client::new(&config);
```

Nachdem Sie Ihren SDK-Client initialisiert haben, können Sie ihn für die Interaktion mit anderen AWS Diensten verwenden. Der Beispielcode ruft die Amazon-S3-`PutObject`-API in der Hilfsfunktion `upload_receipt_to_s3` auf.

## Zugriff auf Umgebungsvariablen
<a name="rust-example-envvars"></a>

In Ihrem Handler-Code können Sie mithilfe der `env::var`-Methode auf beliebige [Umgebungsvariablen](configuration-envvars.md) verweisen. In diesem Beispiel verweisen wir mit der folgenden Codezeile auf die definierte `RECEIPT_BUCKET`-Umgebungsvariable:

```
let bucket_name = env::var("RECEIPT_BUCKET")
    .map_err(|_| "RECEIPT_BUCKET environment variable is not set")?;
```

## Geteilten Zustand verwenden
<a name="rust-shared-state"></a>

Sie können geteilte Variablen deklarieren, die unabhängig vom Handler-Code Ihrer Lambda-Funktion sind. Diese Variablen können Ihnen helfen, Zustandsinformationen während des [Init-Phase](lambda-runtime-environment.md#runtimes-lifecycle-ib) zu laden, bevor Ihre Funktion Ereignisse empfängt. Beispielsweise können Sie den Code auf dieser Seite so ändern, dass bei der Initialisierung des Amazon-S3-Clients ein gemeinsamer Status verwendet wird, indem Sie die `main`-Funktion und die Handler-Signatur aktualisieren:

```
async fn function_handler(client: &Client, event: LambdaEvent<Value>) -> Result<String, Error> {
    ...
    upload_receipt_to_s3(client, &bucket_name, &key, &receipt_content).await?;
    ...
}

...
      
#[tokio::main]
async fn main() -> Result<(), Error> {
    let shared_config = aws_config::from_env().load().await;
    let client = Client::new(&shared_config);
    let shared_client = &client;
    lambda_runtime::run(service_fn(move |event: LambdaEvent<Request>| async move {
        handler(&shared_client, event).await
    }))
    .await
```

## Bewährte Codemethoden für Rust-Lambda-Funktionen
<a name="rust-best-practices"></a>

Halten Sie sich an die Richtlinien in der folgenden Liste, um beim Erstellen Ihrer Lambda-Funktionen die besten Codierungspraktiken anzuwenden:
+ **Trennen Sie den Lambda-Handler von Ihrer Core-Logik.** Auf diese Weise können Sie eine Funktion zur besseren Prüfbarkeit von Einheiten schaffen.
+ **Minimieren Sie die Komplexität Ihrer Abhängigkeiten.** Ziehen Sie einfachere Frameworks vor, die sich schnell beim Start der [Ausführungsumgebung](lambda-runtime-environment.md) laden lassen.
+ **Minimieren Sie die Größe Ihres Bereitstellungspakets auf die für die Laufzeit erforderliche Größe.** Dadurch verkürzt sich die Zeit, die für das Herunterladen und Entpacken Ihres Bereitstellungspakets vor dem Aufruf benötigt wird.

**Nutzen Sie die Wiederverwendung der Ausführungsumgebung zur Verbesserung Ihrer Funktion.** Initialisieren Sie SDK-Clients und Datenbankverbindungen außerhalb des Funktions-Handlers und speichern Sie statische Komponenten lokal im `/tmp`-Verzeichnis. Nachfolgende Aufrufe, die von derselben Instance Ihrer Funktion verarbeitet werden, können diese Ressourcen wiederverwenden. Dies spart Kosten durch Reduzierung der Funktionslaufzeit.

Um potenzielle Datenlecks über Aufrufe hinweg zu vermeiden, verwenden Sie die Ausführungsumgebung nicht, um Benutzerdaten, Ereignisse oder andere Informationen mit Sicherheitsauswirkungen zu speichern. Wenn Ihre Funktion auf einem veränderbaren Zustand beruht, der nicht im Speicher innerhalb des Handlers gespeichert werden kann, sollten Sie für jeden Benutzer eine separate Funktion oder separate Versionen einer Funktion erstellen.

**Verwenden Sie eine Keep-Alive-Direktive, um dauerhafte Verbindungen zu pflegen.** Lambda bereinigt Leerlaufverbindungen im Laufe der Zeit. Der Versuch, eine Leerlaufverbindung beim Aufruf einer Funktion wiederzuverwenden, führt zu einem Verbindungsfehler. Um Ihre persistente Verbindung aufrechtzuerhalten, verwenden Sie die Keep-Alive-Direktive, die Ihrer Laufzeit zugeordnet ist. Ein Beispiel finden Sie unter [Wiederverwenden von Verbindungen mit Keep-Alive in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Verwenden Sie [Umgebungsvariablen](configuration-envvars.md) um Betriebsparameter an Ihre Funktion zu übergeben.** Wenn Sie z. B. Daten in einen Amazon-S3-Bucket schreiben, anstatt den Bucket-Namen, in den Sie schreiben, hartzucodieren, konfigurieren Sie den Bucket-Namen als Umgebungsvariable.

**Vermeiden Sie rekursive Aufrufe** in Ihrer Lambda-Funktion, bei denen die Funktion sich selbst aufruft oder einen Prozess initiiert, der die Funktion erneut aufrufen kann. Dies kann zu unvorhergesehenen Mengen an Funktionsaufrufen führen und höhere Kosten zur Folge haben. Wenn Sie eine unbeabsichtigte Menge von Aufrufen feststellen, legen Sie die reservierte gleichzeitige Ausführung der Funktion auf `0` fest, um sofort alle Aufrufe der Funktion zu drosseln, während Sie den Code aktualisieren.

**Verwenden Sie APIs in Ihrem Lambda-Funktionscode nicht undokumentiert, nicht öffentlich**. Für AWS Lambda verwaltete Laufzeiten führt Lambda regelmäßig Sicherheits- und Funktionsupdates für interne Lambda-Laufzeiten durch. APIs Diese internen API-Updates können abwärtsinkompatibel sein, was zu unbeabsichtigten Folgen wie Aufruffehlern führen kann, wenn Ihre Funktion von diesen nicht öffentlichen Daten abhängig ist. APIs Eine Liste [der öffentlich verfügbaren Programme finden Sie in der API-Referenz.](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) APIs

**Schreiben Sie idempotenten Code.** Das Schreiben idempotenter Code für Ihre Funktionen stellt sicher, dass doppelte Ereignisse auf die gleiche Weise behandelt werden. Ihr Code sollte Ereignisse ordnungsgemäß validieren und doppelte Ereignisse ordnungsgemäß behandeln. Weitere Informationen finden Sie unter [Wie mache ich meine Lambda-Funktion idempotent?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Verwenden des Lambda-Kontextobjekts zum Abrufen von Rust-Funktionsinformationen
<a name="rust-context"></a>

Wenn Lambda Ihre Funktion ausführt, fügt es dem, das der [Handler](rust-handler.md) empfängt LambdaEvent , ein Kontextobjekt hinzu. Dieses Objekt stellt Eigenschaften mit Informationen zum Aufruf, zur Funktion und zur Ausführungsumgebung bereit.

**Context-Eigenschaften**
+  `request_id`: Die vom Lambda-Service generierte AWS Anforderungs-ID. 
+  `deadline`: Die Ausführungsfrist für den aktuellen Aufruf in Millisekunden.
+  `invoked_function_arn`: Der Amazon-Ressourcenname (ARN) der aufgerufenen Lambda-Funktion.
+  `xray_trace_id`: Die AWS X-Ray Trace-ID für den aktuellen Aufruf. 
+  `client_content`: Das vom SDK für AWS Mobilgeräte gesendete Client-Kontextobjekt. Dieses Feld ist leer, es sei denn, die Funktion wird mit einem AWS mobilen SDK aufgerufen. 
+  `identity`: Die Amazon-Cognito-Identität, die die Funktion aufgerufen hat. Dieses Feld ist leer, es sei denn, die Aufrufanforderung an das Lambda APIs wurde mit AWS Anmeldeinformationen gestellt, die von Amazon Cognito Cognito-Identitätspools ausgestellt wurden.
+  `env_config`: Die Lambda-Funktionskonfiguration aus den lokalen Umgebungsvariablen. Diese Eigenschaft umfasst Informationen wie den Funktionsnamen, die Speicherzuweisung, die Version und die Protokollstreams.

## Zugreifen auf Aufrufkontextinformationen
<a name="rust-context-invoke"></a>

Lambda-Funktionen haben Zugriff auf Metadaten über ihre Umgebung und die Aufrufanforderung. Das `LambaEvent` Objekt, das Ihr Funktionshandler empfängt, enthält die `context`-Metadaten:

```
use lambda_runtime::{service_fn, LambdaEvent, Error};
use serde_json::{json, Value};

async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
    let invoked_function_arn = event.context.invoked_function_arn;
    Ok(json!({ "message": format!("Hello, this is function {invoked_function_arn}!") }))
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_runtime::run(service_fn(handler)).await
}
```

# Verarbeitung von HTTP-Ereignissen mit Rust
<a name="rust-http-events"></a>

Amazon API Gateway APIs, Application Load Balancers und [Lambda-Funktionen URLs können HTTP-Ereignisse an Lambda](urls-configuration.md) senden. Sie können den [aws\$1lambda\$1events](https://crates.io/crates/aws_lambda_events) Crate von crates.io verwenden, um Ereignisse aus diesen Quellen zu verarbeiten.

**Example – API Gateway Proxy-Anfrage bearbeiten**  
Beachten Sie Folgendes:  
+ `use aws_lambda_events::apigw::{ApiGatewayProxyRequest, ApiGatewayProxyResponse}`: Der [aws\$1lambda\$1events](https://crates.io/crates/aws-lambda-events) Crate enthält viele Lambda-Ereignisse. Um die Kompilierungszeit zu verkürzen, verwenden Sie Feature-Flags, um die benötigten Ereignisse zu aktivieren. Beispiel: `aws_lambda_events = { version = "0.8.3", default-features = false, features = ["apigw"] }`.
+ `use http::HeaderMap`: Für diesen Import müssen Sie den [HTTP](https://crates.io/crates/http) Crate zu Ihren Abhängigkeiten hinzufügen.

```
use aws_lambda_events::apigw::{ApiGatewayProxyRequest, ApiGatewayProxyResponse};
use http::HeaderMap;
use lambda_runtime::{service_fn, Error, LambdaEvent};

async fn handler(
    _event: LambdaEvent<ApiGatewayProxyRequest>,
) -> Result<ApiGatewayProxyResponse, Error> {
    let mut headers = HeaderMap::new();
    headers.insert("content-type", "text/html".parse().unwrap());
    let resp = ApiGatewayProxyResponse {
        status_code: 200,
        multi_value_headers: headers.clone(),
        is_base64_encoded: false,
        body: Some("Hello AWS Lambda HTTP request".into()),
        headers,
    };
    Ok(resp)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_runtime::run(service_fn(handler)).await
}
```

Der [Rust-Laufzeit-Client für Lambda](https://github.com/aws/aws-lambda-rust-runtime) bietet auch eine Abstraktion dieser Ereignistypen, die es Ihnen ermöglicht, mit nativen HTTP-Typen zu arbeiten, unabhängig davon, welcher Service die Ereignisse sendet. Der folgende Code entspricht dem vorherigen Beispiel und funktioniert sofort mit Lambda-Funktion URLs, Application Load Balancers und API Gateway.

**Anmerkung**  
Der [lambda\$1http](https://crates.io/crates/lambda_http) Crate verwendet den darunter liegenden [lambda\$1runtime](https://crates.io/crates/lambda_runtime) Crate. Sie müssen `lambda_runtime` nicht separat importieren.

**Example – Bearbeitung von HTTP-Anforderungen**  

```
use lambda_http::{service_fn, Error, IntoResponse, Request, RequestExt, Response};

async fn handler(event: Request) -> Result<impl IntoResponse, Error> {
    let resp = Response::builder()
        .status(200)
        .header("content-type", "text/html")
        .body("Hello AWS Lambda HTTP request")
        .map_err(Box::new)?;
    Ok(resp)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_http::run(service_fn(handler)).await
}
```

Ein weiteres Beispiel für die Verwendung `lambda_http` finden Sie im [Codebeispiel http-axum](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-axum/src/main.rs) im Labs-Repository. AWS GitHub 

**Beispiel für HTTP-Lambda-Ereignisse für Rust**
+ [Lambda-HTTP-Ereignisse](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/http-basic-lambda): Eine Rust-Funktion, die HTTP-Ereignisse verarbeitet.
+ [Lambda-HTTP-Ereignisse mit CORS-Headern](https://github.com/aws/aws-lambda-rust-runtime/blob/main/examples/http-cors): Eine Rust-Funktion, die Tower verwendet, um CORS-Header zu injizieren.
+ [Lambda-HTTP-Ereignisse mit gemeinsam genutzten Ressourcen](https://github.com/aws/aws-lambda-rust-runtime/tree/main/examples/basic-shared-resource): Eine Rust-Funktion, die gemeinsam genutzte Ressourcen verwendet, die initialisiert werden, bevor der Funktionshandler erstellt wird.

# Bereitstellen von Lambda-Rust-Funktionen mit ZIP-Dateiarchiven
<a name="rust-package"></a>

Auf dieser Seite wird beschrieben, wie Sie Ihre Rust-Funktion kompilieren und dann die kompilierte Binärdatei AWS Lambda mithilfe von [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html) bereitstellen. Es zeigt auch, wie die kompilierte Binärdatei mit der AWS Command Line Interface und der AWS Serverless Application Model CLI bereitgestellt wird.

**Topics**
+ [

## Voraussetzungen
](#rust-package-prerequisites)
+ [

## Aufbau von Rust-Funktionen auf macOS, Windows oder Linux
](#rust-package-build)
+ [

## Bereitstellung der Binärdatei der Rust-Funktion mit Cargo Lambda
](#rust-deploy-cargo)
+ [

## Aufrufen Ihrer Rust-Funktion mit Cargo Lambda
](#rust-invoke-function)

## Voraussetzungen
<a name="rust-package-prerequisites"></a>
+ [Rust](https://www.rust-lang.org/tools/install)
+ [AWS CLI Version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)

## Aufbau von Rust-Funktionen auf macOS, Windows oder Linux
<a name="rust-package-build"></a>

Die folgenden Schritte zeigen, wie Sie das Projekt für Ihre erste Lambda-Funktion mit Rust erstellen und es mit [Cargo Lambda kompilieren, einer Open-Source-Erweiterung eines Drittanbieters für das Cargo-Befehlszeilentool](https://www.cargo-lambda.info/), die das Erstellen und Bereitstellen von Rust-Lambda-Funktionen vereinfacht.

1. Installieren Sie [Cargo Lambda](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html), eine Open-Source-Erweiterung eines Drittanbieters für das Cargo-Befehlszeilentool, die das Erstellen und Bereitstellen von Rust Lambda-Funktionen vereinfacht:

   ```
   cargo install cargo-lambda
   ```

   Weitere Installationsoptionen finden Sie unter [Installation](https://www.cargo-lambda.info/guide/installation.html) in der Cargo Lambda-Dokumentation.

1. Erstellen Sie die Paketstruktur. Dieser Befehl erstellt einen grundlegenden Funktionscode in `src/main.rs`. Sie können diesen Code zum Testen verwenden oder ihn durch Ihren eigenen ersetzen.

   ```
   cargo lambda new my-function
   ```

1. Führen Sie im Stammverzeichnis des Pakets den Unterbefehl [build](https://www.cargo-lambda.info/commands/build.html) aus, um den Code in Ihrer Funktion zu kompilieren.

   ```
   cargo lambda build --release
   ```

   (Optional) Wenn Sie AWS Graviton2 auf Lambda verwenden möchten, fügen Sie das `--arm64` Flag hinzu, um Ihren Code für ARM zu kompilieren. CPUs

   ```
   cargo lambda build --release --arm64
   ```

1. Bevor Sie Ihre Rust-Funktion bereitstellen, konfigurieren Sie die AWS Anmeldeinformationen auf Ihrem Computer.

   ```
   aws configure
   ```

## Bereitstellung der Binärdatei der Rust-Funktion mit Cargo Lambda
<a name="rust-deploy-cargo"></a>

Verwenden Sie den Unterbefehl [bereitstellen](https://www.cargo-lambda.info/commands/deploy.html), um die kompilierte Binärdatei für Lambda bereitzustellen. Dieser Befehl erstellt eine [Ausführungsrolle](lambda-intro-execution-role.md) und erstellt dann die Lambda-Funktion. Um eine bestehende Ausführungsrolle anzugeben, verwenden Sie die [--iam-role Flag](https://www.cargo-lambda.info/commands/deploy.html#iam-roles).

```
cargo lambda deploy my-function
```

### Bereitstellen Ihrer Rust-Funktionsbinärdatei mit dem AWS CLI
<a name="rust-deploy-aws-cli"></a>

Sie können Ihre Binärdatei auch mit dem bereitstellen AWS CLI.

1. Verwenden Sie den Unterbefehl [build](https://www.cargo-lambda.info/commands/build.html), um das .zip-Bereitstellungspaket zu erstellen.

   ```
   cargo lambda build --release --output-format zip
   ```

1. Um das .zip-Paket in Lambda bereitzustellen, führen Sie den Befehl [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) aus.
   + Legen Sie für `--runtime` die Option `provided.al2023` fest. Dies ist eine [reine Betriebssystem-Laufzeit](runtimes-provided.md). Reine Betriebssystemlaufzeiten werden verwendet, um kompilierte Binärdateien und benutzerdefinierte Laufzeiten für Lambda bereitzustellen.
   + Für `--role` geben Sie den ARN der [Ausführungsrolle](lambda-intro-execution-role.md) an.

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

### Bereitstellen Ihrer Rust-Funktionsbinärdatei mit der AWS SAM CLI
<a name="rust-deploy-sam-cli"></a>

Sie können Ihre Binärdatei auch mit der AWS SAM CLI bereitstellen.

1. Erstellen Sie eine AWS SAM Vorlage mit der Ressourcen- und Eigenschaftsdefinition. Legen Sie für `Runtime` die Option `provided.al2023` fest. Dies ist eine [reine Betriebssystem-Laufzeit](runtimes-provided.md). Reine Betriebssystemlaufzeiten werden verwendet, um kompilierte Binärdateien und benutzerdefinierte Laufzeiten für Lambda bereitzustellen.

   Weitere Informationen zur Bereitstellung von Lambda-Funktionen mit AWS SAM finden Sie [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)im *AWS Serverless Application Model Entwicklerhandbuch*.  
**Example SAM-Ressourcen- und Eigenschaftsdefinition für eine Rust-Binärdatei**  

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: AWS::Serverless-2016-10-31
   Description: SAM template for Rust binaries
   Resources:
     RustFunction:
       Type: AWS::Serverless::Function 
       Properties:
         CodeUri: target/lambda/my-function/
         Handler: rust.handler
         Runtime: provided.al2023
   Outputs:
     RustFunction:
       Description: "Lambda Function ARN"
       Value: !GetAtt RustFunction.Arn
   ```

1. Verwenden Sie den Unterbefehl [build](https://www.cargo-lambda.info/commands/build.html), um die Funktion zu kompilieren.

   ```
   cargo lambda build --release
   ```

1. Verwenden Sie den Befehl [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html), um die Funktion in Lambda bereitzustellen.

   ```
   sam deploy --guided
   ```

Weitere Informationen zum Erstellen von Rust-Funktionen mit der AWS SAM CLI finden Sie unter [Build Rust Lambda functions with Cargo Lambda](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-rust.html) im *AWS Serverless Application Model Developer* Guide.

## Aufrufen Ihrer Rust-Funktion mit Cargo Lambda
<a name="rust-invoke-function"></a>

Verwenden Sie den Unterbefehl [invoke](https://www.cargo-lambda.info/commands/invoke.html), um Ihre Funktion mit einer Nutzlast zu testen.

```
cargo lambda invoke --remote --data-ascii '{"command": "Hello world"}' my-function
```

### Aufrufen Ihrer Rust-Funktion mit dem AWS CLI
<a name="rust-invoke-cli"></a>

Sie können die Funktion auch verwenden AWS CLI , um die Funktion aufzurufen.

```
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"command": "Hello world"}' /tmp/out.txt
```

Die **cli-binary-format** Option ist erforderlich, wenn Sie AWS CLI Version 2 verwenden. Um dies zur Standardeinstellung zu machen, führen Sie `aws configure set cli-binary-format raw-in-base64-out` aus. Weitere Informationen finden Sie unter [Von AWS CLI unterstützte globale Befehlszeilenoptionen](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) im *AWS Command Line Interface -Benutzerhandbuch für Version 2*.

# Arbeiten mit Ebenen für Rust-Lambda-Funktionen
<a name="rust-layers"></a>

Wir empfehlen, keine [Ebenen](chapter-layers.md) zur Verwaltung von Abhängigkeiten für in Rust geschriebene Lambda-Funktionen zu verwenden. Der Grund dafür ist, dass Lambda-Funktionen in Rust zu einer einzigen ausführbaren Datei kompiliert werden, die Sie Lambda bei der Bereitstellung Ihrer Funktion zur Verfügung stellen. Diese ausführbare Datei enthält Ihren kompilierten Funktionscode zusammen mit all seinen Abhängigkeiten. Die Verwendung von Ebenen verkompliziert nicht nur diesen Vorgang, sondern führt auch zu längeren Kaltstartzeiten, da Ihre Funktionen während der Init-Phase zusätzliche Assemblys manuell in den Speicher laden müssen.

Um externe Abhängigkeiten mit Ihren Rust-Handlern zu verwenden, fügen Sie diese direkt in Ihr Bereitstellungspaket ein. So vereinfachen Sie den Bereitstellungsprozess und profitieren außerdem von den integrierten Optimierungen des Rust-Compilers. Ein Beispiel dafür, wie Sie eine Abhängigkeit wie das AWS SDK für Rust in Ihre Funktion importieren und verwenden, finden Sie unter [Definieren von Lambda-Funktionshandlern in Rust](rust-handler.md).

# Rust-Lambda-Funktionen protokollieren und überwachen
<a name="rust-logging"></a>

AWS Lambda überwacht automatisch Lambda-Funktionen in Ihrem Namen und sendet Protokolle an Amazon CloudWatch. Ihre Lambda-Funktion enthält eine CloudWatch Logs-Log-Gruppe und einen Log-Stream für jede Instanz Ihrer Funktion. Die Lambda-Laufzeitumgebung sendet Details zu den einzelnen Aufrufen an den Protokollstream und leitet Protokolle und andere Ausgaben aus dem Code Ihrer Funktion weiter. Weitere Informationen finden Sie unter [Senden von Lambda-Funktionsprotokollen an CloudWatch Logs](monitoring-cloudwatchlogs.md). Hinweise zur Konfiguration von Protokollformaten finden Sie unter[Konfiguration der JSON- und Klartext-Protokollformate](monitoring-cloudwatchlogs-logformat.md). Auf dieser Seite wird beschrieben, wie Sie Protokollausgaben aus dem Code Ihrer Lambda-Funktion erstellen.

## Erstellen einer Funktion, die Protokolle schreibt
<a name="rust-logging-function"></a>

Um Protokolle aus Ihrem Funktionscode auszugeben, können Sie jede Protokollierungsfunktion verwenden, die in `stdout` oder `stderr` schreibt, wie z. B. das `println!`-Makro. Das folgende Beispiel verwendet `println!`, um eine Nachricht zu drucken, wenn der Funktionshandler gestartet wird und bevor er beendet wird.

```
use lambda_runtime::{service_fn, LambdaEvent, Error};
use serde_json::{json, Value};
async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
    println!("Rust function invoked");
    let payload = event.payload;
    let first_name = payload["firstName"].as_str().unwrap_or("world");
    println!("Rust function responds to {}", &first_name);
    Ok(json!({ "message": format!("Hello, {first_name}!") }))
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda_runtime::run(service_fn(handler)).await
}
```

## Implementierung der erweiterten Protokollierung mit der Tracing Crate
<a name="rust-logging-tracing"></a>

[Tracing](https://crates.io/crates/tracing) ist ein Framework zur Instrumentierung von Rust-Programmen zur Erfassung strukturierter, ereignisbasierter Diagnoseinformationen. Dieses Framework bietet Hilfsprogramme zum Anpassen der Logging-Ausgabestufen und -formate, wie zum Beispiel das Erstellen strukturierter JSON-Protokollnachrichten. Um dieses Framework verwenden zu können, müssen Sie einen `subscriber` initialisieren, bevor Sie den Funktionshandler implementieren. Anschließend können Sie Tracing-Makros wie `debug`, `info` und `error` verwenden, um die gewünschte Protokollierungsebene für jedes Szenario anzugeben.

**Example – Verwenden von Tracing Crate**  
Beachten Sie Folgendes:  
+ `tracing_subscriber::fmt().json()`: Wenn diese Option enthalten ist, werden die Protokolle in JSON formatiert. Um diese Option verwenden zu können, müssen Sie das `json`-Feature in die `tracing-subscriber`-Abhängigkeit aufnehmen (z. B. `tracing-subscriber = { version = "0.3.11", features = ["json"] }`).
+ `#[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))]`: Diese Annotation generiert bei jedem Aufruf des Handlers eine Spanne. Diese Spanne fügt jeder Protokollzeile die Anforderungs-ID hinzu.
+ `{ %first_name }`: Dieses Konstrukt fügt das `first_name`-Feld der Protokollzeile hinzu, in der es verwendet wird. Der Wert für dieses Feld entspricht der Variablen mit dem gleichen Namen.

```
use lambda_runtime::{service_fn, Error, LambdaEvent};
use serde_json::{json, Value};
#[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))]
async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
    tracing::info!("Rust function invoked");
    let payload = event.payload;
    let first_name = payload["firstName"].as_str().unwrap_or("world");
    tracing::info!({ %first_name }, "Rust function responds to event");
    Ok(json!({ "message": format!("Hello, {first_name}!") }))
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt().json()
        .with_max_level(tracing::Level::INFO)
        // this needs to be set to remove duplicated information in the log.
        .with_current_span(false)
        // this needs to be set to false, otherwise ANSI color codes will
        // show up in a confusing manner in CloudWatch logs.
        .with_ansi(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        // remove the name of the function from every log entry
        .with_target(false)
        .init();
    lambda_runtime::run(service_fn(handler)).await
}
```

Wenn diese Rust-Funktion aufgerufen wird, druckt sie zwei Protokollzeilen, die den folgenden ähneln:

```
{"level":"INFO","fields":{"message":"Rust function invoked"},"spans":[{"req_id":"45daaaa7-1a72-470c-9a62-e79860044bb5","name":"handler"}]}
{"level":"INFO","fields":{"message":"Rust function responds to event","first_name":"David"},"spans":[{"req_id":"45daaaa7-1a72-470c-9a62-e79860044bb5","name":"handler"}]}
```