継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

DownloadCompleteLogFile を定期実行した時に遭遇した事象についてまとめる

タダです.

前回の記事で RDS ログを S3 にアップロードする処理を ECS で定期実行するように運用し始めました.運用し始めて遭遇した気づきがあり,そのことについて本記事で書いていきます.

sadayoshi-tada.hatenablog.com

運用し始めて発生した事象

定期実行を始めて下記のエラーが頻繁に出るようになりました.DownloadCompleteLogFile のリクエストを発行してそのレスポンスでステータスコードをチェックする機構を設けていたのですが,そのログに記録された 400 のエラーです.また,このエラーは発生するファイルが毎回バラバラだったり,エラーになった後の定期実行ではリクエストが成功していたりしていました.

Error occured: file is error/mysql-error-running.log.2023-xx-xx.xx of hoge-instance and status-error is 400

原因調査

Pythonスクリプトで出力したログではわからなかったため,CloudTrail ログを追ってみました.確認したところ,エラーが発生した時間帯で APIRate exceeded が発生していることがわかりました.API の呼び出しを実行しすぎたために400エラーがでていたのです.

"eventSource": "rds.amazonaws.com",
"eventName": "DownloadCompleteDBLogFile",
"awsRegion": "ap-northeast-1",
"sourceIPAddress": "12.34.56.78",
"userAgent": "python-requests/2.28.2",
"errorCode": "ThrottlingException",
"errorMessage": "Rate exceeded",

原因への対策

API を実行しすぎていたので,間隔を空けて再実行するようにリトライを入れることにしました.変更した箇所だけ抜粋していますが,400エラー時に3秒間隔で3回リトライする処理を入れました.このリトライ処理を入れてから400エラーがなくなり,事象が解消しました.

from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
from requests import Session

retry_config = Retry(total=3, status_forcelist=[400], backoff_factor=3)
http_adapter = HTTPAdapter(max_retries=retry_config)
http_session = Session()
http_session.mount("https://", http_adapter)
awsreq = AWSRequest(method='GET', url=download_complete_logfile_url)
sigv4auth = auth.SigV4Auth(credentials, 'rds', region)
sigv4auth.add_auth(awsreq)
http_session.get(self._download_url(), stream=True, headers={
    'Authorization': awsreq.headers['Authorization'],
    'X-Amz-Date': awsreq.context['timestamp'],
    'X-Amz-Security-Token': credential.token
}

関連情報

urllib3.readthedocs.io

まとめ

DownloadCompleteLogFile の定期実行を運用するようになって遭遇したエラーとその対処についてまとめました.エラーの発生だけじゃわからなかったですが,CloudTrail に原因が記録されていて助かりました.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com