Я запускаю одноразовую задачу 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