108

I can view the log using the following command.

aws logs get-log-events --log-group-name groupName --log-stream-name streamName --limit 100

what is the command to get feature like tail -f so that i can see the log real time

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
LynAs
  • 6,407
  • 14
  • 48
  • 83
  • You can use this command line utility for Python https://pypi.org/project/qaws/ – Jurass May 25 '20 at 05:57
  • If you want the results within memory rather than console output, i.e. `boto3` instead of `awscli`, https://gist.github.com/alanyee/601f995bfd6acfd4c3c16ee7e9115ab5 – Flair Jan 07 '21 at 23:19
  • 9
    TL/DR; Since mid-2019, newer versions of `aws-cli` include: `aws logs tail $group_name` (and it supports handy options like `--since "1h"` and --follow (like `tail -f`) and `--filter-pattern "blah"` (like `grep`).) – MarkHu Jan 27 '21 at 01:16
  • @MarkHu please post such comments as answers. – Vitaly Zdanevich Feb 22 '23 at 18:31

15 Answers15

128

Note that tailing an aws log is now a supported feature of the official awscli, albeit only in awscli v2, which is not released yet. Tailing and following the logs (like tail -f) can now be accomplished by something like:

aws logs tail $group_name --follow

To install the v2 version, see the instructions on this page. It was implemented in this PR. To see it demonstrated at the last re:Invent conference, see this video.

In addition to tailing the logs, it allows viewing the logs back to a specified time using the --since parameter, which can take an absolute or relative time

aws logs tail $group_name --since 5d

To keep the v1 and v2 versions of awscli separate, I installed awscli v2 into a separate python virtual environment and activate it only when I need to use awscli v2.

Anton I. Sipos
  • 3,493
  • 3
  • 27
  • 26
  • 2
    Used this link for aws v2 : https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html , Try installing it using '-i' and '-b' option to provide custom install and binary file locations. – Ashish Sharma Dec 05 '19 at 07:52
  • 2
    Backported as a v1 plugin, for those unable to use v2 : https://pypi.org/project/awscli-plugin-logs-tail/ – Steve Jones Oct 06 '20 at 02:24
  • If you want to look at the current state of the code, it is present in the `v2` branch under https://github.com/aws/aws-cli/tree/v2/awscli/customizations/logs – Flair Jan 07 '21 at 00:48
  • `saw` and `awslogs` work out of the box but `aws logs` results in `An error occurred (ThrottlingException) when calling the FilterLogEvents operation (reached max retries: 2): Rate exceeded`... NICE! – luk2302 Jun 22 '21 at 12:39
  • How to `tail` multiple AWS log groups: `{ aws logs tail /aws/lambda/my-log-one --follow & aws logs tail /aws/lambda/my-log-two --follow; }` – Adam Oct 08 '21 at 09:23
  • 1
    If you're on Windows and you're using Git Bash, then you need to prefix the command with `MSYS_NO_PATHCONV=1` For example: `MSYS_NO_PATHCONV=1 aws logs tail /aws/lambda/my_group_name --since 1h --follow` – Adam Sep 10 '22 at 10:11
  • I also found it helpful to fetch the most recent log group using the following command first, then passing that result into the logs command. You can set the log prefix environment variable or you can change this and hard code it instead: ```group_name=$(aws logs describe-log-groups --log-group-name-prefix $LOG_PREFIX --query 'logGroups[*].[creationTime,logGroupName]' --output text | sort -n | tail -1 | awk '{ print $2 }')``` – Michael Behrens Feb 27 '23 at 16:00
124

I was really disappointed with awslogs and cwtail so I made my own tool called Saw that efficiently streams CloudWatch logs to the console (and colorizes the JSON output):

You can install it on MacOS with:

brew tap TylerBrock/saw
brew install saw

It has a bunch of nice features like the ability to automatically expand (indent) the JSON output (try running the tool with --expand):

saw watch my_log_group --expand

Got a Lambda you want to see error logs for? No Problem:

saw watch /aws/lambda/my_func --filter error 

Saw is great because the output is easily readable and you can stream logs from entire log group, not just a single stream in the group. Filtering and watching streams with a certain prefix is also just as easy!

Tyler Brock
  • 29,626
  • 15
  • 79
  • 79
