เขียน python or shell script ส่งค่า cpu ,memory และ Disk Usage ของ server linux centos และ windows server ขึ้น cloud thingspeak และแจ้งเตือนผ่าน line group
เนื่องจาก ต้องการที่จะทราบค่า CPU,DISK,Memory แบบ realtime โดยแสดงผลเป็นกราฟ และสามารถ นำข้อมูล json ไปใช้งานต่อยอดในระบบอื่นได้ และเมื่อ CPU หรือ memory สูงเกิน 70% ก็ให้แจ้งเตือนผ่าน Line group ด้วย Line notify
หลักการทำงาน
เขียน python รับค่า cpu ,disk ,memory แล้วส่งขึ้นไปยัง cloud thingspeak โดยตั้งค่าว่าถ้าเกิด CPU หรือ memory มากกว่า 70% ก็ให้แจ้งเตือนผ่าน line group ด้วย Line notify
*** กรณีที่ติดตั้ง python แล้วมีปัญหา สามารถใช้ shell script ได้น่ะครับ code อยู่ด้านล่างสุด
เครื่องมือที่ใช้
1.Line notify วิธีการสมัครสามารถอ่านบทความเก่าๆ ของผม หรือ จาก google ได้ครับ
2.Python วิธีติดตั้ง อ่านได้ที่ https://tecadmin.net/install-python-2-7-on-centos-rhel/
3.Thingspeak
วิธีทำ
1.สมัคร thingspeak ก่อน new channel ขึ้นมา และ สร้างมา 4 field สำหรับเก็บข้อมูล
field1 = cpu , field2 = memory (%) , field3 = disk usage , field4 = memory
ต้องสมัครใช้งานก่อนครับ ฟรี https://thingspeak.com/ thingspeak เป็น cloud server ที่ยอมให้รับเก็บข้อมูลดูสามารถ ทำกราฟแบบ realtime ได้ด้วย
หรือ อ่านจากบทความเก่าๆ ของผม ได้ที่ https://havespirit.blogspot.com/2017/02/arduino-esp8266-server-cloud-thingspeak.html
2.ติดตั้ง package ที่จำเป็น 3 package บน linux โดยใช้คำสั่งข้างล่างนี้
2.1 pip install psutil
2.2 pip install thingspeak
2.3 pip install netifaces
or
python -m pip install psutil
python -m pip install thingspeak
python -m pip instal netifaces
หากใครติดตั้งไม่ได้เพราะเป็น python 2.6 สามารถอ่านได้ที่นี่ครับ https://superuser.com/questions/1027526/upgrade-python-from-2-6-to-2-7-on-centos-6-5
แนะนำเป็น python 2.7
3.ลงมือเขียน code python
code python สำหรับ Linux
///////////////////////////////////////////////
#!/usr/bin/env python
import psutil
import httplib, urllib
import time
import os,sys
import netifaces as ni
import requests
from subprocess import call
disk = os.statvfs("/")
used = disk.f_bsize * (disk.f_blocks - disk.f_bavail)
sleep = 60 # how many seconds to sleep between posts to the channel
key = 'api_key' # Thingspeak channel to update
ip = ni.ifaddresses('eth1')[2][0]['addr']
def notify(msg):
req = requests.get("http://xx.xx.xx.xx/push.php?message="+msg)
call(["curl", "-X", "POST", "-H", "Authorization: Bearer line_notify_token", "-F", "message="+msg,"https://notify-api.line.me/api/notify"])
def performance():
while True:
cpu = psutil.cpu_percent()
mem = psutil.virtual_memory().used/1000000
params = urllib.urlencode({'field1':cpu ,'field2':mem,'field3':used/1.073741824e9,'key':key})
headers = {"Content-typZZe": "application/x-www-form-urlencoded","Accept": "text/plain"}
conn = httplib.HTTPConnection("api.thingspeak.com:80")
try:
conn.request("POST", "/update", params, headers)
response = conn.getresponse()
print cpu
if (cpu >= 90):
notify(ip+" - CPU: "+str(cpu))
print mem
mem_percent = (psutil.virtual_memory().used*100/psutil.virtual_memory().total)
print mem_percent
if(mem_percent >= 70):
notify(ip+" - Memory: "+str(mem_percent))
print response.status, response.reason
data = response.read()
conn.close()
except:
print "connection failed",sys.exc_info()
break
#sleep for desired amount of time
if __name__ == "__main__":
while True:
performance()
time.sleep(sleep)
import psutil
import httplib, urllib
import time
import os,sys
import netifaces as ni
import requests
from subprocess import call
disk = os.statvfs("/")
used = disk.f_bsize * (disk.f_blocks - disk.f_bavail)
sleep = 60 # how many seconds to sleep between posts to the channel
key = 'api_key' # Thingspeak channel to update
ip = ni.ifaddresses('eth1')[2][0]['addr']
def notify(msg):
req = requests.get("http://xx.xx.xx.xx/push.php?message="+msg)
call(["curl", "-X", "POST", "-H", "Authorization: Bearer line_notify_token", "-F", "message="+msg,"https://notify-api.line.me/api/notify"])
def performance():
while True:
cpu = psutil.cpu_percent()
mem = psutil.virtual_memory().used/1000000
params = urllib.urlencode({'field1':cpu ,'field2':mem,'field3':used/1.073741824e9,'key':key})
headers = {"Content-typZZe": "application/x-www-form-urlencoded","Accept": "text/plain"}
conn = httplib.HTTPConnection("api.thingspeak.com:80")
try:
conn.request("POST", "/update", params, headers)
response = conn.getresponse()
print cpu
if (cpu >= 90):
notify(ip+" - CPU: "+str(cpu))
print mem
mem_percent = (psutil.virtual_memory().used*100/psutil.virtual_memory().total)
print mem_percent
if(mem_percent >= 70):
notify(ip+" - Memory: "+str(mem_percent))
print response.status, response.reason
data = response.read()
conn.close()
except:
print "connection failed",sys.exc_info()
break
#sleep for desired amount of time
if __name__ == "__main__":
while True:
performance()
time.sleep(sleep)
//////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////
*** ในส่วนของ windows server ก็สามารถทำได้ครับ โดยลง python windows V.2.7.13 แล้วตั้งการทำงานด้วย scheduled tasks ซึ่งก็ได้ผลเหมือนกันครับ
การติดตั้ง Python สำหรับ windows https://www.python.org/ftp/python/2.7.13/python-2.7.13.amd64.msi
การติดตัั้ง libary ให้เข้าไป ที่ c:\Python27\Scripts แล้วพิมพ์ตามรูป
code python สำหรับ Windows edit 2017-03-14การติดตั้ง Python สำหรับ windows https://www.python.org/ftp/python/2.7.13/python-2.7.13.amd64.msi
การติดตัั้ง libary ให้เข้าไป ที่ c:\Python27\Scripts แล้วพิมพ์ตามรูป
/////////////////////////////////////////////////////////////////
#!/usr/bin/env python
import psutil
import httplib, urllib
import time
import os,sys
import netifaces as ni
import requests
from subprocess import call
import socket
import urllib
import urllib2
#disk = os.statvfs("/")
#used = disk.f_bsize * (disk.f_blocks - disk.f_bavail)
used = psutil.disk_usage("C:/").percent
sleep = 60 # how many seconds to sleep between posts to the channel
key = 'thingspeak_api' # Thingspeak channel to update
#ip = ni.ifaddresses('eth1')[2][0]['addr']
ip = socket.gethostbyname(socket.gethostname())
#Report Raspberry Pi internal temperature to Thingspeak Channel
def notify(msg):
url = "https://notify-api.line.me/api/notify"
LINE_HEADERS = {'Content-Type':'application/x-www-form-urlencoded',"Authorization":"Bearer line_notify_api"}
user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'
values = {'message': msg}
data = urllib.urlencode(values)
req = urllib2.Request(url, data, LINE_HEADERS)
response = urllib2.urlopen(req)
the_page = response.read()
def thermometer():
while True:
#Calculate CPU temperature of Raspberry Pi in Degrees C
#temp = int(open('/sys/class/thermal/thermal_zone0/temp').read()) / 1e3 # Get Raspberry Pi CPU temp
cpu = psutil.cpu_percent()
mem = psutil.virtual_memory().used/1000000
temp = 50
mem_percent = (psutil.virtual_memory().used*100/psutil.virtual_memory().total)
#d=$(df -h | awk '$NF=="/"{printf "%d/%d\n", $2,$3,$5}')
params = urllib.urlencode({'field1':cpu ,'field2':mem,'field3':used,'field4':mem_percent,'key':key})
headers = {"Content-typZZe": "application/x-www-form-urlencoded","Accept": "text/plain"}
conn = httplib.HTTPConnection("api.thingspeak.com:80")
try:
conn.request("POST", "/update", params, headers)
response = conn.getresponse()
print cpu
print used
if (cpu >= 90):
notify(ip+" - CPU: "+str(cpu))
print mem
mem_percent = (psutil.virtual_memory().used*100/psutil.virtual_memory().total)
print mem_percent
if(mem_percent >= 70):
notify(ip+" - Memory: "+str(mem_percent))
print response.status, response.reason
data = response.read()
conn.close()
except:
print "connection failed",sys.exc_info()
break
#sleep for desired amount of time
if __name__ == "__main__":
#while True:
thermometer()
# time.sleep(sleep)
ในส่วนของกราฟ เราก็ไปเอา code iframe ของ thingspeak มาแปะที่ server ของเราครับ โดยสร้างไฟล์ html เปล่าๆ ขึ้นมา แล้วเอา code iframe ไปแปะ ในส่วนของ body ครับ
การนำไปใช้จริง ก็เพิ่มเข้าไปใน cronjob ตั้งเวลาให้ทำงาน ทุกๆ 5 นาที
ตัวอย่าง crontab
*/5 * * * * /usr/local/bin/python2.7 /root/monitor/Resource.py
การนำไปใช้จริง ก็เพิ่มเข้าไปใน cronjob ตั้งเวลาให้ทำงาน ทุกๆ 5 นาที
ตัวอย่าง crontab
*/5 * * * * /usr/local/bin/python2.7 /root/monitor/Resource.py
///////////////////////
code ในส่วนของการเรียกใช้ Line notify
push.php
///////////////////////////////
code ในส่วนของการเรียกใช้ Line notify
push.php
<?php
$message = $_REQUEST['message'];
$chOne = curl_init();
curl_setopt( $chOne, CURLOPT_URL, "https://notify-api.line.me/api/notify");
// SSL USE
curl_setopt( $chOne, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt( $chOne, CURLOPT_SSL_VERIFYPEER, 0);
//POST
curl_setopt( $chOne, CURLOPT_POST, 1);
// Message
curl_setopt( $chOne, CURLOPT_POSTFIELDS, $message);
//ถ้าต้องการใส่รุป ให้ใส่ 2 parameter imageThumbnail และimageFullsize
curl_setopt( $chOne, CURLOPT_POSTFIELDS, "message=$message&imageThumbnail=http://10.10.10.10/small.jpg&imageFullsize=http://10.10.10.10/large.jpg");
// follow redirects
curl_setopt( $chOne, CURLOPT_FOLLOWLOCATION, 1);
//ADD header array
$headers = array( 'Content-type: application/x-www-form-urlencoded', 'Authorization: Bearer Kxxxxxxxxxxxxxxxxxxxxh', ); // หลังคำว่า Bearer ใส่ line authen code ไป
curl_setopt($chOne, CURLOPT_HTTPHEADER, $headers);
//RETURN
curl_setopt( $chOne, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec( $chOne );
//Check error
if(curl_error($chOne)) { echo 'error:' . curl_error($chOne); }
else { $result_ = json_decode($result, true);
echo "status : ".$result_['status']; echo "message : ". $result_['message']; }
//Close connect
curl_close( $chOne );
?>
$message = $_REQUEST['message'];
$chOne = curl_init();
curl_setopt( $chOne, CURLOPT_URL, "https://notify-api.line.me/api/notify");
// SSL USE
curl_setopt( $chOne, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt( $chOne, CURLOPT_SSL_VERIFYPEER, 0);
//POST
curl_setopt( $chOne, CURLOPT_POST, 1);
// Message
curl_setopt( $chOne, CURLOPT_POSTFIELDS, $message);
//ถ้าต้องการใส่รุป ให้ใส่ 2 parameter imageThumbnail และimageFullsize
curl_setopt( $chOne, CURLOPT_POSTFIELDS, "message=$message&imageThumbnail=http://10.10.10.10/small.jpg&imageFullsize=http://10.10.10.10/large.jpg");
// follow redirects
curl_setopt( $chOne, CURLOPT_FOLLOWLOCATION, 1);
//ADD header array
$headers = array( 'Content-type: application/x-www-form-urlencoded', 'Authorization: Bearer Kxxxxxxxxxxxxxxxxxxxxh', ); // หลังคำว่า Bearer ใส่ line authen code ไป
curl_setopt($chOne, CURLOPT_HTTPHEADER, $headers);
//RETURN
curl_setopt( $chOne, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec( $chOne );
//Check error
if(curl_error($chOne)) { echo 'error:' . curl_error($chOne); }
else { $result_ = json_decode($result, true);
echo "status : ".$result_['status']; echo "message : ". $result_['message']; }
//Close connect
curl_close( $chOne );
?>
///////////////////////////////
code html สำหรับทำหน้าเว็บแสดงผล
//// show.html /////
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Monitor Server Room 2017</TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<BODY>
<h3 align="center"> IP 10.10.10.10 (Linux) </h3>
<table align="center">
<tr algin="center">
<td align="center">
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/00000/charts/1?bgcolor=%23ffffff&color=%23009900&dynamic=true&results=60&title=CPU+%28+%25+%29&type=line"></iframe>
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/000000/charts/4?bgcolor=%23ffffff&color=%23009900&dynamic=true&results=60&title=Memory+%28+%25+%29&type=line"></iframe>
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/238070/charts/3?bgcolor=%23ffffff&color=%23009900&dynamic=true&results=60&title=Disk+Usage&type=line"></iframe>
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/00000/charts/2?bgcolor=%23ffffff&color=%23009900&dynamic=true&results=60&title=Memory&type=line"></iframe>
</td>
</tr>
</table>
<h3 align="center"> IP 10.10.10.11 (Windows Server )</h3>
<table align="center">
<tr algin="center">
<td align="center">
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/00000/charts/1?bgcolor=%23ffffff&color=%23ffaa00&dynamic=true&results=60&title=CPU+%28+%25+%29&type=line"></iframe>
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/000000/charts/4?bgcolor=%23ffffff&color=%23ffaa00&dynamic=true&results=60&title=Memory+%28+%25+%29&type=line"></iframe>
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/00000/charts/3?bgcolor=%23ffffff&color=%23ffaa00&dynamic=true&results=60&title=Disk+Usage+%28+%25+%29&type=line"></iframe>
<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="https://thingspeak.com/channels/00000/charts/2?bgcolor=%23ffffff&color=%23ffaa00&dynamic=true&results=60&title=Memory&type=line"></iframe>
</td>
</tr>
</table>
</BODY>
</HTML>
*ตรง /channels/000000 ต้องเปลี่ยนเป็นเลข channel ของเราน่ะครับ โดย copy จาก iframe
//////////////////////////////////////////////////
สำหรับกรณี ที่ไม่สามารถใช้ python ได้ ก็ให้ลองใช้ shell script ดูครับ
//////////////////////////////////////////////////////////////////////////
สำหรับกรณี ที่ไม่สามารถใช้ python ได้ ก็ให้ลองใช้ shell script ดูครับ
#!/bin/bash
api_key='thinkspeak_api_key'
m=$(free -m | awk 'NR==2{printf "%s/%s\n", $3,$2,$3*100/$2 }')
d=$(df -h | awk '$NF=="/"{printf "%d/%d\n", $2,$3,$5}')
c=$(top -bn1 | grep load | awk '{printf "%.2f\n", $(NF-2)}')
# post the data to thingspeak
curl -k --data \
"api_key=$api_key&field1=$c&field2=$m&field3=$d" https://api.thingspeak.com/update
//////////////////////////////////////////////////////////////////////////
C:\Users\admin\line\examples>python echobot.py
ตอบลบLogin Failed
Traceback (most recent call last):
File "echobot.py", line 15, in
for op in client.longPoll():
NameError: name 'client' is not defined
ผมจะแก้ไงคับ ผม หาโทเค้นไม่เป็น คับ ช่วยอธิบายทีคับ
แอด เฟส มาทีคับ 0850441786
หมายถึงบทความนี้ หรืออันไหนครับ ถ้าอันนี้มันไม่มี client.lognpoll() ครับ มีไลน์ไหมครับ
ลบเยี่ยมมาก
ตอบลบสวัสดีครับ สงสัยอย่างครับ
ตอบลบdef notify(msg):
req = requests.get("http://xx.xx.xx.xx/push.php?message="+msg)
call(["curl", "-X", "POST", "-H", "Authorization: Bearer line_notify_token", "-F", "message="+msg,"https://notify-api.line.me/api/notify"])
ตรงฟังก์ชั่นการเเจ้งเตือน
ทำไมต้องไปเรียน push.php อีกในเมื่อบรรทัดต่อมา call..... ก็คือการส่งข้อความเตือนผ่านไลน์แล้วครับ
ขอบคุณมากครับ
ตอบลบหวัดดีครับ อยากสอบถาม พวก windows 7 10 สามารถทำได้เปล่าครับ
ตอบลบ