CloudWatch Logs のログストリームごとのサイズを取得する
動機
Amazon CloudWatch Logs のログストリームごとのサイズを知りたいことがありました。
たとえば Amazon EKS クラスタを立ち上げて Fluentd または Fluent Bit でログを CloudWatch Logs に送る設定をすると,Pod のログは単一のロググループ(デフォルトでは /aws/containerinsights/Cluster_Name/application
)に集約されます。
このクラスタで動くアプリケーションのうちのどれかのログが大量に出力されていて,どのアプリケーションなのか突き止める必要がありました。
ロググループ全体のサイズはすぐにわかる
ロググループ全体のログサイズは,Amazon CloudWatch メトリクスで簡単に把握できます。
名前空間 AWS/Logs
のメトリクス IncomingBytes
です。
ロググループ名が次元に指定されています。
ログストリームごとのサイズはすぐにはわからなくなった
一方で,ログストリームごとのログサイズは,DescribeLogStreams API を見ると,storedBytes
があり,これを利用できそうに見えます。
しかし,storedBytes
は2019年に廃止され,0
固定になってしまいました。
この API からは取得できないので,別の方法を考えなければならなくなりました。
Important: As of June 17, 2019, this parameter is no longer supported for log streams, and is always reported as zero. This change applies only to log streams. The storedBytes parameter for log groups is not affected.
https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_LogStream.html#CWL-Type-LogStream-storedBytes
方法
CloudWatch Logs Insights を使って集計します。
fields @logStream, strlen(@message) as messageBytes
| stats sum(messageBytes) as storedBytes by @logStream
| sort storedBytes desc
ログストリームは雑多な名前で乱立するケースが多いので,たとえば最初のハイフンまでの接頭辞で集約して集計するには以下のようにします。
fields @logStream, strlen(@message) as messageBytes
| parse @logStream '*-*' as logStreamPrefix, logStreamSuffix
| stats sum(messageBytes) as storedBytes by logStreamPrefix
| sort storedBytes desc
ポイント
個々のログエントリのサイズを測定し,それを合計するという仕組みです。
ログサイズは文字列関数の strlen があるので,それを使い,ログエントリが格納されている @message
のサイズを取得しました。
個々のログサイズの合計は stats コマンドで sum 関数を使いました。
エイリアスの説明にははっきり書いてありませんが,サンプルクエリに書かれている複数の例の通り,集約関数にもエイリアスを付与できます。
付与したエイリアスを使って最終的な結果をソートすることができます。
注意
スキャン料金
Logs Insights ではクエリのためにスキャンしたデータ量に応じて課金されるので,注意しましょう。
現時点では,東京リージョンで 1 GB あたり 0.0076 USD 課金されます。
クエリ結果
マネジメントコンソールからクエリを実行した場合,実行結果はすぐにダウンロードするようにしましょう。
クエリ保存の画面に遷移して元に戻ったら消えていたということがありました。
Discussion