data.py 10.3 KB
#!/usr/bin/env python

import settings
import psutil
import os
import socket
import urllib

class data():

	cpu_mhz = 0
	cpu_percent = []
	cpu_percent_avg = 0
	network_media = False
	network_status = False
	network_address = "0.0.0.0"
	disk_space = 0
	disk_size = 0
	nfs_space = 0
	nfs_size = 0
	nfs_mounted = False
	load_average = (0.0, 0.0, 0.0)
	ram_total = 0
	ram_avail = 0
	ram_buffer = 0
	errors = []
	
	stats_before = {
		'net_bytes_read' : 0,
		'net_bytes_write' : 0,
		'disk_bytes_read' : 0,
		'disk_bytes_write' : 0,
	}
	
	stats_now = {
		'net_bytes_read' : 0,
		'net_bytes_write' : 0,
		'disk_bytes_read' : 0,
		'disk_bytes_write' : 0,
	}
	stats_bandwidth = {
		'net_bytes_read_bw' : 0,
		'net_bytes_write_bw' : 0,
		'disk_bytes_read_bw' : 0,
		'disk_bytes_write_bw' : 0,	
	}

	def __init__(self):
		""" Init """

	def zap(self):
		""" Reset counters """
		self.stats_before['net_bytes_read'] = 0
		self.stats_before['net_bytes_write'] = 0
		self.stats_before['disk_bytes_read'] = 0
		self.stats_before['disk_bytes_write'] = 0
		
		self.stats_now['net_bytes_read'] = 0
		self.stats_now['net_bytes_write'] = 0
		self.stats_now['disk_bytes_read'] = 0
		self.stats_now['disk_bytes_write'] = 0
	
		self.stats_bandwidth['net_bytes_read_bw'] = 0
		self.stats_bandwidth['net_bytes_write_bw'] = 0
		self.stats_bandwidth['disk_bytes_read_bw'] = 0
		self.stats_bandwidth['disk_bytes_write_bw'] = 0	
		
		self.nfs_size = 0
		self.nfs_space = 0
		self.errors = []

	def update(self, services = False):
		""" Update values """
		
		self.network()
		self.cpu()
		self.disk()
		self.memory()
		self.bandwidth()
		
		if services:
			self.services()
					
	def bandwidth(self):
		""" Calculate bandwidth use """
		
		# Calculate used network bandwidth
		self.stats_bandwidth["net_bytes_read_bw"] = (self.stats_now["net_bytes_read"] - self.stats_before["net_bytes_read"]) / settings.INTERVAL
		self.stats_bandwidth["net_bytes_write_bw"] = (self.stats_now["net_bytes_write"] - self.stats_before["net_bytes_write"]) / settings.INTERVAL
		# Get a total of read+write
		self.stats_bandwidth["net_bytes_rw_bw"] = self.stats_bandwidth["net_bytes_read_bw"] + self.stats_bandwidth["net_bytes_write_bw"]

		# Calculate used disk bandwidth
		self.stats_bandwidth["disk_bytes_read_bw"] = (self.stats_now["disk_bytes_read"] - self.stats_before["disk_bytes_read"]) / settings.INTERVAL
		self.stats_bandwidth["disk_bytes_write_bw"] = (self.stats_now["disk_bytes_write"] - self.stats_before["disk_bytes_write"]) / settings.INTERVAL
		# Get a total of read+write
		self.stats_bandwidth["disk_bytes_rw_bw"] = self.stats_bandwidth["disk_bytes_read_bw"] + self.stats_bandwidth["disk_bytes_write_bw"]

		# Update counters for next loop
		self.stats_before["net_bytes_read"] = self.stats_now["net_bytes_read"]
		self.stats_before["net_bytes_write"] = self.stats_now["net_bytes_write"]
		self.stats_before["disk_bytes_read"] = self.stats_now["disk_bytes_read"]
		self.stats_before["disk_bytes_write"] = self.stats_now["disk_bytes_write"]		

	def memory(self):
		""" RAM information """
		
		# Get ram info
		m = psutil.virtual_memory()
		
		self.ram_total = m.total
		self.ram_avail = m.available
		self.ram_buffer = m.buffers

	def network(self):
		""" Network information """
		
		# Get network read/write byte count
		n = psutil.net_io_counters()
		
		# Update counters
		self.stats_now["net_bytes_write"] = n.bytes_sent
		self.stats_now["net_bytes_read"] = n.bytes_recv
		
		# Get address currently in use by primary interface
		e = psutil.net_if_addrs()
		try:
			for v in e[settings.ETH_DEVICE]:
				# Family=2 is the IPV4 details
				if v.family == 2:
					self.network_address = v.address
		except Exception as e:
			self.network_address = "0.0.0.0"
			
		# Check connections of all devices
		for dev in settings.ETH_DEVICES:
			# Get interface up/down status
			try:
				e = psutil.net_if_stats()
				if e[dev].isup == True:
					self.network_status = "Up"
				else:
					self.network_status = False
					err = settings.ERR_NETWORK_STATUS.replace('ETH', dev)
					if err not in self.errors:
						self.errors.append(err)
			except Exception as e:
				self.network_status = False
				err = settings.ERR_NETWORK_STATUS.replace('ETH', dev)
				if err not in self.errors:
					self.errors.append(err)
			
			# Get media connection status
			try:
				f = open("/sys/class/net/" + dev + "/carrier", "ro")
				fdata = f.read().strip('\n')
				f.close()
				if fdata == '1':
					self.network_media = "Ok"
				else:
					self.network_media = False
					err = settings.ERR_NETWORK_MEDIA.replace('ETH', dev)
					if err not in self.errors:
						self.errors.append(err)
			except Exception as e:
				self.network_media = False
				err = settings.ERR_NETWORK_MEDIA.replace('ETH', dev)
				if err not in self.errors:
					self.errors.append(err)
		
	def disk(self):
		""" Disk information """

		# Get network read/write byte count
		d = psutil.disk_io_counters()
		
		# Update counters
		self.stats_now["disk_bytes_write"] = d.write_bytes
		self.stats_now["disk_bytes_read"] = d.read_bytes

		# Get available disk space
		try:
			d = psutil.disk_usage(settings.DISK_PATH)
			self.disk_space = d.free
			self.disk_size = d.total
		except Exception as e:
			if settings.ERR_DISK_STATUS not in self.errors:
				self.errors.append(settings.ERR_DISK_STATUS)
			self.disk_space = 0
			self.disk_size = 0
			
		# Get available nfs space and check it is mounted.
		try:
			d = psutil.disk_usage(settings.NFS_PATH)
			if os.path.ismount(settings.NFS_PATH):
				pass
			else:
				if settings.ERR_NFS_STATUS not in self.errors:
					self.errors.append(settings.ERR_NFS_STATUS)
			self.nfs_space = d.free
			self.nfs_size = d.total	
		except Exception as e:
			if settings.ERR_NFS_STATUS not in self.errors:
				self.errors.append(settings.ERR_NFS_STATUS)
			self.nfs_space = 0
			self.nfs_size = 0
		
	def cpu(self):
		""" Processor utilisation """
		self.cpu_percent = psutil.cpu_percent(interval=None, percpu=True)
		self.cpu_percent_avg = psutil.cpu_percent(interval=None, percpu=False)
		self.load_average = os.getloadavg()
		
		f = open('/proc/cpuinfo', 'r')
		cpuinfo = f.readlines()
		f.close()
		for l in cpuinfo:
			if 'MHz' in l:
				self.cpu_mhz = l.split(':')[1].split('.')[0].strip() 
				return
		
	def services(self):
		""" Check status of services """
				
		# Check SSH
		if "ssh" in settings.SERVICE_CHECKS:
			try:
				s = socket.create_connection((self.network_address, "22"))
				s.close()
			except Exception as e:
				if settings.ERR_SERVICE_SSH in self.errors:
					pass
				else:
					self.errors.append(settings.ERR_SERVICE_SSH)
						
		# Check mysql
		if "mysql" in settings.SERVICE_CHECKS:
			port_open = False
			i = psutil.net_if_addrs()
			# Check that MySQL is listening on at least one of the defined
			# interfaces in our list
			for dev in settings.ETH_DEVICES:
				print(dev)
				for iface in i[dev]:
					if iface.family == 2:
						#print("Checking MySQL on %s:3306" % iface.address)
						try:
							s = socket.create_connection((iface.address, "3306"))
							s.close()
							port_open = True
							#print("Connected OK")
						except Exception as e:
							pass
			if port_open:
				pass
			else:
				if settings.ERR_SERVICE_MYSQL in self.errors:
					pass
				else:
					self.errors.append(settings.ERR_SERVICE_MYSQL)
		
		# check apache
		if "httpd" in settings.SERVICE_CHECKS:
			try:
				u = urllib.urlopen("http://" + self.network_address)
				if u.getcode() != 200:
					if settings.ERR_SERVICE_HTTPDa in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_HTTPDa)
			except Exception as e:
				print("Exception while connecting to httpd service: %s" % e)
				if settings.ERR_SERVICE_HTTPDb in self.errors:
					pass
				else:
					self.errors.append(settings.ERR_SERVICE_HTTPDb)	
			
		# check openstack keystone - identity
		if "keystone" in settings.SERVICE_CHECKS:
			if settings.SERVICE_CHECK_TYPE == "server":
				# Check keystone server
				t = os.system("keystone discover 2>/dev/null | grep 'Keystone found at'")
				if t != 0:
					if settings.ERR_SERVICE_KEYSTONEa in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_KEYSTONEa)
			
		# check openstack nova - compute
		if "nova" in settings.SERVICE_CHECKS:
			if settings.SERVICE_CHECK_TYPE == "server":
				# Check nova server daemons
				t = os.system("systemctl status openstack-nova-api")
				if t != 0:
					if settings.ERR_SERVICE_NOVAa in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_NOVAa)
			else:
				# Check nova client daemons
				t = os.system("systemctl status openstack-nova-compute")
				if t != 0:
					if settings.ERR_SERVICE_NOVAb in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_NOVAb)
			
		# check openstack cinder - block
		if "cinder" in settings.SERVICE_CHECKS:
			if settings.SERVICE_CHECK_TYPE == "server":
				# Check cinder 
				t = os.system("systemctl status openstack-cinder-api")
				if t != 0:
					if settings.ERR_SERVICE_CINDERa in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_CINDERa)

		# Check cinder volume
		if "cinder-volume" in settings.SERVICE_CHECKS:
			if settings.SERVICE_CHECK_TYPE == "server":
				# Check cinder volume
				t = os.system("systemctl status openstack-cinder-volume")
				if t != 0:
					if settings.ERR_SERVICE_CINDERb in self.errors:		
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_CINDERb)
					
	
		# check openstack glance - image/iso
		if "glance" in settings.SERVICE_CHECKS:
			if settings.SERVICE_CHECK_TYPE == "server":
				# Check glance server
				t = os.system("systemctl status openstack-glance-api")
				if t != 0:
					if settings.ERR_SERVICE_GLANCE in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_GLANCE)
			
		# check openstack neutron - networking
		if "neutron" in settings.SERVICE_CHECKS:
			if settings.SERVICE_CHECK_TYPE == "server":
				# Check neutron server related daemons
				t = os.system("systemctl status neutron-server")
				if t != 0:
					if settings.ERR_SERVICE_NEUTRONa in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_NEUTRONa)
			else:
				# Check neutron client related daemons
				t = os.system("systemctl status neutron-linuxbridge-agent")
				if t != 0:
					if settings.ERR_SERVICE_NEUTRONb in self.errors:
						pass
					else:
						self.errors.append(settings.ERR_SERVICE_NEUTRONb)