iT邦幫忙

DAY 12
3

MySQL漫談,由使用Python撰寫之MySQL工具程式出發系列 第 12

MySQL漫談,由使用Python撰寫之MySQL工具程式出發(12)

今天將延續昨天介紹的Linux資訊報告,介紹各項內容,與程式碼解說.
首先先看今天產生的報告.

$ ./Linux_Quick_Report.py 
###### Hitomi Linux Qucik Report Version:1.1 ######
Report Create Time  2012-10-15 13:23:13
------------------------------------------------------------
  System Boot Time - Mon Oct 15 07:39:35 2012
           Release - Linux Mint 13 Maya
              CPUs -       4 
      CPU #1 Model - Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
      CPU #2 Model - Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
      CPU #3 Model - Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
      CPU #4 Model - Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
   CPU #1 bogomips - 6186.15 
   CPU #2 bogomips - 6185.90 
   CPU #3 bogomips - 6185.91 
   CPU #4 bogomips - 6185.90 
            Memory -    7.68 GB
         Swap Size -    7.88 GB
 Swap Used Percent -   84.00 %
   Total Processes -  168.00 
  System Processes -   89.00 
------------------------------------------------------------
Disk Info
        Filesystem -     /dev/sda1
              Size -     923G
              Used -     446G
         Available -     431G
       Use Percent -     51%
        Mounted on -     /
============================================================
      Working Time - 0.022233 second

跟昨天的略有不同,以下將逐項介紹,首先是檔頭部份.檔頭先顯示程式名稱及版本,
再來是報告產生時間.
第二部份是系統一些資訊:
(1) System Boot Time 是系統開機時間
(2) Release 是Linux 發行版的資訊
(3) CPUs 是系統目前可以使用的CPU數量,在此要說明一下,因為現代科技進步,有多核的CPU,所以在此回報的是核心數目,不是現在新技術的一顆CPU.
(4) 再來是各個CPU的型號,雖然我們都知道這是一個多核CPU的情況,但也有多CPU的型號略有差異的情況,故在此就一一列出.
(5) 接著是各個CPU的運算能力的一個衡量值,這是一個Linux 核心自己內部計算產生的一個估計值,可以用來作相對比較使用.
(6) Memory 就是系統可用的 Memory
(7) Swap Size 是 Swap 的大小
(8) Swap Used Percent 是 Swap已經使用多少百分比
(9) Total Processes 系統現有多少 Processes 在執行
(10) System Processes 有多少是系統啟動的 Processes
再來是 Disk Info部份
(1) Filesystem 是哪個分割區
(2) Size 是容量
(3) Used 是已使用量
(4) Available 是可用量
(5) Use Percent 是已使用百分比
(6) Mounted on 掛載點
最後是檔尾,列印出本程式總執行時間.

程式碼如下:

#!/usr/bin/env python
#----------------------------
# Python
# Hardware & OS Information
# ---------------------------
import subprocess
import os
import time
import datetime

# --- Gloabl Variables Section ---
PROC_NAME = 'Hitomi Linux Qucik Report'
PROC_VERSION = '1.1'
# -------------------------
# --- Utility Functions ---
def kilo_to_giga(kilo):
    return round(float(kilo) / 1048576, 2)

def get_systime():
    time_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    return time_str

def print_split(style=1):
    if style == 1:
        print '-' * 60
    else:
        print '=' * 60

def myprint(topic, num, unit_str='', style=1):
   if style == 1:
        print '%18s - %7.2f %s' % (topic, num, unit_str)
   elif style == 2:
        print '%18s - %7d %s' % (topic, num, unit_str)

def myprint_str(topic, pstr, spacenum=1):
    print '%18s -%s%s' % (topic, ' '*spacenum, pstr)
# ---------------------
def get_release_info():
    with open('/etc/lsb-release', 'r') as lines:
        for line in lines:
            if line.startswith('DISTRIB_DESCRIPTION'):
                release = line.split('=')[1].strip().lstrip('"').rstrip('"')
        #
        return release