59

Have a look at awslogs.

If you happen to be working with Lambda/API Gateway specifically, have a look at apilogs.

RyanG
  • 3,973
  • 25
  • 19
  • 2
    `awslogs` package is amazing. Solved a problem I had this morning where a business team member just wanted to "grep the logs to find stuff". Definitely the way to go for simple solutions. – Adam Link Dec 08 '17 at 18:57
  • 1
    Minus one point for shameless self promotion. Looks cool though! – RyanG Jun 20 '18 at 19:08
  • 1
    @TylerBrock a lot of console apps are built on Python, including the official aws-cli, so your point is not 100% valid. Reasoning aside, great tool you've built! – Hnatt Sep 17 '18 at 16:33
  • 2
    but... python comes pre-installed in a lot of unix based os :) – RicardoE Dec 18 '18 at 21:47
  • Awslogs are not bad but this one looks better to me: https://pypi.org/project/qaws/ – Jurass May 25 '20 at 05:57
  • @TylerBrock `saw` does look cool. But I have to point out that you complained about needing to install python, while `saw` is asking me to do something far more painful: `Please update to Xcode 11.3.1`. I'm on OS 10.14 still so I'd actually have to update my OS too! – totalhack Dec 03 '20 at 15:00
  • @totalhack if you get it from the releases page it should be already compiled for you, just extract the archive and run! – Tyler Brock Dec 03 '20 at 23:58
  • I dont see an example how to tail. – jNayden Sep 27 '21 at 14:22
13

I've just discovered cwtail and it works well (to watch a lambda function's CloudWatch logs).

To install:

npm install -g cwtail

To list log groups:

cwtail -l

Then, once you've picked which log group to 'tail':

cwtail -f /aws/lambda/ExampleFunction
Greg Sadetsky
  • 4,863
  • 1
  • 38
  • 48
  • 1
    And if you wanted to format the json coming back from cwtail, this might work. Running in a bash shell. $ echo '{"j":[' `cwtail -e /aws/connect/carbonated | sed 's/$/,/' | sed '$ s/.$//'` ']}' | python -m json.tool – Chai Ang Sep 05 '19 at 23:37
  • 1
    Missed a very important detail `-e`, else it will show the log as one big paragraph, completely unreadable. Use `cwtail -e group_name`. – Lalit Fauzdar Aug 06 '22 at 08:49
10

AWS allows you to tail the logs now. Exactly like tail -f. use the following command

aws logs tail <log group name> --follow

E.g. if you are using ElasticBeanStalk with app name myapp-prd and want to tail web1.log it would be

aws logs tail /aws/elasticbeanstalk/myapp-prd/var/log/web-1.log --follow
Sacky San
  • 1,535
  • 21
  • 26
8

Because CloudWatch logs can be delayed (i.e. not "realtime" by precise definition) you parse the previous events for the last timestamp and start the next iteration there. This script uses aws logs get-log-events for which you must specify a valid stream_name.

#!/bin/bash
    
group_name='<log-group-name>'
stream_name='<log-stream-name>'
start_seconds_ago=300

start_time=$(( ( $(date -u +"%s") - $start_seconds_ago ) * 1000 ))
while [[ -n "$start_time" ]]; do
    loglines=$(aws logs get-log-events --log-group-name "$group_name" --log-stream-name "$stream_name" --start-time $start_time --output text)
    [ $? -ne 0 ] && break
      next_start_time=$( sed -nE 's/^EVENTS.([[:digit:]]+).+$/\1/ p' <<< "$loglines" | tail -n1 )
    [ -n "$next_start_time" ] && start_time=$(( $next_start_time + 1 ))
    echo "$loglines"
    sleep 15
done

Or if you want to tail an entire log group, this script uses aws logs filter-log-events without a stream name:

#!/bin/bash

group_name='<log-group-name>'
start_seconds_ago=300
  
start_time=$(( ( $(date -u +"%s") - $start_seconds_ago ) * 1000 ))
while [[ -n "$start_time" ]]; do
    loglines=$(aws logs filter-log-events --log-group-name "$group_name" --interleaved --start-time $start_time --output text)
    [ $? -ne 0 ] && break
    next_start_time=$( sed -nE 's/^EVENTS.([^[:blank:]]+).([[:digit:]]+).+$/\2/ p' <<< "$loglines" | tail -n1 )
    [ -n "$next_start_time" ] && start_time=$(( $next_start_time + 1 ))
    echo "$loglines"
    sleep 15
