Require feedback for glusterfsiostat

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,



Basing my first patch to Gluster as a stepping stone, I've written a small utility glusterfsiostat, in python which you can find attached with this email. Currently, the modifications done by my patch to io-stats which is under review as of now, dumps private information from the xlator object to the proper file for private info in the meta directory. This includes total bytes read/written along with read/write speed in the previous 10 seconds. The speed at every 1 second is identified by it's respective unix timestamp and hence given out in bytes/second. These values at discrete points of time can be used to generate a graph. 

The python tool first identifies all gluster mounts in the system, identifies the mount path and parses the meta xlator output in order to generate output similar to the iostat tool. Passing '-j' option gives you extra information in a consumable json format. By default, the tool pretty prints the basic stats which are human readable. This tool is supposed to be a framework on which other applications can be built upon. I'm putting this out for community feedback so as to improve it further.

Do you think the stats and the way they're generated as of now is something that might be usable by someone? Any other implementation suggestions or addition of some more stats that I can/should possibly provide with the utility?

Note: In order to test this, you need to apply my patch(http://review.gluster.org/#/c/8030/) in your repo first, build and then mount a volume. Preferably perform a big read/write operation with a file on your Gluster mount before executing the python script. Then run it as 'python stat.py' or 'python stat.py -j'
 

Regards
Vipul Nayyar 
# glusterfsiostat - A client side tool to gather I/O stats from every Gluster mount.
# Author : Vipul Nayyar <nayyar_vipul@xxxxxxxxx>

import commands
import re
import os
import json
import sys
from optparse import OptionParser

status, output=commands.getstatusoutput('mount')
mountlines = output.split("\n")

if status != 0:
	print "Unable to gather mount statistics"
	exit(1)

mntarr = []

for i in mountlines:
	matchobj = re.search(r" type fuse.glusterfs \(.*\)$",i)
	if matchobj:
		i = i.replace(matchobj.group(),"")
		i = i.split(" on ")
		mntname = i[0]
		mntpath = i[1]
		temp = {}
		temp["mount_path"] = mntpath
		temp["name"] = mntname
		mntarr.append(temp)

for i in xrange(0,len(mntarr)):
	os.chdir(mntarr[i]["mount_path"])
	os.chdir(".meta")
	os.chdir("graphs/active")

	status, output=commands.getstatusoutput("ls")
	if status != 0:
		print mntpath + ": components not accessible"
		continue
	
	lsarr = output.split('\n')

	for j in lsarr:
		io_stats_path = ""
		status, output=commands.getstatusoutput("cat "+ j + "/type")
		if output == "debug/io-stats":
			os.chdir(j)
			io_stats_path = os.getcwd()
			break
	if io_stats_path == "": continue

	priv_content = commands.getstatusoutput("cat private")

	priv_content = priv_content[1].split('\n')

	mntarr[i]["read_speed"] = {}
	mntarr[i]["write_speed"] = {}

	for j in priv_content:

		match = re.search(r"write_speed\((.*)\) = (.*)$",j)
		if(match):
			mntarr[i]["read_speed"][match.group(1)] = match.group(2)
		
		match = re.search(r"read_speed\((.*)\) = (.*)$",j)
		if(match):
			mntarr[i]["write_speed"][match.group(1)] = match.group(2)
		
		match = re.search(r"data_read_cumulative = (.*)$",j)
		if(match):
			mntarr[i]["read_cumulative"] = match.group(1)
		
		match = re.search(r"data_read_incremental = (.*)$",j)
		if(match):
			mntarr[i]["read_incremental"] = match.group(1)

		match = re.search(r"data_written_cumulative = (.*)$",j)
		if(match):
			mntarr[i]["write_cumulative"] = match.group(1)

		match = re.search(r"data_written_incremental = (.*)$",j)
		if(match):
			mntarr[i]["write_incremental"] = match.group(1)

parser = OptionParser()

parser.add_option("-j", "--json", action = "store_true", dest = "json", help = "Get extra output in json format", default = False)

(options, args) = parser.parse_args()

if(len(mntarr) == 0):
	print "No gluster mounts found."
	exit(1)

if(options.json == True):
	print json.dumps(mntarr)
else:
	sys.stdout.write("Device:")
	length = len(mntarr[i]["name"]) - 7
	if(length > 0):
		for x in xrange(0,length):
			sys.stdout.write(" ")

	sys.stdout.write("    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn\n")
	for i in xrange(0,len(mntarr)):
		if(len(mntarr[i]["read_speed"]) > 0):
			r_speed = int(mntarr[i]["read_speed"][max(mntarr[i]["read_speed"].iterkeys())])/1024
		else:
			r_speed = 0

		if(len(mntarr[i]["write_speed"]) > 0):
			w_speed = int(mntarr[i]["write_speed"][max(mntarr[i]["write_speed"].iterkeys())])/1024
		else:
			w_speed = 0

		sys.stdout.write(str(mntarr[i]["name"])+"    " + str(r_speed) + "    " + str(w_speed) + "    ")
		sys.stdout.write(str(int(mntarr[i]["read_cumulative"])/1024) + "    ")
		sys.stdout.write(str(int(mntarr[i]["write_cumulative"])/1024))
		sys.stdout.write("\n")
_______________________________________________
Gluster-users mailing list
Gluster-users@xxxxxxxxxxx
http://supercolony.gluster.org/mailman/listinfo/gluster-users

[Index of Archives]     [Gluster Development]     [Linux Filesytems Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux