Concatenar mensagens de log de várias linhas ou de rastreamento de pilha do Amazon ECS - Amazon Elastic Container Service

Concatenar mensagens de log de várias linhas ou de rastreamento de pilha do Amazon ECS

Começando com AWS para o Fluent Bit versão 2.22.0, um filtro de várias linhas está incluído. O filtro de várias linhas ajuda a concatenar mensagens de log que pertencem originalmente a um contexto, mas foram divididas em vários registros ou linhas de log. Para obter mais informações sobre o filtro multilinha, consulte a documentação do Fluent Bit.

Exemplos comuns de mensagens de log dividido incluem:

  • Rastreamentos de pilhas.

  • Aplicações que imprimem logs em várias linhas.

  • Mensagens de log que foram divididas porque eram maiores que o tamanho máximo do buffer do runtime especificado. É possível concatenar mensagens de log divididas pelo runtime do contêiner seguindo o exemplo no GitHub: Exemplo do FireLens: Concatenar logs de contêiners parciais/divididos.

Permissões obrigatórias do IAM

Você deve primeiro ter as permissões do IAM necessárias para que o agente de contêiner extraia as imagens de contêiner do Amazon ECR e para que o contêiner encaminhe logs ao CloudWatch Logs.

Para essas permissões, você precisa ter as seguintes funções:

  • Uma função do IAM de tarefa.

  • Um perfil do IAM de execução de tarefa.

Para usar o editor de políticas JSON para criar uma política
  1. Faça login no AWS Management Console e abra o console do IAM em https://console.aws.amazon.com/iam/.

  2. No painel de navegação à esquerda, escolha Policies (Políticas).

    Se essa for a primeira vez que você escolhe Políticas, a página Bem-vindo às políticas gerenciadas será exibida. Escolha Começar.

  3. Na parte superior da página, escolha Criar política.

  4. Na seção Editor de políticas, escolha a opção JSON.

  5. Insira o seguinte documento de política JSON:

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents" ], "Resource": "*" }] }
  6. Escolha Próximo.

    nota

    É possível alternar entre as opções de editor Visual e JSON a qualquer momento. Porém, se você fizer alterações ou escolher Próximo no editor Visual, o IAM poderá reestruturar a política a fim de otimizá-la para o editor visual. Para obter mais informações, consulte Restruturação de política no Guia do usuário do IAM.

  7. Na página Revisar e criar, insira um Nome de política e uma Descrição (opcional) para a política que você está criando. Revise Permissões definidas nessa política para ver as permissões que são concedidas pela política.

  8. Escolha Criar política para salvar sua nova política.

Determinar quando usar configuração de logs multilinha

Veja a seguir um exemplo de trechos de log exibidos no console do CloudWatch Logs com a configuração de log padrão. É possível ver a linha que começa com log para determinar se precisa do filtro multilinha. Quando o contexto é o mesmo, você pode usar a configuração de log de várias linhas. Neste exemplo, o contexto é "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" }

Depois de usar a configuração de log multilinha, a saída será semelhante ao exemplo abaixo.

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

Opções de análise e concatenação

Para analisar logs e concatenar linhas divididas devido a novas linhas, use qualquer uma destas duas opções.

  • Use seu próprio arquivo do analisador que contém as regras para analisar e concatenar linhas que pertencem à mesma mensagem.

  • Usar um analisador integrado do Fluent Bit. Para obter uma lista de idiomas compatíveis com os analisadores integrados Fluent Bit, consulte a documentação do Fluent Bit.

O tutorial a seguir orientará você sobre as etapas de cada caso de uso. As etapas mostram como concatenar várias linhas e enviar os logs para o Amazon CloudWatch. É possível especificar um destino diferente para os logs.

Exemplo: use um analisador criado por você

Neste exemplo, você concluirá as seguintes etapas:

  1. Criar e carregar a imagem para um contêiner Fluent Bit.

  2. Criar e carregar a imagem para uma aplicação de várias linhas de demonstração que executa, falha e gera um rastreamento de pilha de várias linhas.

  3. Criar a definição de tarefa e executar a tarefa.

  4. Exibir os logs para verificar se as mensagens que abrangem várias linhas aparecem concatenadas.

Criar e carregar a imagem para um contêiner Fluent Bit

Essa imagem incluirá o arquivo do analisador no qual você especifica a expressão regular e um arquivo de configuração que faz referência ao arquivo do analisador.

  1. Criar uma pasta com o nome FluentBitDockerImage.

  2. Na pasta, crie um arquivo do analisador que contém as regras para analisar o log e concatenar linhas que pertencem à mesma mensagem.

    1. Cole o seguinte conteúdo no arquivo do analisador:

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

      À medida que você personaliza seu padrão de regex, recomendamos que você use um editor de expressões regulares para testar a expressão.

    2. Salve o arquivo como parsers_multiline.conf.

  3. Dentro da pasta FluentBitDockerImage, crie um arquivo de configuração personalizado que faça referência ao arquivo do analisador que você criou na etapa anterior.

    Para obter mais informações sobre o arquivo de configuração personalizado, consulte Especificar um arquivo de configuração personalizado no Guia do desenvolvedor do Amazon Elastic Container Service

    1. Cole o seguinte conteúdo no arquivo:

      [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

      Você deve usar o caminho absoluto do analisador.

    2. Salve o arquivo como extra.conf.

  4. Dentro da pasta FluentBitDockerImage, crie o Dockerfile com a imagem Fluent Bit e os arquivos do analisador e de configuração que você criou.

    1. Cole o seguinte conteúdo no arquivo:

      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest ADD parsers_multiline.conf /parsers_multiline.conf ADD extra.conf /extra.conf
    2. Salve o arquivo como Dockerfile.

  5. Usando o Dockerfile, crie uma imagem Fluent Bit personalizada com os arquivos de configuração personalizados e do analisador incluídos.

    nota

    É possível colocar o arquivo do analisador e o arquivo de configuração em qualquer lugar da imagem do Docker, exceto em /fluent-bit/etc/fluent-bit.conf, pois esse caminho de arquivo é usado pelo FireLens.

    1. Crie a imagem: docker build -t fluent-bit-multiline-image .

      Onde: fluent-bit-multiline-image é o nome da imagem neste exemplo.

    2. Verifique se a imagem foi criada corretamente: docker images —filter reference=fluent-bit-multiline-image

      Se tiver êxito, a saída mostrará a imagem e a etiqueta latest.

  6. Carregue a imagem personalizada do Fluent Bit no Amazon Elastic Container Registry.

    1. Crie um repositório do Amazon ECR para armazenar a imagem: aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1

      Onde: fluent-bit-multiline-repo é o nome do repositório e us-east-1 é a região neste exemplo.

      A saída fornece os detalhes do novo repositório.

    2. Marque sua imagem com o valor repositoryUri da saída anterior: docker tag fluent-bit-multiline-image repositoryUri

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

    3. Execute a imagem do Docker para verificar se ela é executada corretamente: docker images —filter reference=repositoryUri

      Na saída, o nome do repositório muda de fluent-bit-multiline-repo para o repositoryUri.

    4. Autentique-se no Amazon ECR executando o comando aws ecr get-login-password e especificando o ID de registro para o qual deseja fazer a autenticação: aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com

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

      Uma mensagem de login com êxito é exibida.

    5. Envie a imagem para o Amazon ECR: docker push registry ID.dkr.ecr.region.amazonaws.com/repository name

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

Crie e carregue a imagem para uma aplicação de várias linhas de demonstração

Essa imagem incluirá um arquivo de script Python que executa a aplicação e um arquivo de log de amostra.

Quando você executa a tarefa, a aplicação simula execuções, depois falha e cria um rastreamento de pilha.

  1. Crie uma pasta denominada multiline-app: mkdir multiline-app

  2. Crie um arquivo de script do Python.

    1. Na pasta multiline-app, crie um arquivo de texto e denomine-o main.py.

    2. Cole o seguinte conteúdo no arquivo:

      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.")
    3. Salve o arquivo main.py.

  3. Crie um arquivo de log de exemplo.

    1. Na pasta multiline-app, crie um arquivo de texto e denomine-o test.log.

    2. Cole o seguinte conteúdo no arquivo:

      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...
    3. Salve o arquivo test.log.

  4. Dentro da pasta multiline-app, crie o Dockerfile.

    1. Cole o seguinte conteúdo no arquivo:

      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"]
    2. Salve o arquivo Dockerfile.

  5. Usando o Dockerfile, crie uma imagem.

    1. Crie a imagem: docker build -t multiline-app-image .

      Onde: multiline-app-image é o nome da imagem neste exemplo.

    2. Verifique se a imagem foi criada corretamente: docker images —filter reference=multiline-app-image

      Se tiver êxito, a saída mostrará a imagem e a etiqueta latest.

  6. Carregue a imagem no Amazon Elastic Container Registry.

    1. Crie um repositório do Amazon ECR para armazenar a imagem: aws ecr create-repository --repository-name multiline-app-repo --region us-east-1

      Onde: multiline-app-repo é o nome do repositório e us-east-1 é a região neste exemplo.

      A saída fornece os detalhes do novo repositório. Anote o valor do repositoryUri, pois ele será necessário na próxima etapa.

    2. Marque sua imagem com o valor repositoryUri da saída anterior: docker tag multiline-app-image repositoryUri

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

    3. Execute a imagem do Docker para verificar se ela é executada corretamente: docker images —filter reference=repositoryUri

      Na saída, o nome do repositório muda de multiline-app-repo para o valor repositoryUri.

    4. Envie a imagem para o Amazon ECR: docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name

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

Crie a definição da tarefa e execute a tarefa
  1. Crie um arquivo de definição de tarefa com o nome de arquivo multiline-task-definition.json.

  2. Cole o seguinte conteúdo no arquivo 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" }

    Substitua o seguinte na definição de tarefa multiline-task-definition.json:

    1. task role ARN

      Para encontrar o ARN da função de tarefa, acesse o console do IAM. Escolha Roles (Funções) e encontre a função de tarefa ecs-task-role-for-firelens que você criou. Escolha a função e copie o ARN que consta na seção Summary (Resumo).

    2. execution role ARN

      Para encontrar o ARN da função de execução, acesse o console do IAM. Selecione Roles (Funções) e localize a função ecsTaskExecutionRole. Escolha a função e copie o ARN que consta na seção Summary (Resumo).

    3. aws_account_id

      Para encontrar seu aws_account_id, faça login no AWS Management Console. Escolha seu nome de usuário no canto superior direito e copie o ID da conta.

    4. us-east-1

      Substitua a região, se necessário.

  3. Registre o arquivo de definição de tarefa: aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region region

  4. Abra o console em https://console.aws.amazon.com/ecs/v2.

  5. No painel de navegação, selecione Task Definitions (Definições de tarefa) e, em seguida, escolha a família firelens-example-multiline, pois registramos a definição de tarefa para essa família na primeira linha da definição de tarefa acima.

  6. Escolha a versão mais recente.

  7. Escolha Implantar, Executar tarefa.

  8. Na página Executar tarefa, para Cluster, escolha o cluster e, em seguida, em Rede, para Sub-redes, escolha as sub-redes disponíveis para sua tarefa.

  9. Escolha Criar.

Verifique se as mensagens de log de várias linhas no Amazon CloudWatch parecem concatenadas
  1. Abra o console do CloudWatch em https://console.aws.amazon.com/cloudwatch/.

  2. No painel de navegação, expanda Logs e escolha Log groups (Grupos de log).

  3. Escolha o grupo de logs multiline-test/applicatio.

  4. Escolha o log. Vejas as mensagens. As linhas que correspondem às regras no arquivo do analisador são concatenadas e aparecem como uma única mensagem.

    O trecho de log a seguir mostra linhas concatenadas em um único evento de rastreamento de pilha 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" }

    O trecho de log a seguir mostra como a mesma mensagem é exibida com apenas uma única linha se você executar um contêiner do Amazon ECS que não esteja configurado para concatenar mensagens de log multinha.

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

Exemplo: use um analisador integrado Fluent Bit

Neste exemplo, você concluirá as seguintes etapas:

  1. Criar e carregar a imagem para um contêiner Fluent Bit.

  2. Criar e carregar a imagem para uma aplicação de várias linhas de demonstração que executa, falha e gera um rastreamento de pilha de várias linhas.

  3. Criar a definição de tarefa e executar a tarefa.

  4. Exibir os logs para verificar se as mensagens que abrangem várias linhas aparecem concatenadas.

Criar e carregar a imagem para um contêiner Fluent Bit

Essa imagem incluirá um arquivo de configuração que faz referência ao analisador Fluent Bit.

  1. Criar uma pasta com o nome FluentBitDockerImage.

  2. Dentro da pasta FluentBitDockerImage, crie um arquivo de configuração personalizado que faça referência ao arquivo do analisador integrado Fluent Bit.

    Para obter mais informações sobre o arquivo de configuração personalizado, consulte Especificar um arquivo de configuração personalizado no Guia do desenvolvedor do Amazon Elastic Container Service

    1. Cole o seguinte conteúdo no arquivo:

      [FILTER] name multiline match * multiline.key_content log multiline.parser go
    2. Salve o arquivo como extra.conf.

  3. Dentro da pasta FluentBitDockerImage, crie o Dockerfile com a imagem Fluent Bit e os arquivos do analisador e de configuração que você criou.

    1. Cole o seguinte conteúdo no arquivo:

      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest ADD extra.conf /extra.conf
    2. Salve o arquivo como Dockerfile.

  4. Usando o Dockerfile, crie uma imagem Fluent Bit personalizada com o arquivo de configuração personalizado incluído.

    nota

    É possível colocar o arquivo de configuração em qualquer lugar da imagem do Docker, exceto em /fluent-bit/etc/fluent-bit.conf, pois esse caminho de arquivo é usado pelo FireLens.

    1. Crie a imagem: docker build -t fluent-bit-multiline-image .

      Onde: fluent-bit-multiline-image é o nome da imagem neste exemplo.

    2. Verifique se a imagem foi criada corretamente: docker images —filter reference=fluent-bit-multiline-image

      Se tiver êxito, a saída mostrará a imagem e a etiqueta latest.

  5. Carregue a imagem personalizada do Fluent Bit no Amazon Elastic Container Registry.

    1. Crie um repositório do Amazon ECR para armazenar a imagem: aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1

      Onde: fluent-bit-multiline-repo é o nome do repositório e us-east-1 é a região neste exemplo.

      A saída fornece os detalhes do novo repositório.

    2. Marque sua imagem com o valor repositoryUri da saída anterior: docker tag fluent-bit-multiline-image repositoryUri

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

    3. Execute a imagem do Docker para verificar se ela é executada corretamente: docker images —filter reference=repositoryUri

      Na saída, o nome do repositório muda de fluent-bit-multiline-repo para o repositoryUri.

    4. Autentique-se no Amazon ECR executando o comando aws ecr get-login-password e especificando o ID de registro para o qual deseja fazer a autenticação: aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com

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

      Uma mensagem de login com êxito é exibida.

    5. Envie a imagem para o Amazon ECR: docker push registry ID.dkr.ecr.region.amazonaws.com/repository name

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

Crie e carregue a imagem para uma aplicação de várias linhas de demonstração

Essa imagem incluirá um arquivo de script Python que executa a aplicação e um arquivo de log de amostra.

  1. Crie uma pasta denominada multiline-app: mkdir multiline-app

  2. Crie um arquivo de script do Python.

    1. Na pasta multiline-app, crie um arquivo de texto e denomine-o main.py.

    2. Cole o seguinte conteúdo no arquivo:

      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.")
    3. Salve o arquivo main.py.

  3. Crie um arquivo de log de exemplo.

    1. Na pasta multiline-app, crie um arquivo de texto e denomine-o test.log.

    2. Cole o seguinte conteúdo no arquivo:

      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
    3. Salve o arquivo test.log.

  4. Dentro da pasta multiline-app, crie o Dockerfile.

    1. Cole o seguinte conteúdo no arquivo:

      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"]
    2. Salve o arquivo Dockerfile.

  5. Usando o Dockerfile, crie uma imagem.

    1. Crie a imagem: docker build -t multiline-app-image .

      Onde: multiline-app-image é o nome da imagem neste exemplo.

    2. Verifique se a imagem foi criada corretamente: docker images —filter reference=multiline-app-image

      Se tiver êxito, a saída mostrará a imagem e a etiqueta latest.

  6. Carregue a imagem no Amazon Elastic Container Registry.

    1. Crie um repositório do Amazon ECR para armazenar a imagem: aws ecr create-repository --repository-name multiline-app-repo --region us-east-1

      Onde: multiline-app-repo é o nome do repositório e us-east-1 é a região neste exemplo.

      A saída fornece os detalhes do novo repositório. Anote o valor do repositoryUri, pois ele será necessário na próxima etapa.

    2. Marque sua imagem com o valor repositoryUri da saída anterior: docker tag multiline-app-image repositoryUri

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

    3. Execute a imagem do Docker para verificar se ela é executada corretamente: docker images —filter reference=repositoryUri

      Na saída, o nome do repositório muda de multiline-app-repo para o valor repositoryUri.

    4. Envie a imagem para o Amazon ECR: docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name

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

Crie a definição da tarefa e execute a tarefa
  1. Crie um arquivo de definição de tarefa com o nome de arquivo multiline-task-definition.json.

  2. Cole o seguinte conteúdo no arquivo 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" }

    Substitua o seguinte na definição de tarefa multiline-task-definition.json:

    1. task role ARN

      Para encontrar o ARN da função de tarefa, acesse o console do IAM. Escolha Roles (Funções) e encontre a função de tarefa ecs-task-role-for-firelens que você criou. Escolha a função e copie o ARN que consta na seção Summary (Resumo).

    2. execution role ARN

      Para encontrar o ARN da função de execução, acesse o console do IAM. Selecione Roles (Funções) e localize a função ecsTaskExecutionRole. Escolha a função e copie o ARN que consta na seção Summary (Resumo).

    3. aws_account_id

      Para encontrar seu aws_account_id, faça login no AWS Management Console. Escolha seu nome de usuário no canto superior direito e copie o ID da conta.

    4. us-east-1

      Substitua a região, se necessário.

  3. Registre o arquivo de definição de tarefa: aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region us-east-1

  4. Abra o console em https://console.aws.amazon.com/ecs/v2.

  5. No painel de navegação, selecione Task Definitions (Definições de tarefa) e, em seguida, escolha a família firelens-example-multiline, pois registramos a definição de tarefa para essa família na primeira linha da definição de tarefa acima.

  6. Escolha a versão mais recente.

  7. Escolha Implantar, Executar tarefa.

  8. Na página Executar tarefa, para Cluster, escolha o cluster e, em seguida, em Rede, para Sub-redes, escolha as sub-redes disponíveis para sua tarefa.

  9. Escolha Criar.

Verifique se as mensagens de log de várias linhas no Amazon CloudWatch parecem concatenadas
  1. Abra o console do CloudWatch em https://console.aws.amazon.com/cloudwatch/.

  2. No painel de navegação, expanda Logs e escolha Log groups (Grupos de log).

  3. Escolha o grupo de logs multiline-test/applicatio.

  4. Escolha o log e veja as mensagens. As linhas que correspondem às regras no arquivo do analisador são concatenadas e aparecem como uma única mensagem.

    O trecho de log a seguir mostra um rastreamento de pilha Go concatenado em um único 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" }

    O trecho de log a seguir mostra como o mesmo evento aparece se você executar um contêiner ECS que não esteja configurado para concatenar mensagens de log de várias linhas. O campo de log contém uma única linha.

    { "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 seus registros forem para arquivos de log em vez da saída padrão, recomendamos especificar os parâmetros de configuração multiline.parser e multiline.key_content no Plug-in de entrada final em vez do Filtro.