ことの発端
Lambda(Node.js) に log4js を入れて、ログレベルを分けてロギングさせようとした。
↓
いざ出力してみると1行ごとに CloudWatch のログが出力されている。
↓
console.log の出力では改行しても 1 行(1 つのタイムスタンプ)で出力されるという違いに気づく。
↓
行数が増えて課金額が増えてしまうのでは???
↓
調査しよう。
ログのテスト
このようなテスト用のオブジェクトの配列を用意しました。
これを出力します。
const testObjects = [
{
key1: "test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1",
key2: "test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1",
key3: "test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1test1",
},
{
key1: "test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2",
key2: "test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2",
key3: "test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2",
},
{
key1: "test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3",
key2: "test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3",
key3: "test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3test3",
},
]
console.log で出力
まずは通常の console.log で出力します。
console.log(testObjects)
こちらが結果の一部です。
log4js で出力
log4js で出力してみます。
const logger = log4js.getLogger()
logger.level = log4js.levels.ALL
logger.info(testObjects)
こちらが結果の一部です。
2 つの手法の出力の違い
見てもらうとわかるように、log4js では行が分かれてしまっています。
その分タイムスタンプの文字列が増えるので、ログ容量も増えると予測されます。
因みに log4js では、文字化けして?が表示されていますが、エクスポートして確認したところ、U+001B(エスケープ)でした。
CloudWatch メトリクスでログの容量を見てみる
IncomingBytes を見ることでログデータの量を出すことができそうです。
取り込み料金には、CloudWatch Logs サービスによって取り込まれたログデータの量が反映されます。CloudWatch メトリクス IncomingBytes は、サービスによって処理されたログデータの量を報告します。このメトリクスを CloudWatch グラフまたはダッシュボードで視覚化することで、さまざまなワークロードによって生成されるログの量をモニタリングできます。
https://repost.aws/ja/knowledge-center/cloudwatch-understand-and-reduce-charges
ということで、以下の条件でメトリクスを検索し、容量を割り出してみます。
- 名前空間:AWS/Logs
- メトリクス名:SUM(IncomingBytes)
- フィルター条件:LogGroupName=/aws/lambda/関数名
1.console.log のパターン
2,065 Byte
2.log4js のパターン
2,612 Byte
約 550 バイトの差が出ました。
料金計算
東京リージョンでの料金(23/07/04 時点)
- 収集 (データの取り込み):0.76USD/GB
- 保存 (アーカイブ):0.033USD/GB
差を見たいので、無料分は無視します。
pricing calculator がちょうど使えそうだったので、これで計算します。
例えばテストで試したログが 100 万回実施され、1 か月保存した場合で計算してみます。
2065Byte × 100 万回 ≒ 1.92GB
2612Byte × 100 万回 ≒ 2.43GB
これだけのログでもおよそ 0.39USD の差がありますね。
1USD が 144 円だと、56 円程度です。
実際業務で扱うようなログはもっと多くのデータがあることが多いと思うので、かなり差が開いていくと思います。
因みに保存の料金は、15%程に圧縮されてその容量が課金計算に使われるようです。(知らなかった)
最後に
Lambda で log4js を使うと CloudWatch Logs で 無駄に行が多くなる場合があり、費用が増加する可能性があることがわかったので、利用を避けようと思います。
設定次第でどうにかなるんでしょうか。
そもそも log4js の機能である、ローテートとかファイル出力が Lambda と相性が悪いと思っているので、わざわざ使う必要もないかなと思います。