done

I've also put up the scripts that I use as GitHub gists: https://gist.github.com/tekwiz/964a3a8d2d84ff4c8b5288d9a703fbce.

Warning: the above code & scripts are written for my macOS system which is customized (bastardized??) with Homebrew and GNU coreutils, so some command options may need to be tweaked for your system. Edits are welcome :)

MarkHu
  • 1,694
  • 16
  • 29
Travis Warlick
  • 644
  • 4
  • 14
  • Nice one. Can you show me how to get the log streams list . I want to build a solution to filter log stream by its name for k8s containers. But aws is not returning anything when I query the logstreams api ? Any idea why? – Arun George Jun 29 '21 at 18:14
7

To tail CloudWatch Logs effectively I created a tool called cw.

It's super easy to install (it supports brew, snap and scoop), fast (it targets the specific hardware architecture, no intermediate runtime) and it has a set of features that make life easier.

Your example with cw would be:

cw tail -f groupName:streamName
Luca Grulla
  • 79
  • 1
  • 1
7

After checking many options and testing some custom tools aws logs tail worked the best for me.

Here there is a simple example command:

aws logs tail <GROUP_NAME> --follow

and here is the official doc which was very useful:

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/tail.html

Fabián Bertetto
  • 1,721
  • 17
  • 14
4

I created a JetBrains plugin called awstail to do this :)

godzsa
  • 2,105
  • 4
  • 34
  • 56
  • Why did you remove it from JB Marketplace? – Kirill Aug 11 '21 at 06:34
  • 1
    @Kirill AWS has their own plugin for which has this exact feature. Therefore I am not planning to support and fix bugs on my tool. https://aws.amazon.com/intellij/ – godzsa Aug 16 '21 at 13:02
3

You can use awslogs, a python package to tail aws logwatch logs.

Install it with

pip install awslogs

List all the groups with

awslogs groups        

Then select a stream and watch it with

awslogs get staging-cluster --watch

You can also filter logs with matching patterns.

# tail logs of a cluster
awslogs get staging-cluster --watch

# tail logs of a lambda function
awslogs get /aws/lambda/some-service --watch

# print all logs containg "error"
awslogs get staging-cluster --watch --filter-pattern="error"

# print all logs *not* containg "error"
awslogs get staging-cluster --watch --filter-pattern="-error"

See project readme for more information on using awslogs.

Chillar Anand
  • 27,936
  • 9
  • 119
  • 136
  • This Python utility uses better time ranges and provides CloudWatch Insights queries: https://pypi.org/project/qaws/ – Jurass May 25 '20 at 05:59
2

This is not currently a feature of the CLI since it just exposes the HTTP API for CloudWatch Logs. You could fairly trivially emulate the functionality with a shell script:

#! /bin/sh

end_time=$(($(date +"%s") * 1000))
aws logs get-log-events --log-group-name groupName --log-stream-name streamName --end-time $end_time

while :
do
    start_time=$end_time
    end_time=$(($(date +"%s") * 1000))
    aws logs get-log-events --log-group-name groupName --log-stream-name streamName --start-time $start_time --end-time $end_time
    sleep 1
done

Disclaimer: this won't work on Windows, and there may be a better way to get the time in milliseconds.

Jordon Phillips
  • 14,963
  • 4
  • 35
  • 42
  • Thank you for your answer. It helped but this work for me since server time and my local machine time is different. i tried changing my local time but still it wont sync properly. – LynAs Dec 02 '15 at 06:26
  • CloudWatch logs are stored with the timezone, and the CloudWatch API uses of UTC for timestamps (UNIX epoch in milliseconds), so this will only get events in the past if you're system uses a timezone east of GMT (and nothing if you're west of GMT). Also, CloudWatch logs are almost always delayed by a couple seconds, so the likelihood this will return events even if you correct the time to UTC is pretty low (in my experience). – Travis Warlick Jun 27 '16 at 12:32
2