#
def get_cpus_quantity():
    return os.sysconf('SC_NPROCESSORS_ONLN')
#
def get_cpus_info():
    with open('/proc/cpuinfo', 'r') as infos:
        cpus_dict = {}
        mips_dict = {}
        cpu_num = 0
        for line in infos:
            if line.lower().startswith('model name'):
                model = line.split(':')[1].lstrip().split('\n')[0]
                cpu_num = cpu_num + 1
                cpus_dict[cpu_num] = model
            if line.lower().startswith('bogomips'):
                mips = line.split(':')[1].lstrip().split('\n')[0]
                mips_dict[cpu_num] = float(mips)
        #
        return cpus_dict, mips_dict
#
def get_memory_info():
    output = subprocess.check_output(
            'cat /proc/meminfo | head -1', shell=True,)
    mem = output.split(':')[1].strip()
    mem_val, mem_unit = mem.split(' ')
    if mem_unit.lower() == 'kb':
        mem_val = kilo_to_giga(mem_val)
        mem_unit = 'GB'
    #
    return mem_val, mem_unit
#
def get_boot_time_str():
    with open('/proc/stat', 'r') as lines:
        for line in lines:
                if line.startswith('btime'):
                    bt = float(line.strip().split()[1])
        #
        return time.ctime(bt)
#
def get_disk_info():
    output = subprocess.check_output(
            'df -h', shell=True,)
    disk_info = output.splitlines()
    disk_info.pop(0)
    volumes_list = []
    for line in disk_info:
        line = line.split()
        if line[0].startswith('/dev'):
            volumes_list.append(line)
    #
    return volumes_list
#
def get_process_info():
    output = subprocess.check_output(
            'ps aux', shell=True,)
    ps_info = output.splitlines()
    root_cnt = 0
    cnt = 0
    for line in ps_info:
        cnt = cnt + 1
        line = line.split()
        if line[0] == 'root':
            root_cnt = root_cnt + 1
    #
    return cnt, root_cnt
def get_swap_info():
    output = subprocess.check_output(
            'cat /proc/swaps', shell=True,)
    swap_info = output.splitlines()
    swap_info.pop(0)
    swap = swap_info[0].split()
    swap_size = kilo_to_giga(swap[2])
    swap_used_percent = float(swap[3])
    return swap_size, swap_used_percent
# ----------------------------
def display_report():
    print_header()
    print_boot_time()
    print_release_info()
    print_cpu_info()
    print_mem_info()
    print_swap_info()
    print_ps_info()
    print_disk_info()
    print_tail()
#
def print_boot_time():
    boot = get_boot_time_str()
    myprint_str('System Boot Time', boot)

def print_header():
    print '###### %s Version:%s ######' % (PROC_NAME, PROC_VERSION)
    print 'Report Create Time  %s' % get_systime()
    print_split()

def print_release_info():
    release_info = get_release_info()
    myprint_str('Release', release_info)

def print_cpu_info():
    cpus_quantity = get_cpus_quantity()
    myprint('CPUs', cpus_quantity, style=2)
    cpu_info, mips_info = get_cpus_info()
    for i in range(1, cpus_quantity+1):
        cpu_num = 'CPU #%d Model' % i
        cpu_model = cpu_info[i]
        myprint_str(cpu_num, cpu_model)
        
    for i in range(1, cpus_quantity+1):
        cpu_num = 'CPU #%d bogomips' % i
        mips = mips_info[i]
        myprint(cpu_num, mips)
        
def print_mem_info():
    memval, memunit = get_memory_info()
    myprint('Memory', memval, memunit)

def print_swap_info():
    swap_size, swap_usage = get_swap_info()
    myprint('Swap Size', swap_size, 'GB')
    myprint('Swap Used Percent', swap_usage, '%')

def print_ps_info():
    tot, root = get_process_info()
    myprint('Total Processes', tot)
    myprint('System Processes', root)

  
