国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Python > 正文

使用Python寫個(gè)小監(jiān)控

2020-01-04 17:48:02
字體:
供稿:網(wǎng)友
最近使用python寫了個(gè)小監(jiān)控,為什么使用python?簡(jiǎn)單、方便、好管理,Python如何實(shí)現(xiàn)簡(jiǎn)單的小監(jiān)控,感興趣的小伙伴們可以參考一下
 

1.入門

首先你得用過C/C++、java、Javascript等的一種,編程小白估計(jì)比較艱難,有一定編程經(jīng)驗(yàn)的python小白相對(duì)簡(jiǎn)單些。

1.1 Hello World!

Python安裝比較簡(jiǎn)單,到官網(wǎng)上下載安裝包,一路下一步就可以了。因?yàn)槲业姆?wù)器上安裝的是2.6.6,所以我也下了這個(gè)版本。話說2.x的差別不是很大,如果想用3.x,可能下面的代碼直接運(yùn)行不過,不過也差不多,稍微改改即可。
新建一個(gè)文件,命名為hello.py。使用python的IDLE打開hello.py,寫入以下代碼:

print "Hello World!"

按F5,就可以看見輸出結(jié)果了。

1.2 基本語法

每一行是一條語句。C語言是通過分號(hào)”;“;
通過縮進(jìn)來組織代碼塊。C語言是通過大括號(hào)”{}“;
注釋使用井號(hào)”#“。

1.3 數(shù)據(jù)類型、運(yùn)算符、數(shù)據(jù)結(jié)構(gòu)

運(yùn)算符和C語言差不多,C語言有的基本上直接用就可以。
數(shù)據(jù)類型有數(shù)值型,字符串。數(shù)據(jù)結(jié)構(gòu)有 list, tuple, dict, set。介紹一下tuple, 不能修改,通過索引進(jìn)行查找。dict類似于map,存放鍵值對(duì)。來看例子,看看tuple使用:

>>> t=(1,2,[1,2])>>> t[2][1, 2]

1.4 流程控制

Python中可以使用if elif else、for和 while 來實(shí)現(xiàn)流程控制。同樣有 break 和 continue。有一點(diǎn)和C不同,如果有一個(gè)分支什么都不做,要使用 pass。例如

list=[0, 1, 2, 3, 4, 5]for item in list:  if item == 1:    print item  elif item in (2, 3, 4, 5):    print "aha " + str(item)  else:    pass

運(yùn)行結(jié)果是:
1
aha 2
aha 3
aha 4
aha 5

1.5 模塊組織

有方法和類。

方法這樣定義

def func(var):   some code here

類和C++等有些不同

class MyClass(object):  common = 1  def __init__(self):    self.myvariable = 5  def myfunction(self, arg1, arg2):    return self.myvariable

common變量相當(dāng)于C++中用 static 修飾的變量,所有類通用;繼承也非常簡(jiǎn)單,可以看看開始推薦的那篇文章。

1.6 異常處理

異常處理非常簡(jiǎn)單,直接貼代碼了:

def some_function():  try:    # Division by zero raises an exception    10 / 0  except ZeroDivisionError:    print "Oops, invalid."  else:    # Exception didn't occur, we're good.    pass  finally:    # This is executed after the code block is run    # and all exceptions have been handled, even    # if a new exception is raised while handling.    print "We're done with that."

1.7 工程組織

直接引用庫(kù),或者從庫(kù)中引入某一個(gè)方法或變量。

import randomfrom time import clock

2. 數(shù)據(jù)庫(kù)查詢

既然是監(jiān)控,免不了和數(shù)據(jù)庫(kù)打交道。我使用的是PostgreSQL,所以就介紹一下python怎么調(diào)用postgres。

連接postgres首先要安裝一個(gè)庫(kù)psycopg2,Windows下直接下載安裝即可,注意選對(duì)版本。我的服務(wù)器是CentOS,安裝直接運(yùn)行

yum install python-psycopg2

就OK了。

2.1 首先創(chuàng)建數(shù)據(jù)庫(kù)連接

#get database connectdef get_con():    host = '127.0.0.1'  port = "5432"  database = 'platform'  user = 'postgres'  password = 'postgres'  conn = psycopg2.connect(database=database, user=user, password=password, host=host, port=port)  return conn

2.2 執(zhí)行SQL語句

