[アップデート]CloudWatch dashboardに任意のLambda関数の結果を表示できるcustom widgetsが使えるようになりました

2021.08.28

CloudWatch dashboardに、任意のLambda関数の結果を表示できるという新機能、custom widgetsがリリースされました。

まずはどんなものか見てください。

customWidgetEcho-js-us-east-1

はい、ダッシュボード内に文字列とか、テキストフォームとかが入ったウィジェットがありますね。こちらはAWSから提供されているcustom widgetのサンプルです。

仕組み

dashboardをつくるCFnテンプレートResourcesセクションが以下です。

  demoDashboard:
    Type: AWS::CloudWatch::Dashboard
    Condition: CreateExampleDashboard
    Properties:
      DashboardName: !Sub ${AWS::StackName}-${AWS::Region}
      DashboardBody:
        !Sub
          >
          {
              "widgets": [
                  {
                      "type": "custom",
                      "width": 12,
                      "height": 8,
                      "properties": {
                          "endpoint": "${lambdaFunction.Arn}",
                          "params": {
                              "echo": "<h1>Echo echo echo</h1>"
                          }
                      }
                  },
                  {
                      "type": "custom",
                      "width": 12,
                      "height": 8,
                      "properties": {
                          "endpoint": "${lambdaFunction.Arn}",
                          "params": {
                              "echo": "<h2 style='color:red';>Input:</h2><input type='text' value='echo'>"
                          }
                      }
                  }
              ]
          }

DashboardBodyでtypeがcustomのwidgetsが2つ定義されていますね。そしてendpointにLambda関数のARNが指定されています。paramは関数実行時に渡されるパラメーターです。

このLambda関数の中身を見てみましょう。

// CloudWatch Custom Widget sample: simple echo script
const DOCS = `
## Echo
A simple echo script. Anyting passed in \`\`\`echo\`\`\` parameter is returned as the content of custom widget.

### Widget parameters
Param | Description
---|---
**echo** | The content to echo back

### Example parameters
\`\`\` yaml
echo: <h1>Hello world</h1>
\`\`\`
`;

exports.handler = async (event) => {
    if (event.describe) {
        return DOCS;   
    }
    return event.echo || '<pre>No "echo" parameter specified</pre>';
};

下から2行目でreturn event.echoとしていますね。つまり関数に渡されたパラメーターechoをそのまま返す関数です。CFnテンプレート内の1つ目のwidget(=最初にお見せしたダッシュボード内の左側のwidget)は<h1>Echo echo echo</h1>をパラメーターとして渡しているので、大きい字で「Echo echo echo」が表示され、2つ目のwidget(=ダッシュボード内の右側のwidget)のパラメーターは<h2 style='color:red';>Input:</h2><input type='text' value='echo'>なので、赤字のテキストとテキストフォームが表示されたわけです。

こんな感じで、HTMLを返すLambda関数を作成してそれを呼ぶwidgetを作成すると、関数実行結果がdashboardに表示される、という機能です。

JSON、MarkdownもOK

Lambda関数の返り値はJSONでも構いません。整形された状態でJSONがwidgetに表示されます。 cwdb-json.png

またMarkdownもOKです。Markdownの場合は以下のようにmarkdown要素の値として返す必要があります。

exports.handler = async (event) => {
    const md = `
# h1
## h2
- aaaa
  - bbbb
`;
    let retObj = { markdown: md};
    return retObj;
};

markdown-result2

ユースケース

Lambda関数が使えてHTMLが使えるので、実質あらゆるデータをあらゆる方法で表示できるようになったと言ってよいのでは無いでしょうか。複数種類のデータソースからグラフを作る、みたいなことができますね。また、リンクを設置することで、関連ページへの移動を容易にする/何かアクションを実行するといった使い方もできそうです。

custom widget内のボタンからさらにLambda関数を呼ぶこともできる

