izumotto blog

たまには真面目に

MackerelとMS Flowでポプテピピックのクソ具合を監視する

はてな社のサーバ監視サービスMackerel(マカレル)を使ってみたい気持ちが前からあったので、前回の記事に引き続きMicrosoft Flowを活用してサーバじゃない何かを監視してみようと思い立った結果、Twitterのツイート情報からポプテピピックのクソ具合を監視してみたという内容です。

※監視までの手順をじっくり書いてます。監視結果だけ知りたい場合はページ下部の4)通知を受け取るへどうぞ。

 

目次

 

今回やること

 今回Flowで実装するのは以下のフローです。

  1. 「#ポプテピピック」を含むツイートを15分毎に100件取得
  2. 取得した100ツイートの内「クソ」が含まれるツイート数をMackerelに送信
  3. クソ具合が高まるとメールで警報を発報する

Flowを利用することで、ツイート情報の取得からクソ具合の計算、Mackerelへのデータ送信までをノンプログラミングで構築することを目指します。

 

0)ポプテピピックとは 

暗闇はなく、無知があるのみ。

ポプテピピックとは、大川ぶくぶ先生がWEBコミックサイトのまんがライフWINで連載しているしていた四コマ漫画です。

2018年1月からTVアニメ放送が開始し、毎週土曜日25:00からTOKYO MX1やBS11で視聴可能な上、ニコニコ動画Amazonビデオでも地上波と同時刻に配信開始されています。

私は主にAmazonビデオ(時々地上波)で視聴しており、Amazon上での作品説明は「どうあがいても、クソ。」となっており、ポプテピピックと「クソ」という単語に親和性があることが伺えます。

今回、Mackerelを使おうと思ったタイミングがポプテピピック第4話(2018/01/28放送)を見た後だったため、なんとなく監視してみることにしてみた次第です。

 

1)Mackerelを準備する

Mackerelはサーバ監視ツールですが、サーバ以外にも任意の数値データを渡すことでグラフ化してくれる「サービスメトリック」という機能が備わっており、今回はそちらを利用します。

ということで、まずはMackerelの準備から。Mackerelにアクセスして、サインインします。

f:id:izumotto:20180130233633p:plain

左メニューの「Services」を選択すると、作成済みのサービス一覧が表示されます。今回はTwitter監視用の新しいサービスを作成するため、「サービスを追加」を選択します。

f:id:izumotto:20180130234806p:plain

任意の「サービス名」を入力して「作成」を選択します。ここで入力したサービス名は、後で数値データを送信する際に使用します。

f:id:izumotto:20180130235115p:plain

サービスの作成ができた後は、このサービスに数値データを送るための準備です。サービスメトリックへのデータ送信はAPIを利用します。左メニューのオーガニゼーション名部分を選択するとダッシュボードが表示されるので、「APIキー」タブを選択します。

f:id:izumotto:20180131002100p:plain

既に作成済みのAPIキー一覧が表示されます。Read/Write共に許可されたdefaultという名前のAPIキーが最初から用意されているため、これを利用してもいいですが、用途に応じて使い分けたいので今回は「新しいAPIキーを追加」を選択してキーを新規に払い出します。

f:id:izumotto:20180131002643p:plain

APIキーの新規作成画面が表示されるので、必要事項を入力します。

f:id:izumotto:20180131002857p:plain

  • 名前
    Mackerel上でAPIキーを区別するための名前です。好きな名前をつけます。
  • メモ
    個人用のメモを任意で記入できます。
  • 権限
    APIキーに与える権限を指定できます。サービスメトリックを投稿するAPIRead, Write共に権限が必要なので、両方にチェックを入れます。

必要事項の入力が完了したら、「作成」ボタンを押します。これらの入力内容は後から編集して修正することが可能です。

ダッシュボードに戻り、今作成したAPIキーが払い出されていればMackerel側の準備は完了です。APIキーをコピーしておき、次はFlow側の設定を行います。

 

2)Flowを準備する

Mackerelのデータ受け入れ準備が整ったので、次はFlowで試行錯誤の時間です。Microsoft Flowにアクセスして、サインインします。

f:id:izumotto:20171230143612p:plain

メニュー左上の「マイフロー」を選択すると今まで作成したフロー一覧が表示されます。今回はテンプレートを使わないので、「一から作成」を選択します。

f:id:izumotto:20171230144521p:plain

ここからステップを組み合わせていきます。ステップの概要は以下の通りです。

  1. 繰り返し処理の設定
  2. 現在の時間をエポック秒UNIX時間)で取得する
  3. Twitterからツイートを取得する
  4. ツイートの本文を解析して数を数える
  5. Mackerelにデータを送信する

2-1)繰り返し処理の設定

最初のトリガー選択で、「スケジュール - 繰り返し」を選択します。