#執(zhí)行sql查詢def query(conn, sql):  cursor = conn.cursor()  cursor.execute(sql)  results = cursor.fetchall()  #close cursor  cursor.close()  return results

2.3 然后就可以寫具體業(yè)務(wù)了

def getUsers():  conn = get_con()#open connect  sql = """select *     from t_user     order by intime DESC     limit 5"""  items = query(conn , sql)  print str(items)  conn.close() #close connect

注意3個(gè)引號(hào)”””,就是普通字符串,不過可以換行。

3. 發(fā)送郵件

查詢到數(shù)據(jù)之后不能及時(shí)通知管理員的話監(jiān)控就沒有意義了。所以我們通過郵件來通知,直接使用python的標(biāo)準(zhǔn)庫(kù) smtplib 就可以了。寫個(gè)發(fā)送郵件的函數(shù):

#發(fā)送郵件def send_email(subject, content):  sender = "yourmail@***.com"  password = "******" #密碼是看不見的哦  receivers = [tq8117179#163.com] #本人真實(shí)郵箱,歡迎發(fā)郵件討論技術(shù)問題  host = "smtp.exmail.qq.com"  port = 465  msg = MIMEText(content,'html','utf-8')  msg['From'] = sender  msg['To'] = ",".join(receivers)  msg['Subject'] = Header(subject, 'utf-8')  try:    smtp = smtplib.SMTP_SSL(host, port)    smtp.login(sender, password)    smtp.sendmail(sender, receivers, msg.as_string())  except Exception, e:    logger.error(e)  logger.info(content)

4.日志

發(fā)送郵件時(shí)我們使用了logger,這個(gè)logger是怎么來的呢?新建一個(gè)log.py,代碼如下

# coding=utf-8import loggingimport logging.handlerslogger = logging.getLogger('monitor')logger.setLevel(logging.DEBUG)filehandler = logging.handlers.TimedRotatingFileHandler(     "/mnt/log/monitor/monitor_log", 'midnight', 1, 7)# 設(shè)置文件后綴名稱filehandler.suffix = "%Y%m%d.log"formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s: %(message)s')filehandler.setFormatter(formatter)logger.addHandler(filehandler)通過logging.getLogger(‘monitor')生成一個(gè)logger,然后配置一個(gè)文件處理器。然后在我們監(jiān)控程序中引用即可:from log import logger

5. 把可配置信息放到配置文件中

如果我們添加一個(gè)管理員怎么辦?如果我們的郵箱密碼變了怎么辦?直接修改python文件啊,哈哈。python不用編譯直接改代碼就好了,可是我們的程序以后要打包呢,所以最好寫個(gè)配置文件,python的配置文件讀取非常簡(jiǎn)單,使用python庫(kù) ConfigParser 即可:

config = None#get configdef getConfig():  global config  if config is None:    config = ConfigParser.ConfigParser()    config.read("monitor.ini")  return config

然后這樣使用:

#get database connectdef get_con():    host = getConfig().get('db', 'host')  port = getConfig().get('db', 'port')  database = getConfig().get('db', 'database')  user = getConfig().get('db', 'user')  password = getConfig().get('db', 'password')  conn = psycopg2.connect(database=database, user=user, password=password, host=host, port=port)  return conn#發(fā)送郵件def send_email(subject, content):  sender = getConfig().get('mail', 'sender')  password = getConfig().get('mail', 'password')  receivers = getConfig().get('mail', 'receivers').split(",")  host = getConfig().get('mail', 'host')  port = getConfig().getint('mail', 'port')  msg = MIMEText(content,'html','utf-8')  msg['From'] = sender  msg['To'] = ",".join(receivers)  msg['Subject'] = Header(subject, 'utf-8')  try:    smtp = smtplib.SMTP_SSL(host, port)    smtp.login(sender, password)    smtp.sendmail(sender, receivers, msg.as_string())  except:    logger.exception("Exception: ")  logger.info(content)

配置文件是monitor.ini,內(nèi)容如下:

#數(shù)據(jù)庫(kù)配置[db]host = 127.0.0.1port = 5432database = platformuser = postgrespassword = postgres#郵件配置[mail]sender = yourmail@XXX.compassword = ******#多個(gè)聯(lián)系人用英文逗號(hào)隔開receivers = tq8117179#163.comhost = smtp.exmail.qq.comport = 465

6. 加點(diǎn)控制

