

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.

# Verketten mehrzeiliger oder Stack-Trace-Protokollnachrichten in Amazon ECS
<a name="firelens-concatanate-multiline"></a>

Ab Version 2.22.0 von Fluent Bit ist ein mehrzeiliger Filter enthalten. AWS Der Mehrzeilenfilter hilft bei der Verkettung von Protokollmeldungen, die ursprünglich zu einem Kontext gehören, aber auf mehrere Datensätze oder Protokollzeilen aufgeteilt wurden. Weitere Informationen zum mehrzeiligen Filter finden Sie in der [ Fluent-Bit-Dokumentation](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace). 

Häufige Beispiele für geteilte Protokollmeldungen sind:
+ Stack-Traces. 
+ Anwendungen, die Protokolle auf mehreren Zeilen drucken. 
+ Protokollmeldungen, die geteilt wurden, weil sie länger waren als die angegebene maximale Puffergröße der Laufzeit. [Sie können Protokollnachrichten, die nach der Container-Laufzeit aufgeteilt sind, verketten, indem Sie dem Beispiel unter folgen: Beispiel: Container-Logs verketten. GitHub FireLens Partial/Split ](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/filter-multiline-partial-message-mode)

## Erforderliche IAM-Berechtigungen
<a name="iam-permissions"></a>

Sie verfügen über die erforderlichen IAM-Berechtigungen, damit der Container-Agent die Container-Images aus Amazon ECR abrufen kann und der Container Protokolle an CloudWatch Logs weiterleitet.

Für diese Berechtigungen müssen Sie über die folgenden Rollen verfügen: 
+ Eine Aufgaben-IAM-Rolle. 
+ Eine IAM-Rolle für die Aufgabenausführung 

Sie benötigen die folgenden Berechtigungen:
+ `logs:CreateLogStream`
+ `logs:CreateLogGroup`
+ `logs:PutLogEvents`

## Festlegen, wann die Einstellung für mehrzeiliges Protokoll verwendet werden soll
<a name="determine-filter"></a>

Im Folgenden finden Sie Beispiele für Protokollausschnitte, die Sie in der CloudWatch Logs-Konsole mit der Standardprotokolleinstellung sehen. Sie können sich die Zeile ansehen, die mit `log` beginnt, um festzustellen, ob Sie den Mehrzeilenfilter benötigen. Wenn der Kontext derselbe ist, können Sie die Einstellung für das mehrzeilige Protokoll verwenden. In diesem Beispiel ist der Kontext „com.myproject.model“. MyProject“.

```
2022-09-20T15:47:56:595-05-00                           {"container_id": "82ba37cada1d44d389b03e78caf74faa-EXAMPLE", "container_name": "example-app", "source=": "stdout", "log": ": "     at com.myproject.modele.(MyProject.badMethod.java:22)",
    {
      "container_id":  "82ba37cada1d44d389b03e78caf74faa-EXAMPLE",
      "container_name: ": "example-app",
      "source": "stdout",
      "log": ": "     at com.myproject.model.MyProject.badMethod(MyProject.java:22)",
      "ecs_cluster": "default",
      "ecs_task_arn": "arn:aws:region:123456789012:task/default/b23c940d29ed4714971cba72cEXAMPLE",
      "ecs_task_definition": "firelense-example-multiline:3"
     }
```

```
2022-09-20T15:47:56:595-05-00                           {"container_id": "82ba37cada1d44d389b03e78caf74faa-EXAMPLE", "container_name": "example-app", "stdout", "log": ": "     at com.myproject.modele.(MyProject.oneMoreMethod.java:18)",
    {
      "container_id":  "82ba37cada1d44d389b03e78caf74faa-EXAMPLE",
      "container_name: ": "example-app",
      "source": "stdout",
      "log": ": "     at com.myproject.model.MyProject.oneMoreMethod(MyProject.java:18)",
      "ecs_cluster": "default",
      "ecs_task_arn": "arn:aws:region:123456789012:task/default/b23c940d29ed4714971cba72cEXAMPLE,
      "ecs_task_definition": "firelense-example-multiline:3"
     }
```

Nachdem Sie die mehrzeilige Protokolleinstellung verwendet haben, sieht die Ausgabe ähnlich aus wie im Beispiel unten. 

```
2022-09-20T15:47:56:595-05-00                           {"container_id": "82ba37cada1d44d389b03e78caf74faa-EXAMPLE", "container_name": "example-app", "stdout",...
    {
      "container_id":  "82ba37cada1d44d389b03e78caf74faa-EXAMPLE",
      "container_name: ": "example-app",
      "source": "stdout",
      "log:    "September 20, 2022 06:41:48 Exception in thread \"main\" java.lang.RuntimeException: Something has gone wrong, aborting!\n    
    at com.myproject.module.MyProject.badMethod(MyProject.java:22)\n    at   
    at com.myproject.model.MyProject.oneMoreMethod(MyProject.java:18) com.myproject.module.MyProject.main(MyProject.java:6)",
      "ecs_cluster": "default",
      "ecs_task_arn": "arn:aws:region:123456789012:task/default/b23c940d29ed4714971cba72cEXAMPLE",
      "ecs_task_definition": "firelense-example-multiline:2"
     }
```

