

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Concatenazione di messaggi di log Amazon ECS multilinea o di traccia dello stack
<a name="firelens-concatanate-multiline"></a>

A partire AWS dalla versione 2.22.0 di Fluent Bit, è incluso un filtro multilinea. Il filtro multilinea aiuta a concatenare i messaggi di log originariamente appartenenti a un contesto ma suddivisi su più record o righe di registro. Per ulteriori informazioni sul filtro multilinea, consulta la [documentazione di Fluent Bit](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace). 

Esempi comuni di messaggi di log divisi sono:
+ Tracce dello stack. 
+ Applicazioni che stampano i log su più righe. 
+ Registra i messaggi che sono stati divisi perché erano più lunghi della dimensione massima del buffer di runtime specificata. [È possibile concatenare i messaggi di registro suddivisi in base al runtime del contenitore seguendo l'esempio su GitHub: Esempio: Concatenate Container Logs. FireLens Partial/Split ](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/filter-multiline-partial-message-mode)

## Autorizzazioni IAM richieste
<a name="iam-permissions"></a>

Disponi delle autorizzazioni IAM necessarie affinché l'agente container estragga le immagini del contenitore da Amazon ECR e che il container instrada i log verso Logs. CloudWatch 

Per tali autorizzazioni devi disporre anche dei seguenti ruoli: 
+ Un ruolo IAM del processo. 
+ Un ruolo IAM di esecuzione di attività. 

Sono necessarie le seguenti autorizzazioni:
+ `logs:CreateLogStream`
+ `logs:CreateLogGroup`
+ `logs:PutLogEvents`

## Determinazione dei casi in cui utilizzare l'impostazione del log multilinea
<a name="determine-filter"></a>

Di seguito sono riportati alcuni esempi di frammenti di log visualizzati nella console CloudWatch Logs con l'impostazione di registro predefinita. Puoi guardare la riga che inizia con `log` per determinare se è necessario il filtro multilinea. Quando il contesto è lo stesso, puoi utilizzare l'impostazione di registro multilinea. In questo esempio, il contesto è «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"
     }
