여러 줄 또는 스택 추적 Amazon ECS 로그 메시지 연결 - Amazon Elastic Container Service

여러 줄 또는 스택 추적 Amazon ECS 로그 메시지 연결

AWS for Fluent Bit 버전 2.22.0부터 여러 줄 필터가 포함됩니다. 여러 줄 필터를 사용하면 원래 하나의 컨텍스트에 속하지만 여러 레코드 또는 로그 라인으로 분할된 로그 메시지를 연결할 수 있습니다. 여러 줄 필터에 대한 자세한 내용은 Fluent Bit 문서를 참조하세요.

분할 로그 메시지의 일반적인 예는 다음과 같습니다.

  • 스택 추적.

  • 여러 줄에 로그를 인쇄하는 애플리케이션.

  • 지정된 런타임 최대 버퍼 크기보다 길기 때문에 분할된 메시지를 로그합니다. GitHub의 예제를 따라 컨테이너 런타임으로 분할된 로그 메시지를 연결할 수 있습니다. FireLens 예제: 부분/분할 컨테이너 로그 연결.

필수 IAM 권한

컨테이너 에이전트가 Amazon ECR에서 컨테이너 이미지를 가져오고 컨테이너가 로그를 CloudWatch Logs로 라우팅하는 데 필요한 IAM 권한이 있는지 확인해야 합니다.

이러한 권한의 경우 다음 역할이 있어야 합니다.

  • 태스크 IAM 역할.

  • 작업 실행 IAM 역할.

JSON 정책 편집기를 사용하여 정책을 생성하려면
  1. AWS Management Console에 로그인하여 https://console.aws.amazon.com/iam/ 에서 IAM 콘솔을 엽니다.

  2. 왼쪽의 탐색 창에서 정책을 선택합니다.

    정책을 처음으로 선택하는 경우 관리형 정책 소개 페이지가 나타납니다. 시작하기를 선택합니다.

  3. 페이지 상단에서 정책 생성을 선택합니다.

  4. 정책 편집기 섹션에서 JSON 옵션을 선택합니다.

  5. 다음 JSON 정책 문서를 입력합니다.

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents" ], "Resource": "*" }] }
  6. Next(다음)를 선택합니다.

    참고

    언제든지 시각적 편집기 옵션과 JSON 편집기 옵션 간에 전환할 수 있습니다. 그러나 변경을 적용하거나 시각적 편집기에서 다음을 선택한 경우 IAM은 시각적 편집기에 최적화되도록 정책을 재구성할 수 있습니다. 자세한 내용은 IAM 사용 설명서정책 재구성을 참조하십시오.

  7. 검토 및 생성 페이지에서 생성하는 정책에 대한 정책 이름설명(선택 사항)을 입력합니다. 이 정책에 정의된 권한을 검토하여 정책이 부여한 권한을 확인합니다.

  8. 정책 생성을 선택하고 새로운 정책을 저장합니다.

여러 줄 로그 설정을 사용할 시기 지정

기본 로그 설정과 함께 CloudWatch Logs 콘솔에 표시되는 예제 로그 코드 조각은 다음과 같습니다. log로 시작하는 줄을 보고 여러 줄의 필터가 필요한지 결정할 수 있습니다. 컨텍스트가 동일한 경우, 여러 줄 로그 설정을 사용할 수 있습니다. 이 예제에서는 컨텍스트가 '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" }

여러 줄 로그 설정을 사용한 이후에는 아래의 예시와 유사한 출력이 나옵니다.

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

구문 분석 및 연결 옵션

줄 바꿈으로 인해 로그를 구문 분석하고 분할된 줄을 연결하려면, 다음 두 옵션 중 하나를 사용할 수 있습니다.

  • 동일한 메시지에 속하는 줄을 구문 분석하고 연결하는 규칙이 포함된 고유한 구문 분석기 파일을 사용합니다.

  • Fluent Bit 기본 제공 구문 분석을 사용합니다. Fluent Bit 기본 제공 구문 분석에서 지원하는 언어 목록은 Fluent Bit 설명서를 참조하세요.

다음 자습서에서는 각 사용 사례에 대한 단계를 안내합니다. 이 단계에서는 여러 줄을 연결하고 Amazon CloudWatch로 로그를 전송하는 방법을 보여줍니다. 로그에 대해 다른 대상을 지정할 수 있습니다.

예: 생성한 구문 분석기 사용

이 예에서는 다음 단계를 완료합니다.

  1. Fluent Bit 컨테이너용 이미지를 빌드하고 업로드합니다.

  2. 여러 줄 스택 추적을 실행, 실패 및 생성하는 데모 여러 줄 애플리케이션에 대한 이미지를 빌드하고 업로드합니다.

  3. 태스크 정의를 생성하고 태스크를 실행합니다.

  4. 로그를 보고 여러 줄에 걸쳐 있는 메시지가 연결된 것처럼 보이는지 확인합니다.

Fluent Bit 컨테이너용 이미지 빌드 및 업로드

이 이미지에는 정규식을 지정하는 구문 분석기 파일과 구문 분석기 파일을 참조하는 구성 파일이 포함됩니다.

  1. FluentBitDockerImage라는 폴더를 생성합니다.

  2. 폴더 내에 동일한 메시지에 속하는 줄을 구문 분석하고 연결하는 규칙이 포함된 구문 분석기 파일을 생성합니다.

    1. 구문 분석기 파일에 다음 내용을 붙여넣습니다.

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

      정규식 패턴을 사용자 지정할 때 정규식 편집기를 사용하여 표현식을 테스트하는 것이 좋습니다.

    2. 파일을 parsers_multiline.conf(으)로 저장합니다.

  3. FluentBitDockerImage 폴더 내에 이전 단계에서 생성한 구문 분석기 파일을 참조하는 사용자 정의 구성 파일을 생성합니다.

    사용자 정의 구성 파일에 대한 자세한 정보는 Amazon Elastic Container Service 개발자 안내서사용자 정의 구성 파일 지정을 참조하세요.

    1. 파일에 다음 내용을 붙여넣습니다.

      [SERVICE] flush 1 log_level info parsers_file /parsers_multiline.conf [FILTER] name multiline match * multiline.key_content log multiline.parser multiline-regex-test
      참고

      구문 분석기의 절대 경로를 사용해야 합니다.

    2. 파일을 extra.conf(으)로 저장합니다.

  4. FluentBitDockerImage 폴더 내에서 Fluent Bit 이미지와 생성한 구문 분석기 및 구성 파일로 Dockerfile을 생성합니다.

    1. 파일에 다음 내용을 붙여넣습니다.

      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest ADD parsers_multiline.conf /parsers_multiline.conf ADD extra.conf /extra.conf
    2. 파일을 Dockerfile(으)로 저장합니다.

  5. Dockerfile을 사용하여 구문 분석기 및 사용자 정의 구성 파일이 포함된 사용자 정의 Fluent Bit 이미지를 빌드합니다.

    참고

    이 파일 경로는 FireLens에서 사용하므로 /fluent-bit/etc/fluent-bit.conf를 제외한 Docker 이미지의 아무 곳에나 구문 분석기 파일과 구성 파일을 배치할 수 있습니다.

    1. 이미지를 빌드합니다. docker build -t fluent-bit-multiline-image .

      여기서 fluent-bit-multiline-image는 이 예에서 이미지의 이름입니다.

    2. 이미지가 올바르게 생성되었는지 확인합니다. docker images —filter reference=fluent-bit-multiline-image

      성공하면 출력에 이미지와 latest 태그가 표시됩니다.

  6. Amazon Elastic Container Registry에 사용자 정의 Fluent Bit 이미지를 업로드합니다.

    1. 이미지를 저장할 Amazon ECR 리포지토리를 생성합니다. aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1

      여기서 fluent-bit-multiline-repo는 리포지토리의 이름이고 us-east-1은 이 예에서 리전입니다.

      출력은 새 리포지토리의 세부 정보를 제공합니다.

    2. 이전 출력의 repositoryUri 값으로 이미지에 태깅합니다. docker tag fluent-bit-multiline-image repositoryUri

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

    3. Docker 이미지를 실행하여 올바르게 실행되었는지 확인합니다. docker images —filter reference=repositoryUri

      출력에서 리포지토리 이름이 fluent-bit-multiline-repo에서 repositoryUri로 변경됩니다.

    4. aws ecr get-login-password 명령을 실행하고 인증하려는 레지스트리 ID를 지정하여 Amazon ECR에 인증합니다. aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com

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

      로그인 성공 메시지가 나타납니다.

    5. 이미지를 Amazon ECR에 푸시합니다. docker push registry ID.dkr.ecr.region.amazonaws.com/repository name

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