## Analyse und Verkettung von Optionen
<a name="parse-multiline-log"></a>

Um Protokolle zu analysieren und Zeilen zu verketten, die aufgrund von Zeilenumbrüchen geteilt wurden, können Sie eine dieser beiden Optionen verwenden.
+ Verwenden Sie Ihre eigene Parserdatei, die die Regeln zum Analysieren und Verketten von Zeilen enthält, die zu derselben Nachricht gehören.
+ Einen integrierten Parser für Fluent Bit verwenden. Eine Liste der Sprachen, die von den integrierten Parsern Fluent Bit unterstützt werden, finden Sie unter [Fluent-Bit-Dokumentation.](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace)

Das folgende Tutorial führt Sie durch die Schritte für jeden Anwendungsfall. Die Schritte zeigen Ihnen, wie Sie mehrere Zeilen verketten und die Protokolle an Amazon senden. CloudWatch Sie können ein anderes Ziel für Ihre Protokolle angeben.

### Beispiel: Verwenden eines Parsers, den Sie erstellen
<a name="customer-parser"></a>

In diesem Beispiel führen Sie die folgenden Schritte aus: 

1. Erstellen und laden Sie das Image für einen Fluent-Bit-Container hoch. 

1. Erstellen und laden Sie das Image für eine mehrzeilige Demo-Anwendung hoch, die einen mehrzeiligen Stack-Trace ausführt, fehlschlägt und generiert.

1. Erstellen Sie die Aufgabendefinition und führen Sie die Aufgabe aus. 

1. Zeigen Sie die Protokolle an, um zu überprüfen, ob Nachrichten, die sich über mehrere Zeilen erstrecken, verkettet erscheinen. 

**Erstellen und Hochladen des Images für einen Fluent-Bit-Container**

Dieses Image enthält die Parserdatei, in der Sie den regulären Ausdruck angeben, und eine Konfigurationsdatei, die auf die Parser-Datei verweist. 

1. Erstellen Sie einen Ordner mit dem Namen `FluentBitDockerImage`. 

1. Erstellen Sie innerhalb des Ordners eine Parserdatei, die die Regeln zum Analysieren des Protokolls und zum Verketten von Zeilen enthält, die zu derselben Nachricht gehören.

   1. Fügen Sie den folgenden Inhalt in die Parser-Datei ein:

      ```
      [MULTILINE_PARSER]
          name          multiline-regex-test
          type          regex
          flush_timeout 1000
          #
          # Regex rules for multiline parsing
          # ---------------------------------
          #
          # configuration hints:
          #
          #  - first state always has the name: start_state
          #  - every field in the rule must be inside double quotes
          #
          # rules |   state name  | regex pattern                  | next state
          # ------|---------------|--------------------------------------------
          rule      "start_state"   "/(Dec \d+ \d+\:\d+\:\d+)(.*)/"  "cont"
          rule      "cont"          "/^\s+at.*/"                     "cont"
      ```

      Wenn Sie Ihr Regex-Muster anpassen, empfehlen wir Ihnen, den Ausdruck mit einem Editor für reguläre Ausdrücke zu testen.

   1. Speichern Sie die Datei als `parsers_multiline.conf`. 

