雑記帳
2014-07-23 (Wed) [長年日記]
■ [AWS] Amazon RDSのログをダウンロードするスクリプトを作った
Amazon RDSは、ログを直接参照できないので、APIを使ってログをダウンロードすることができる。AWS Management Consoleでdownloadボタンをポチポチ押してダウンロードすることもできるが、大量にあるログを一気に取得したかったので、スクリプトを作った。
githubで公開してます。 https://github.com/muramasa64/rds-log-downloader
いくつかハマるポイントがあった。
download_db_log_file_portionを実行するときのmarkerの初期値は0を指定する
ログファイルのサイズが大きい場合は、一度のAPI呼び出しで全て取得できない。続きがある場合は、レスポンスにmarkerという値が返ってくるので、次の呼び出し時に渡してあげると、続きを取得することができる。
当初は特に値を渡さずに実行していたのだが、その場合は最初からではなくて途中から最後までが取得できるようで、最初が取得できなかった。最初から取得したい場合は、markerを0にすればよい。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def download_db_log_file(server, logfilenames, logdir) | |
logfilenames.each do |filename| | |
marker = '0' | |
body = '' | |
begin | |
resp = @rds.client.download_db_log_file_portion( | |
:db_instance_identifier => server, | |
:log_file_name => filename, | |
:marker => marker | |
) | |
marker = resp[:marker].to_s | |
body += resp[:log_file_data].to_s | |
end while(resp[:additional_data_pending]) | |
save_db_log_file(server, filename, logdir, body) | |
end | |
end |
describe_db_log_filesのfile_last_writtenには、ミリ秒単で指定する
ファイル一覧を取得する際に、フィルタの条件で、最後に更新された日時を指定するfile_last_writtenオプションがあるのだが、この値の単位はミリ秒である。Rubyで、Time.to_iを実行すると取得できる値は秒単位であるため、1000倍した値を渡すようにしている。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def end_of_day_timestamp(date) | |
date.to_time.to_i * 1000 | |
end | |
def collect_db_log_filenames(instance, last_written) | |
marker = '0' | |
logfilenames = [] | |
begin | |
resp = @rds.client.describe_db_log_files( | |
:db_instance_identifier => instance, | |
:file_last_written => end_of_day_timestamp(last_written), | |
:marker => marker | |
) | |
marker = resp[:marker].to_s | |
logfilenames.concat(resp[:describe_db_log_files].map {|i| i[:log_file_name] }) | |
end while(marker != '') | |
logfilenames | |
end |
[ツッコミを入れる]