LoginSignup
1
0

CloudWatch LogsからS3バケットにエクスポートするシェルスクリプト

Posted at

はじめに

先日先人が作り上げた、偉大なログエクスポートを実行するStepFunctionsがコケていました。
先人ほどのスキルもないので、CloudShellを利用してCloudWatchLogsからS3へエクスポートするシェルスクリプトを作成したので記事として残します。
StepFunctionsの根本対応が必要ですが、まずは一時的な対応としてシェルスクリプトを作成。
マネジメントコンソールからGUI操作も可能ですが、対象となるCloudWatchLogsの量が多いことや、アクセスキーが払い出されていないことから、本番環境のCloudShellで作業実施を決めました。

参考:
AWS ドキュメント「AWS CLI を使用してログデータを Amazon S3 にエクスポートする」


構成図



構築

1.S3バケットの準備

実機ではStepFunctionsから毎晩ログが対象のS3バケットにエクスポートされているため設定は不要。
ただし検証するために新規作成しているため、新たに作成したS3バケットに、以下バケットポリシーを追記する。
※東京リージョンを想定
arn:aws:s3:::[YOUR-BUCKET-NAME]部分は、ログが転送されるS3バケット名を入力する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-1.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::[YOUR-BUCKET-NAME]"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-1.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::[YOUR-BUCKET-NAME]/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}


2.CloudWatch LogsからS3バケットにエクスポートするシェルスクリプト

2.1.転送するCloudWatchLogsのリストファイルを作成

S3へ転送したい CloudWatchLogsのロググループをテキストファイル形式で作成して保存
※下記log.txtの内容にS3に転送したいロググループ名を記載する


【例】log.txt

/aws/lambda/cfn-sf-inamura-LambdaHumanApprovalSendEmailFunctio-wPwtEbDmKEg3
/aws/lambda/cfn-stepfunctions-inamura-LambdaHumanApprovalSendE-3j0qFdWkOpat
/aws/lambda/cfn-stepfunctions-inamura-LambdaHumanApprovalSendE-D92dYTTBLAmy
/aws/lambda/cfn-stepfunctions-inamura-LambdaHumanApprovalSendE-IbgVOxScNeUI
/aws/lambda/cfn-stepfunctions-inamura-LambdaHumanApprovalSendE-UTH7yskJ5b79

2.2.CloudWatch LogsからS3バケットにエクスポートするシェルスクリプトを作成


【シェルスクリプト】bash export_log_groups_to_s3.sh

#!/bin/bash
#エラーが発生した場合停止する
set -e

#引数$1:ログリストパス
#引数$2:保存先S3バケット名の記載がない場合はエラー表示
if [ -z "$1" ] || [ -z "$2" ]; then
  echo "Please provide both a log group name file and a bucket name as arguments."
  exit 1
fi

log_group_name_file=$1
s3_bucket_name=$2

#検索開始・終了時間
start_time=$(($(date -d "2020/01/01" +%s)*1000)) 
end_time=$(($(date -d "2023/05/01" +%s)*1000))

#ログリストを一行ずつ実行
while IFS= read -r log_group_name
do
  #空行になるまで繰り返す
  if [ -z "$log_group_name" ]; then
    continue
  fi

  #タスクネーム作成
  task_name="ExportTask-$(date +%Y%m%d%H%M%S)"

  #ロググループ名の一文字めの"/"を削除するr
  prefix=${log_group_name#/}
  
  #エクスポートタスクを作成しタスクIDを取得
  task_id=$(aws logs create-export-task --task-name "${task_name}" --log-group-name "${log_group_name}" --from ${start_time} --to ${end_time} --destination "${s3_bucket_name}" --destination-prefix "${prefix}" --query 'taskId' --output text)
  
  #エクスポートタスク作成が失敗した場合、どのロググループで失敗したか表示
  if [ $? -ne 0 ]; then
    echo "Failed to create export task for log group ${log_group_name}"
    exit 1
  fi
  
  #エクスポートタスクのステータスを取得
  while true; do
    status=$(aws logs describe-export-tasks --task-id "${task_id}" --query 'exportTasks[0].status.code' --output text)

    #エクスポートステータスが”COMPLETED”なら、次のタスクを実行するためループ終了
    if [[ "${status}" == "COMPLETED" ]]; then
      echo "Export task for log group ${log_group_name} completed successfully."
      break
    fi

    #エクスポートタスクが”FAILED”なら、どのロググループで失敗したか表示して終了
    if [[ "${status}" == "FAILED" ]]; then
      echo "Export task for log group ${log_group_name} failed."
      exit 1
    fi

    #エクスポートタスクが"RUNNING","PENDING"なら30秒sleep後、再実行
    if [[ "${status}" == "RUNNING" ]] || [[ "${status}" == "PENDING" ]]; then
      echo "Export task for log group ${log_group_name} wait please."
      sleep 30
    fi
  done
done < "$log_group_name_file"


挙動の確認

1.CloudShellで実行

$1引数:S3へ出力したいログリストのテキストファイル
$2引数:出力先とするS3バケット

$ bash export_log_groups_to_s3.sh "log.txt" "20220214-inamura"

2.実行結果の確認

2.1.CloudShell画面での実行結果確認

何度かS3バケットに送れないということで「wait please」が出ましたが、30秒待機して再トライして送信ができてることがターミナル画面からわかる



2.2.実行後のS3バケット画面での確認

S3にも出力されていることを確認できる


2.3.CloudWatchLogsの画面での確認

2.3.1.「Amazon S3へのすべてのエクスポートを表示」画面へ遷移

CloudWatch > ロググループ > アクション > Amazon S3へのすべてのエクスポートを表示 を押下


2.3.2.エクスポートタスクでの確認

エクスポートタスクが完了しており、ステータスが「Completed successfully」となっていることを確認


さいごに

ログ転送中は同時に2つの処理を実行できないことは新たな学びでした。
さて一時対応が済んだので、StepFuncitonsの根本解決に着手していこうと思います。
※利用したS3バケットは検証終了したため削除されています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0