Is there easy way to run an ECS Task attached or to follow the logs only while the container is Running (ie. Detach after displaying all of the logs associated)?
Using the AWS CLI (1.17.0) and ecs-cli (1.21.0), I have gotten decently close with the following two commands:
aws ecs run-task --cluster "mycluster" --task-definition testhelloworldjob --launch-type FARGATE --network-configuration etc.etc.etc.
ecs-cli logs --task-id {TASK_ID_HERE_FROM_OUTPUT_OF_PREVIOUS_COMMAND} --follow
I am currently have two issues with the above approach:
ecs-cli logs waiting for the logs to exist, there is an error immediately thrown.ecs-cli logs the command refuses to detach even AFTER the task is finished and in a Post Running status.For the first issue I could poll until there is a post activating/pending status, prior to calling logs. For the second issue I could draft some type of threaded call that would poll to stop the following of a log after the container in question is no longer running.... But there has to be an easier way?
To clarify I am coming from numerous other container orchestration tools/technologies that seemingly supported this very seamlessly. Here are some examples of tools and their associated commands that would yield me my intended results:
Docker CLI:
docker run hello-world
Docker-Compose Yaml:
docker-compose up
K8 Kubectl Yaml:
kubectl apply -f ./hello-k8.yaml && kubectl logs --follow hello-world
I don't know of an easy way, I also wanted to do this and ended up writing some bash magic to do it. It is a bit long, but I wrap it in a function that you can just call with a task ID which works for my purposes. The general idea to solve the above issues is:
aws ecs wait tasks-running to block until the log group is created--since until the task is stopped# Prints logs like 'tail -f' for an ecs task
function tail_task_logs {
local TASKID=$1
local CLUSTER
local TASK_DEFINITION
local LGROUP
CLUSTER=$(echo "$TASKID" | cut -d/ -f1,2 | sed 's/task/cluster/')
# Lookup the log group name
TASK_DEFINITION=$(aws ecs describe-tasks \
--cluster "$CLUSTER" \
--tasks "$TASKID" \
--query 'tasks[0].taskDefinitionArn' \
--output text)
LGROUP=$(aws ecs describe-task-definition \
--task-definition "$TASK_DEFINITION" \
--query 'taskDefinition.containerDefinitions[0].logConfiguration.options."awslogs-group"' \
--output text)
# Start tailing once container is running
SINCE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "Waiting for task to start.."
aws ecs wait tasks-running \
--cluster "$CLUSTER" \
--tasks "$TASKID"
STATUS="None"
while [[ $STATUS == "None" ]]; do
# print new messages
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
aws logs tail "$LGROUP" --since "$SINCE"
SINCE="$NOW"
sleep 2
# Check if container is still running
STATUS=$(aws ecs describe-tasks \
--cluster "$CLUSTER" \
--tasks "$TASKID" \
--query 'tasks[0].stopCode' \
--output text)
done
# Print final messages
aws logs tail "$LGROUP" --since "$SINCE"
echo "Container exited: $STATUS"
}
I tried to make it easy to call, so it does some work to figure the log group which you could remove if you already know it. You can call it like this
tail_task_logs "some-task-id"
You might be able to simplify using ecs-cli but I wanted a version with no extra dependencies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With