我們每5分鐘查一下數(shù)據(jù),可是業(yè)務(wù)sql只能查詢最近的幾條,所以要加個(gè)時(shí)間段限制,弄個(gè)開始、結(jié)束時(shí)間。

 

start_time = "2015-10-1 16:24:24"end_time = None#update end_time, invoke before get new datadef update_end_time():  global end_time  now = time.mktime(datetime.now().timetuple())  end_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now))  return end_time#update end_time, invoke after get new datadef update_start_time():  global start_time  global end_time  start_time = end_time  return start_timegetUsers可以改寫成:def getUsers (conn):  global start_time  global end_time  sql = """select *     from t_user     where intime>=""" +"'"+start_time+"' and intime<"+"'"+end_time+"';"  items = query(conn, sql)  if items is not None and len(items)>0:    count = len(items)    tip = "又有"+str(count)+"個(gè)用戶已經(jīng)注冊(cè)了。"+end_time    send_email(tip, tip+"/n"+str(items))

然后寫個(gè)統(tǒng)一的調(diào)度:

def task():  #init end_time and start_time, must init end_time first!!!  end_time = update_end_time()  start_time = update_start_time()  #init config  getConfig()  while True:    conn = get_con()   #open connect    end_time = update_end_time()    ############## process ##############    logger.info("query: "+end_time)    getUsers (conn)    #do some task else here    ## end    update_start_time()    conn.close()#close connect    time.sleep(5*60)  #end of whiledef run_monitor():  monitor = threading.Thread(target=task)  monitor.start()if __name__ == "__main__":  run_monitor()

在task這個(gè)函數(shù)的while中,首先更新end_time,也就是當(dāng)前時(shí)間;執(zhí)行完再把start_time更新成剛剛的end_time,這樣就不會(huì)有漏網(wǎng)之魚了。還有一個(gè)需要注意的地方,關(guān)鍵字global。 在python中,使用全局變量是需要global關(guān)鍵字進(jìn)行聲明的,否則會(huì)出問題。

7. 運(yùn)行

打開linux 控制臺(tái),直接運(yùn)行python monitor.py是可以運(yùn)行的,可是shell一旦退出,任務(wù)也就停止了。于是我就選擇了一個(gè)進(jìn)程管理工具:Supervisor。Supervisor 在進(jìn)程中斷時(shí)還能自動(dòng)重啟。

7.1. 安裝supervisor

首先安裝python-setuptools

yum install python-setuptools

安裝supervisor

 easy_install supervisor

生成supervisor配置文件

 echo_supervisord_conf > /etc/supervisord.conf

然后在/etc/supervisord.conf添加:

[program:monitor]command = python /usr/monitor/monitor.pydirectory = /usr/monitoruser = root

7.2. 運(yùn)行監(jiān)控

然后在終端中運(yùn)行supervisord啟動(dòng)supervisor。
在終端中運(yùn)行supervisorctl,進(jìn)入shell,運(yùn)行status查看腳本的運(yùn)行狀態(tài)。

7.3. 關(guān)閉監(jiān)控 以及常用命令

以下命令全部在supervisorctl的shell中執(zhí)行。

  • shutdown 停止Supervisor(子進(jìn)程也會(huì)被停止) ;
  • start monitor 開啟monitor進(jìn)程服務(wù)(一旦monitor進(jìn)程退出,會(huì)自啟動(dòng)) ;
  • stop monitor 關(guān)閉monitor進(jìn)程服務(wù) ;
  • restart monitor 關(guān)閉正在運(yùn)行的monitor進(jìn)程,并且重新啟動(dòng)monitor進(jìn)程服務(wù) ;
  • reload 重新加載supervisor配置文件 ;
  • exit 退出supervisorctl的shell。

程序基本上就寫完了,也可以跑起來了,是不是很酷,大家快點(diǎn)動(dòng)手實(shí)踐一下吧!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 水城县| 南开区| 鹤庆县| 内黄县| 河北省| 漯河市| 靖西县| 台江县| 原平市| 游戏| 白河县| 秦皇岛市| 深水埗区| 泌阳县| 寿阳县| 苍梧县| 阿拉善右旗| 定结县| 随州市| 凯里市| 西盟| 丁青县| 杭锦后旗| 方正县| 东辽县| 黄山市| 分宜县| 通辽市| 龙井市| 娱乐| 镇坪县| 长顺县| 睢宁县| 涞水县| 安塞县| 左权县| 双桥区| 观塘区| 江川县| 红原县| 浪卡子县|