데모 여러 줄 애플리케이션용 이미지 빌드 및 업로드

이 이미지에는 애플리케이션을 실행하는 Python 스크립트 파일과 샘플 로그 파일이 포함됩니다.

태스크를 실행하면 애플리케이션이 실행을 시뮬레이션한 다음 실패하고 스택 추적을 생성합니다.

  1. multiline-app이라는 폴더를 생성합니다. mkdir multiline-app

  2. Python 스크립트 파일을 생성합니다.

    1. multiline-app 폴더 내에 파일을 생성하고 이름을 main.py로 지정합니다.

    2. 파일에 다음 내용을 붙여넣습니다.

      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. main.py 파일을 저장합니다.

  3. 샘플 로그 파일을 생성합니다.

    1. multiline-app 폴더 내에 파일을 생성하고 이름을 test.log로 지정합니다.

    2. 파일에 다음 내용을 붙여넣습니다.

      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. test.log 파일을 저장합니다.

  4. multiline-app 폴더 내에 Dockerfile을 생성합니다.

    1. 파일에 다음 내용을 붙여넣습니다.

      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. Dockerfile 파일을 저장합니다.

  5. Dockerfile을 사용하여 이미지를 빌드합니다.

    1. 이미지를 빌드합니다. docker build -t multiline-app-image .

      여기서 multiline-app-image는 이 예에서 이미지의 이름입니다.

    2. 이미지가 올바르게 생성되었는지 확인합니다. docker images —filter reference=multiline-app-image

      성공하면 출력에 이미지와 latest 태그가 표시됩니다.

  6. Amazon Elastic 컨테이너 레지스트리로 이미지를 업로드합니다.

    1. 이미지를 저장할 Amazon ECR 리포지토리를 생성합니다. aws ecr create-repository --repository-name multiline-app-repo --region us-east-1

      여기서 multiline-app-repo는 리포지토리의 이름이고 us-east-1은 이 예에서 리전입니다.

      출력은 새 리포지토리의 세부 정보를 제공합니다. 다음 단계에서 필요하므로 repositoryUri 값을 기록해 둡니다.

    2. 이전 출력의 repositoryUri 값으로 이미지에 태깅합니다. docker tag multiline-app-image repositoryUri

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

    3. Docker 이미지를 실행하여 올바르게 실행되었는지 확인합니다. docker images —filter reference=repositoryUri

      출력에서 리포지토리 이름이 multiline-app-repo에서 repositoryUri 값으로 변경됩니다.

    4. 이미지를 Amazon ECR에 푸시합니다. docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name

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

