New Relic のサーバーレスモニタリング for AWS Lambdaを手動で導入してみた

稼働中のシステムで何がおきているかは調べたい、でも変更は最小限にしたい、、、という脳内想定でお送りします。
2020.12.16

みなさん、可観測性してますか!(誤用

本記事はNewRelic Advent Calendar 2020の16日目の記事です。

少し前に、AWS Lambda にLambda Extensionsという機能がプレビューリリースされました!
みなさんもご記憶のことと思います。

それにあわせて、New Relic の Lambda 向けサーバーレスモニタリングも Lambda Extensions を使ったものに切り替わったそうです。

詳細は上の記事を読んでもらうとして、利用者側としては「APM のようにがっつりコードに埋め込まなくても、ログやメトリック以上のデータが手に入るような気がしてうれしくなります。

本当にそうなのか? とりあえず既存の Lambda 関数にnewrelic-lambda-extensionだけ追加してみてみました!

ドキュメント

このあたりのドキュメントを参照しつつすすめます。

公式手順はnewrelic-lambda CLI を使って、CloudWatch Logs やメトリクス(AWS インテグレーション)までがつっと設定する流れですが、仕組みを理解する意味でも、ここからnewrelic-lambda-extentionをくっつける部分だけ手動でやってみます。
あまりこの方法に関する公式情報がまとまってないのですが、上記リポジトリ内の README やサンプルスクリプト・テンプレートなどを眺めたりすると、なんとなく見えてきますね。

今回は Python で書かれた Lambda を対象にするので、このあたりを眺めつつ進めます。

流れ

  • New Relic のアカウント ID を確認し、ライセンス・キーを発行しておく
  • 既存 Lambda にnewrelic-lambda-extensionLayer をくっつける
  • 既存 Lambda の設定を変更する
    • 環境変数を追記(後述)
    • ハンドラをnewrelic-lambda-extensionのものに変更
      • newrelic_lambda_wrapper.handler

という感じでよさそうです。追加で設定する環境変数は下記のとおりです:

キー
NEW_RELIC_LAMBDA_HANDLER もともとのハンドラ
NEW_RELIC_ACCOUNT_ID New Relic アカウント ID
NEW_RELIC_LICENSE_KEY 同ライセンス・キー
NEW_RELIC_LAMBDA_EXTENSION_ENABLED true

ライセンス・キーは本来管理を厳重にする必要があるため、公式では AWS Secrets Manager を利用する手順となっていますが、ここでは動作検証が目的なのでそのまま環境変数にいれてます。

なお、アカウント ID の調べ方やキーの発行方法については、不明な方はここらあたりが参考になると思いますのでご参照ください!

被験者

観測する対象の Lambda 関数ですが、適当なものが手元になかったので、Blueprint から作った素のhello-world-pythonを使いました(観測してもあまり面白くなさそうと思いつつ)。

  • Runtime : Python 3.7
  • Handler : lambda_function.lambda_handler

Runtime が 3.7 なので、適用するnewrelic-lambda-extensionARN は下記になります:

  • arn:aws:lambda:ap-northeast-1:451483290750:layer:NewRelicPython37:27

やってみた

前置きが長くなってしまいましたが、さっそくやってみます!

1. newrelic-lambda-extension の追加

AWS マネジメントコンソールの Lambda 画面で該当の Lambda(hello-world-python)の詳細を開き、デザイナーで Layers を選択、「レイヤーの追加」をクリックします。

「ARN を指定」を選択し、上で調べた ARN を入力します。

2. 環境変数の追加・ハンドラの変更

同じくマネジメントコンソールの画面で、デザイナーで Lambda 関数(hello-world-python)を選択。
必要事項を記入して「保存」をクリックします。

ハンドラもnewrelic-lambda-extensionのものに変更します。

警告がでてきますがいったんはスルーしましょう。

以上で準備完了です!

実行

テスト実行してみたのがこちらです。[NR_EXT] となっているところがnewrelic-lambda-extensionの実行結果のようですね、送信成功となってます!

確認

どんなデータが収集されているか、New Relic 上で確認してみます。
実は上記だけだと New Relic 上で確認ができなかったので、下記を参考にインテグレーションの設定もしています(ぼくの確認方法が悪いだけかもしれませんが)。

収集対象のサービスに Lambda を入れておきます。

再度テストを複数回実行して少し時間をおくと、New Relic上のEntity explorer > Lambda functionsから以下のようなデータが確認できました。

Function ごとの Duration など、インテグレーションの設定だけだと収集できない、Distributed tracing(分散トレーシング)のデータが収集できてますね!
今回の試験対象の Lambda 関数内に Function がひとつしかないので、まったく面白みがありませんがw

また余録になりますが、newrelic-lambda-extensionを追加したことで、下記のような簡単なコード で New Relic にカスタムメトリクスを送信することが可能になるそうです。

from newrelic import agent

agent.record_custom_event ("MyPythonEvent", {
    "zip": "zap"
})

agent.add_custom_parameter ('customAttribute',
    'customAttributeValue'
)

ビジネス KPI などはこの方法で送信するとよさそうですね。

新しい価格体系のおかげで、こういった情報も Free プランのまま観測できるようになりました。使わない手はないと思います!

まとめ

可観測性は高めたい、でもコードにはなかなか手を入れられない。そういうケースは少なくないと思いますが、まずは最小限の変更で出来ることもあります。いろいろとやってみましょう!