In order to delete a log stream from a log group using the CLI command , individual log stream names are required . Is there a way to delete all log streams belonging to a log group using a single command?
12 Answers
You can achieve this through using --query to target the results of describe-log-streams. This allows you to loop through and delete the results.
aws logs describe-log-streams --log-group-name $LOG_GROUP_NAME --query 'logStreams[*].logStreamName' --output table | awk '{print $2}' | grep -v ^$ | while read x; do aws logs delete-log-stream --log-group-name $LOG_GROUP_NAME --log-stream-name $x; done
You can use --query to target all or specific groups or streams.
Delete streams from a specific month
aws logs describe-log-streams --log-group-name $LOG_GROUP --query 'logStreams[?starts_with(logStreamName,`2017/07`)].logStreamName' --output table | awk '{print $2}' | grep -v ^$ | while read x; do aws logs delete-log-stream --log-group-name $LOG_GROUP --log-stream-name $x; done
Delete All log groups - Warning, it deletes EVERYTHING!
aws logs describe-log-groups --query 'logGroups[*].logGroupName' --output table | awk '{print $2}' | grep -v ^$ | while read x; do aws logs delete-log-group --log-group-name $x; done
Clearing specific log groups
aws logs describe-log-groups --query 'logGroups[?starts_with(logGroupName,`$LOG_GROUP_NAME`)].logGroupName' --output table | awk '{print $2}' | grep -v ^$ | while read x; do aws logs delete-log-group --log-group-name $x; done
Implemented script with command from @Stephen's answer. The script shows summary before deletion and tracks progress of deletion.
#!/usr/bin/env bash
LOG_GROUP_NAME=${1:?log group name is not set}
echo Getting stream names...
LOG_STREAMS=$(
aws logs describe-log-streams \
--log-group-name ${LOG_GROUP_NAME} \
--query 'logStreams[*].logStreamName' \
--output table |
awk '{print $2}' |
grep -v ^$ |
grep -v DescribeLogStreams
)
echo These streams will be deleted:
printf "${LOG_STREAMS}\n"
echo Total $(wc -l <<<"${LOG_STREAMS}") streams
echo
while true; do
read -p "Prceed? " yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
*) echo "Please answer yes or no." ;;
esac
done
for name in ${LOG_STREAMS}; do
printf "Delete stream ${name}... "
aws logs delete-log-stream --log-group-name ${LOG_GROUP_NAME} --log-stream-name ${name} && echo OK || echo Fail
done
Here is Script to delete all logs in a log group using python. Just change the logGroupName to match your logGroup.
import boto3
client = boto3.client('logs')
response = client.describe_log_streams(
logGroupName='/aws/batch/job'
)
def delete_stream(stream):
delete_response = client.delete_log_stream(
logGroupName='/aws/batch/job',
logStreamName=stream['logStreamName']
)
print(delete_response)
results = map(lambda x: delete_stream(x), response['logStreams'])
To delete all log streams associated with a specific log group, run the following command, replacing NAME_OF_LOG_GROUP with your group:
aws logs describe-log-streams --log-group-name NAME_OF_LOG_GROUP --output text | awk '{print $7}' | while read x;
do aws logs delete-log-stream --log-group-name NAME_OF_LOG_GROUP --log-stream-name $x
done
Based on @german-lashevich's answer
If you have thousands of log streams, you will needed to parallelize.
#!/usr/bin/env bash
LOG_GROUP_NAME=${1:?log group name is not set}
echo Getting stream names...
LOG_STREAMS=$(
aws logs describe-log-streams \
--log-group-name ${LOG_GROUP_NAME} \
--query 'logStreams[*].logStreamName' \
--output table |
awk '{print $2}' |
grep -v ^$ |
grep -v DescribeLogStreams
)
echo These streams will be deleted:
printf "${LOG_STREAMS}\n"
echo Total $(wc -l <<<"${LOG_STREAMS}") streams
echo
while true; do
read -p "Prceed? " yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
*) echo "Please answer yes or no." ;;
esac
done
step() {
local name=$1
printf "Delete stream ${name}... "
aws logs delete-log-stream --log-group-name ${LOG_GROUP_NAME} --log-stream-name ${name} && echo OK || echo Fail
}
N=20
for name in ${LOG_STREAMS}; do ((i=i%N)); ((i++==0)) && wait ; step "$name" & done
For Windows users this powershell script could be usefull, to remove all the log streams in a log group:
#Set your log group name
$log_group_name = "/production/log-group-name"
aws logs describe-log-streams --log-group-name $log_group_name --query logStreams --output json | ConvertFrom-json | ForEach-Object {$_.logStreamName} | ForEach-Object {
aws logs delete-log-stream --log-group-name $log_group_name --log-stream-name $_
Write-Host ($_ + " -> deleted") -ForegroundColor Green
}
Just save it as your_script_name.ps1 and execute it in powershell.
The others have already described how you can paginate through all the log streams and delete them one by one.
I would like to offer two alternative ways that have (more or less) the same effect, but don't require you to loop through all the log streams.
Deleting the log group, then re-creating it has the desired effect: All the log streams of the log group will be deleted.
followed by:
CAVEAT: Deleting a log group can have unintended consequences. For example, subscriptions and the retention policy will be deleted as well, and those have to be restored too when the log group is re-created.
Another workaround is to set a 1 day retention period.
It won't have an immediate effect, you will have to wait ca. a day, but after that all the old data will be deleted. The name of the old streams and their meta data (last event time, creation time, etc.) will remain though, but you won't be charged for that (as far as I can tell based on my own bill).
So it is not exactly what you asked for. However, probably the most important reason why one would want to delete all the log streams is to delete the logged data (to reduce costs, or for compliance reasons), and this approach achieves that.
WARNING: Don't forget to change the retention policy after the old data is gone, or you will continually delete data after 1 day, and chances are, it is not what you want in the long run.
--log-group-name is not optional in aws cli, you can try using an * for --log-group-name value (in test environment)
aws logs delete-log-group --log-group-name my-logs
Reference URL: http://docs.aws.amazon.com/cli/latest/reference/logs/delete-log-group.html
An alternative version using Powershell CLI on Windows, launch powershell command line and use:
$LOG_GROUP_NAME="cloud-watch-group-name";
$LOG_STREAM_NAMEP="cloud-watch-log-stream-name";
Set-DefaultAWSRegion -Region us-your-regions;
Set-AWSCredential -AccessKey ACCESSKEYEXAMPLE -SecretKey sEcReTKey/EXamPLE/xxxddddEXAMPLEKEY -StoreAs MyProfileName
Get-CWLLogStream -loggroupname $LOG_GROUP_NAME -logstreamnameprefix $LOG_GROUP_NAMEP | Remove-CWLLogStream -LogGroupName $LOG_GROUP_NAME;
You may use -Force parameter on the Remove-CWLogStream Cmdlet in case you don´t want to confirm one by one.
References https://docs.aws.amazon.com/powershell/latest/reference/Index.html
If you are using a prefix, you could use the following command.
aws logs describe-log-streams --log-group-name <log_group_name> --log-stream-name-prefix"<give_a_log_group_prefix>" --query 'logStreams[*].logStreamName' --output table | awk '{print $2}' | grep -v ^$ | while read x; do aws logs delete-log-stream --log-group-name <log_group_name> --log- stream-name $x;done;
If you are doing this in zshell /zsh and you only need simple one liner command then just update the values :
* Pattern
AWS_SECRET_ACCESS_KEY
AWS_ACCESS_KEY_ID
AWS_DEFAULT_REGION
- Pattern can any text , you can also add ^ for begging of the line or $ for end of the line.
run the below command !
Pattern="YOUR_PATTERN" && setupKeys="AWS_ACCESS_KEY_ID=YOUR_KEY AWS_SECRET_ACCESS_KEY=YOUR_KEY AWS_DEFAULT_REGION=YOUR_REGION" &&
eval "${setupKeys} aws logs describe-log-groups --query 'logGroups[*].logGroupName' --output table | sed 's/|//g'| sed 's/\s//g'| grep -i ${Pattern} "| while read x; do echo "deleting $x" && $setupKeys aws logs delete-log-group --log-group-name $x; done