f:id:izumotto:20180203154157p:plain

  • 間隔
    15
  • 頻度

繰り返し処理の設定はこれで完了で、15分に1度このフローを自動で実行してくれるようになります。監視するのに15分間隔は長すぎるのでは?と思われるかもしれませんが、Microsoft Flowで15分より短い間隔で繰り返し処理を実行するにはプラン変更する必要があるようでしたので諦めました。

f:id:izumotto:20180203154727p:plain

Microsoft FlowにはFreeプランを含めて4つのプランが用意されており、1ヶ月あたりの実行回数や仕様できるコネクタの種類に違いがあります。

ちなみに、Freeプランが1ヶ月に実行できる回数は750回まで。15分間隔で自動実行するフローを作ると、1週間とちょっとで限度に達してしまいますのでご注意を。

2-2)現在の時間をエポック秒UNIX時間)で取得する

Mackerelのサービスメトリックに投稿するAPIを確認すると、値と一緒に時刻情報を送信する必要があり、その形式はエポック秒(UNIX時間)である必要があります。

エポック秒UNIX時間)を端的に説明すると、1970年1月1日0時0分0秒からの経過秒数で日時を表現する方法です。

Flowには「日付と時刻 - 現在の時刻」というアクションが用意されていますが、エポック秒の出力には対応していないので、頑張って計算することにします。

まずは、新しいステップで「変数 - 変数を初期化する」を選択します。

f:id:izumotto:20180203172248p:plain

  • 名前
    任意の名前を指定できます。今回は分かりやすくtimeにします。
  • 種類
    整数

  • 初期値を設定できます。入力は任意ですが、今回は0を入れています。

エポック秒を計算した結果を、このtime変数に入れることにします。Flowには「データ操作」というコネクタもありますが、「変数」コネクタは整数やFloatといったデータ型を指定できるため、数字を扱う際は「変数」コネクタを利用するのが良いみたいです。

続いて、「日付と時刻 - 現在の時刻」をステップに追加します。「現在の時刻」は項目指定等は何もありません。このアクションで取得できるのは世界標準時です。

f:id:izumotto:20180203185805p:plain

続いてこれをエポック時間に変換します。まずは、今の年月日時分秒という日時表現を秒だけにするため、次のステップに「変数 - 変数の設定」を追加します。

f:id:izumotto:20180203175439p:plain

  • 名前
    先に作った変数名を指定します。今回はtimeです。

  • 動的なコンテンツの追加」から「文字列関数の式」を使って秒に変換します。日時関係の関数にticks関数が用意されており、これを用いて先に取得した日時をNTタイムエポック値に変換し、更に数学関数からdiv関数を使って値を1000万で割ります。実際の入力内容は以下の通り。
    div(ticks(body('現在の時刻')),10000000)

Flowのイケてない所というか、Microsoftさんの歴史が関係しているのでしょうが、ticks関数を使うと日時を表す文字列をNTタイムエポック値に変換することができます。

NTタイムエポック値を端的に説明すると、1601年1月1日0時0分0秒からの経過ティック秒数で日時を表現する方法です。これは、Windowsで主に用いられる時間の数え方みたいです。

エポック秒と時刻の起点が違いますし、単位もティック秒と秒で違っているので、エポック秒になるようざっくりと調整します。1ティック秒は100ナノ秒で、100ナノ秒は10^(-7)秒なので、先のdiv関数を使って10^7(1000万)で割ることで値をティック秒から秒に変換したことにしています。

後は、時刻の起点の違いによるズレ等を修正します。新しいステップ「変数 - 変数の値を減らす」を追加します。

f:id:izumotto:20180203193429p:plain

  • 名前
    先に作った変数名を指定します。今回はtimeです。

  • 固定値「62135596800」を入力します。

ここの固定値は正直割り切りです。先の1000万で割っただけの数値をエポック秒と見なすと1969年分のズレが生まれていたので、それを相殺するため、3939年(1970年+1969年)のエポック秒(62135596800)を固定値で減算しました。これで現在日時のエポック秒の取得は完了です。

2-3)Twitterからツイートを取得する

次にツイートの取得です。ステップに「Twitter - ツイートの検索」を追加します。

※FlowとTwitterを初めて連携させる際には、Twitter側での承認が必要です。画面に指示が出てくるので、指示に従ってFlowに許可を与えてください。

f:id:izumotto:20180203194407p:plain

  • 検索テキスト
    検索ワードを指定します。今回は「#ポプテピピック」です。
  • 結果の最大件数
    詳細オプションを開くと表示され、取得する結果の最大数を指定できます。100が最大だったので100にしています。
  • sinceId
    用途は不明ですが、今回は何も指定しません。

