Задача AWS Fargate - драйвер awslogs - Прерывистые журналы - PullRequest
0 голосов
/ 08 января 2019

Я запускаю одноразовую задачу Fargate, которая запускает небольшой скрипт на python. Определение задачи настроено на использование awslogs для отправки журналов в Cloudwatch, но я сталкиваюсь с очень странной периодически возникающей проблемой.

Журналы иногда появляются во вновь созданном потоке Cloudwatch, а иногда нет. Я попытался удалить части моего кода, и сейчас вот что у меня есть.

Когда я удаляю логику выборки asyncio / aiohttp, операторы печати обычно отображаются в журналах Cloudwatch. Хотя проблема носит временный характер, я не могу быть на 100% уверен, что это всегда будет происходить.

Однако, с включенной логикой выборки, я иногда получаю потоки журналов, которые полностью пусты после выхода из задачи Fargate. Нет журналов с надписью «Начало работы», «Окончание работы» или «Помещение файла в S3». Нет журналов ошибок. Несмотря на это, когда я проверяю корзину S3, файл с соответствующей меткой времени был создан, указывая, что скрипт действительно выполнялся. Я не могу понять, как это возможно.

dostuff.py

#!/usr/bin/env python3.6

import asyncio
import datetime
import time

from aiohttp import ClientSession
import boto3


def s3_put(bucket, key, body):
    try:
        print(f"Putting file into {bucket}/{key}")
        client = boto3.client("s3")
        client.put_object(Bucket=bucket,Key=key,Body=body)
    except Exception:
        print(f"Error putting object into S3 Bucket: {bucket}/{key}")
        raise


async def fetch(session, number):
    url = f'https://jsonplaceholder.typicode.com/todos/{number}'
    try:
        async with session.get(url) as response:
            return await response.json()
    except Exception as e:
        print(f"Failed to fetch {url}")
        print(e)
        return None


async def fetch_all():
    tasks = []
    async with ClientSession() as session:
        for x in range(1, 6):
            for number in range(1, 200):
                task = asyncio.ensure_future(fetch(session=session,number=number))
                tasks.append(task)
        responses = await asyncio.gather(*tasks)
    return responses


def main():
    try:
        loop = asyncio.get_event_loop()
        future = asyncio.ensure_future(fetch_all())
        responses = list(filter(None, loop.run_until_complete(future)))
    except Exception:
        print("uh oh")
        raise

    # do stuff with responses

    body = "whatever"
    key = f"{datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d_%H-%M-%S')}_test"
    s3_put(bucket="my-s3-bucket", key=key, body=body)


if __name__ == "__main__":
    print("Job starting")
    main()
    print("Job complete")

Dockerfile

FROM python:3.6-alpine
COPY docker/test_fargate_logging/requirements.txt /
COPY docker/test_fargate_logging/dostuff.py /
WORKDIR /
RUN pip install --upgrade pip && \
    pip install -r requirements.txt
ENTRYPOINT python dostuff.py

Определение задачи

{
    "ipcMode": null,
    "executionRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/ecsInstanceRole",
    "containerDefinitions": [
        {
            "dnsSearchDomains": null,
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "test-fargate-logging-stg-log-group",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "ecs"
                }
            },
            "entryPoint": null,
            "portMappings": [],
            "command": null,
            "linuxParameters": null,
            "cpu": 256,
            "environment": [],
            "ulimits": null,
            "dnsServers": null,
            "mountPoints": [],
            "workingDirectory": null,
            "secrets": null,
            "dockerSecurityOptions": null,
            "memory": 512,
            "memoryReservation": null,
            "volumesFrom": [],
            "image": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/test-fargate-logging-stg-ecr-repository:xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "disableNetworking": null,
            "interactive": null,
            "healthCheck": null,
            "essential": true,
            "links": null,
            "hostname": null,
            "extraHosts": null,
            "pseudoTerminal": null,
            "user": null,
            "readonlyRootFilesystem": null,
            "dockerLabels": null,
            "systemControls": null,
            "privileged": null,
            "name": "test_fargate_logging"
        }
    ],
    "placementConstraints": [],
    "memory": "512",
    "taskRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/ecsInstanceRole",
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/test-fargate-logging-stg-task-definition:2",
    "family": "test-fargate-logging-stg-task-definition",
    "requiresAttributes": [
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "ecs.capability.task-eni"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "targetId": null,
            "targetType": null,
            "value": null,
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        }
    ],
    "pidMode": null,
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "networkMode": "awsvpc",
    "cpu": "256",
    "revision": 2,
    "status": "ACTIVE",
    "volumes": []
}

Наблюдения

  • Когда я уменьшаю количество заданий (URL для извлечения) до 10 вместо ~ 1000, журналы, кажется, появляются чаще всего / все (?) Времени. Опять проблема временная, поэтому я не могу быть уверен на 100%.
  • Мой оригинальный скрипт имел дополнительную логику для повторной выборки при сбоях и логику синтаксического анализа, которую я удалил при устранении неполадок. В поведении журналирования тогда, по крайней мере, были журналы «Запуск задания» и журналы во время асинхронных запросов aiohttp. Однако журналы для записи в S3 и окончательный журнал «Задание завершено» появлялись периодически. С приведенным выше упрощенным сценарием я, похоже, получаю либо все журналы, либо ни одного вообще.
  • Проблема происходила и с библиотекой logging в python, которую я изменил на print, чтобы исключить проблемы с logging

1 Ответ

0 голосов
/ 14 февраля 2019

Проблема

У меня были те же проблемы; периодически теряю логи задач ECS Fargate в CloudWatch.

Хотя я не могу ответить, почему это происходит, я могу предложить обходной путь, который я только что опробовал.

Что сработало для меня:

Обновление до версии Python 3.7 (я вижу, вы используете 3.6. Как и я, когда возникали те же проблемы).

Теперь я вижу все свои журналы и пользуюсь последней версией Python.

Надеюсь, это поможет вам, как и мне.

...