MY Scribbling...

AWS Community Hero Masanori YAMAGUCHI の 雑なメモ

【AWS Lambda編】New Relic で サーバーレスアプリケーション をモニタリングする

はじめに

New Relic 初心者の私が AWS Serverless Workshop の1つ AWS Innovator Island にNew Relic を計装することまでの記録を記事として残していきます。

github.com

その初回をCalendar for New Relic | Advent Calendar 2021 - Qiita 21日目として投稿します。

New Relic に対するわたしの知識レベル

  • New Relic のトレーニング受講などの経験なし
  • New Relic のオンラインセミナーに2回ほど参加した(k8sとObservabilityがテーマのもの)
  • New Relic 本と New Relic 公式サイトの情報をもとに進める
  • この記事で New Relic のアカウントをはじめて作成しました!

1. AWS アカウントと New Relic アカウントの接続

New Relic にAWSアカウントのインベントリを作成して、Lambda 関数の CloudWatch メトリクスを収集するため必要な手順

必要なもの

  • AWS CLI v2 がインストールされていて、aws configure などにより profile が登録されていること
  • Python 3.3 以降がインストールされていること
  • newrelic-lambda CLI がインストールされている
    pip3 install newrelic-lambda-cli でインストールできる
  • New Relic アカウントに対して、管理者の役割、またはインフラストラクチャマネージャーのadd-on role が必要(インフラストラクチャマネージャーの add-on role が何かは分からなかった
  • New Relic API ユーザーキー
  • IAM リソース、マネージドシークレット、Lambda関数 を作成するためのアクセス許可を持つIAM ユーザー(プロファイル)
    必要な権限は https://docs.newrelic.com/jp/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/account-linking/ に記載されている
1-1. newrelic-lambdaCLI をインストールする
$ pip3 install newrelic-lambda-cli
1-2. new relic cli を使って AWS アカウントと統合する
newrelic-lambda integrations install --nr-account-id <YOUR_NR_ACCOUNT_ID> \
--nr-api-key <YOUR_NEW_RELIC_USER_KEY>

任意の AWS CLI プロファイルを指定する場合は、--aws-profile オプションをつける

$ newrelic-lambda integrations install --nr-account-id 3XXXXXXX --nr-api-key NRAK-QQQQQQQQQQQQQQQQQQQQQQQQQQQ --aws-profile nr-test

下記のように実行ログが出力される。✨ Install Complete ✨ が出れば AWS アカウントと New Relic アカウントの接続は完了となる

Validating New Relic credentials
Retrieving integration license key
Creating the AWS role for the New Relic AWS Lambda Integration
Waiting for stack creation to complete... ✔️ Done
✔️ Created role [NewRelicLambdaIntegrationRole_3XXXXXXX] in AWS account.
Linking New Relic account to AWS account
✔️ Cloud integrations account [New Relic AWS Integration - 1XXXXXXXXXXXX] was created in New Relic account [3XXXXXXX] with IAM role [arn:aws:iam::1XXXXXXXXXXXX:role/NewRelicLambdaIntegrationRole_3XXXXXXX].
Enabling Lambda integration on the link between New Relic and AWS
✔️ Integration [id=1XXXXXXXX, name=Lambda] has been enabled in Cloud integrations account [New Relic AWS Integration - 1XXXXXXXXXXXX] of New Relic account [3XXXXXXX].
Creating the managed secret for the New Relic License Key
Setting up NewRelicLicenseKeySecret stack in region: ap-northeast-1
Creating change set: NewRelicLicenseKeySecret-CREATE-1XXXXXXXX
Waiting for change set creation to complete, this may take a minute... Waiting for change set to finish execution. This may take a minute... ✔️ Done
Creating newrelic-log-ingestion Lambda function in AWS account
Setting up 'newrelic-log-ingestion' function in region: ap-northeast-1
Fetching new CloudFormation template url
Creating change set: NewRelicLogIngestion-CREATE-1XXXXXXXX
Waiting for change set creation to complete, this may take a minute... Waiting for change set to finish execution. This may take a minute... ✔️ Done
✨ Install Complete ✨

実行結果として、下記の CloudFormation スタックがデプロイされる

  • NewRelicLambdaIntegrationRole
  • NewRelicLicenseKeySecret
  • NewRelicLogIngestion

2. テスト用の Lambda 関数による動作確認

公式手順: https://docs.newrelic.com/jp/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-example/

独自の Lambda 関数に計装する前にテスト用の Lambda で計装を学べるとのこと。これをスキップすると後でハマりそうなので試してみる。

Node.js、Python、Go、Java、.NET それぞれテスト用の Lambda 関数 があるが、Innovator Islands で使われる Lambda 関数は Node.js なので、今回は Node.js の Lambda 関数 を試してみる。

必要なもの

2.1 デプロイスクリプトの実行

githubリポジトリをクローンする

git clone [https://github.com/newrelic/newrelic-lambda-extension.git](https://github.com/newrelic/newrelic-lambda-extension.git)
cd newrelic-lambda-extension/examples/sam/node

AWS CLI の実行にプロファイル指定が必要な場合は下記のように deploy.sh を修正する

#!/bin/bash

accountId=$1
region=$2
profile=$3

echo "region set to ${region}"

sam build --use-container

bucket="newrelic-example-${region}-${accountId}"

aws s3 mb --region "${region}" "s3://${bucket}" --profile "${profile}"

sam package --region "${region}" --s3-bucket "${bucket}" --output-template-file packaged.yaml --profile "${profile}"

sam deploy \
    --region "${region}" \
    --template-file packaged.yaml \
    --stack-name NewrelicExampleNode \
    --capabilities CAPABILITY_IAM \
    --parameter-overrides "NRAccountId=${accountId}" \
    --profile "${profile}"

AWS CLI の実行にプロファイル指定が必要な場合は下記の引数で deploy.sh を実行する

./deploy.sh <NEWRERICID> <AWS REGION> <AWS CLIのプロファイル>

AWS CLI の実行時にプロファイル指定が必要ない場合は deploy.sh の修正は必要なく、第3引数を除外して deploy.sh を実行する

./deploy.sh <NEWRERICID> <AWS REGION> 

下記のように実行ログが出力され、newrelic-example-nodejs という Lambda 関数がデプロイされる

region set to ap-northeast-1
Starting Build inside a container
Building codeuri: /newrelic-lambda-extension/examples/sam/node/newrelic-example-node runtime: nodejs12.x metadata: {} architecture: x86_64 functions: ['NewRelicExample']

Fetching public.ecr.aws/sam/build-nodejs12.x:latest-x86_64 Docker container image......
Mounting /newrelic-lambda-extension/examples/sam/node/newrelic-example-node as /tmp/samcli/source:ro,delegated inside runtime container

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided

Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
make_bucket: newrelic-example-ap-northeast-1-3XXXXXX
Uploading to 655a6a97cb1410cc550ad7586848d5d1  128736 / 128736  (100.00%)

Successfully packaged artifacts and wrote output template to file packaged.yaml.
Execute the following command to deploy the packaged template
sam deploy --template-file /NR-Lambda/newrelic-lambda-extension/examples/sam/node/packaged.yaml --stack-name <YOUR STACK NAME>

    Deploying with following values
    ===============================
    Stack name                   : NewrelicExampleNode
    Region                       : ap-northeast-1
    Confirm changeset            : False
    Disable rollback             : False
    Deployment s3 bucket         : None
    Capabilities                 : ["CAPABILITY_IAM"]
    Parameter overrides          : {"NRAccountId": "3XXXXXX"}
    Signing Profiles             : {}

Initiating deployment
=====================

Waiting for changeset to be created..

CloudFormation stack changeset
-------------------------------------------------------------------------------------------------
Operation                LogicalResourceId        ResourceType             Replacement
-------------------------------------------------------------------------------------------------
+ Add                    Logs                     AWS::Logs::LogGroup      N/A
+ Add                    NewRelicExampleRole      AWS::IAM::Role           N/A
+ Add                    NewRelicExample          AWS::Lambda::Function    N/A
-------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:7XXXXXXXXXXX:changeSet/samcli-deploy1639833290/7b9bdabd-6dd0-45e8-b377-cc04161b0e44

2021-12-18 22:15:02 - Waiting for stack create/update to complete

CloudFormation events from stack operations
-------------------------------------------------------------------------------------------------
ResourceStatus           ResourceType             LogicalResourceId        ResourceStatusReason
-------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS       AWS::IAM::Role           NewRelicExampleRole      -
CREATE_IN_PROGRESS       AWS::IAM::Role           NewRelicExampleRole      Resource creation
                                                                           Initiated
CREATE_COMPLETE          AWS::IAM::Role           NewRelicExampleRole      -
CREATE_IN_PROGRESS       AWS::Lambda::Function    NewRelicExample          -
CREATE_IN_PROGRESS       AWS::Lambda::Function    NewRelicExample          Resource creation
                                                                           Initiated
CREATE_COMPLETE          AWS::Lambda::Function    NewRelicExample          -
CREATE_IN_PROGRESS       AWS::Logs::LogGroup      Logs                     -
CREATE_IN_PROGRESS       AWS::Logs::LogGroup      Logs                     Resource creation
                                                                           Initiated
CREATE_COMPLETE          AWS::Logs::LogGroup      Logs                     -
CREATE_COMPLETE          AWS::CloudFormation::S   NewrelicExampleNode      -
                         tack
-------------------------------------------------------------------------------------------------

Successfully created/updated stack - NewrelicExampleNode in ap-northeast-1

New Relic One のコンソールから確認すると Instrumental が Yes の Lambda 関数としてデプロイした Lambda 関数が表示されている

f:id:kinunori:20211219193553p:plain

実行時間やエラーレート、コールドスタート、さらにトレースなどの情報がとれた。Insturmental が Yes ではない Lambda 関数の場合、CloudWatch メトリクスとして記録されている情報は確認できたが、コールドスタートやトレースなどの情報は確認できないという違いがあった

手順1で作成された newrelic-log-ingestion という Lambda 関数は実行されていないようで、このLambda 関数の出番は今のところ不明

f:id:kinunori:20211219193608p:plain

次回は Innovator Island の Lambda 関数で New Relic へのテレメトリーデータ送信を計装してみる