kintoneのWebhookイベントをfluentdで受け取る


0. 前書き

2017年2月にkintoneがアップデートでWebhook機能に対応し、kintoneアプリのイベントに対してWebhookを設定することが可能となりました。
このWebhookイベントをfluentdで受け取るfluentdプラグインを作成したので、使い方紹介します。

kintoneアップデート情報ページより

1. fluentdの紹介

fluentdはオープンソースのログ収集ツールです。
柔軟かつ堅牢な仕組みと、プラグインと呼ばれる機構で多くのクラウドサービスや各種リソースとの接続が可能です。
https://www.idcf.jp/words/fluentd.html
https://www.fluentd.org/

2. fluent-plugin-webhook-kintone

https://github.com/okahashi117/fluent-plugin-webhook-kintone
fluentdのインプットプラグインです。
httpsでのkintone Webhoookイベントを待ち受けます。

3. 導入と設定

rubyおよびfluentd環境は導入済みとします。

GitHubよりリポジトリをクローンしビルドします。

$ git clone https://github.com/okahashi117/fluent-plugin-webhook-kintone.git
$ cd fluent-plugin-webhook-kintone
$ rake build
fluent-plugin-webhook-kintone 0.0.1 built to pkg/fluent-plugin-webhook-kintone-0.0.1.gem.
$ gem install pkg/fluent-plugin-webhook-kintone-0.0.1.gem
Successfully installed fluent-plugin-webhook-kintone-0.0.1
Parsing documentation for fluent-plugin-webhook-kintone-0.0.1
Done installing documentation for fluent-plugin-webhook-kintone after 0 seconds
1 gem installed

kintoneのWebhookを受けて標準出力するfluentdの設定ファイル。
kintoneのWebhookはhttpsが必須なので、サーバー証明書の指定が必要です。
またオレオレ証明書はkintone側で受け付けてもらえずエラーとなるので使えません。

待受のデフォルトポートは3838です。
443などのwell-knownポートを使いたい場合はfluentdの起動に充分な権限が必要です。

~/fluent.conf
<source>
  @type webhook_kintone
  tag debug.kintone
  secure true
  cert_pth path/for/certificate/cert.pem
  private_key_path path/for/certificate/key.pem
  chain_path path/for/certificate/chaincertpem
</source>

<match debug.**>
  @type stdout
  @id stdout_output
</match>

あとkintoneアプリでのURL指定をわすれずに(この場合であればfluentdが動作しているサーバーのURL your.site.com:3838)

4. いざ!

動作を確認します。
まずfluentdを起動します。上記の設定ファイルを指定して起動します。

fluentd -c ~/fluent.conf

起動が確認できたら、kintoneのサンプルアプリ日報を使って 新規レコードの追加と削除をおこなってみてください。
以下のようなログが確認できます。(実際は一行ですがみやすさのため加工しています)

追加