태스크 정의 생성 및 태스크 시작
  1. 파일 이름이 multiline-task-definition.json인 태스크 정의 파일을 생성합니다.

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

    multiline-task-definition.json 태스크 정의에서 다음을 바꿉니다.

    1. task role ARN

      태스크 역할 ARN을 찾으려면 IAM 콘솔로 이동합니다. 역할(Roles)을 선택하고 생성한 ecs-task-role-for-firelens 태스크 역할을 찾습니다. 역할을 선택하고 요약(Summary) 섹션에 표시되는 ARN을 복사합니다.

    2. execution role ARN

      실행 역할 ARN을 찾으려면 IAM 콘솔로 이동합니다. 역할(Roles)을 선택하고 ecsTaskExecutionRole 역할을 찾습니다. 역할을 선택하고 요약(Summary) 섹션에 표시되는 ARN을 복사합니다.

    3. aws_account_id

      aws_account_id를 찾으려면 AWS Management Console에 로그인합니다. 오른쪽 상단에서 사용자 이름을 선택하고 계정 ID를 복사합니다.

    4. us-east-1

      필요한 경우 리전을 바꿉니다.

  3. 태스크 정의 파일을 등록합니다. aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region region

  4. https://console.aws.amazon.com/ecs/v2에서 콘솔을 엽니다.

  5. 탐색 창에서 태스크 정의를 선택한 다음 위의 태스크 정의의 첫 번째 줄에서 이 제품군에 태스크 정의를 등록했기 때문에 firelens-example-multiline 제품군을 선택합니다.

  6. 최신 버전을 선택합니다.

  7. 배포, 작업 실행을 선택합니다.

  8. 작업 실행 페이지의 클러스터에서 클러스터를 선택한 다음 네트워킹 아래의 서브넷에서 작업에 사용할 수 있는 서브넷을 선택합니다.

  9. 생성(Create)을 선택합니다.

Amazon CloudWatch의 여러 줄 로그 메시지가 연결된 것으로 나타나는지 확인
  1. https://console.aws.amazon.com/cloudwatch/에서 CloudWatch 콘솔을 엽니다.

  2. 왼쪽 탐색 창에서 로그를 확장하고 로그 그룹을 선택합니다.

  3. multiline-test/applicatio 로그 그룹을 선택합니다.

  4. 로그를 선택합니다. 메시지를 봅니다. 구문 분석기 파일의 규칙과 일치하는 줄은 연결되어 단일 메시지로 나타납니다.

    다음 로그 조각은 단일 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" }

    다음 로그 조각은 여러 줄 로그 메시지를 연결하도록 구성되지 않은 Amazon ECS 컨테이너를 실행할 경우 한 줄로 동일한 메시지가 어떻게 나타나는지 보여줍니다.

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

예: Fluent Bit 기본 제공 구문 분석 사용

이 예에서는 다음 단계를 완료합니다.

  1. Fluent Bit 컨테이너용 이미지를 빌드하고 업로드합니다.

  2. 여러 줄 스택 추적을 실행, 실패 및 생성하는 데모 여러 줄 애플리케이션에 대한 이미지를 빌드하고 업로드합니다.

  3. 태스크 정의를 생성하고 태스크를 실행합니다.

  4. 로그를 보고 여러 줄에 걸쳐 있는 메시지가 연결된 것처럼 보이는지 확인합니다.

Fluent Bit 컨테이너용 이미지 빌드 및 업로드