1. Erstellen Sie im `FluentBitDockerImage`-Ordner eine benutzerdefinierte Konfigurationsdatei, die auf die Parserdatei verweist, die Sie im vorherigen Schritt erstellt haben.

   Weitere Informationen zur benutzerdefinierten Konfigurationsdatei finden Sie unter [Angeben einer benutzerdefinierten Konfigurationsdatei](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html#firelens-taskdef-customconfig) im *Entwicklerhandbuch für Amazon Elastic Container Service* 

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      [SERVICE]
          flush                 1
          log_level             info
          parsers_file          /parsers_multiline.conf
          
      [FILTER]
          name                  multiline
          match                 *
          multiline.key_content log
          multiline.parser      multiline-regex-test
      ```
**Anmerkung**  
Sie müssen den absoluten Pfad des Parsers verwenden. 

   1. Speichern Sie die Datei als `extra.conf`. 

1. Erstellen Sie im `FluentBitDockerImage`-Ordner die Dockerfile mit dem Fluent-Bit-Image und den von Ihnen erstellten Parser- und Konfigurationsdateien.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest
      
      ADD parsers_multiline.conf /parsers_multiline.conf
      ADD extra.conf /extra.conf
      ```

   1. Speichern Sie die Datei als `Dockerfile`.

1. Erstellen Sie mit der Dockerfile ein benutzerdefiniertes Fluent-Bit-Image mit dem Parser und benutzerdefinierten Konfigurationsdateien.
**Anmerkung**  
Sie können die Parser-Datei und die Konfigurationsdatei an einer beliebigen Stelle im Docker-Image platzieren, es sei `/fluent-bit/etc/fluent-bit.conf` denn, dieser Dateipfad wird von verwendet. FireLens

   1. Entwickeln Sie das Image: `docker build -t fluent-bit-multiline-image.`

      Wobei: `fluent-bit-multiline-image` der Name für das Image in diesem Beispiel ist.

   1. Überprüfen Sie, ob das Image korrekt erstellt wurde: `docker images —filter reference=fluent-bit-multiline-image` 

      Bei Erfolg zeigt die Ausgabe das Image und das `latest`-Tag.

1. Laden Sie das benutzerdefinierte Fluent-Bit-Image in Amazon Elastic Container Registry hoch.

   1. Erstellen Sie ein Amazon-ECR-Repository zum Speichern des Images: `aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1`

      Wobei: `fluent-bit-multiline-repo` der Name für das Repository und `us-east-1` die Region in diesem Beispiel ist. 

      Die Ausgabe gibt Ihnen die Details des neuen Repositorys. 

   1. Markieren Sie Ihr Image mit dem `repositoryUri`-Wert aus der vorherigen Ausgabe: `docker tag fluent-bit-multiline-image repositoryUri` 

      Beispiel: `docker tag fluent-bit-multiline-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo` 

   1. Führen Sie das Docker-Image aus, um zu überprüfen, ob es korrekt ausgeführt wurde: `docker images —filter reference=repositoryUri`

      In der Ausgabe ändert sich der Repository-Name von fluent-bit-multiline-repo zu. `repositoryUri`

   1. Authentifizieren Sie sich bei Amazon ECR, indem Sie den Befehl `aws ecr get-login-password` ausführen und die Registry-ID angeben, bei der Sie sich authentifizieren möchten: `aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com` 

      Beispiel: `ecr get-login-password | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com`

      Eine erfolgreiche Anmeldemeldung wird angezeigt.

   1. Verschieben Sie das Image zu Amazon ECR: `docker push registry ID.dkr.ecr.region.amazonaws.com/repository name` 

      Beispiel: `docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo`

**Erstellen und Hochladen des Images für eine mehrzeilige Demo-Anwendung**

Dieses Image enthält eine Python-Skriptdatei, die die Anwendung ausführt, und eine Beispielprotokolldatei. 

Wenn Sie die Aufgabe ausführen, simuliert die Anwendung Ausführungen, schlägt dann fehl und erstellt einen Stack-Trace. 

1. Erstellen Sie einen Ordner mit dem Namen `multiline-app`: `mkdir multiline-app` 

1. Erstellen Sie eine Python-Skriptdatei.

   1. Erstellen Sie im `multiline-app`-Ordner eine Datei und nennen Sie sie `main.py`.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      import os
      import time
      file1 = open('/test.log', 'r')
      Lines = file1.readlines()
       
      count = 0
      
      for i in range(10):
          print("app running normally...")
          time.sleep(1)
      
      # Strips the newline character
      for line in Lines:
          count += 1
          print(line.rstrip())
      print(count)
      print("app terminated.")
      ```

   1. Speichern Sie die `main.py`-Datei.

1. Erstellen Sie eine Beispielprotokolldatei. 

   1. Erstellen Sie im `multiline-app`-Ordner eine Datei und nennen Sie sie `test.log`.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      single line...
      Dec 14 06:41:08 Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
          at com.myproject.module.MyProject.badMethod(MyProject.java:22)
          at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
          at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
          at com.myproject.module.MyProject.someMethod(MyProject.java:10)
          at com.myproject.module.MyProject.main(MyProject.java:6)
      another line...
      ```

   1. Speichern Sie die `test.log`-Datei.

1. Erstellen Sie innerhalb des Ordners `multiline-app` die Docker-Datei.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      FROM public.ecr.aws/amazonlinux/amazonlinux:latest
      ADD test.log /test.log
      
      RUN yum upgrade -y && yum install -y python3
      
      WORKDIR /usr/local/bin
      
      COPY main.py .
      
      CMD ["python3", "main.py"]
      ```

   1. Speichern Sie die `Dockerfile`-Datei.

1. Erstellen Sie mit der Dockerfile ein Image.

   1. Entwickeln Sie das Image: `docker build -t multiline-app-image `

      Wobei: `multiline-app-image` der Name für das Image in diesem Beispiel ist.

   1. Überprüfen Sie, ob das Image korrekt erstellt wurde: `docker images —filter reference=multiline-app-image` 

      Bei Erfolg zeigt die Ausgabe das Image und das `latest`-Tag.

1. Laden Sie das Image in Amazon-Elastic-Container-Registry hoch.

   1. Erstellen Sie ein Amazon-ECR-Repository zum Speichern des Images: `aws ecr create-repository --repository-name multiline-app-repo --region us-east-1`

      Wobei: `multiline-app-repo` der Name für das Repository und `us-east-1` die Region in diesem Beispiel ist. 

      Die Ausgabe gibt Ihnen die Details des neuen Repositorys. Notieren Sie sich den `repositoryUri`-Wert, da Sie ihn in den nächsten Schritten benötigen. 

   1. Markieren Sie Ihr Image mit dem `repositoryUri`-Wert aus der vorherigen Ausgabe: `docker tag multiline-app-image repositoryUri` 

      Beispiel: `docker tag multiline-app-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo` 

   1. Führen Sie das Docker-Image aus, um zu überprüfen, ob es korrekt ausgeführt wurde: `docker images —filter reference=repositoryUri`

      In der Ausgabe ändert sich der Repository-Name von `multiline-app-repo` in den `repositoryUri`-Wert.

   1. Verschieben Sie das Image zu Amazon ECR: `docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name` 

      Beispiel: `docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo`

**Erstellen einer Aufgabendefinition und Ausführen der Aufgabe**

1. Erstellen Sie eine Aufgabendefinitionsdatei mit dem Dateinamen `multiline-task-definition.json`. 

1. Fügen Sie den folgenden Inhalt in die `multiline-task-definition.json`-Datei ein: 

   ```
   {
       "family": "firelens-example-multiline",
       "taskRoleArn": "task role ARN,
       "executionRoleArn": "execution role ARN",
       "containerDefinitions": [
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-image:latest",
               "name": "log_router",
               "firelensConfiguration": {
                   "type": "fluentbit",
                   "options": {
                       "config-file-type": "file",
                       "config-file-value": "/extra.conf"
                   }
               },
               "memoryReservation": 50
           },
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/multiline-app-image:latest",
               "name": "app",
               "logConfiguration": {
                   "logDriver": "awsfirelens",
                   "options": {
                       "Name": "cloudwatch_logs",
                       "region": "us-east-1",
                       "log_group_name": "multiline-test/application",
                       "auto_create_group": "true",
                       "log_stream_prefix": "multiline-"
                   }
               },
               "memoryReservation": 100
           }
       ],
       "requiresCompatibilities": ["FARGATE"],
       "networkMode": "awsvpc",
       "cpu": "256",
       "memory": "512"
   }
   ```

   Ersetzen Sie Folgendes in der `multiline-task-definition.json`-Aufgabendefinition:

   1. `task role ARN`

      Um den Aufgabenrollen-ARN zu finden, gehen Sie zur IAM-Konsole. Wählen Sie **Roles** (Rollen) und suchen Sie die `ecs-task-role-for-firelens`-Aufgabenrolle, die Sie erstellt haben. Wählen Sie die Rolle aus und kopieren Sie den **ARN**, der im Abschnitt **Summary** (Zusammenfassung) angezeigt wird.

   1. `execution role ARN`

      Verwenden Sie die IAM-Konsole, um die Ausführungsrollen-ARN zu finden. Wählen Sie **Roles** (Rollen) aus und finden Sie die `ecsTaskExecutionRole`-Rolle. Wählen Sie die Rolle aus und kopieren Sie den **ARN**, der im Abschnitt **Summary** (Zusammenfassung) angezeigt wird.

   1. `aws_account_id`

      Um Ihr `aws_account_id` zu finden, melden Sie sich bei AWS-Managementkonsole an. Wählen Sie oben rechts Ihren Benutzernamen und kopieren Sie Ihre Konto-ID.

   1. `us-east-1`

      Ersetzen Sie die Region bei Bedarf.

1. Registrieren Sie die Aufgabendefinitionsdatei: `aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region region` 

1. Öffnen Sie die Konsole auf [https://console.aws.amazon.com/ecs/Version](https://console.aws.amazon.com/ecs/v2) 2.

1. Wählen Sie im Navigationsbereich **Task Definitions** (Aufgabendefinitionen) und dann die `firelens-example-multiline`-Familie aus, da wir die Aufgabendefinition für diese Familie in der ersten Zeile der Aufgabendefinition oben registriert haben.

1. Wählen Sie die neueste Version aus. 

1. Wählen Sie **Bereitstellen**, **Aufgabe ausführen** aus. 

1. Wählen Sie auf der Seite **Task ausführen** für **Cluster** den Cluster aus, und wählen Sie dann unter **Netzwerk** für **Subnetze** die verfügbaren Subnetze für Ihre Aufgabe aus. 

1. Wählen Sie **Erstellen** aus. 

**Stellen Sie sicher, dass mehrzeilige Protokollnachrichten in Amazon verkettet CloudWatch angezeigt werden**

1. Öffnen Sie die Konsole unter. CloudWatch [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)

1. Erweitern Sie im Navigationsbereich **Logs** (Protokolle) und wählen Sie **Log groups** (Protokollgruppen) aus. 

1. Wählen Sie die Protokollgruppe `multiline-test/applicatio` aus. 

1. Wählen Sie das Protokoll aus. Nachrichten anzeigen. Zeilen, die mit den Regeln in der Parser-Datei übereinstimmen, werden verkettet und werden als einzelne Nachricht angezeigt. 

   Das folgende Protokoll-Snippet zeigt Zeilen an, die in einem einzigen Java-Stack-Trace-Ereignis verkettet sind: 

   ```
   {
       "container_id": "xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "log": "Dec 14 06:41:08 Exception in thread \"main\" java.lang.RuntimeException: Something has gone wrong, aborting!\n    at com.myproject.module.MyProject.badMethod(MyProject.java:22)\n    at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)\n    at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)\n    at com.myproject.module.MyProject.someMethod(MyProject.java:10)\n    at com.myproject.module.MyProject.main(MyProject.java:6)",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:2"
   }
   ```

   Das folgende Protokoll-Snippet zeigt, wie dieselbe Meldung mit nur einer einzigen Zeile angezeigt wird, wenn Sie einen Amazon-ECS-Container ausführen, der nicht für die Verkettung von mehrzeiligen Protokollmeldungen konfiguriert ist. 

   ```
   {
       "log": "Dec 14 06:41:08 Exception in thread \"main\" java.lang.RuntimeException: Something has gone wrong, aborting!",
       "container_id": "xxxxxx-xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:3"
   }
   ```

### Beispiel: Verwenden eines integrierten Parsers für Fluent Bit
<a name="fluent-bit-parser"></a>

In diesem Beispiel führen Sie die folgenden Schritte aus: 

1. Erstellen und laden Sie das Image für einen Fluent-Bit-Container hoch. 

1. Erstellen und laden Sie das Image für eine mehrzeilige Demo-Anwendung hoch, die einen mehrzeiligen Stack-Trace ausführt, fehlschlägt und generiert.

1. Erstellen Sie die Aufgabendefinition und führen Sie die Aufgabe aus. 

1. Zeigen Sie die Protokolle an, um zu überprüfen, ob Nachrichten, die sich über mehrere Zeilen erstrecken, verkettet erscheinen. 

**Erstellen und Hochladen des Images für einen Fluent-Bit-Container**

Dieses Image enthält eine Konfigurationsdatei, die auf den Fluent-Bit-Parser verweist. 

1. Erstellen Sie einen Ordner mit dem Namen `FluentBitDockerImage`. 

1. Erstellen Sie innerhalb des `FluentBitDockerImage`-Ordners eine benutzerdefinierte Konfigurationsdatei, die auf die integrierte Parser-Datei von Fluent Bit verweist.

   Weitere Informationen zur benutzerdefinierten Konfigurationsdatei finden Sie unter [Angeben einer benutzerdefinierten Konfigurationsdatei](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html#firelens-taskdef-customconfig) im *Entwicklerhandbuch für Amazon Elastic Container Service* 

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      [FILTER]
          name                  multiline
          match                 *
          multiline.key_content log
          multiline.parser      go
      ```

   1. Speichern Sie die Datei als `extra.conf`. 

