AWS SDK for Python (Boto3) を使用して使われなくなったCloudWatch Logs ロググループを削除してみた

2023.05.31

Lambda関数の検証などを行っているとCloudWatch Logsにロググループが溜まっていきます。
放置していると料金も発生してくるので使われなくなったロググループを削除するスクリプトを作成してみました。

作成したスクリプト

作成したスクリプトは以下のGitHubリポジトリに格納しています。
https://github.com/Kobayashi-Riku0226/python_script

import boto3
from datetime import datetime, timedelta

one_month_ago = datetime.now() - timedelta(days=30)
one_month_ago_int = int(one_month_ago.timestamp() * 1000)

logs = boto3.client('logs')

log_groups = logs.describe_log_groups()

for log_group in log_groups['logGroups']:
    log_group_name = log_group['logGroupName']
    log_stream = logs.describe_log_streams(
            logGroupName=log_group_name,
            orderBy='LastEventTime',
            descending=True,
            limit=1
            )
    last_event_timestamp = log_stream['logStreams'][0]['lastEventTimestamp']

    if last_event_timestamp < one_month_ago_int:
        while True:
            print('ロググループ' + log_group_name  + 'を削除します。')
            delete_flag = input('問題無い場合はyキーを押下してください。削除しない場合はnキーを押下してください。>')
            if delete_flag == 'y':
                logs.delete_log_group(logGroupName=log_group_name)
                print(log_group_name  + 'は削除されました。')
                break
            elif delete_flag == 'n':
                print(log_group_name  + 'は削除されませんでした。')
                break
            else:
                print("指定されたキー以外が入力されました。もう一度入力してください。")

上記のスクリプトを動かすと1ヵ月前から使用されていない (ログストリームが作成されていない) ロググループを削除します。
処理の内容は以下のようになります。

  • 4~5行目でスクリプトを動かした日から30日前のUnix Timeを取得します。
  • 9行目でdescribe_log_groupsロググループの一覧を取得します。
  • 11行目でfor文を使いロググループの数だけ処理を行うようにしています。
  • 12行目でロググループの名前を取得して、13~18行目でdescribe_log_streamsを使用して最新のログストリームを取得します。
  • 19行目でログストリームから最終更新日を取得します。
  • 21行目で最終更新日が30日前のUnix Timeよりも小さい場合に削除処理を行えるようif文を入れています。
  • 22~33行目で本当に削除してよいのか確認を行うようにしました。
    • yキーを押下すると削除します。
    • nキーを押下すると削除されません。
    • それ以外のキーの場合はもう一度キーを押下させるようにしています。

確認などは不要で今すぐ該当のロググループを消したい人向けに確認無しのスクリプトも作成しました。

import boto3
from datetime import datetime, timedelta

one_month_ago = datetime.now() - timedelta(days=30)
one_month_ago_int = int(one_month_ago.timestamp() * 1000)

logs = boto3.client('logs')

log_groups = logs.describe_log_groups()

for log_group in log_groups['logGroups']:
    log_group_name = log_group['logGroupName']
    log_stream = logs.describe_log_streams(
            logGroupName=log_group_name,
            orderBy='LastEventTime',
            descending=True,
            limit=1
            )
    last_event_timestamp = log_stream['logStreams'][0]['lastEventTimestamp']

    if last_event_timestamp < one_month_ago_int:
        logs.delete_log_group(logGroupName=log_group_name)
        print(log_group_name  + 'は削除されました。')

動かし方

実行環境はCloudShellを使用しました。
CloudShellを開き以下のコマンドを実行してください。
CloudShellの使用方法は以下のドキュメントを参照してください。
AWS CloudShell の開始方法

git clone https://github.com/Kobayashi-Riku0226/python_script.git
cd python_script/cloudwatch_delete/
chmod 755 cloudwatch_logs_delete.py
python3 cloudwatch_logs_delete.py

上記のコマンドを実行すると一つ一つ削除するか確認する方のスクリプトを実行します。
確認を行わないで全て削除するスクリプトを動かす場合は3行目と4行目のファイル名を「cloudwatch_logs_delete_all.py」に変更してください。

さいごに

基本的に今回作成したスクリプトはシステムの検証環境や開発環境でだけ使用することをお勧めします。
本番環境にあるログは殆どが重要なものになるはずなので、操作ミスで削除してしまうリスクは減らしましょう。
どうしても本番環境で削除したい場合は以下のブログにある弊社千葉の作成した保持設定を一括で変更するLambda関数を使用するのがよいと思います。