はじめに
この記事はヤプリ #1 Advent Calendar 2022 & New Relic Advent Calendar 2022の23日目の記事です。
こんにちは!SREの三橋です。
ECS/Fargateへのログ転送方式とLogs in Context導入方法の見直しを行ったため、その内容を記載いたします。
想定する読者
- Logs in Contextについて興味がある方
- Logs in Contextの導入を考えている方
- ECS/FargateのログをLambda経由でNew Relicに転送している方
- ECS/FargateのログをCloudWatch LogsではなくNew Relicにまとめたいと考えている方
- Yappliの裏側に興味がある方
背景
Yappliではバックエンドの多くがECS/Fargate上で動いており、ログはCloudWatch LogsおよびNew Relicに転送されるようになっています。 しかし、これではCloudWatch LogsとNew Relicの両方にログが保存されることになりコストが割高になってしまいます。 そこで障害調査目的のログの転送先を一本化しコストを削減させることを検討いたしました。 また、最近のアップデートでLogs in Contextの導入が楽になったとお聞きしたため、その方法で利用できないか調査いたしました。
結論
はじめに結論を書いておくと以下のようになります。
- FluentBitを利用することで障害調査用のログをNew Relicのみで管理することが可能であり、Lambda経由でNew Relicにログを転送する方法より圧倒的にコストが安くなる
- アップデートによりLogs in Contextの導入は楽になったがAPMエージェントに対応していないログライブラリ、アプリケーションフレームワークなどを利用している場合導入方法は変わらない
ログ転送先の検討
CloudWatch Logsはデータを取り込む際の料金が比較的高いため、SREの方々の悩みの種となることが多いかと思います。 私の観測する範囲ではECS/FargateのログはFireLensの登場以降、FluentBit経由で障害調査目的のログをCloudWatch Logsに、監査目的のログをS3に保存するパターンが多くなって来ている印象があります。 dev.classmethod.jp しかし、YappliではNew Relicを利用しているため障害調査目的のログはCloudWatch Logsを使うのではなく、可能な限りNew Relic側に寄せたいと考えています。 また、New Relicは長期のログ保管ができないため監査目的のログはS3に保存する方向で検討したいと思います。
Logs in Context
Logs in Contextとは
Logs in Contextとは簡単に書くとログをその他のデータ(APM, 分散トレース, etc.)と紐づけて見ることができる機能です。
例えば以下のようなことができます。
- APMでパフォーマンスに問題がありそうな時間帯を見つけそこからログを辿る
- ログからボトルネックになっている部分を探す
わかりやすいようにRedashでのLogs in Contextの利用例を記載します。
まずAPMの画面から13:01付近で処理が遅くなっていることがわかります。
ここからログの画面に飛ぶことができます。
ログの画面から怪しげなログを選択し、Exploreボタンを押すことで分散トレーシングの画面に飛ぶことができます。
分散トレーシングの画面からquery_resultという処理でDBにアクセスする際に時間がかかっていることがわかります。
パフォーマンス改善や障害調査に非常に役立つ機能であるため、New Relicを利用している場合利用しない手はないと考えています。
Logs in Contextの利用に必要なもの
Logs in Contextを利用するにはAPMエージェントを導入する必要があります。
APMエージェントの具体的なインストール方法はここでは割愛しますが、言語ごとに対応が異なるため注意が必要です。
例えばGo言語の場合ソースコードにモジュールを組み込む必要がありますが、Pythonの場合アプリケーションの起動コマンドを少しいじるだけで導入が可能です。
※ ログライブラリやアプリケーションフレームワークにAPMエージェントが対応していない場合はもう少し導入手順が煩雑になります。
参考: https://docs.newrelic.com/jp/docs/apm/new-relic-apm/getting-started/introduction-apm/
またNew Relicに転送したログをLogs in Contextに認識させるには、ログに付加情報(entity.guid, entity.name, hostname, trace.id, span.idなど)を与える(=Enrichmentを行う)必要があります。 これまではログのEnrichmentはユーザ側で行う必要がありましたが、最近のアップデートによりAPMエージェント側でEnrichmentを行うことができるようになっただけでなくログフォワーダーを介さずにログを転送することができるようなりました。
ログ転送パターン
以上の内容からNew Relicにログの転送を行い、Logs in Contextを利用できるパターンを比較しました。
言語ごとに若干の違いはありますが大まかに以下のいずれかのパターンとなります。
参考: https://docs.newrelic.com/jp/docs/logs/logs-context/logs-in-context/
1. APMエージェントからNew Relicに直接ログを転送する
- APMエージェントでログのEnrichmentを行い、エージェントからNew Relicに直接ログを転送するパターン
- 最新のエージェントバージョンの場合、これがデフォルトで有効化されている (※ 別の仕組みでログをNew Relicに転送している場合、二重転送となるので注意が必要)
- シンプルで導入しやすい方法であるが、New Relicのみにログを転送するため今回のように監査目的用のログを保存する必要がある場合は別途仕組み(ログフォワーダーでS3に転送する、Streaming ExportでNew RelicからFirehoseに配信する、etc.)が必要となりメリットが小さくなる
2. APMエージェントにログのEnrichmentだけを行ってもらいログをフォワーディングする
- APMエージェントにログのEnrichmentだけ行ってもらい、ログフォワーダーでNew Relicに転送するパターン
- New Relic以外にもログを転送したい場合(今回のユースケースのようにS3に監査目的用のログを保管したいなど)はこちらの方法が最も導入が楽である
3. ログのEnrichment処理を実装しフォワーディングする
- ログのEnrichmentを行う処理を追加し、ログフォワーダー経由でNew Relicに転送するパターン
- APMエージェントがログライブラリやアプリケーションフレームワークに対応していない場合こちらの方法となる
- Yappliでは上記に該当するため自力でのEnrichmentが必須であった (すでにサーバーサイドのメンバーが対応していた)
4. ログのEnrichment処理を実装しNew Relicに直接ログを転送する
- ログのEnrichmentを行う処理を追加し、APMエージェントからNew Relicに直接ログを転送するパターン
- 2022年12月2日現在対応していない (サポート問い合わせ回答より)
最適なアーキテクチャ
上記の結果からYappliではパターン3の「ログのEnrichment処理を実装しフォワーディングする」対応が必要であることがわかりました。
またログのEnrichment処理の実装自体はすでに対応が完了しているためLambda経由で転送していたログをFirehose(FireLens)経由に変更するだけでよさそうということがわかりました。
図にすると以下のようになります。
Before
After
ログ関連の料金比較
従来の料金と変更後の月額料金を比較してみると下記のようになります。
項目 | Before | After |
---|---|---|
CW Logs収集料 | =$0.76*500GB=$380 | 0 |
CW Logs保存料 | =$0.033*500GB=$16.5 | 0 |
Firehose収集料 | 0 | =$0.036*500GB=$18 |
S3保存料 | 0 | =$0.25*500GB*0.6=$75 |
Lambda利用料 | α | 0 |
New Relic利用料 | β | β |
合計 | $396.5+α+β | $93+β |
※1. 単価はap-northeast-1リージョン2022年12月19日現在の情報です
※2. ログ量は月500GBと仮定し、データ圧縮率は60%で算出しています
※3. 通信料や保存期間など細かい設定は無視しています
※4. FluentBitのログ量は通常少ないため考慮していません
上記の結果より月500GBのログ量の場合、月額で約300ドル近くコストが削減できることがわかりました。
まとめ
ECS/Fargateのログ転送方式の見直しとLogs in Context導入パターンの整理を行った結果、ログをFirehose経由でNew Relicに転送するように変更するだけでAWSの利用費が大幅に削減できることがわかりました。
残念ながらLogs in Contextの導入方法は変わらなかったため、今後のアップデートに期待したいと思います。