이 이미지에는 Fluent Bit 구문 분석기를 참조하는 구성 파일이 포함됩니다.

  1. FluentBitDockerImage라는 폴더를 생성합니다.

  2. FluentBitDockerImage 폴더 내에 Fluent Bit 기본 제공 구문 분석기 파일을 참조하는 사용자 정의 구성 파일을 생성합니다.

    사용자 정의 구성 파일에 대한 자세한 정보는 Amazon Elastic Container Service 개발자 안내서사용자 정의 구성 파일 지정을 참조하세요.

    1. 파일에 다음 내용을 붙여넣습니다.

      [FILTER] name multiline match * multiline.key_content log multiline.parser go
    2. 파일을 extra.conf(으)로 저장합니다.

  3. FluentBitDockerImage 폴더 내에서 Fluent Bit 이미지와 생성한 구문 분석기 및 구성 파일로 Dockerfile을 생성합니다.

    1. 파일에 다음 내용을 붙여넣습니다.

      FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:latest ADD extra.conf /extra.conf
    2. 파일을 Dockerfile(으)로 저장합니다.

  4. Dockerfile을 사용하여 사용자 정의 구성 파일이 포함된 사용자 정의 Fluent Bit 이미지를 빌드합니다.

    참고

    이 파일 경로는 FireLens에서 사용하므로 /fluent-bit/etc/fluent-bit.conf를 제외한 Docker 이미지의 아무 곳에나 구성 파일을 배치할 수 있습니다.

    1. 이미지를 빌드합니다. docker build -t fluent-bit-multiline-image .

      여기서 fluent-bit-multiline-image는 이 예에서 이미지의 이름입니다.

    2. 이미지가 올바르게 생성되었는지 확인합니다. docker images —filter reference=fluent-bit-multiline-image

      성공하면 출력에 이미지와 latest 태그가 표시됩니다.

  5. Amazon Elastic Container Registry에 사용자 정의 Fluent Bit 이미지를 업로드합니다.

    1. 이미지를 저장할 Amazon ECR 리포지토리를 생성합니다. aws ecr create-repository --repository-name fluent-bit-multiline-repo --region us-east-1

      여기서 fluent-bit-multiline-repo는 리포지토리의 이름이고 us-east-1은 이 예에서 리전입니다.

      출력은 새 리포지토리의 세부 정보를 제공합니다.

    2. 이전 출력의 repositoryUri 값으로 이미지에 태깅합니다. docker tag fluent-bit-multiline-image repositoryUri

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

    3. Docker 이미지를 실행하여 올바르게 실행되었는지 확인합니다. docker images —filter reference=repositoryUri

      출력에서 리포지토리 이름이 fluent-bit-multiline-repo에서 repositoryUri로 변경됩니다.

    4. aws ecr get-login-password 명령을 실행하고 인증하려는 레지스트리 ID를 지정하여 Amazon ECR에 인증합니다. aws ecr get-login-password | docker login --username AWS --password-stdin registry ID.dkr.ecr.region.amazonaws.com

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

      로그인 성공 메시지가 나타납니다.

    5. 이미지를 Amazon ECR에 푸시합니다. docker push registry ID.dkr.ecr.region.amazonaws.com/repository name

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

데모 여러 줄 애플리케이션용 이미지 빌드 및 업로드

이 이미지에는 애플리케이션을 실행하는 Python 스크립트 파일과 샘플 로그 파일이 포함됩니다.

  1. multiline-app이라는 폴더를 생성합니다. mkdir multiline-app

  2. Python 스크립트 파일을 생성합니다.

    1. multiline-app 폴더 내에 파일을 생성하고 이름을 main.py로 지정합니다.

    2. 파일에 다음 내용을 붙여넣습니다.

      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. main.py 파일을 저장합니다.

  3. 샘플 로그 파일을 생성합니다.

    1. multiline-app 폴더 내에 파일을 생성하고 이름을 test.log로 지정합니다.

    2. 파일에 다음 내용을 붙여넣습니다.

      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. test.log 파일을 저장합니다.

  4. multiline-app 폴더 내에 Dockerfile을 생성합니다.

    1. 파일에 다음 내용을 붙여넣습니다.

      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. Dockerfile 파일을 저장합니다.

  5. Dockerfile을 사용하여 이미지를 빌드합니다.

    1. 이미지를 빌드합니다. docker build -t multiline-app-image .

      여기서 multiline-app-image는 이 예에서 이미지의 이름입니다.

    2. 이미지가 올바르게 생성되었는지 확인합니다. docker images —filter reference=multiline-app-image

      성공하면 출력에 이미지와 latest 태그가 표시됩니다.

  6. Amazon Elastic 컨테이너 레지스트리로 이미지를 업로드합니다.

    1. 이미지를 저장할 Amazon ECR 리포지토리를 생성합니다. aws ecr create-repository --repository-name multiline-app-repo --region us-east-1

      여기서 multiline-app-repo는 리포지토리의 이름이고 us-east-1은 이 예에서 리전입니다.

      출력은 새 리포지토리의 세부 정보를 제공합니다. 다음 단계에서 필요하므로 repositoryUri 값을 기록해 둡니다.

    2. 이전 출력의 repositoryUri 값으로 이미지에 태깅합니다. docker tag multiline-app-image repositoryUri

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

    3. Docker 이미지를 실행하여 올바르게 실행되었는지 확인합니다. docker images —filter reference=repositoryUri

      출력에서 리포지토리 이름이 multiline-app-repo에서 repositoryUri 값으로 변경됩니다.

    4. 이미지를 Amazon ECR에 푸시합니다. docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository name

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