```

Dopo aver utilizzato l'impostazione del log multilinea, l'output sarà simile all'esempio seguente. 

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

## Opzioni di analisi e concatenazione
<a name="parse-multiline-log"></a>

Per analizzare i log e concatenare righe divise a causa di nuove righe, puoi utilizzare una di queste due opzioni.
+ Utilizza il tuo file parser contenente le regole per analizzare e concatenare le righe che appartengono allo stesso messaggio.
+ Utilizzare un parser integrato Fluent Bit. Per l'elenco dei linguaggi supportati dai parser integrati Fluent Bit, consulta la [documentazione di Fluent Bit.](https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace)

Il seguente tutorial illustra i passaggi per ogni caso d'uso. I passaggi mostrano come concatenare più righe e inviare i log ad Amazon. CloudWatch Puoi specificare una destinazione diversa per i log.

### Esempio: utilizzare un parser creato
<a name="customer-parser"></a>

In questo esempio eseguirai i passaggi seguenti: 

1. Crea e carica l'immagine per un container Fluent Bit. 

1. Crea e carica l'immagine per un'applicazione demo multilinea che esegue, fallisce e genera una traccia dello stack multilinea.

1. Crea la definizione di un processo e avviare il processo. 

1. Visualizza i log per verificare che i messaggi che si estendono su più righe appaiano concatenati. 

**Creare e caricare l'immagine per un container Fluent Bit**

Questa immagine includerà il file parser in cui si specifica l'espressione regolare e un file di configurazione che fa riferimento al file parser. 

1. Crea una cartella con il nome `FluentBitDockerImage`. 

1. Nella cartella, crea il file parser contenente le regole per analizzare il log e concatenare le righe che appartengono allo stesso messaggio.

   1. Incolla i contenuti seguenti nel file parser:

      ```
      [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"
      ```

      Mentre personalizzi il modello di regex, ti consigliamo di utilizzare un editor di espressioni regolari per provare l'espressione.

   1. Salva il file con nome `parsers_multiline.conf`. 

1. All'interno della cartella `FluentBitDockerImage`, crea un file di configurazione personalizzato che fa riferimento al file parser creato nel passaggio precedente.

   Per ulteriori informazioni sul file di configurazione personalizzato, consulta [Specifica di un file di configurazione personalizzato](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html#firelens-taskdef-customconfig) nella *Guida per gli sviluppatori di Amazon Elastic Container Service* 

   1. Incolla i contenuti seguenti nel file:

      ```
      [SERVICE]
          flush                 1
          log_level             info
          parsers_file          /parsers_multiline.conf
          
      [FILTER]
          name                  multiline
          match                 *
          multiline.key_content log
          multiline.parser      multiline-regex-test
      ```
**Nota**  
È necessario utilizzare il percorso assoluto del parser. 

   1. Salva il file con nome `extra.conf`. 

1. All'interno della cartella `FluentBitDockerImage`, crea il Dockerfile con l'immagine Fluent Bit e il parser e i file di configurazione creati.

   1. Incolla i contenuti seguenti nel file:

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

   1. Salva il file con nome `Dockerfile`.

1. Utilizzando il Dockerfile, crea un'immagine Fluent Bit personalizzata con il parser e i file di configurazione personalizzati inclusi.
**Nota**  
Puoi posizionare il file di analisi e il file di configurazione in qualsiasi punto dell'immagine Docker, tranne `/fluent-bit/etc/fluent-bit.conf` quando questo percorso del file viene utilizzato da. FireLens

   1. Crea l'immagine: `docker build -t fluent-bit-multiline-image.`

      Dove: `fluent-bit-multiline-image` è il nome dell'immagine in questo esempio.

   1. Verifica che l'immagine sia stata creata correttamente: `docker images —filter reference=fluent-bit-multiline-image` 

      In caso di esito positivo, l'output mostra l'immagine e il tag `latest`.

1. Carica l'immagine Fluent Bit personalizzata in Amazon Elastic Container Registry.

   1. Crea un repository Amazon ECR per archiviare l'immagine: `aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1`

      Dove: `fluent-bit-multiline-repo` è il nome del repository e `us-east-1` è la regione in questo esempio. 

      L'output fornisce i dettagli del nuovo repository. 

   1. Applica un tag all'immagine con il valore `repositoryUri` ricavato dall'output precedente: `docker tag fluent-bit-multiline-image repositoryUri` 

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

   1. Esegui l'immagine Docker per verificare che sia stata eseguita correttamente: `docker images —filter reference=repositoryUri`

      Nell'output, il nome del repository cambia da a fluent-bit-multiline-repo. `repositoryUri`

   1. Effettua l'autenticazione su Amazon ECR eseguendo il comando `aws ecr get-login-password` e specificando l'ID del log in cui desideri eseguire l'autenticazione: `aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com` 

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

      Viene visualizzato un messaggio di accesso riuscito.

   1. Invia l'immagine ad Amazon ECR: `docker push registry ID.dkr.ecr.region.amazonaws.com/repository name` 

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

**Crea e carica l'immagine per un'applicazione demo multilinea**

Questa immagine includerà un file di script Python che esegue l'applicazione e un file di log di esempio. 

Quando esegui il processo, l'applicazione simula le esecuzioni, quindi fallisce e crea una traccia dello stack. 

1. Crea una cartella denominata `multiline-app`: `mkdir multiline-app` 

1. Crea un file di script Python.

   1. Nella cartella `multiline-app`, crea un file con il nome `main.py`.

   1. Incolla i contenuti seguenti nel file:

      ```
      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. Salvare il file `main.py`.

1. Crea un file di log di esempio. 

   1. Nella cartella `multiline-app`, crea un file con il nome `test.log`.

   1. Incolla i contenuti seguenti nel file:

      ```
      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. Salvare il file `test.log`.

1. All'interno della cartella `multiline-app`, crea il Dockerfile.

   1. Incolla i contenuti seguenti nel file:

      ```
      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. Salvare il file `Dockerfile`.

1. Usando il Dockerfile, crea un'immagine.

   1. Crea l'immagine: `docker build -t multiline-app-image `

      Dove: `multiline-app-image` è il nome dell'immagine in questo esempio.

   1. Verifica che l'immagine sia stata creata correttamente: `docker images —filter reference=multiline-app-image` 

      In caso di esito positivo, l'output mostra l'immagine e il tag `latest`.

1. Carica l'immagine nel registro del container Amazon Elastic.

   1. Crea un repository Amazon ECR per archiviare l'immagine: `aws ecr create-repository --repository-name multiline-app-repo --region us-east-1`

      Dove: `multiline-app-repo` è il nome del repository e `us-east-1` è la regione in questo esempio. 

      L'output fornisce i dettagli del nuovo repository. Annota il valore `repositoryUri` poiché sarà necessario nei passaggi successivi. 

   1. Applica un tag all'immagine con il valore `repositoryUri` ricavato dall'output precedente: `docker tag multiline-app-image repositoryUri` 

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

   1. Esegui l'immagine Docker per verificare che sia stata eseguita correttamente: `docker images —filter reference=repositoryUri`

      Nell'output, il nome del repository cambia da `multiline-app-repo` al valore `repositoryUri`.

   1. Invia l'immagine ad Amazon ECR: `docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name` 

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

**Crea la definizione di un processo e avviare il processo**

1. Crea un file di definizione del processo con il nome del file `multiline-task-definition.json`. 

1. Incolla i contenuti seguenti nel file `multiline-task-definition.json`: 

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

   Sostituisci quanto segue nella definizione del processo `multiline-task-definition.json`:

   1. `task role ARN`

      Per trovare l'ARN del ruolo del processo, vai alla Console IAM. Scegliere **Ruoli** e trovare il ruolo del processo `ecs-task-role-for-firelens` che è stato creato. Scegli il ruolo e copia l'**ARN** che appare nella sezione **Summary** (Riepilogo).

   1. `execution role ARN`

      Per trovare l'ARN del ruolo di esecuzione, vai alla Console IAM. Scegli **Roles** (Ruoli) e trova il ruolo `ecsTaskExecutionRole`. Scegli il ruolo e copia l'**ARN** che appare nella sezione **Summary** (Riepilogo).

   1. `aws_account_id`

      Per trovare l'`aws_account_id`, accedi alla Console di gestione AWS. Scegli il tuo nome utente in alto a destra e copia il tuo ID account.

   1. `us-east-1`

      Sostituisci la regione se necessario.

1. Registra il file di definizione del processo: `aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region region` 

1. Apri la console alla [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2).

1. Nel pannello di navigazione, scegli **Task Definitions** (Definizioni dei processi) quindi scegli la famiglia `firelens-example-multiline`, perché sopra abbiamo registrato la definizione dell'attività processo in questa famiglia nella prima riga della definizione del processo.

1. Scegli la versione più recente. 

1. Scegli **Distribuisci**, **Esegui attività**. 

1. Nella pagina **Esegui attività**, in **Cluster** scegli il cluster, quindi in **Reti** scegli le sottoreti disponibili per tale attività in **Sottoreti**. 

1. Scegli **Create** (Crea). 

**Verifica che i messaggi di log multilinea in Amazon CloudWatch appaiano concatenati**

1. Apri la console all'indirizzo. CloudWatch [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)

1. Nel pannello di navigazione, espandi **Logs** (Log) e scegli **Log groups** (Gruppi di log). 

1. Scegli il gruppo di log `multiline-test/applicatio`. 

1. Scegli il log. Visualizza i messaggi. Le righe che corrispondono alle regole nel file parser vengono concatenate e appaiono come un singolo messaggio. 

   Il seguente frammento di log mostra le righe concatenate in un singolo evento di traccia dello stack Java: 

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

   Il seguente frammento di log mostra come viene visualizzato lo stesso messaggio con una singola riga se esegui un container Amazon ECS non configurato per concatenare messaggi di log multilinea. 

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

### Esempio: utilizzo di un parser integrato Fluent Bit
<a name="fluent-bit-parser"></a>

In questo esempio eseguirai i passaggi seguenti: 

1. Crea e carica l'immagine per un container Fluent Bit. 

1. Crea e carica l'immagine per un'applicazione demo multilinea che esegue, fallisce e genera una traccia dello stack multilinea.

1. Crea la definizione di un processo e avviare il processo. 

1. Visualizza i log per verificare che i messaggi che si estendono su più righe appaiano concatenati. 

**Crea e carica l'immagine per un container Fluent Bit**

Questa immagine includerà un file di configurazione che fa riferimento al parser Fluent Bit. 

1. Crea una cartella con il nome `FluentBitDockerImage`. 

1. All'interno della cartella `FluentBitDockerImage`, crea un file di configurazione personalizzato che fa riferimento al file parser integrato Fluent Bit.

   Per ulteriori informazioni sul file di configurazione personalizzato, consulta [Specifica di un file di configurazione personalizzato](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html#firelens-taskdef-customconfig) nella *Guida per gli sviluppatori di Amazon Elastic Container Service* 

   1. Incolla i contenuti seguenti nel file:

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

   1. Salva il file con nome `extra.conf`. 

1. All'interno della cartella `FluentBitDockerImage`, crea il Dockerfile con l'immagine Fluent Bit e il parser e i file di configurazione creati.

   1. Incolla i contenuti seguenti nel file:

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

   1. Salva il file con nome `Dockerfile`.

1. Utilizzando il Dockerfile, crea un'immagine Fluent Bit personalizzata con il file di configurazione personalizzato inclusi.
**Nota**  
È possibile posizionare il file di configurazione in qualsiasi punto dell'immagine Docker, a meno che `/fluent-bit/etc/fluent-bit.conf` questo percorso del file non venga utilizzato da FireLens.

   1. Crea l'immagine: `docker build -t fluent-bit-multiline-image.`

      Dove: `fluent-bit-multiline-image` è il nome dell'immagine in questo esempio.

   1. Verifica che l'immagine sia stata creata correttamente: `docker images —filter reference=fluent-bit-multiline-image` 

      In caso di esito positivo, l'output mostra l'immagine e il tag `latest`.

1. Carica l'immagine Fluent Bit personalizzata in Amazon Elastic Container Registry.

   1. Crea un repository Amazon ECR per archiviare l'immagine: `aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1`

      Dove: `fluent-bit-multiline-repo` è il nome del repository e `us-east-1` è la regione in questo esempio. 

      L'output fornisce i dettagli del nuovo repository. 

   1. Applica un tag all'immagine con il valore `repositoryUri` ricavato dall'output precedente: `docker tag fluent-bit-multiline-image repositoryUri` 

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

   1. Esegui l'immagine Docker per verificare che sia stata eseguita correttamente: `docker images —filter reference=repositoryUri`

      Nell'output, il nome del repository cambia da fluent-bit-multiline-repo a. `repositoryUri`

   1. Effettua l'autenticazione su Amazon ECR eseguendo il comando `aws ecr get-login-password` e specificando l'ID del log in cui desideri eseguire l'autenticazione: `aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com` 

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

      Viene visualizzato un messaggio di accesso riuscito.

   1. Invia l'immagine ad Amazon ECR: `docker push registry ID.dkr.ecr.region.amazonaws.com/repository name` 

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

**Crea e carica l'immagine per un'applicazione demo multilinea**

Questa immagine includerà un file di script Python che esegue l'applicazione e un file di log di esempio. 

1. Crea una cartella denominata `multiline-app`: `mkdir multiline-app` 

1. Crea un file di script Python.

   1. Nella cartella `multiline-app`, crea un file con il nome `main.py`.

   1. Incolla i contenuti seguenti nel file:

      ```
      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. Salvare il file `main.py`.

1. Crea un file di log di esempio. 

   1. Nella cartella `multiline-app`, crea un file con il nome `test.log`.

   1. Incolla i contenuti seguenti nel file:

      ```
      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. Salvare il file `test.log`.

1. All'interno della cartella `multiline-app`, crea il Dockerfile.

   1. Incolla i contenuti seguenti nel file:

      ```
      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. Salvare il file `Dockerfile`.

1. Usando il Dockerfile, crea un'immagine.

   1. Crea l'immagine: `docker build -t multiline-app-image `

      Dove: `multiline-app-image` è il nome dell'immagine in questo esempio.

   1. Verifica che l'immagine sia stata creata correttamente: `docker images —filter reference=multiline-app-image` 

      In caso di esito positivo, l'output mostra l'immagine e il tag `latest`.

1. Carica l'immagine nel registro del container Amazon Elastic.

   1. Crea un repository Amazon ECR per archiviare l'immagine: `aws ecr create-repository --repository-name multiline-app-repo --region us-east-1`

      Dove: `multiline-app-repo` è il nome del repository e `us-east-1` è la regione in questo esempio. 

      L'output fornisce i dettagli del nuovo repository. Annota il valore `repositoryUri` poiché sarà necessario nei passaggi successivi. 

   1. Applica un tag all'immagine con il valore `repositoryUri` ricavato dall'output precedente: `docker tag multiline-app-image repositoryUri` 

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

   1. Esegui l'immagine Docker per verificare che sia stata eseguita correttamente: `docker images —filter reference=repositoryUri`

      Nell'output, il nome del repository cambia da `multiline-app-repo` al valore `repositoryUri`.

   1. Invia l'immagine ad Amazon ECR: `docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name` 

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

**Crea la definizione di un processo e avviare il processo**

1. Crea un file di definizione del processo con il nome del file `multiline-task-definition.json`. 

1. Incolla i contenuti seguenti nel file `multiline-task-definition.json`: 

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

   Sostituisci quanto segue nella definizione del processo `multiline-task-definition.json`:

   1. `task role ARN`

      Per trovare l'ARN del ruolo del processo, vai alla Console IAM. Scegliere **Ruoli** e trovare il ruolo del processo `ecs-task-role-for-firelens` che è stato creato. Scegli il ruolo e copia l'**ARN** che appare nella sezione **Summary** (Riepilogo).

   1. `execution role ARN`

      Per trovare l'ARN del ruolo di esecuzione, vai alla Console IAM. Scegli **Roles** (Ruoli) e trova il ruolo `ecsTaskExecutionRole`. Scegli il ruolo e copia l'**ARN** che appare nella sezione **Summary** (Riepilogo).

   1. `aws_account_id`

      Per trovare l'`aws_account_id`, accedi alla Console di gestione AWS. Scegli il tuo nome utente in alto a destra e copia il tuo ID account.

   1. `us-east-1`

      Sostituisci la regione se necessario.

1. Registra il file di definizione del processo: `aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region us-east-1` 

1. Apri la console alla [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2).

1. Nel pannello di navigazione, scegli **Task Definitions** (Definizioni dei processi) quindi scegli la famiglia `firelens-example-multiline`, perché sopra abbiamo registrato la definizione dell'attività processo in questa famiglia nella prima riga della definizione del processo.

1. Scegli la versione più recente. 

1. Scegli **Distribuisci**, **Esegui attività**. 

1. Nella pagina **Esegui attività**, in **Cluster** scegli il cluster, quindi in **Reti** scegli le sottoreti disponibili per tale attività in **Sottoreti**. 

1. Scegli **Create** (Crea). 

**Verifica che i messaggi di log multilinea in Amazon CloudWatch appaiano concatenati**

1. Apri la console all'indirizzo. CloudWatch [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)

1. Nel pannello di navigazione, espandi **Logs** (Log) e scegli **Log groups** (Gruppi di log). 

1. Scegli il gruppo di log `multiline-test/applicatio`. 

1. Scegli il log e visualizza i messaggi. Le righe che corrispondono alle regole nel file parser vengono concatenate e appaiono come un singolo messaggio. 

   Il seguente snippet di log mostra una traccia dello stack Go concatenata in un singolo evento: 

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

   Il seguente snippet di log mostra come viene visualizzato lo stesso evento se si esegue un container ECS non configurato per concatenare messaggi di log multilinea. Il campo di log contiene una singola riga.

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

**Nota**  
Se i tuoi log passano ai file di log anziché all'output standard, ti consigliamo di specificare i parametri di configurazione `multiline.parser` e `multiline.key_content` nel [plug-in Tail input](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-support) anziché nel filtro.