1. Erstellen Sie im `FluentBitDockerImage`-Ordner die Dockerfile mit dem Fluent-Bit-Image und den von Ihnen erstellten Parser- und Konfigurationsdateien.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest
      ADD extra.conf /extra.conf
      ```

   1. Speichern Sie die Datei als `Dockerfile`.

1. Erstellen Sie mit der Dockerfile ein benutzerdefiniertes Fluent-Bit-Image mit der enthaltenen benutzerdefinierten Konfigurationsdatei.
**Anmerkung**  
Sie können die Konfigurationsdatei an einer beliebigen Stelle im Docker-Image platzieren, es sei `/fluent-bit/etc/fluent-bit.conf` denn, dieser Dateipfad wird von FireLens verwendet.

   1. Entwickeln Sie das Image: `docker build -t fluent-bit-multiline-image.`

      Wobei: `fluent-bit-multiline-image` der Name für das Image in diesem Beispiel ist.

   1. Überprüfen Sie, ob das Image korrekt erstellt wurde: `docker images —filter reference=fluent-bit-multiline-image` 

      Bei Erfolg zeigt die Ausgabe das Image und das `latest`-Tag.

1. Laden Sie das benutzerdefinierte Fluent-Bit-Image in Amazon Elastic Container Registry hoch.

   1. Erstellen Sie ein Amazon-ECR-Repository zum Speichern des Images: `aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1`

      Wobei: `fluent-bit-multiline-repo` der Name für das Repository und `us-east-1` die Region in diesem Beispiel ist. 

      Die Ausgabe gibt Ihnen die Details des neuen Repositorys. 

   1. Markieren Sie Ihr Image mit dem `repositoryUri`-Wert aus der vorherigen Ausgabe: `docker tag fluent-bit-multiline-image repositoryUri` 

      Beispiel: `docker tag fluent-bit-multiline-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo` 

   1. Führen Sie das Docker-Image aus, um zu überprüfen, ob es korrekt ausgeführt wurde: `docker images —filter reference=repositoryUri`

      In der Ausgabe ändert sich der Repository-Name von fluent-bit-multiline-repo zu. `repositoryUri`

   1. Authentifizieren Sie sich bei Amazon ECR, indem Sie den Befehl `aws ecr get-login-password` ausführen und die Registry-ID angeben, bei der Sie sich authentifizieren möchten: `aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com` 

      Beispiel: `ecr get-login-password | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com`

      Eine erfolgreiche Anmeldemeldung wird angezeigt.

   1. Verschieben Sie das Image zu Amazon ECR: `docker push registry ID.dkr.ecr.region.amazonaws.com/repository name` 

      Beispiel: `docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-repo`

**Erstellen und Hochladen des Images für eine mehrzeilige Demo-Anwendung**

Dieses Image enthält eine Python-Skriptdatei, die die Anwendung ausführt, und eine Beispielprotokolldatei. 

1. Erstellen Sie einen Ordner mit dem Namen `multiline-app`: `mkdir multiline-app` 

1. Erstellen Sie eine Python-Skriptdatei.

   1. Erstellen Sie im `multiline-app`-Ordner eine Datei und nennen Sie sie `main.py`.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      import os
      import time
      file1 = open('/test.log', 'r')
      Lines = file1.readlines()
       
      count = 0
      
      for i in range(10):
          print("app running normally...")
          time.sleep(1)
      
      # Strips the newline character
      for line in Lines:
          count += 1
          print(line.rstrip())
      print(count)
      print("app terminated.")
      ```

   1. Speichern Sie die `main.py`-Datei.