태스크 정의 생성 및 태스크 시작
  1. 파일 이름이 multiline-task-definition.json인 태스크 정의 파일을 생성합니다.

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

    multiline-task-definition.json 태스크 정의에서 다음을 바꿉니다.

    1. task role ARN

      태스크 역할 ARN을 찾으려면 IAM 콘솔로 이동합니다. 역할(Roles)을 선택하고 생성한 ecs-task-role-for-firelens 태스크 역할을 찾습니다. 역할을 선택하고 요약(Summary) 섹션에 표시되는 ARN을 복사합니다.

    2. execution role ARN

      실행 역할 ARN을 찾으려면 IAM 콘솔로 이동합니다. 역할(Roles)을 선택하고 ecsTaskExecutionRole 역할을 찾습니다. 역할을 선택하고 요약(Summary) 섹션에 표시되는 ARN을 복사합니다.

    3. aws_account_id

      aws_account_id를 찾으려면 AWS Management Console에 로그인합니다. 오른쪽 상단에서 사용자 이름을 선택하고 계정 ID를 복사합니다.

    4. us-east-1

      필요한 경우 리전을 바꿉니다.

  3. 태스크 정의 파일을 등록합니다. aws ecs register-task-definition --cli-input-json file://multiline-task-definition.json --region us-east-1

  4. https://console.aws.amazon.com/ecs/v2에서 콘솔을 엽니다.

  5. 탐색 창에서 태스크 정의를 선택한 다음 위의 태스크 정의의 첫 번째 줄에서 이 제품군에 태스크 정의를 등록했기 때문에 firelens-example-multiline 제품군을 선택합니다.

  6. 최신 버전을 선택합니다.

  7. 배포, 작업 실행을 선택합니다.

  8. 작업 실행 페이지의 클러스터에서 클러스터를 선택한 다음 네트워킹 아래의 서브넷에서 작업에 사용할 수 있는 서브넷을 선택합니다.

  9. 생성(Create)을 선택합니다.

Amazon CloudWatch의 여러 줄 로그 메시지가 연결된 것으로 나타나는지 확인
  1. https://console.aws.amazon.com/cloudwatch/에서 CloudWatch 콘솔을 엽니다.

  2. 왼쪽 탐색 창에서 로그를 확장하고 로그 그룹을 선택합니다.

  3. multiline-test/applicatio 로그 그룹을 선택합니다.

  4. 로그를 선택하고 메시지를 봅니다. 구문 분석기 파일의 규칙과 일치하는 줄은 연결되어 단일 메시지로 나타납니다.

    다음 로그 조각은 단일 이벤트로 연결된 Go 스택 추적을 보여줍니다.

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

    다음 로그 조각은 여러 줄 로그 메시지를 연결하도록 구성되지 않은 ECS 컨테이너를 실행할 경우 동일한 이벤트가 어떻게 나타나는지 보여줍니다. 로그 필드에는 한 줄이 포함됩니다.

    { "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"
참고

로그가 표준 출력 대신 로그 파일로 이동하는 경우 필터 대신 Tail 입력 플러그 인에서 multiline.parsermultiline.key_content 구성 파라미터를 지정하는 것이 좋습니다.