System info by psutil

This module can be used on Windows, OS X, Linux, FreeBSD and Sun Solaris, etc. The unit is byte, so if you need to show in human readable way, you need to modify the data a little bit.

First , install the module,

pip3 install psutil

Then pull the info:

1. CPU – psutil.cpu_times()

Get CPU whole info:

>>> import psutil

>>>psutil.cpu_times( )

If you want to show the logic core info, add argument percpu=True:

>>psutil.cpu_times( percpu=True) scputimes( user=38.039999999999999, nice=0.01, system=110.88, idle=177062.59, iowait=53.399999999999999, irq=2.9100000000000001, softirq=79.579999999999998, steal=0.0, guest=0.0)

Get the percentage the current user’s process take:

 

>psutil.cpu_times( ) .user

38.0

To get the logical core number , by default logical=True

>psutil.cpu_count( )

4

Only show physical Processor number:

>psutil.cpu_count( logical=False)

2

2. Memory info – virtual_memory( ) , swap_memory( )

use psutil.virtual_memory() and psutil.swap_memory()to get the memory info.

Then use property, such as total, used, free, buffers, cache, swap to get the specific info you need.

3. Disk info – disk_usage() , disk_partitions(), disk_io_counters()

The disk IO info includes read_count , write_count , read_bytes , write_bytes , read_time ,write_time etc.

Following code show the memory info and network info.

4. Network statistic – net_io_counters()

By default, the method collect all the network activity summary, not by each NIC, which means the default argument pernic=False.

>>psutil.net_io_counters( )

snetio( bytes_sent=27098178, bytes_recv=28220119, packets_sent=200978, packets_recv=212672, errin=0, errout=0, dropin=0, dropout=0)

To show the statistic of each NIC:

>>psutil.net_io_counters( pernic=True)
{‘lo’: snetio( bytes_sent=26406824, bytes_recv=26406824, packets_sent=198526, packets_recv=198526, errin=0, errout=0, dropin=0, dropout=0) , ‘eth0’: snetio( bytes_sent=694750, bytes_recv=1816743, packets_sent=2478, packets_recv=14175, errin=0, errout=0, dropin=0, dropout=0) }

Example:

import psutil
mem=psutil.virtual_memory()  # Get the total memory info by method "virtual_memory"
total_mem=mem.total/(1024**3) 
used_mem=mem.free/(1024**3)
print("The total memory in this PC is %.2f GB.\n" % total_mem,"The free memory is %.2f GB" % used_mem)

# following code can show the network statistics
net_counter=str(psutil.net_io_counters())
print(net_counter)
snetio(bytes_sent=137603096, bytes_recv=942048301, packets_sent=515173, packets_recv=890816, errin=0, errout=0, dropin=0, dropout=0)

To make the info more readable, first we split the message by comma, then remove the open and close parenthesis :

 

net_index=net_counter.split(',')
for index in net_index:
    if index is net_index[0]:
        print(" The network statistic is :\n"+ index[7:])
    elif index is net_index[-1]:
        print(index[1:-1])
    else:
        print(index[1:])

5. other system info

  • User info:

>>>psutil.users( )

[suser( name=’root’, terminal=’pts/0’, host=’192.168.1.103’, started=1394638720.0) , suser( name=’root’, terminal=’pts/1’, host=’192.168.1.103’, started=1394723840.0) ]
  • Boot time:

>> import psutil, datetime

>>psutil.boot_time()
1389563460.0

To convert into readable time format:

>>datetime.datetime.fromtimestamp(psutil.boot_time()) .strftime( “%Y-%m- %d %H: %M: %S”)

‘2014-01-12 22: 51: 00’

Process management
  • To get all the process PID: psutil.pids()
  • psutil.Process(pid)to get info about a single process, such as the name(name()), app path(exe()), status(status()), absolute current working directory (cwd()) and system resource usage, etc.

if the java is running with pid 2424:

>>> p = psutil.Process( 2424)

>>> p.name( )

‘java’

>>> p.exe( )

‘/usr/java/jdk1.6.0_45/bin/java’

 

>>>p.cwd( )

‘/usr/local/hadoop-1.2.1’

 

>>>p.status( )

‘sleeping’

 

>>>p.create_time( )     # process creating time

1394852592.6900001

 

>>>p.uids( )

puids( real=0, effective=0, saved=0)

 

>>>p.gids( ) #process gid