1. Erstellen Sie eine Beispielprotokolldatei. 

   1. Erstellen Sie im `multiline-app`-Ordner eine Datei und nennen Sie sie `test.log`.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      panic: my panic
      
      goroutine 4 [running]:
      panic(0x45cb40, 0x47ad70)
        /usr/local/go/src/runtime/panic.go:542 +0x46c fp=0xc42003f7b8 sp=0xc42003f710 pc=0x422f7c
      main.main.func1(0xc420024120)
        foo.go:6 +0x39 fp=0xc42003f7d8 sp=0xc42003f7b8 pc=0x451339
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x44b4d1
      created by main.main
        foo.go:5 +0x58
      
      goroutine 1 [chan receive]:
      runtime.gopark(0x4739b8, 0xc420024178, 0x46fcd7, 0xc, 0xc420028e17, 0x3)
        /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc420053e30 sp=0xc420053e00 pc=0x42503c
      runtime.goparkunlock(0xc420024178, 0x46fcd7, 0xc, 0x1000f010040c217, 0x3)
        /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc420053e70 sp=0xc420053e30 pc=0x42512e
      runtime.chanrecv(0xc420024120, 0x0, 0xc420053f01, 0x4512d8)
        /usr/local/go/src/runtime/chan.go:506 +0x304 fp=0xc420053f20 sp=0xc420053e70 pc=0x4046b4
      runtime.chanrecv1(0xc420024120, 0x0)
        /usr/local/go/src/runtime/chan.go:388 +0x2b fp=0xc420053f50 sp=0xc420053f20 pc=0x40439b
      main.main()
        foo.go:9 +0x6f fp=0xc420053f80 sp=0xc420053f50 pc=0x4512ef
      runtime.main()
        /usr/local/go/src/runtime/proc.go:185 +0x20d fp=0xc420053fe0 sp=0xc420053f80 pc=0x424bad
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420053fe8 sp=0xc420053fe0 pc=0x44b4d1
      
      goroutine 2 [force gc (idle)]:
      runtime.gopark(0x4739b8, 0x4ad720, 0x47001e, 0xf, 0x14, 0x1)
        /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003e768 sp=0xc42003e738 pc=0x42503c
      runtime.goparkunlock(0x4ad720, 0x47001e, 0xf, 0xc420000114, 0x1)
        /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003e7a8 sp=0xc42003e768 pc=0x42512e
      runtime.forcegchelper()
        /usr/local/go/src/runtime/proc.go:238 +0xcc fp=0xc42003e7e0 sp=0xc42003e7a8 pc=0x424e5c
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x44b4d1
      created by runtime.init.4
        /usr/local/go/src/runtime/proc.go:227 +0x35
      
      goroutine 3 [GC sweep wait]:
      runtime.gopark(0x4739b8, 0x4ad7e0, 0x46fdd2, 0xd, 0x419914, 0x1)
        /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003ef60 sp=0xc42003ef30 pc=0x42503c
      runtime.goparkunlock(0x4ad7e0, 0x46fdd2, 0xd, 0x14, 0x1)
        /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003efa0 sp=0xc42003ef60 pc=0x42512e
      runtime.bgsweep(0xc42001e150)
        /usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc42003efd8 sp=0xc42003efa0 pc=0x419973
      runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003efe0 sp=0xc42003efd8 pc=0x44b4d1
      created by runtime.gcenable
        /usr/local/go/src/runtime/mgc.go:216 +0x58
      one more line, no multiline
      ```

   1. Speichern Sie die `test.log`-Datei.

1. Erstellen Sie innerhalb des Ordners `multiline-app` die Docker-Datei.

   1. Fügen Sie den folgenden Inhalt in die Datei ein:

      ```
      FROM public.ecr.aws/amazonlinux/amazonlinux:latest
      ADD test.log /test.log
      
      RUN yum upgrade -y && yum install -y python3
      
      WORKDIR /usr/local/bin
      
      COPY main.py .
      
      CMD ["python3", "main.py"]
      ```

   1. Speichern Sie die `Dockerfile`-Datei.

1. Erstellen Sie mit der Dockerfile ein Image.

   1. Entwickeln Sie das Image: `docker build -t multiline-app-image `

      Wobei: `multiline-app-image` der Name für das Image in diesem Beispiel ist.

   1. Überprüfen Sie, ob das Image korrekt erstellt wurde: `docker images —filter reference=multiline-app-image` 

      Bei Erfolg zeigt die Ausgabe das Image und das `latest`-Tag.

1. Laden Sie das Image in Amazon-Elastic-Container-Registry hoch.

   1. Erstellen Sie ein Amazon-ECR-Repository zum Speichern des Images: `aws ecr create-repository --repository-name multiline-app-repo --region us-east-1`

      Wobei: `multiline-app-repo` der Name für das Repository und `us-east-1` die Region in diesem Beispiel ist. 

      Die Ausgabe gibt Ihnen die Details des neuen Repositorys. Notieren Sie sich den `repositoryUri`-Wert, da Sie ihn in den nächsten Schritten benötigen. 

   1. Markieren Sie Ihr Image mit dem `repositoryUri`-Wert aus der vorherigen Ausgabe: `docker tag multiline-app-image repositoryUri` 

      Beispiel: `docker tag multiline-app-image xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo` 

   1. Führen Sie das Docker-Image aus, um zu überprüfen, ob es korrekt ausgeführt wurde: `docker images —filter reference=repositoryUri`

      In der Ausgabe ändert sich der Repository-Name von `multiline-app-repo` in den `repositoryUri`-Wert.

   1. Verschieben Sie das Image zu Amazon ECR: `docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name` 

      Beispiel: `docker push xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/multiline-app-repo`

**Erstellen einer Aufgabendefinition und Ausführen der Aufgabe**

1. Erstellen Sie eine Aufgabendefinitionsdatei mit dem Dateinamen `multiline-task-definition.json`. 

1. Fügen Sie den folgenden Inhalt in die `multiline-task-definition.json`-Datei ein: 

   ```
   {
       "family": "firelens-example-multiline",
       "taskRoleArn": "task role ARN,
       "executionRoleArn": "execution role ARN",
       "containerDefinitions": [
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/fluent-bit-multiline-image:latest",
               "name": "log_router",
               "firelensConfiguration": {
                   "type": "fluentbit",
                   "options": {
                       "config-file-type": "file",
                       "config-file-value": "/extra.conf"
                   }
               },
               "memoryReservation": 50
           },
           {
               "essential": true,
               "image": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/multiline-app-image:latest",
               "name": "app",
               "logConfiguration": {
                   "logDriver": "awsfirelens",
                   "options": {
                       "Name": "cloudwatch_logs",
                       "region": "us-east-1",
                       "log_group_name": "multiline-test/application",
                       "auto_create_group": "true",
                       "log_stream_prefix": "multiline-"
                   }
               },
               "memoryReservation": 100
           }
       ],
       "requiresCompatibilities": ["FARGATE"],
       "networkMode": "awsvpc",
       "cpu": "256",
       "memory": "512"
   }
   ```

   Ersetzen Sie Folgendes in der `multiline-task-definition.json`-Aufgabendefinition:

   1. `task role ARN`

      Um den Aufgabenrollen-ARN zu finden, gehen Sie zur IAM-Konsole. Wählen Sie **Roles** (Rollen) und suchen Sie die `ecs-task-role-for-firelens`-Aufgabenrolle, die Sie erstellt haben. Wählen Sie die Rolle aus und kopieren Sie den **ARN**, der im Abschnitt **Summary** (Zusammenfassung) angezeigt wird.

   1. `execution role ARN`

      Verwenden Sie die IAM-Konsole, um die Ausführungsrollen-ARN zu finden. Wählen Sie **Roles** (Rollen) aus und finden Sie die `ecsTaskExecutionRole`-Rolle. Wählen Sie die Rolle aus und kopieren Sie den **ARN**, der im Abschnitt **Summary** (Zusammenfassung) angezeigt wird.

   1. `aws_account_id`

      Um Ihr `aws_account_id` zu finden, melden Sie sich bei AWS-Managementkonsole an. Wählen Sie oben rechts Ihren Benutzernamen und kopieren Sie Ihre Konto-ID.

   1. `us-east-1`

      Ersetzen Sie die Region bei Bedarf.

1. Registrieren Sie die Aufgabendefinitionsdatei: `aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region us-east-1` 

1. Öffnen Sie die Konsole auf [https://console.aws.amazon.com/ecs/Version](https://console.aws.amazon.com/ecs/v2) 2.

1. Wählen Sie im Navigationsbereich **Task Definitions** (Aufgabendefinitionen) und dann die `firelens-example-multiline`-Familie aus, da wir die Aufgabendefinition für diese Familie in der ersten Zeile der Aufgabendefinition oben registriert haben.

1. Wählen Sie die neueste Version aus. 

1. Wählen Sie **Bereitstellen**, **Aufgabe ausführen** aus. 

1. Wählen Sie auf der Seite **Task ausführen** für **Cluster** den Cluster aus, und wählen Sie dann unter **Netzwerk** für **Subnetze** die verfügbaren Subnetze für Ihre Aufgabe aus. 

1. Wählen Sie **Erstellen** aus. 

**Stellen Sie sicher, dass mehrzeilige Protokollnachrichten in Amazon verkettet CloudWatch angezeigt werden**

1. Öffnen Sie die Konsole unter. CloudWatch [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)

1. Erweitern Sie im Navigationsbereich **Logs** (Protokolle) und wählen Sie **Log groups** (Protokollgruppen) aus. 

1. Wählen Sie die Protokollgruppe `multiline-test/applicatio` aus. 

1. Wählen Sie das Protokoll aus und sehen Sie sich die Nachrichten an. Zeilen, die mit den Regeln in der Parser-Datei übereinstimmen, werden verkettet und werden als einzelne Nachricht angezeigt. 

   Das folgende Protokoll-Snippet zeigt einen Go-Stack-Trace, der zu einem einzigen Ereignis verkettet ist: 

   ```
   {
       "log": "panic: my panic\n\ngoroutine 4 [running]:\npanic(0x45cb40, 0x47ad70)\n  /usr/local/go/src/runtime/panic.go:542 +0x46c fp=0xc42003f7b8 sp=0xc42003f710 pc=0x422f7c\nmain.main.func1(0xc420024120)\n  foo.go:6 +0x39 fp=0xc42003f7d8 sp=0xc42003f7b8 pc=0x451339\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x44b4d1\ncreated by main.main\n  foo.go:5 +0x58\n\ngoroutine 1 [chan receive]:\nruntime.gopark(0x4739b8, 0xc420024178, 0x46fcd7, 0xc, 0xc420028e17, 0x3)\n  /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc420053e30 sp=0xc420053e00 pc=0x42503c\nruntime.goparkunlock(0xc420024178, 0x46fcd7, 0xc, 0x1000f010040c217, 0x3)\n  /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc420053e70 sp=0xc420053e30 pc=0x42512e\nruntime.chanrecv(0xc420024120, 0x0, 0xc420053f01, 0x4512d8)\n  /usr/local/go/src/runtime/chan.go:506 +0x304 fp=0xc420053f20 sp=0xc420053e70 pc=0x4046b4\nruntime.chanrecv1(0xc420024120, 0x0)\n  /usr/local/go/src/runtime/chan.go:388 +0x2b fp=0xc420053f50 sp=0xc420053f20 pc=0x40439b\nmain.main()\n  foo.go:9 +0x6f fp=0xc420053f80 sp=0xc420053f50 pc=0x4512ef\nruntime.main()\n  /usr/local/go/src/runtime/proc.go:185 +0x20d fp=0xc420053fe0 sp=0xc420053f80 pc=0x424bad\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420053fe8 sp=0xc420053fe0 pc=0x44b4d1\n\ngoroutine 2 [force gc (idle)]:\nruntime.gopark(0x4739b8, 0x4ad720, 0x47001e, 0xf, 0x14, 0x1)\n  /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003e768 sp=0xc42003e738 pc=0x42503c\nruntime.goparkunlock(0x4ad720, 0x47001e, 0xf, 0xc420000114, 0x1)\n  /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003e7a8 sp=0xc42003e768 pc=0x42512e\nruntime.forcegchelper()\n  /usr/local/go/src/runtime/proc.go:238 +0xcc fp=0xc42003e7e0 sp=0xc42003e7a8 pc=0x424e5c\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x44b4d1\ncreated by runtime.init.4\n  /usr/local/go/src/runtime/proc.go:227 +0x35\n\ngoroutine 3 [GC sweep wait]:\nruntime.gopark(0x4739b8, 0x4ad7e0, 0x46fdd2, 0xd, 0x419914, 0x1)\n  /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003ef60 sp=0xc42003ef30 pc=0x42503c\nruntime.goparkunlock(0x4ad7e0, 0x46fdd2, 0xd, 0x14, 0x1)\n  /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003efa0 sp=0xc42003ef60 pc=0x42512e\nruntime.bgsweep(0xc42001e150)\n  /usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc42003efd8 sp=0xc42003efa0 pc=0x419973\nruntime.goexit()\n  /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003efe0 sp=0xc42003efd8 pc=0x44b4d1\ncreated by runtime.gcenable\n  /usr/local/go/src/runtime/mgc.go:216 +0x58",
       "container_id": "xxxxxx-xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:2"
   }
   ```

   Das folgende Protokoll-Snippet zeigt, wie dasselbe Ereignis angezeigt wird, wenn Sie einen ECS-Container ausführen, der nicht für die Verkettung von mehrzeiligen Protokollmeldungen konfiguriert ist. Das Protokollfeld enthält eine einzelne Zeile.

   ```
   {
       "log": "panic: my panic",
       "container_id": "xxxxxx-xxxxxx",
       "container_name": "app",
       "source": "stdout",
       "ecs_cluster": "default",
       "ecs_task_arn": "arn:aws:ecs:us-east-1:xxxxxxxxxxxx:task/default/xxxxxx",
       "ecs_task_definition": "firelens-example-multiline:3"
   ```

**Anmerkung**  
Wenn Ihre Protokolle anstelle der Standardausgabe in Protokolldateien gehen, empfehlen wir, die `multiline.parser`- und `multiline.key_content`-Konfigurationsparameter im [Tail-Eingabe-Plug-In](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-support) anstelle des Filters anzugeben.