RDSにてスロークエリーログの分析レポートを定期的取得してGitHubで管理する
はじめに
DBの負荷高騰時に、毎回pt-query-digest
をローカルから実行して分析していたのですが、取得と共有が面倒だったので、GitHubActionsを使うことでサクッと解決しました。
pt-query-digestとは?
pt-query-digest
は最近発売した「達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践」でも紹介されているスロークエリーログの分析ツールです。
前提
スロークエリーの取得が有効になっていること
当然ですがスロークエリーログを元に分析するため、ログの取得は有効にしている必要があります。
未設定の場合は以下のリンクなどを参考に設定してください。
AWS OIDCにてGitHubActionsの設定が完了していること
スロークエリーはCloudWatchLogsに保存されているため、GitHubActionsからAWSのリソースへのアクセス権限を設定する必要があります。
OIDC経由での権限付与の方式でGitHubActionsを作成しているため、事前に以下の設定を行う必要があります。
分析頻度は毎時で直近の時間帯を取得
毎時0分でのスケジュール実行で、実行された時間の1時間前の00分〜59分
をスロークエリーログの取得範囲とするとこで、毎時でのレポートを生成しています。
分析頻度を変更したい方は、GitHubActionsのschedule
設定と、スロークエリーログ取得部分をよきに変更してください。(突貫なので汎用的には作ってないです。)
設定
GitHubActions
name: Slow Query Summary
permissions:
id-token: write
contents: write
issues: write
pull-requests: write
on:
schedule:
- cron: '0 * * * *'
workflow_dispatch:
env:
## スロークエリーログが保存されているロググループ名を設定
LOG_GROUP: <CloudWatchLogGroupName>
jobs:
pt-query-digest:
runs-on: ubuntu-latest
strategy:
matrix:
## ロググループ内のストリーム名を設定 複数台構成の場合は複数指定(ライターとリーダーの両方を取得する想定)
db: [<CloudWatchLogStreamName1>, <CloudWatchLogStreamName2>]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: ap-northeast-1
## OIDC経由のアクセスするIAMロールARNを設定
role-to-assume: arn:aws:iam::**********:role/<GitHubActionsOIDCARoleName>
role-session-name: ${{ github.event.repository.name }}
- name: install pt-query-digest
run: |
sudo apt-get install percona-toolkit
- name: make slow query report
env:
LOG_GROUP: ${{ env.LOG_GROUP }}
LOG_STREAM: ${{ matrix.db }}
run: |
report_date=$(TZ=JST-9 date '+%Y%m%d' --date '1 hour ago')
report_dir="${report_date}/${LOG_STREAM}"
if [ ! -d ${report_dir} ];then mkdir -p $report_dir; fi
cd $report_dir
start=$(TZ=JST-9 date '+%Y-%m-%d %H:00:00' --date '1 hour ago')
end=$(TZ=JST-9 date '+%Y-%m-%d %H:59:59' --date '1 hour ago')
starttime=$(expr `TZ=JST-9 date --date "$start" +%s` \* 1000)
endtime=$(expr `TZ=JST-9 date --date "$end" +%s` \* 1000)
echo "starttime: ${starttime}, endtime ${endtime}"
aws logs get-log-events \
--log-group-name ${LOG_GROUP} \
--log-stream-name ${LOG_STREAM} \
--start-time ${starttime} \
--end-time ${endtime} \
--query 'events[].message' \
|jq -r '.[]' \
| pt-query-digest > $(TZ=JST-9 date '+%H00' --date '1 hour ago').txt
- name: git push files
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "Add changes"
git pull --rebase
git push
実行
実行すると以下のように日付ディレクトリ配下で、リーダーとライターそれぞれのインスタンスのスロークエリーの分析結果が時間帯毎にGitHubリポジトリに保存されます。
├── 20220605
│ ├── <CloudWatchLogStreamName1>
│ │ ├── 0800.txt
│ │ ├── 0900.txt
│ │ ├── 1000.txt
│ │ ├── 1100.txt
│ │ ├── 1200.txt
│ │ └── 1300.txt
│ └── <CloudWatchLogStreamName2>
│ ├── 0800.txt
│ ├── 0900.txt
│ ├── 1000.txt
│ ├── 1100.txt
│ ├── 1200.txt
│ └── 1300.txt
まとめ
GitHubActionsを利用することでサクッと作ってみました!
この辺の稼働レポート系はS3に集約して分析とか、Lambda使っていい感じに整形してSlack通知とか、いろいろ手段があるのですが、やろうとするとAWSのリソースの作成やLambdaコードの作成など手間が多いです。
GitHubActionsのスケジュール機能とデータの保存場所をGitHubリポジトリそのものにすることで、追加のリソース作成などせずGitHubで全てが完結するので、最近はよく利用しています。
この情報がだれかのトイルの削減に役立てば幸いです!
Discussion