pgids( real=0, effective=0, saved=0)

 

>>p.cpu_times( ) #process CPU times info, including user、 system’s times

pcputimes( user=9.0500000000000007, system=20.25)

 

>>>p.cpu_affinity( ) #get the CPU affinity value

[0, 1]

 

>>p.memory_percent( )

14.147714861289776

 

>>>p.memory_info( ) #进程内存rss、 vms信息

pmem( rss=71626752, vms=1575665664)

 

>>>p.io_counters( )

pio( read_count=41133, write_count=16811, read_bytes=37023744, write_bytes=4722688)

 

>>>p.connections( )   #return the info of socket namedutples list, includeing fs、 family、 laddr

[pconn( fd=65, family=10, type=1, laddr=( ‘: : ffff: 192.168.1.20’, 9000) , raddr=( ) , ……]

 

>>p.num_threads( )

33

pids=psutil.pids()
for pid in pids:
    p=psutil.Process(pid)
    pname=p.name()
    print(" The process {} with process ID {} " .format(pname,pid))

> import psutil
>>>from subprocess import PIPE

>>> p = psutil.Popen( [“/usr/bin/python”, “-c”, “print( ‘hello’) “],stdout=PIPE)
>>>p.name( )
‘python’
>>>p.username( )
‘root’
>>>p.communicate( )
( ‘hello\n’, None)
>>>p.cpu_times( )
pcputimes( user=0.01, system=0.040000000000000001)

 

IP module IPy

The IP address is in x.x.x.x/x format

Version

 

from IPy import IP

IP_version1=IP('10.0.0.0/8').version()

IP_version2=IP("::1").version()

print(IP_version1,IP_version2)
network addreee / net mask / broadcast address

 

 

its=IP('10.0.0.0/8')

print('net: %s' % its.net() ) 

print('netmask: %s' % its.netmask() ) 

print('broadcast: %s' % its.broadcast() )

 

Address length – len()
ip=IP ('192.168.1.0/24')

ip_len=ip.len()

print(ip_len)

for x in ip:

    print(x)
256

192.168.1.0

192.168.1.1

192.168.1.2

192.168.1.3

192.168.1.4

192.168.1.5
....
>>>ip = IP( '192.168.1.20')
>>>ip.reverseNames( ) 
['20.1.168.192.in-addr.arpa.']
Type , format

 

>>>ip.iptype( )
>>> IP('8.8.8.8').iptype( )
'PUBLIC'
>>> IP( "8.8.8.8") .int( ) 
134744072
>>> IP( '8.8.8.8') .strHex( ) 
'0x8080808'
>>> IP( '8.8.8.8') .strBin( ) 
'00001000000010000000100000001000'

Net-mask length

you can use format IP(‘Network_address/net_mask’, make_net=True) or IP(‘Network_address’).make_net(‘net_mask’) or IP(‘start_IP-end_ip’, make_et=True):

print( IP('192.168.1.0').make_net('255.255.255.0'))

192.168.1.0/24

print(IP('192.168.1.0/255.255.224.0',make_net=True))

192.168.0.0/19

print(IP('192.168.1.0-192.168.1.255',make_net=True))

192.168.1.0/24

You can also use strNormal method with parameter wantprefixlen to show in the format you want:

IP(‘Network_address_in_either_format’).strNormal(wantprefixlen)

wantprefixlen:

·wantprefixlen=0, no mask or prefix, 如192.168.1.0;
·wantprefixlen=1, prefix, e.g 192.168.1.0/24;
·wantprefixlen=2, in decimalnetmask format, e.g 192.168.1.0/255.255.255.0;
·wantprefixlen=3, lastIP format, e. g 192.168.1.0-192.168.1.255

>>>IP( '192.168.1.0/24') .strNormal( 0)
'192.168.1.0'
>>>IP( '192.168.1.0/24') .strNormal( 1)
'192.168.1.0/24'
>>>IP( '192.168.1.0/24') .strNormal( 2)
'192.168.1.0/255.255.255.0'
>>>IP( '192.168.1.0/24') .strNormal( 3)
'192.168.1.0-192.168.1.255'

Relation
  • Contain:
    IP(‘192.168.1.10’) in IP(‘192.168.1.0/24’), it will return True.
    OrIP(‘12.0.0.8/30’) in IP(‘12.0.0.0/24’)
  • overlaps:
    over_laps=IP(‘192.168.0.0/23’).overlaps(‘192.168.1.0/24’) If the return value is 1 means overlap, 0 means not overlap.

 

DNS module DNSpython

dnspython provides a DNS resolver to do the domain name lookup by query action:

Syntax: query( self, qname, rdtype=1, rdclass=1, tcp=False, source=None,raise_on_no_answer=True, source_port=0)

  •  qname is the domain name。
  • rdtype means the type of record you are looking for:

·A record;
·MX record: there are some special properties: preference, exchange
·CNAME record;
·NS record;
·PTR record;
·SOA record。

  • rdclass means the network type, IN、 CH or HS , the default type is IN.
  • Tcp: means if use TCP protocol do the query, default is false.
  • Source and source_port: the source IP address and port number, default is local machine IP, and port 0
  • Raise_on_no_answer: means if trigger event if now reply from the query.
Example

A record:

#! /usr/bin/env python

import dns.resolver

domain = input('Please input an domain: ') 

A = dns.resolver.query( domain,'A') 

for i in A.response.answer: 

    for j in i.items: 

        print(j.address)

MX record:

#! /usr/bin/env python

import dns.resolver

domain = input('Please input an domain: ')

MX = dns.resolver.query(domain,'MX') 

for i in MX: 

    print ('MX preference =', i.preference,'mail exchanger =',i.exchange)

 

Output

Please input an domain: gmail.com

MX preference = 20 mail exchanger = alt2.gmail-smtp-in.l.google.com.

MX preference = 5 mail exchanger = gmail-smtp-in.l.google.com.

MX preference = 40 mail exchanger = alt4.gmail-smtp-in.l.google.com.

MX preference = 30 mail exchanger = alt3.gmail-smtp-in.l.google.com.

MX preference = 10 mail exchanger = alt1.gmail-smtp-in.l.google.com.

NS record:

note that you must input a domain name , not a subdomain name. Eg. you should use google.com , not www.google.com.

import dns.resolver

domain=input("please type a domain name: ")

ns=dns.resolver.query(domain,'NS')

for i in ns.response.answer:

    for j in i.items:

        print (j.to_text())

Output:

please type a domain name: google.com

ns3.google.com.

ns4.google.com.

ns2.google.com.

ns1.google.com.

CNAME

change the two ns into cname.

Example:

In this example we will check the availability of the web servers in the round robin load balancer. The idea is first do a dns lookup and list out all the ip addresses in this cluster, then we will use http.client module to read the first first 6 characters (<html> for html5) or 14 characters ( <!DOCTYPE html)

#! /usr/bin/python
import dns.resolver as dr
import os
import http.client
import binascii

iplist=[]
appdomain="163.com"
#Following function resolve the domain name to IP address
def get_iplist (domain=""):
 try:
     A = dr.query(domain, 'A')
 except Exception as e:
     print("dns resolver error:" + str(e))
 return
 for i in A.response.answer:
     for j in i.items:
         iplist.append(j.address)
# print(j.address)
 return True

def checkip(ip):
    checkurl=ip+":80"
    getcontent=""
    conn=http.client.HTTPConnection(checkurl, timeout=5)
#the data type is byte, needs converting to string
 try:
     conn.request ("GET", "/", headers = {"Host": appdomain})
     r=conn.getresponse()

#Then we will judge if we get a webpage. In the header, for pre-h5 first 14 characters are "<!DOCTYPE html" , for h5 first 6 characters are "<html>", we will read once, then test twice.
#if we get either one, means the webserver is alive
 getcontent_preh5=r.read(14)
#The web page may be encoded into different types, so we need to decode it.
 getcontent_preh5txt=getcontent_preh5.decode("utf-8")
# print(getcontent_preh5txt)
#get the first 6 characters for h5 testing
 getcontent_h5_txt=getcontent_preh5txt[:6]
# print(getcontent_h5_txt)
 finally:
 if ((getcontent_h5_txt=="<html>")or(getcontent_preh5txt=="<!DOCTYPE html")):
     print(ip + "[OK!]")
 else:
     print(ip + "[Error!]")
# if __name__=="__main__":
#    if get_iplist(appdomain) and len (iplist) > 0:
#        for ip in iplist:
#            checkip(ip)
#    else:
#        print("DNS resolver error!")
get_iplist(appdomain) 
for ip in iplist:
    checkip(ip)
Reference

https://github.com/giampaolo/psutil

http://www.dnspython.org/examples.html