LoginSignup
4
1

LambdaからのLambda呼び出し、Instanaでどう見える?

Last updated at Posted at 2023-12-31

はじめに

以前、こちらの記事を投稿しましたが、その後さらにLambdaから別のLambdaを呼び出した際、どの様にInstana側で見えるのか?ちゃんとトレースは追えるのか?を検証する機会があったので記事に起こしました。

前回はPythonでしたが、今回はNode.js(14.x)で試しています。

では早速いきましょう

子となるLambdaの準備

Lambdaの作成

関数名を任意のもの、ランタイムを Node.js 14.x に設定し、[関数の作成]をクリックします。
image.png

このLambdaが呼び出されるたびランダムに正常/異常のレスポンスおよびログ出力を行うように上書きします。

exports.handler = async (event) => {
  var ok = [100, 200, 300];
  var ng = [400, 500];

  const ri = Math.floor(Math.random() * 11);
  if (ri <= 2) {
    const mes = "something error occurred!: " + ri;
    console.error('(child)' + mes);
    return {
      statusCode: ng[Math.floor(Math.random() * ng.length)],
      body: JSON.stringify(mes),
    };
  } else if (ri <= 5) {
    console.warn("(child)something warn occurred!: " + ri);
  } else {
    console.info("(child)healthy!: " + ri);
  }
  return {
    statusCode: ok[Math.floor(Math.random() * ok.length)],
    body: JSON.stringify('Hello Instana!: ' + ri),
  };
};

変更ができたら、[Deploy] をクリックします。
動作を確認したい方は、Testにてテスト用のイベントを作成(デフォルトのままでOKです)し何度か実行してみましょう。

Instanaの設定

Instanaのトップ画面から[エージェントのデプロイ]をクリックします。

プラットフォームはAWS,
テクノロジーはAWS Lambda,
LambdaランタイムはNode.js 10.x以降,
AWSリージョンは自身の作成したリージョン(今回は東京リージョンなのでap-northeast-1)
を選択します。
image.png

設定値が表示されたらLambda側に入力していきます。

レイヤーの追加

[レイヤーの追加] をクリックし、[ARNを指定] を選択し、Instana側に表示されているARNをコピペします。
[検証] をクリックすると、情報が取得できるはずなので、エラーになる場合はコピペを再度してみてください。
問題なければ [追加] をクリックします。
image.png

ハンドラーの変更

ランタイム設定の [編集] をクリックし、Instana側に表示されているハンドラで上書きしたら [保存] をクリックします。
image.png

環境変数の追加

[設定タブ] > [環境変数] > [編集] をクリックします。
INSTANA_ENDPOINT_URLINSTANA_AGENT_KEYの2つを新たに設定し [保存] をクリックします。
image.png

Instana側で任意の名前で表示をしたい場合は、INSTANA_SERVICE_NAME を設定します。

親となるLambdaの準備

IAMの設定

親→子のLambda呼び出しを実現するために、AWS SDKのInvokeを使用します。
その際、IAMロールにて"lambda:InvokeFunction"のポリシーを許可しておく必要があるので、IAMの設定から始めます。

ポリシーの作成

AWSのコンソールから [IAM] > [アクセス管理] > [ポリシー] > [ポリシーの作成] と進みます。
ポリシーエディタをJSONに変更し、下記JSONで上書きした後 Resource の値を変更します。
リソースを絞らない場合は "*" でもOKです。

カスタム信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "子のlmabdaのARN"
            ]
        }
    ]
}

[次へ] をクリックします。

ポリシー名に任意の名前を入力し、 [ポリシーの作成] をクリックします。
image.png

ロールの作成

[アクセス管理] > [ロール] > [ロールを作成] と進みます。

エンティティタイプはAWSのサービス、ユースケースはLambdaを選択して [次へ] をクリックします。
image.png

先ほど作成したポリシーを追加して [次へ] をクリックします。
image.png

ロール名に任意の名前を入力して、[ロールを作成] をクリックします。
image.png

Lambdaの作成

関数名を任意のもの、ランタイムを Node.js 14.x に設定します。

デフォルトの実行ロールの変更で 既存のロールを使用する を選択し、先ほど作成したロール(今回は exec_lambda )を指定します。
今回もサクッと試したいので、関数URLを有効化し認証タイプは NONE を指定し [関数を作成] をクリックします。
image.png

親のLambdaの実装は受け取ったレスポンスのHTTPステータスコードおよびボディをそのままレスポンスとして返すように上書きします。(warningもInstana側で見たかったので3xx系を使ってます。深い意味はありません)

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
exports.handler = async (event) => {
    const params = {
        FunctionName: '子のLambda名(今回の場合は'qiita_child')',
        InvocationType: 'RequestResponse',
    };
    
    const response = await lambda.invoke(params).promise();
        
    const statusCode = JSON.parse(response.Payload).statusCode;
    const body = JSON.parse(response.Payload).body;
    console.log(statusCode);
    
    switch (statusCode){
        case 500:
        case 400:
            console.error("(parent)error statusCode : " + statusCode);
            return {
                statusCode: statusCode,
                body: JSON.stringify('error : ' + body)
            };
        case 300:
            console.warn("(parent)warn statusCode : " + statusCode);
            return {
                statusCode: statusCode,
                body: JSON.stringify('warn : ' + body)
            };
        default:
            console.info("(parent)healthy statusCode : " + statusCode);
            return {
                statusCode: statusCode,
                body:JSON.stringify(body),
            };
    };
};

変更ができたら、[Deploy] をクリックします。
動作を確認したい方は、Testにてテスト用のイベントを作成(デフォルトのままでOKです)し何度か実行してみましょう。

初回起動時はLambdaがコールドスタートになる都合もあり少し時間がかかります。
タイムアウトはデフォルト3秒なのでエラーになる可能性が高いですが、何度か実行すると正常に動作する様になります。

Instanaの設定

子側と同じため割愛します。

Instanaで見てみよう

ターミナルで下記コマンドを実行して、1秒ずつLambdaを叩いて様子を見てみましょう。

watch -n 1 "curl 親の関数URL"

Instanaのホーム画面から、[アプリケーション] > [サービス] と移動し、テクノロジーを AWS Lambda で絞り込みます。
まずは無事に親と子が出ていますね。(node14_child, node14_parent)
image.png

親側を開いてみると良い感じにゴールデンシグナルが見えています。
image.png

呼び出しの棒グラフをクリックして、 [分析で表示] をさらにクリックし深掘りしてみます。

色々発生していますが、今回は500エラーの中身を見てみましょう。
適当な呼び出し(GET /)をクリックします。
image.png

そうするとトレースの画面に飛びます。
しっかりと子Lambdaまでトレースが取れていることも確認できます。
image.png

ログはどこで吐き出しているかわかる様に頭に(child)もしくは(parent)と出力する様に実装していたのですが、それぞれのログも1画面で見られる様になっています。
良い感じ!
image.png

その他画面

こんな感じで見ることできますよ〜と画面キャプチャを一応残しておきます。

フロー

image.png

この画面でわかる様に、Invokeで別のLambdaを呼び出す際、HTTPではなくRPCを使用します。
そのため、子のLambdaの画面を開くと、HTTPステータスコードの内訳を確認することができませんのでご注意ください。

エンドポイント

image.png

エラー・メッセージ

image.png

ログ・メッセージ

image.png

まとめ

以上でこの記事は終了です。
Lambdaから別のLambdaを呼び出した時もそれほど大きな修正なくトレースが取れることを確認できたかな、と思います。

参考になれば幸いです。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1