2018-03-0113:35:11.722184349+0900 debug.kintone.{  
   "id"   =>"cfe3fd32-e529-450f-b21a-73617347b709",
   "type"   =>"ADD_RECORD",
   "app"   =>   {  
      "id"      =>"5",
      "name"      =>"\u65E5\u5831"
   },
   "record"   =>   {  
      "\u30EC\u30B3\u30FC\u30C9\u756A\u53F7"      =>      {  
         "type"         =>"RECORD_NUMBER",
         "value"         =>"13"
      },
      "\u66F4\u65B0\u8005"      =>      {  
         "type"         =>"MODIFIER",
         "value"         =>         {  
            "code"            =>"Administrator",
            "name"            =>"Administrator"
         }
      },
      "\u4F5C\u6210\u8005"      =>      {  
         "type"         =>"CREATOR",
         "value"         =>         {  
            "code"            =>"Administrator",
            "name"            =>"Administrator"
         }
      },
      "\u30E9\u30B8\u30AA\u30DC\u30BF\u30F3"      =>      {  
         "type"         =>"RADIO_BUTTON",
         "value"         =>"\u9054\u6210"
      },
      "\u30C9\u30ED\u30C3\u30D7\u30C0\u30A6\u30F3"      =>      {  
         "type"         =>"DROP_DOWN",
         "value"         =>"\u958B\u767A"
      },
      "$revision"      =>      {  
         "type"         =>"__REVISION__",
         "value"         =>"1"
      },
      "\u66F4\u65B0\u65E5\u6642"      =>      {  
         "type"         =>"UPDATED_TIME",
         "value"         =>"2018-03-01T04:35:00         Z"
      },
      "\u6587\u5B57\u5217__\u8907\u6570\u884C__0"      =>      {  
         "type"         =>"MULTI_LINE_TEXT",
         "value"         =>"\u975E\u5E38\u306B\u96E3\u3057\u3044"
      },
      "\u6587\u5B57\u5217__\u8907\u6570\u884C_"      =>      {  
         "type"         =>"MULTI_LINE_TEXT",
         "value"         =>"\u4ECA\u65E5\u306FOSS\u6D3B\u52D5\u3092\u304A\u3053\u306A\u3063\u305F"
      },
      "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB"      =>      {  
         "type"         =>"FILE",
         "value"         =>         [  

         ]
      },
      "\u4F5C\u6210\u65E5\u6642"      =>      {  
         "type"         =>"CREATED_TIME",
         "value"         =>"2018-03-01T04:35:00         Z"
      },
      "\u65E5\u4ED8"      =>      {  
         "type"         =>"DATE",
         "value"         =>"2018-03-01"
      },
      "$id"      =>      {  
         "type"         =>"__ID__",
         "value"         =>"13"
      }
   },
   "recordTitle"   =>"13",
   "url"   =>"https://#####.cybozu.com/k/5/show#record=13"
}:{  
   "id":"cfe3fd32-e529-450f-b21a-73617347b709",
   "type":"ADD_RECORD",
   "app":{  
      "id":"5",
      "name":"日報"
   },
   "record":{  
      "レコード番号":{  
         "type":"RECORD_NUMBER",
         "value":"13"
      },
      "更新者":{  
         "type":"MODIFIER",
         "value":{  
            "code":"Administrator",
            "name":"Administrator"
         }
      },
      "作成者":{  
         "type":"CREATOR",
         "value":{  
            "code":"Administrator",
            "name":"Administrator"
         }
      },
      "ラジオボタン":{  
         "type":"RADIO_BUTTON",
         "value":"達成"
      },
      "ドロップダウン":{  
         "type":"DROP_DOWN",
         "value":"開発"
      },
      "$revision":{  
         "type":"__REVISION__",
         "value":"1"
      },
      "更新日時":{  
         "type":"UPDATED_TIME",
         "value":"2018-03-01T04:35:00Z"
      },
      "文字列__複数行__0":{  
         "type":"MULTI_LINE_TEXT",
         "value":"非常に難しい"
      },
      "文字列__複数行_":{  
         "type":"MULTI_LINE_TEXT",
         "value":"今日はOSS活動をおこなった"
      },
      "添付ファイル":{  
         "type":"FILE",
         "value":[  

         ]
      },
      "作成日時":{  
         "type":"CREATED_TIME",
         "value":"2018-03-01T04:35:00Z"
      },
      "日付":{  
         "type":"DATE",
         "value":"2018-03-01"
      },
      "$id":{  
         "type":"__ID__",
         "value":"13"
      }
   },
   "recordTitle":"13",
   "url":"https://#####.cybozu.com/k/5/show#record=13"
}

削除

2018-03-0113:41:54.781115656+0900 debug.kintone.{  
   "id"   =>"1f464ae3-df11-4cb6-9d1f-65c4d9bbd5cf",
   "type"   =>"DELETE_RECORD",
   "app"   =>   {  
      "id"      =>"5",
      "name"      =>"\u65E5\u5831"
   },
   "recordId"   =>"13",
   "deletedBy"   =>   {  
      "code"      =>"Administrator",
      "name"      =>"Administrator"
   },
   "deletedAt"   =>"2018-03-01T04:41:54   Z"
}:{  
   "id":"1f464ae3-df11-4cb6-9d1f-65c4d9bbd5cf",
   "type":"DELETE_RECORD",
   "app":{  
      "id":"5",
      "name":"日報"
   },
   "recordId":"13",
   "deletedBy":{  
      "code":"Administrator",
      "name":"Administrator"
   },
   "deletedAt":"2018-03-01T04:41:54Z"
}

あとはfluentdのエコシステムを使って別の場所にアウトプットするなり連動させるなり自由です。

5. Q&A

・kintoneのwebhookイベントで何したらいいの
→ あなた次第

・fluentdからの直接ポートを外部公開ってあり?
→ 一度別のEndpointでうけて、そこからfluentdに転送する形もいんじゃないでしょうか。この場合fluent-plugin-webhook-kintoneを無理に使う必要はありません。

・可用性や信頼性はどうなの
→ fluentd自体はいけてると思います。fluent-plugin-webhook-kintoneはプルリクを受付中です。

おしまい