심플하게 crontab,python,telegram을 이용하여 서버의 cpu와 memory를 특정 주기로 검사하여 기준값 초과시 텔레그램으로 알림을 주도록 합니다. python 은 설치되어 있고 아래 내용들을 따라가면서 발생하는 trouble shooting이 어느 정도 가능한 분들을 대상으로 작성합니다.

 

1. 텔레그램 봇 생성

1) 텔레그램 클라이언트에서 @BotFather 사용자 추가후 스타트 버튼 클릭

2) /newbot 입력

3) 생성할 봇의 이름 입력(ex) NOTIFICATION_BOT 또는 알림_로봇 -> 반드시 BOT 또는 로봇이 들어가 있어야 생성됨)

4) 이렇게 생성된 봇을 알림을 받고 싶은 채널에 사용자 추가를 한다

* chat_id를 알아내는 방법

@BotFather에서 /token 을 누르고 생성한 봇을 선택하면 HTTP API 토큰값을 얻을 수 있다

https://api.telegram.org/bot토큰/getUpdates 으로 나온 응답값의 chat_id로 메세지 전송이 가능하다

https://api.telegram.org/bot토큰/sendMessage?chat_id=&text=Hello%20World%21

 

2. python telepot 모듈을 이용한 메세지 전송

1) pip 설치

- sudo yum install python-pip

2) telepot 설치 ( api 명세 : http://telepot.readthedocs.io/en/latest/ )

- pip install telepot

3) 테스트 코드 (send_msg.py)

 

#!/usr/bin/env python
import telepot
import os
import socket
import commands
import string
import sys

#Telegram bot
NOTI_API_TOKEN = '위방법으로 알아낸 토큰값 설정하면 됩니다'
NOTI_CHAT_ID = 위방법으로알아낸chat_id
bot = telepot.Bot(NOTI_API_TOKEN)

def send(chat):
 bot.sendMessage(NOTI_CHAT_ID, chat, parse_mode='HTML')

if len(sys.argv) == 1:
    print "# need more parameter"
    exit(1)

msg=''
for idx, value in enumerate(sys.argv):
    if idx > 0:
        msg += value + "\n"
send(msg)

테스트 -> python send_msg.py 'hello, world'

 

3. cpu와 memory 체크 및 알림 코드 (noti_monitoring.py, 본인에 맞게 커스터마이징 하세요)

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import telepot
import os
import socket
import commands
import string
import sys
import psutil
import time
 
# 기준 및 초기값 설정
cpuLimit = 50 # 서버 환경에 맞게 수정하세요
memLimit = 50 # 서버 환경에 맞게 수정하세요
serverName = '서버이름'
title = '[' + serverName + ' 서버]\n'
msg = title
 
#Telegram bot
NOTI_API_TOKEN = '알아서넣으세요'
NOTI_CHAT_ID = 알아서넣으세요
bot = telepot.Bot(NOTI_API_TOKEN)
 
# 텔레그램 메세지 전송
def send(chat):
        bot.sendMessage(NOTI_CHAT_ID, chat, parse_mode='HTML')
 
# cpu 사용율 계산
def getCpuUsage():
        cpu = 0
        for x in range(2):
            cpu += psutil.cpu_percent(interval=1)
        return round(float(cpu)/3,2)
 
# memory 사용량 계산
def getMemUsage():
        mem=str(os.popen('free -t -m').readlines())
        T_ind=mem.index('T')
        mem=mem[T_ind+6:]
        mem_T=mem[:13]
        mem_sub=mem[14:]
        mem_U=mem_sub[:13]
        return round(float(mem_U)/float(mem_T)*100,2)
 
avgCpu = getCpuUsage()
memUsage = getMemUsage()
 
if avgCpu > cpuLimit:
        msg += 'cpu 사용량이 기준값(' + str(cpuLimit) + '%)을 초과하였습니다.\n'
        msg += 'cpu usage : ' + str(avgCpu) + '%\n'
 
if memUsage > memLimit:
        msg += 'memory 사용량이 기준값(' + str(memLimit) + '%)을 초과하였습니다.\n'
        msg += 'memory usage : ' + str(memUsage) + '%\n'
 
if avgCpu > cpuLimit or memUsage > memLimit:
        msg += serverName + ' 무엇무엇을 합니다'
        send(msg)
        os.system('커멘트라인 명령으로 필요한 작업, 필요없을 경우 주석처리')
        time.sleep(5)
        msg = title + '재시작후 cpu & memory는 아래와 같습니다.\n'
        msg += 'cpu usage : ' + str(getCpuUsage()) + '%\n'
        msg += 'memory usage : ' + str(getMemUsage()) + '%\n'
        send(msg)

4. crontab에 등록할 스크립트 생성 (noti_monitoring.sh, 본인에 맞게 커스터마이징 하세요)

 

 

python /스크립트경로/noti_monitoring.py

 

5. crontab 등록(crontab -e)

 

# 매1분 단위로 실행 (자세한 설정은 구글링하세요)
*/1 * * * * /스크립트경로/noti_monitoring.sh > /dev/null  2>&1

 

원인 : 쉘스크립트 실행시 유닉스 개행문자와 윈도우 개행문자가 섞여 있을때 ^M 발생


해결

1. 바이너리 편집 모드로 파일 열기 

   # vi -b  파일명

2. 명령 모드에서 아래를 입력하여 ^M 삭제

   %s/^M//g 


주의 : ^M 입력시 ctrl + v, ctrl + M 으로 입력해야 정상적으로 입력된다.


메모리 누수가 의심될때 한가지는 스왑 메모리의 사용량이다. 아래 내용으로 간단히 확인 가능하다.

 

  • 배경
    • 리눅스는 free 메모리를 최대한 cache 메모리로 사용하여 시간이 지날수록 cache 메모리 사용량이 증가하면서 애플리케이션의 로딩 속도가 향상됨.
      • free 메모리가 필요한 순간에는 cache 메모리를 줄이고 free 메모리를 확보함.
  • top 예제
  • 위 그림에서 used는 실제 메모리 사용량이 아니라 빨간색으로 묶은 buffers + cached, 그리고 여기에 표시되지 않은 다른 메모리사용량(실제 메모리 사용량)을 합한 값으로 보여지게 된다.

 

  • free 예제


    • 실제 메모리 사용량을 확인할 수가 있는데, 빨간색으로 보여지는 부분의 used가 실제 메모리 사용량이고 free가 실제 여유 메모리를 나타낸다.
      • 첫번째 라인의 used는 buffers + cached + 실제 메모리사용량 --> 1420 = 167 + 1072 + 180 (mb로 표시하여 1의 오차가 발생, free -k로 보면 값이 정확함)
      • 두번째 라인의 free는 첫번째 라인의 free + buffers + cached --> 1845 = 606 + 167 + 1072 (mb로 표시하여 1의 오차가 발생, free -k로 보면 값이 정확함)

 

+ Recent posts