<cwdb-action>という特殊タグを使うことで、custom widget内のボタンからさらにLambda関数を呼ぶこともできちゃいます。前述の「何かアクションを実行するボタン」の作成が捗りますね。

aタグを置いて、その直後に<cwdb-action>タグを配置します。というHTMLを返すLambda関数をcustom widgetに設定します。

<a class="btn">execute lambda</a>
<cwdb-action 
    display="widget"
    action="call" 
    endpoint="arn:aws:lambda:us-east-1:123456789012:function:cwdb-action-test"
> 
</cwdb-action>

<cwdb-action>で呼び出されるLambda関数の中身は以下です。

exports.handler = async (event) => {
    // TODO 何か処理を実行する
    const response = 'result'
    return response;
};

この状態でdashboardを開くと、ボタンが一つあるwidgetが表示されます。 cwdb ボタンをクリックすると… cwdb-result Lambda関数が実行され、返り値でwidgetの中身が更新されました。

上記はLambda関数結果でwidgetを更新する例でしたが、Lambda関数を使わなかったり、widgetの中身を更新する代わりにポップアップを表示したり、クリックの代わりにダブルクリックやマウスオーバーでアクションをトリガーしたりもできます。詳細は以下を御覧ください。

Lambda関数にはdescribeパラメーターの定義を推奨

custom widgetで呼び出すLambda関数のコードでは、describeパラメーターを渡すと関数の使い方を返すようにしておくと良いです。custom widgetの作成が捗ります。最初に載せたサンプル関数もそうなってますね。

再掲

// CloudWatch Custom Widget sample: simple echo script
const DOCS = `
## Echo
A simple echo script. Anyting passed in \`\`\`echo\`\`\` parameter is returned as the content of custom widget.

### Widget parameters
Param | Description
---|---
**echo** | The content to echo back

### Example parameters
\`\`\` yaml
echo: <h1>Hello world</h1>
\`\`\`
`;

exports.handler = async (event) => {
    if (event.describe) {
        return DOCS;   
    }
    return event.echo || '<pre>No "echo" parameter specified</pre>';
};

  こうしておくと、custom widget作成フォームで関数を選んだ後に、「Get documentation」ボタンが表示されます。 get-doc1.png

このボタンを押すと、describeパラメーターを渡した状態で該当の関数が実行され、その結果がフォームに表示されます。 パラメーターの指定方法などを書いておくと便利でしょう。 get-doc2

ただしこの「Get documentation」ボタンはCloudWatch Dashboardの新しいインターフェイスでしか使えないようです。(現在Dashboardは新旧のインターフェイスを切り替えられるようになっています。)旧インターフェイスになっている場合はまず右上のリンクから新版に切り替えてください。 link-to-new

その他細かい仕様

  • リリース情報には大阪リージョンで使えると書いてなかったのですが、大阪リージョンでも使えました。(謎)
  • custom widgetを使うのに追加料金はかかりません。が、custom widgetが表示されるたびにLambda関数が実行されるので、その料金はかかります。
  • セキュリティの観点により、関数が返すHTML内にJavaScriptは使えません。削除されます。<iframe><use>タグなども同様です。
  • widget内の要素はデフォルトでdashboardのスタイルが適用されますが、cwdb-no-default-styleクラスを付与することでこれを無効化できます。
  • aタグにbtnクラスを付与することで、AWSコンソール標準のボタンのデザインが簡単に使えます。
    • <a class="btn" href="https://amazon.com”>Open Amazon</a> btn
  • btn btn-primaryクラスだと強調表示されたAWSコンソール標準のボタンのデザインが使えます。
    • <a class="btn btn-primary" href="https://amazon.com”>Open Amazon</a> btn-primary

サンプルいっぱいあるし触ってみるのがいいよ

すでに沢山のサンプルが用意されているので、まずはこちらのページから読み進めてとりあえずcustom widgetを作って見るのが楽しいかと思います。面白い使い方を是非編み出してください!

参考情報