検索するワードは「#ポプテピピック」です。ハッシュタグを付けましたが特に意味はありません。正直なお話、Flowに用意されているTwitterコネクタの挙動はよく分かっていません。ひとまず、このように指定すれば「#ポプテピピック」を含むツイートが最大100件取得できるみたいです。取得したツイートの中にはリツイートも含まれているみたいでしたが、取得に関する詳細な条件は未確認です。実際の挙動として、「#ポプテピピック」を含むツイートは数多く存在するので、毎度100件取得できるものと考えています。

2-4)ツイートの本文を解析して数を数える

最大100件のツイートそれぞれの本文を解析していきます。数を数えるために、まずは「変数 - 変数を初期化する」を追加して変数を用意します。

f:id:izumotto:20180203195238p:plain

変数timeを用意した時と使い方は同じです。今回は整数型のcount変数を初期値0で用意しました。

変数が用意できたので、ツイート本文の解析を始めます。ツイートは最大100件あり、それぞれの本文を解析するため、繰り返し処理(Apply to each)を追加します。

f:id:izumotto:20180203195432p:plain

  • 以前の手順から出力を選択
    繰り返し参照する対象を選択します。「動的なコンテンツの追加」を用いて、取得したツイートの"本文"を指定します。
  • 追加
    繰り返し処理の中の最初のステップは「条件」を追加します。

条件には、比較する2つの値と、比較条件を指定します。

f:id:izumotto:20180203195938p:plain

  • 値の選択1
    「動的なコンテンツの追加」を用いて、ツイートの本文である"TweetText"を指定します。
  • 比較条件
    TweetTextの中に「クソ」が入っているかを知りたいため、「次の値を含む」を指定します。
  • 値の選択2
    「クソ」を指定します。

これで、ツイート本文に「クソ」が含まれるかどうかを判断可能になりました。今回は「クソ」が含まれる場合の数を数えたいので、「はいの場合」にアクション「変数 - 変数の数を増やす」を追加します。

f:id:izumotto:20180203200629p:plain

  • 名前
    先に作った変数名を指定します。今回はcountです。

  • 固定値「1」を入力します。

これで、「#ポプテピピック」を含む最大100ツイートの内「クソ」を含むツイートが何件あるかを取得できるようになりました。

2-5)Mackerelにデータを送信する

最後に、データをMackerelに送信します。MackerelのAPIを利用するため、ステップ「HTTP」を追加します。

f:id:izumotto:20180203202244p:plain

  • 方法
    POST
  • URI
    https://api.mackerelio.com/api/v0/services/{Mackerelのサービス名}/tsdb
  • ヘッダー
    Enterキー:X-Api-Key
    値の入力:MackerelのAPIキー(Write権限を持っているもの)
  • 本文
    APIドキュメントに基づき、3つのKeyを送信します。
    [
     {
      "name" : "{任意のメトリック名}",
      "time" : {「動的なコンテンツの追加」からtimeを指定},
      "value" : {「動的なコンテンツの追加」からcountを指定}
     }
    ]

ここまでできればFlowの準備は完了です!

 

3)監視ルールを設定する

Mackerelに戻り、先に作成したサービスの「サービスメトリック」タブを選択すると、15分に一度Flowから送られてくるデータが綺麗にグラフ化されていることが確認できます。

f:id:izumotto:20180203203125p:plain

これだけでは、単にグラフ化しただけなので、値が一定数を超えたらメールで通知がくるように設定します。左メニューの「Monitors」を選択すると監視ルール設定が表示されるので、「監視ルールを追加」を選択します。

f:id:izumotto:20180203203754p:plain

新規監視ルールを作成する画面が表示されるので、「サービスメトリック監視」タブを選択します。

f:id:izumotto:20180203204052p:plain

  • メトリック
    プルダウンメニューから、任意のメトリックを選択します。
  • 閾値(Warning条件)
    Warningの通知が発報される条件を指定します。今回、値は0から100の範囲内なので、まずは「>50」としました。
  • 閾値(Critical条件)
    Criticalの通知が発報される条件を指定します。今回は「>90」にしました。
  • 閾値(平均値監視)
    生データを直接監視せず、直近n回の平均値を監視して通知するように設定できます。今回は15分に1度しか情報がアップデートされないため、平均はとらず「1」を指定しました。
  • アラート発生までの最大試行回数
    一度だけたまたま閾値を超えた場合等に備えて、n回連続で閾値を超えてから通知をするように設定できます。こちらも同様の理由で「1」を指定しました。

f:id:izumotto:20180203205053p:plain

  • 基本設定(監視ルール名)
    任意の監視ルール名を設定します。
  • 基本設定(監視ルールのメモ)
    個人用のメモを任意で記入できます。
  • オプション
    通常、通知は1度実施されると再通知はされません。閾値を超え続けている間、繰り返し通知して欲しい場合は、間隔を指定して再通知を受け取ることができます。今回は利用しませんでした。

