Bag of ML Words

ML = Machine Learning, Music Love, and Miscellaneous things in daily Livings

slack webhookでログをslackに自動投げ込み

webhookなる仕組みを使って、slackにcurlで直接メッセージを投げ込むことができるらしい。これ使えば、入力フォームから誤訳文対が報告されるたびにslackに投げてみることができるっぽい?

 

api.slack.com

 

とりあえずslackの公式APIページを見ると使い方が一番わかりやすい。

 curlでPOSTするために、メッセージ取ってきて、JSON形式にしてあげればよろしい。

あとはメッセージを取得する方法(最新のログファイルを監視して追いかける)と、それをJSONにフォーマットする部分ですね。

 

ログ監視パート

ログ監視、tailfとgrepで頑張るのも良いですが、logmonっていうのもあるみたい。

service コマンドで動かせるっていうのはわかりやすくていいですね。

 

qiita.com

 

我々の例だと、

/var/www/html/log.txt に全部書き出されるはずなので、これを監視して、何か入ってきたらechoなりで標準出力に吐き出されるようにすればいいのかな?

(logmonをインストールしてから) /etc/logmon/logmon.conf

 

# Monitor for messages
:/var/www/html/log.txt
(,)  # commaは絶対あるので
echo -n "<%%%%>" >> /var/log/logmon-enja.log

 

# sudo service logmon check

# sudo service logmon restart

 

 よし。

 

 

slack webhookパート

これとは別にslack webhookをやる。

送るものとかを整形することを考えると、何らかのstdin入力を受け取って、

各行ごとに処理、jsonに整形、curlでPOST、というスクリプトを書くのがいいかなぁ。

 

qiita.com

swfz.hatenablog.com

 

このあたりにしたがって順番にやってみる。

 

単純POST by curl

slackのアプリのあちこちをいじるとincoming webhookを設定するところにいくので、送りたいchannelを指定してwebhook urlを取得する。

これをcurlでPOSTする。curlの例文はwebhook URLを取得したら下に書いてあります。優しさ。

f:id:Dr_KayAi:20170713124647p:plain

curl -X POST --data-urlencode 'payload={"channel": "送るチャンネル名", "username": "goyakubot", "text": "This is a webhook test", "icon_eomji": ":ghost:"}' https://hooks.slack.com/services/XXXXXXXXXXXX

 

おお、とどいた!これだけでうれしい!

f:id:Dr_KayAi:20170713124906p:plain

 

スクリプト経由にする

慣れたpythonにstdinでファイルとかcatして、見た目お化粧したい。

jsonとrequestsモジュールを使えば簡単簡単。

 

python3でも日本語処理が必要になるのね。。。

 

(slack_webhook_post.py)

 

# -*- coding: utf-8 -*-
#
# given the stdin INPUT (tab-separted), break in line, send.

import json
import requests

def _main():

# Set the webhook_url to the one provided by Slack when you create the webhook at https://my.slack.com/services/new/incoming-webhook/
webhook_url = "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXX"
slack_data = {
"channel": "送るチャンネル名",
"username": "goyakubot",
"text": "This is a webhook test from パイソンだよ",
"icon_eomji": ":ghost:"
}

response = requests.post(
webhook_url, data=json.dumps(slack_data, ensure_ascii=False).encode("utf-8"),
headers={'Content-Type': 'application/json'}
)
if response.status_code != 200:
raise ValueError(
'Request to slack returned an error %s, the response is:\n%s'
% (response.status_code, response.text)
)

# end main

_main()

 

 

f:id:Dr_KayAi:20170713131745p:plain

 

やったぜ。

あとはtext部分を通常のpythonと同様にinput()から受け取った内容でparseすればよいね!

 

結合パート

 logmon.confのecho部分を、メッセージゲット --> Pythonにパイプ、これでいいはず

echo -n "<%%%%>" >> /var/log/logmon-enja.log

--->

echo -n "<%%%%>" | /full/path/to/python /full/path/to/slack_webhook_post.py

 

できたー!!

f:id:Dr_KayAi:20170713134915p:plain

 

 とおもったらechoからのメッセージに日本語が入るとだめ。なぜ・・・

 

http://qiita.com/FGtatsuro/items/f45c349e06d6df95839b#%E3%82%82%E3%81%86unicodeencodeerror%E3%82%82%E6%81%90%E3%81%8F%E3%81%AA%E3%81%84

に回答がありました。つまり、locale環境変数が効かないということです。

echo -n "<%%%%>" | /full/path/to/python /full/path/to/slack_webhook_post.py

-->

echo -n "<%%%%>" | PYTHONIOENCODING=utf-8:surrogateescape /full/path/to/python /full/path/to/slack_webhook_post.py 

 で解決!!