このエントリは Mackerel Advent Calendar 2022 および GitHub Actions Advent Calendar 2022 の20日目の記事です。*1
今回はMackerelのサービスメトリックを投稿するためのGitHub Actionsを新規で作ったのでその紹介をします。
- GitHub Actions経由でメトリクスを簡単にMackerelに投稿したい
- 既存のGitHub Actions
- 自分のユースケースでの気になり
- stefafafan/post-mackerel-metrics の紹介
- 初めて作ったGitHub Actionについての感想や困りなど
- 終わりに
GitHub Actions経由でメトリクスを簡単にMackerelに投稿したい
弊社ではよくメトリクスをMackerelに投稿しています。事例としては以下のようなものがあります。
- 定期的にコードの行数を数えてMackerelに投稿する
- TODOコメントの数を数えてMackerelに投稿する
- ビルド時間を計測してMackerelに投稿する
- PageSpeed Insightsの計測結果をMackerelに投稿する
Mackerelのサービスメトリックとして投稿するにはAPIキーを用意し、以下のドキュメントに従ってPOSTするだけで簡単にできます。GitHub Actions上で素朴に実装するならばリクエストを手作りしてからcurlでPOSTする、とかになるでしょうか。 mkr をインストールして実行するというやり方もあるかもしれません。
mackerel.io
既存のGitHub Actions
既存のGitHub Actionsがいくつかあるのでそれらを使うことはできます。
yutailang0119/action-mackerel-api
yutailang0119/action-mackerel-api
を使う場合は以下のような記述でサービスメトリックを投稿することができます。
- uses: yutailang0119/action-mackerel-api@v3 with: api-key: ${{ secrets.MACKEREL_APIKEY }} http-method: POST path: services/${{ secrets.MACKEREL_SERVICENAME }}/tsdb body: | [ { "name": "foo-metric.count", "time": 1670747231, "value": 12345.678 } ]
susisu/setup-mkr
susisu/setup-mkr
はGitHub Actions上で簡単に mkr をセットアップするためのActionです。 mkr throw
を使えばサービスメトリックの投稿ができます。
- uses: susisu/setup-mkr@v1 - run: echo "foo-metric.count 12345.678 $(date +%s)" | mkr throw --service ${{ secrets.MACKEREL_SERVICENAME }} env: MACKEREL_APIKEY: ${{ secrets.MACKEREL_APIKEY }}
なおGitHub ActionsのRunnerとしてUbuntu等で動かしている場合は普通にmkrをインストールする形でも問題ないです。
紹介記事:
susisu.hatenablog.com
自分のユースケースでの気になり
上記のようなActionsでやりたいことは実現できますが、自分の場合サービスメトリック以外の機能をGitHub Actionsで使うケースが少ないのでちょっとオーバーキルだと感じました。
yutailang0119/action-mackerel-api
はREADMEを見る限り色々なAPIを網羅的に対応するような薄いラッパーで、mkr
に関しては強力だけどサービスメトリックへのPOSTのためだけにこれをインストールするほどでもないなとも。
あとは単純に自分でもCustomなGitHub Actionsを作ってみるという経験がほしかったというのもあります(これが一番大きい)。
stefafafan/post-mackerel-metrics の紹介
ということで作りました。
サービスメトリックを投稿したい場合は以下のような使い勝手になります。
uses: stefafafan/post-mackerel-metrics@v1 with: api-key: ${{ secrets.MACKEREL_APIKEY }} service-name: ${{ secrets.MACKEREL_SERVICENAME }} metric-name: 'foo-metric.count' metric-value: 12345.678
推しポイントとしては以下のような点があります。
- mkr のダウンロードは不要なので軽量で素早い
- APIの仕様やmkrの使い方など詳細を知らなくても使えるシンプルさ
- JSONの組み立てなども不要なのでMackerelに投稿するために凡ミスで四苦八苦することが少ないはず
- 投稿日時は内部で現在時刻を指定してくれるのでGitHub Actions上で
$(date +%s)
のようなことをやる必要がない
また、複数のサービスメトリックを同時に投稿したい場合は metrics
という input で Multiline String をサポートしているので以下のように指定して投稿できるようにしてあります。
uses: stefafafan/post-mackerel-metrics@v1 with: api-key: ${{ secrets.MACKEREL_APIKEY }} service-name: ${{ secrets.MACKEREL_SERVICENAME }} metrics: | foo-metric.count 12345.678 1670747999 foo-metric.count2 7777.777 1670747999
上記の形式はMackerelのプラグインや mkr throw
するときのフォーマットに揃えてあるので馴染み深い形になっていると思います*2。Actionの内部実装としては \s+
区切りでパースしてあるのでタブ文字でもスペースでも複数スペース連続していても問題なく利用できる形にしてあります。また、最後のタイムスタンプも省略して現在日時を内部で採用してもらうという使い方もできます。
逆に使えないユースケースとしては、サービスメトリックの投稿に特化しているので、他のAPIであれこれしたい場合は yutailang0119/action-mackerel-api
や mkr
を使ってください。
実際に活用している事例
リポジトリにもWorkflowの例を載せていますが、以下のような記述をすれば簡単にコードの行数をMackerelに投稿することができます。
name: Count and Post lines of Code to Mackerel on: push: branches: - main jobs: count-and-post: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - id: count-lines name: count lines of TypeScript code run: | lines=$(find src/ -name '*.ts' -print0 | xargs -0 cat | wc -l | tr -d ' ') echo "lines=${lines}" >> $GITHUB_OUTPUT - name: Post to Mackerel uses: stefafafan/post-mackerel-metrics@v1 with: api-key: ${{ secrets.MACKEREL_APIKEY }} service-name: ${{ secrets.MACKEREL_SERVICENAME }} metric-name: 'lines.typescript' metric-value: ${{ steps.count-lines.outputs.lines }}
Mackerelのサービスメトリックへの投稿が面倒そうと思って敬遠している方がもしいれば参考にしてもらえれば幸いです。
テクニック紹介: 他のStepからMultiline Stringの受け渡し
例えばGitHub Actionsの他のStepで計算した複数の値を1つずつOutputとして出力するのではなく、まとめてMultiline Stringとして受け渡したくなるかもしれません。こちらについても紹介しておきます。
Bashで色々やっている場合はdelimiterを指定しつつ $GITHUB_OUTPUT
に出力するということをやることになります。以下の例ではActions上で直接メトリックの結果をechoしてありますが、これをたとえば実行可能なshell scriptとして用意しておいてActions内ではそれを実行して $GITHUB_OUTPUT
に出力するだけ、みたいに実現することもできそうです。
- id: multiline-output run: | delimiter="$(openssl rand -hex 8)" echo "metrics<<${delimiter}" >> $GITHUB_OUTPUT echo "multiline.metric1 12345 $(date +%s)" >> $GITHUB_OUTPUT echo "multiline.metric2 67890 $(date +%s)" >> $GITHUB_OUTPUT echo "${delimiter}" >> $GITHUB_OUTPUT - name: Post to Mackerel uses: stefafafan/post-mackerel-metrics@v1 with: api-key: ${{ secrets.MACKEREL_APIKEY }} service-name: ${{ secrets.MACKEREL_SERVICENAME }} metrics: ${{ steps.multiline-output.outputs.metrics }}
参考ドキュメント
- https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
- https://github.com/orgs/community/discussions/26288#discussioncomment-3876281
actions/github-script を使いたい場合は core.setOutput
を利用して受け渡しすることができます。
- id: multiline-output uses: actions/github-script@v6 with: result-encoding: string script: | const metrics = ` multiline.metric1 12345 multiline.metric2 67890 multiline.metric3 77777 `; core.setOutput('metrics', metrics); - name: Post to Mackerel uses: stefafafan/post-mackerel-metrics@v1 with: api-key: ${{ secrets.MACKEREL_APIKEY }} service-name: ${{ secrets.MACKEREL_SERVICENAME }} metrics: ${{ steps.multiline-output.outputs.metrics }}
GitHub APIであれこれした後にまとめてサービスメトリックとして投稿したい場合はこういう風にMultiline StringをOutputして利用すると良いでしょう。
初めて作ったGitHub Actionについての感想や困りなど
今回CustomなGitHub Actionを作るにあたって参考にしたのは主に以下のドキュメントです。
またリポジトリについては TypeScript Action を作るためのテンプレートリポジトリがあったので以下のテンプレートを利用しました。
テンプレートがあるのは初めて作る上でとても助かりました。構成やCIの整備などに迷うことなく既にある雛形に自分のコードを追加する形で作れました。脆弱性検知をしてくれるCodeQLのActionが最初から組み込まれているのも良いですね。
一方でこのテンプレートで利用しているライブラリの依存が更新されていないという点が気になりで、実装を始める前にDependabotを有効化したらそれだけで9つのPull Requestが開かれて体験が悪かったです。気になったので最初はひたすらバージョンを上げていました。
バージョンといえばJavaScript Actionが使うNode.jsのバージョンも現状 v12 か v16 固定というポイントもちょっとイマイチでした。この記事を書いてる段階では Node.js v18 が Active LTS なのでそれを最初から指定したかったですがそうは行かないようでした。しょうがないですね。
github.com
何はともあれサクッと自分がほしいと思ったCustomなGitHub Actionを作れたので満足しています。
終わりに
この記事は Mackerel Advent Calendar 2022 および GitHub Actions Advent Calendar 2022 の記事でした。
Mackerel Advent Calendar 明日は id:buty4649 さんの予定です。GitHub Actions Advent Calendarは @taptappun さんの予定です。お楽しみに!