AWS RDS PostgreSQLのクエリログをawscliで取得するワンライナー
事前の設定
AWS RDS PostgreSQLでクエリのログをすべてログに残すには、パラメータグループで以下のように設定します。
log_statement=all log_min_duration_statement=0
log_statement=all
はすべての種類のクエリログを記録するという指示で、log_min_duration_statement=0
はクエリ実行にかかった時間によらずすべてのクエリをログに記録するという指示です。
log_min_duration_statement
はミリ秒単位で1000にすれば処理に1秒以上かかったクエリのみをログに残すということになります。
RDSでないPostgreSQLであれば postgresql.conf
に書く内容です。
ログの取得
ログはPostgreSQLの動いているインスタンスにファイルとして保存されているのですが、RDSの中のファイルにはアクセスできません。awscliであればaws rds describe-db-log-files
コマンドとaws rds download-db-log-file-portion
コマンドでログファイルを取得できます。
ファイル名を取得
まずログのファイル名を調べます。aws rds describe-db-log-files
コマンドです。DB_IDENTIFIERのところにはRDSのインスタンス名を入れます。
$ aws rds describe-db-log-files --db-instance-identifier DB_IDENTIFIER
awscliの設定がデフォルトであればJSONで以下のように表示されます。
{ "DescribeDBLogFiles": [ { "LogFileName": "error/postgresql.log.2020-04-25-11", "LastWritten": 1587815792000, "Size": 3912 }, { "LogFileName": "error/postgresql.log.2020-04-25-12", "LastWritten": 1587819393000, "Size": 3912 }, { "LogFileName": "error/postgresql.log.2020-04-25-13", "LastWritten": 1587822994000, "Size": 3912 },
jq
がインストールされていれば、jq
を使ってカラー表示するにはこんな感じ。
$ aws rds describe-db-log-files --db-instance-identifier DB_IDENTIFIER | jq .
長くてページャーを入れたい場合は、こんな感じ。jq
に-C
が、less
に-R
が必要です。
$ aws rds describe-db-log-files --db-instance-identifier DB_IDENTIFIER | jq . -C | less -R
ログファイルの中身を取得
ファイル名がわかったら次はaws rds download-db-log-file-portion
コマンドを使います。ファイル名を指定してその中身を取得できます。
$ aws rds download-db-log-file-portion --db-instance-identifier DB_IDENTIFIER --log-file-name error/postgresql.log.2020-05-02-11
{ "LogFileData": "2020-05-02 11:25:00 UTC:172.31.30.61(35058):postgres@postgres:[25683]:LOG: statement: select * from tbla;\n........................\n" }
なんとファイルの中身全体を1つの文字列として包んだJSONが返ってきてしまいます。とても見づらいです。
こんなときはjq
を使えばよいです。jq
に-r
を付けます。
$ aws rds download-db-log-file-portion --db-instance-identifier DB_IDENTIFIER --log-file-name error/postgresql.log.2020-04-25-11 | jq .LogFileData -r
2020-05-02 11:25:00 UTC:172.31.30.61(35058):postgres@postgres:[25683]:LOG: statement: select * from tbla; 2020-05-02 11:25:00 UTC:172.31.30.61(35058):postgres@postgres:[25683]:LOG: duration: 4.193 ms
全ログファイルを結合
ファイル名を1つずつ指定してダウンロードしないといけないのが面倒で、保存されているログファイルを時系列で並べて全部結合したい場合は、ワンライナーですと次のようになります。
$ for f in $(aws rds describe-db-log-files --db-instance-identifier DB_IDENTIFIER | jq ".DescribeDBLogFiles[] | .LogFileName" -r | grep 'error/postgresql.log.' | sort); do aws rds download-db-log-file-portion --db-instance-identifier DB_IDENTIFIER --log-file-name $f | jq .LogFileData -r; done
2020/11/06追記
上記ワンライナーですと途中でログが途切れてしまう問題や日本語が文字化けする問題がありましたので、以下の記事に改良版を書きました。ワンライナーではなくなってしまいますが。