AWS launched a console page specifically to support near real time tailing across multiple logGroups and across linked accounts checkout Cloud watch Live tail

Nishanth
  • 21
  • 4
  • Super useful feature. But can I use an exclude on the filter as opposed to an include? – chromebookdev Aug 15 '23 at 23:19
  • 1
    Yes you can! Place a hyphen/minus symbol ("-") before the terms that you want to exclude do `-INFO` to exclude INFO logs.. You can also use a combination of include and exclude, for example `ERROR -ARGUMENTS` to include ERROR but exclude ARGUMENTS. [AWS docs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html#matching-terms-events) have more examples. – Nishanth Aug 17 '23 at 15:06
1

Amazon recently announced Live tail option to see the real time streaming experience to monitor logs as they occur. Live tail is focused on real-time monitoring and troubleshooting, while log groups are more about log storage, organization, and analysis over a longer period.

Navigate to AWS CloudWatch and select Live tail option under logs.

AWS CloudWatch Livetail

0

The aws cli does not provide a live tail -f option.

Those other tools mentioned above do provide a tailing feature, however, I tried all these tools, awslogs, cwtail and found them frustrating. They were slow to download events, often unreliable and not helpful in displaying JSON log data and were primitive with query options.

I wanted an extremely fast, simple log viewer that would allow me to instantly and easily see application errors and status. The CloudWatch logs viewer is slow and CloudWatch Insights can take > 1m for some pretty basic queries.

So I created SenseLogs, a free AWS CloudWatch Logs viewer that runs entirely in your browser. There is no server-side services required. SenseLogs transparently downloads log data and stores events in your browser application cache for immediate viewing, smooth infinite scrolling and full text queries. SenseLogs has live tail with infinite back scrolling. See https://github.com/sensedeep/senselogs/blob/master/README.md for details.

SenseDeep
  • 3,026
  • 3
  • 17
  • 19
  • The unreleased aws cli v2 now does include a live `tail -f` option, although you would specifically have to install v2. See my answer https://stackoverflow.com/a/56959236/149416 – Anton I. Sipos Jul 09 '19 at 19:15
0

Here's a bash script that you can use. The script requires the AWS CLI and jq.

#!/bin/bash

# Bail out if anything fails, or if we do not have the required variables set
set -o errexit -o nounset

LOG_GROUP_NAME=$1
LOG_BEGIN=$(date --date "${2-now}" +%s)
LOG_END=$(date --date "${3-2 minutes}" +%s)
LOG_INTERVAL=5
LOG_EVENTIDS='[]'

while (( $(date +%s) < $LOG_END + $LOG_INTERVAL )); do
  sleep $LOG_INTERVAL
  LOG_EVENTS=$(aws logs filter-log-events --log-group-name $LOG_GROUP_NAME --start-time "${LOG_BEGIN}000" --end-time "${LOG_END}000" --output json)
  echo "$LOG_EVENTS" | jq -rM --argjson eventIds "$LOG_EVENTIDS" '.events[] as $event | select($eventIds | contains([$event.eventId]) | not) | $event | "\(.timestamp / 1000 | todateiso8601) \(.message)"'
  LOG_EVENTIDS=$(echo "$LOG_EVENTS" | jq -crM --argjson eventIds "$LOG_EVENTIDS" '$eventIds + [.events[].eventId] | unique')
done

Usage: save the file, chmod +x it, and then run it: ./cloudwatch-logs-tail.sh log-group-name. The script also takes parameters for begin and end times, which default to now and 2 minutes respectively. You can specify any strings which can be parsed by date --date for these parameters.

How it works: the script keeps a list of event IDs that have been displayed, which is empty to begin with. It queries CloudWatch Logs to get all log entries in the specified time interval, and displays those which do not match our list of event IDs. The it saves all of the event IDs for the next iteration.

The script polls every few seconds (set by LOG_INTERVAL in the script), and keeps polling for one more interval past the end time to account for the delay between log ingestion and availability.

Note that this script is not going to be great if you want to keep tailing the logs for more than a few minutes at a time, because the query results that it gets from AWS will keep getting bigger with every added log item. It's fine for quick runs though.

Nikhil Dabas
  • 2,343
  • 2
  • 18
  • 18