เขียน python or shell script ส่งค่า cpu ,memory และ Disk Usage ของ server linux centos และ windows server ขึ้น cloud thingspeak และแจ้งเตือนผ่าน line group




ภาพแสดงกราฟ



ภาพแสดงการแจ้งเตือนผ่าน Line group ด้วย Line notify


แนวคิด

    เนื่องจาก ต้องการที่จะทราบค่า 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)



//////////////////////////////////////////////

***  ในส่วนของ 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    แล้วพิมพ์ตามรูป

 


สำหรับการตั้งค่า schedule task  ให้ใส่ตามรูปเลยครับ



code  python  สำหรับ Windows  edit 2017-03-14
/////////////////////////////////////////////////////////////////


 #!/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


///////////////////////

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 );

?>



///////////////////////////////
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 ดูครับ

#!/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


//////////////////////////////////////////////////////////////////////////



ความคิดเห็น

  1. 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

    ตอบลบ
    คำตอบ
    1. หมายถึงบทความนี้ หรืออันไหนครับ ถ้าอันนี้มันไม่มี client.lognpoll() ครับ มีไลน์ไหมครับ

      ลบ
  2. สวัสดีครับ สงสัยอย่างครับ
    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..... ก็คือการส่งข้อความเตือนผ่านไลน์แล้วครับ

    ตอบลบ
  3. หวัดดีครับ อยากสอบถาม พวก windows 7 10 สามารถทำได้เปล่าครับ

    ตอบลบ

แสดงความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

แจ้งเตือนเข้าไลน์กลุ่ม ผ่าน Line notify เมื่อมีคน login เข้า server ของเราผ่าน SSH (linux) หรือ remote desktop เข้ามา (windows server)

การทำ cloud iot ด้วย thingsboard ไว้ใช้เองครับ

การประยุกต์ใช้ line notify ในการแจ้งปัญหาการใช้งาน สำหรับ php