เคยไหมครับที่เราจะต้องรันคำสั่งบางคำสั่งที่ทำงานนานๆ อย่างเช่น dump database ขนาดมหึมา หรืออื่นๆ
คืองานพวกนี้เราไม่ได้ต้องทำบ่อยๆ เวลาทำก็รันคำสั่งทิ้งไว้ใน Tmux แล้วก็ไปทำอะไรเพลิน กลับมาเช็คเรื่อยๆ
ด้วยความขี้เกียจ เลยคิดว่าเราน่าจะมีอะไรมาเตือนเนอะ ว่า Command นั้นรันเสร็จรึยัง หรือ พังไหม เลยพาลไปนึกถึง Slack ซึ่ง mesodiar เคยเขียนไว้ เรื่อง [Cron] เขียน slackbot ส่ง notification เตือน standup meeting เลยคิดว่าน่าจะเอามาทำอะไรเล่นๆได้เร็วเพราะมีโค้ดมาเลย เอามายำๆ
มาเริ่มกันดีกว่า
เริ่มแรก เราจะสร้าง virtualenv และ virtualenvwrapper มาเพื่อไม่ให้โปรเจ็กของเราไปกระทบกับ python ของเครื่อง และจะได้ง่ายในการจัดการหรือพัฒนาต่อ
$ mkvirtualenv lazy-bot
ลง Slack API ใน virtualenv
(lazy-bot) $ pip install slackclient
สร้าง BOT บน Slack
แอ็ด BOT เราเข้าไปใน Channel ด้วยนะครับ เดียวจะเหวอว่าทำไมข้อความไปมา
จากนั้นเอา API Token มาเก็บไว้ เดียวเราจะเอาไปใส่ในโค้ดของเราครับ
ตัว Template ของโค้ด ผมหยิบเอามาจาก บล็อก ข้างต้นที่กล่าวไว้
send.py
from slackclient import SlackClient slack_token = "YOUR_SLACK_API_TOKEN" slack_client = SlackClient(slack_token) api_call = slack_client.api_call("channels.list") if slack_client.rtm_connect(): print "Successfully connected" for channel in api_call.get("channels"): if channel.get("name") == "test_server_notificat": response = "Your job is done" slack_client.api_call("chat.postMessage", channel="test_server_notificat", text=response, as_user=True) else: print "Connection failed"
ครับ ก็ ง่ายๆครับ
ทดลองด้วยการรัน
python send.py
ข้อความก็จะเข้ามาใน Channel แบบ ชิคๆคูลๆ
โดยเราจะใช้การที่เรารันโปรแกรมของเราแล้วส่งข้อความเนี่ยแหละ มาประยุกต์ใช้กับงานที่ต้องรัน นานๆ
ตอนนี้ผมจะใช้การรันในแบบ
$ sleep 50; python send.py #หรือ $ sleep 50 && python send.py
โดยถ้าเป็นแบบนี้ มันจะทำงานแรกให้เสร็จก่อน แล้วค่อยรัน send.py
ของเรา
ถ้าอยากให้มันแจ้งคนใน Channel เช่น @here หรือ @channel จะทำได้โดยใส่เป็น tag ดูเพิ่มเติมได้ที่ Basic message formatting ผมใส่
<!here>
หรืออ่านว่า ไอ-เฮีย เย้ย!
จากนั้นผมก็เพิ่มให้โปรแกรมของเราสามารถส่งข้อมูล hostname และ IP มาด้วยกะ message เพื่อให้ง่ายต่อการดูข้อความถ้าเราไปรันบนเครื่อง Server
Get Hostname ด้วยการใช้ socket.gethostname()
#ส่วนนี้เป็นการไปเอา Hostname มา import socket hostname = socket.gethostname()
Get IP ด้วยการใช้ request.get ไปใช้ API ของเว็บ ipify
from requests import get ip = get('https://api.ipify.org').text
หรืออาจจะใช้วิธีอื่นที่ไม่ต้อง Call API ทุกครั้งจะทำงานได้เร็วกว่าครับ
จากนั้นเราก็จะต้องนำค่า Hostname กับ IP ที่ได้มาไปรวมเข้ากับ Message ที่เราส่ง
ตอนนี้โค้ดเราจะหน้าตาแบบนี้ครับ
from slackclient import SlackClient from requests import get import socket slack_token = "YOUR_SLACK_API_TOKEN" slack_client = SlackClient(slack_token) api_call = slack_client.api_call("channels.list") hostname = socket.gethostname() ip = get('https://api.ipify.org').text if slack_client.rtm_connect(): print "Successfully connected" for channel in api_call.get("channels"): if channel.get("name") == "test_server_notificat": response = "<!here> Your job on " + hostname + " IP:" + ip + " is done" slack_client.api_call("chat.postMessage", channel="test_server_notificat", text=response, as_user=True) else: print "Connection failed"
จะได้ข้อความาแบบนี้ แถมโดนเด้งเตือนกันทั้ง Channel
จริงๆคร่าวๆก็มีประมาณนี้ ที่ได้มาลองเล่น SlackAPI ของ Python แบบขำๆ แต่ทีนี้โปรเจ็กนี้ผมเขียนขึ้นมาหลังจากที่รัน Command ไปแล้ว ก็เลยไปลองหาทริคที่จะโปรแกรมของเราส่งข้อความหลังจาก Process นั้นหายไปโดยจะใช้
watch -g ps -opid -p <PID>; python send.py
ที่มาของคำสั่งนี้จาก superuser.com
คือจะไปดู Process ของเราจาก PID ของ Process โดยดู PID จากวิธีต่างๆเช่นใช้ top หรือ htop ไปดู command ที่รันไปแล้วยังรันค้างอยู่ เป็นต้น
watch เป็นคำสั่งที่ใช้ดู Process ที่รันอยู่แบบเต็มหน้าจอ
-g เป็น Option ของ watch ที่จะออกจาก command เมื่อมี Output เปลี่ยนแปลงไป
หวังว่าโปรเจ็กเล่นๆขำๆของผมจะพอมีประโยขน์สำหรับคนอื่นบ้าง โค้ดนี้ยังพัฒนาต่อให้ใช้งานได้ง่ายกว่านี้เช่นไปทำ executable file ไว้ใน bin จะได้ใช้งานง่ายๆสะดวกกว่านี้ หรือใครมีวิธีที่ง่ายกว่านี้ก็สามารถนำมาเสนอแนะกันได้นะครับผม
(・`ω´・)
Leave a Reply