def print_disk_info():
    print_split()
    print 'Disk Info'
    disk_info = get_disk_info()
    for disk in disk_info:
       filesystem = disk[0]
       size = disk[1]
       used = disk[2]
       available = disk[3]
       use_percent = disk[4]
       mount = disk[5]
       myprint_str('Filesystem', filesystem, spacenum=5)
       myprint_str('Size', size, spacenum=5)
       myprint_str('Used', used, spacenum=5)
       myprint_str('Available', available, spacenum=5)
       myprint_str('Use Percent', use_percent, spacenum=5)
       myprint_str('Mounted on', mount, spacenum=5)
#
def print_tail():
    print_split(style=2)
    
# --------------------------
if __name__ == '__main__':
    start_time = datetime.datetime.now()
    display_report()
    end_time = datetime.datetime.now()
    working_time = end_time - start_time
    print '%18s - %d.%06d second' % ('Working Time', working_time.seconds, working_time.microseconds)

程式碼說明:
Line 6~9 是將需要的模式載入, Line 11~14 是定義程式名稱與版號.
Line 15~37 是一些輔助函式, kilo_to_giga() 是將 K 轉換為 Giga,因為系統回報的資訊
有許多還是用K,對現代人來說,用G比較直觀; get_systime()是取得系統時間, print_split()
列印分割線, myprint() 用來列印 標題-數字 型態的資料, myprint_str()用來列印 標題-字串
型態的資料.

get_release_info() 是讀取 /etc/lsb-release 的內容,找出 DISTRIB_DESCRIPTION 的內容.

get_cpus_quantity() 是利用 os 模組的功能,找出 SC_NPROCESSORS_ONLN 的值,這是系統上目前可
運作的CPU的值.

get_cpus_info() 是讀取 /proc/cpuinfo 的內容,這檔案包含許多 CPU相關的資訊,在此只讀取兩組,
分別是 model name 與 bogomips.

get_memory_info() 是呼叫 cat 與 head 合作將 /proc/meminfo 的值取出第1行,其實也可以用直接
讀取的,在此是要示範呼叫 Linux 的指令,而且這樣使用,也簡單;然後判斷讀到的值若是用 Kb, 則換算
為 GB,返回值也包含了單位.

get_boot_time_str() 是讀取 /proc/stat 的內容,取出 btime的值,這是紀錄開機時刻,以自 1970/1/1
的 UNIX紀元開始的秒數格式來紀錄,使用 time.ctime()換算成本地時間.

get_disk_info() 是呼叫 df -h 執行後,將 /dev 開頭的部份擷取出來.

get_process_info() 是呼叫 ps aux ,然後計算總 processes與 root 啟動的 processes數量.

get_swap_info() 是用 呼叫cat 來顯示 /proc/swaps 的內容,再擷取 swap的大小與許用百分比.

display_report() 是依序呼叫各個 print_開頭的函式來列印報告.

Line 131~194 是各個列印的函式.
Line 195~200 是主程式所在,先判斷本程式是否是以主程式的身份來執行,然後紀錄啟動時刻,
接著呼叫 display_report(),來進行各個區塊的列印以產生報告,最後計算出總運行時間並列印.

也許會有人覺得要這樣先寫函式取得資訊,再用列印的函式來呼叫,有點多此一舉,其實這是Python
程式慣用的一種方法,本程式可以被別的Python當作模組引用,然後就能呼叫裡面的函式,而本程式
因為不是主程式,所以 Line 195的部份不會執行,就不會列印報表.這樣子很方便讓函式被引用.


上一篇
MySQL漫談,由使用Python撰寫之MySQL工具程式出發(11)
下一篇
MySQL漫談,由使用Python撰寫之MySQL工具程式出發(13)
系列文
MySQL漫談,由使用Python撰寫之MySQL工具程式出發30

1 則留言

0
patrickcheng
iT邦新手 4 級 ‧ 2012-10-16 09:45:09

逐項說明的方式,也適合未來出書,good.

我要留言

立即登入留言