以上の入力が完了したら「作成」ボタンを押して、監視ルールの設定は完了です。ようやく、全ての準備が整いました。後はMackerelに監視をまかせ、通知を受け取るだけです!

 

4)通知を受け取る

監視のルールを要約すると、以下の通りです。

  • 15分に1度、「#ポプテピピック」を含むツイートを100件取得し、その100件の内「クソ」を本文に含むツイートの割合を計算する。
  • 割合が50%を超えると、Warningの通知がメールで届く
  • 割合が90%を超えると、Criticalの通知がメールで届く

果たしてどうなったのか。

まず、監視はおおよそ2018/01/28(日) 23:00から開始しました。ポプテピピックのアニメは日曜日の1:00から放送開始なので、すでに最新話の放送から22時間経過した時間からの監視開始でしたが、クソ具合はこんな感じです。

f:id:izumotto:20180204180650p:plain

監視開始してから24時間、概ね5%~10%の間を行き来しています。その間の最大値は1/29(月) 16:40の15%。思っていたよりクソではないように見受けられます。このような状態は、2/2(金)まで5日間続きました。

そして、転機は2/3(土)深夜にやってきます。

f:id:izumotto:20180204180938p:plain

Warning発生(メール受信)

第5話放送の約24時間前から、Twitter上でのクソ具合が初めて50%を超えました。そして、多少の増減を繰り返しながらクソ具合は50%前後を維持し、第5話放送の約7時間前、18:10頃に78%のクソ具合をマークしました。

f:id:izumotto:20180204181204p:plain

この結果は、アニメ最新話に対する期待の表れなのかもしれません。が、ここで様子が変わります。

f:id:izumotto:20180204181338p:plain

78%のピーク時から緩やかにクソ具合は減少し、放送2時間前の23:00頃からはついに50%を切りました。その後急激に減少し、放送開始の2/4(日) 1:00には2%に。放送中の30分間の平均値は3%と、その前後で最低値をマークしました。

4-1)クソ具合についての考察

  • 「#ポプテピピック」と「クソ」に一定の共起性を感じる(定量的根拠はなし)
  • 最新話放送開始前のクソ具合の上昇具合が異常。(1)「クソ」を含んだツイートがバズっており、そのRTが多量に取得されていた可能性がある。(2)最新話放送前に前回までの内容の振り返り・おさらいをするユーザが多くおり、その感想として「クソ」と呟いた可能性がある。
  • いざ放送が始まるとクソ具合が減少した。(1)視聴に集中して「クソ」と呟かれなかった可能性がある。(2)今回の放送内容が「クソ」ではなかった可能性がある。(3)リアルタイム視聴するユーザが少なく、単純に視聴者が睡眠に入った可能性がある。
  • 放送終了後のクソ具合は10%~15%の推移に戻った。
  • 総括:ポプテピピックは一定のクソ具合を性質として持っており、時にWarningは発生するが、Criticalな問題は発生しなかった。

 

まとめ

おさらいすると、今回実現したかったことは以下の通りです。

  1. 「#ポプテピピック」を含むツイートを15分毎に100件取得
  2. 取得した100ツイートの内「クソ」が含まれるツイート数をMackerelに送信
  3. クソ具合が高まるとメールで警報を発報する

最終的なFlowは以下のようになりました。

  1. 繰り返し:15分に1度実行する
  2. 変数エポック秒取得の準備1
  3. 時間:現在の日時を取得
  4. 変数エポック秒取得の準備2
  5. 変数エポック秒取得
  6. Twitter:ツイートの取得
  7. 変数:クソ具合取得の準備1
  8. 繰り返し:クソ具合の計算
  9. 変数:クソ具合取得
  10. HTTP:クソ具合をMackerelに送信

サーバの管理はしたことがないので、サーバ監視ツールを使ったことも全くありませんでしたが、今回のように時系列データのグラフ化と監視を行いたい場合にMackerelは使えるなと感じました。Freeプランはデータ保存期間が1日なので、それが許容できる用途であれば充分かなという感じです。

ただ、Flowの繰り返し実行処理に対する時間制限と回数制限を考えると、今回のような用途にFlowは向いていないと思いました。内容的にプログラムを組んでもいいですが、こういった繰り返し処理に使いやすくなると個人的には嬉しいです。基本的には、手作業の自動化+αみたいな立ち位置を目指したサービスなのかもしれませんが。あと、色んなサービスとの連携を前提としていながらNTタイムエポック値しか使えないのは少し困りました。

最後に、ポプテピピック大川ぶくぶ先生に敬意を表して、今回の記事は終わります。

 

ダイ・ハード [DVD]

ダイ・ハード [DVD]