summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extras/gnfs-loganalyse.py143
1 files changed, 143 insertions, 0 deletions
diff --git a/extras/gnfs-loganalyse.py b/extras/gnfs-loganalyse.py
new file mode 100644
index 000000000..16e356247
--- /dev/null
+++ b/extras/gnfs-loganalyse.py
@@ -0,0 +1,143 @@
+#!/bin/python
+"""
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+"""
+
+import os
+import string
+import sys
+
+
+class NFSRequest:
+ def __init__ (self, logline, linecount):
+ self.calllinecount = 0
+ self.xid = ""
+ self.op = ""
+ self.opdata = ""
+ self.replydata = ""
+ self.replylinecount = 0
+
+ tokens = logline.strip ().split (" ")
+ if "XID:" not in tokens:
+ return None
+
+ if "args:" not in tokens:
+ return None
+
+ self.calllinecount = linecount
+
+ xididx = tokens.index ("XID:")
+ self.xid = tokens [xididx+1].strip(",")
+
+ opidx = tokens.index ("args:")
+ self.op = tokens [opidx-1].strip (":")
+ self.opdata = " ".join(tokens [opidx+1:])
+
+
+ def getXID (self):
+ return self.xid
+
+ def setReply (self, logline, linecount):
+ tokens = logline.strip ().split (" ")
+ statidx = tokens.index ("NFS:")
+ self.replydata = " ".join (tokens [statidx+1:])
+ self.replylinecount = linecount
+
+ def dump (self):
+ print "ReqLine: " + str(self.calllinecount) + " XID: " + self.xid + " " + self.op + " ARGS: " + self.opdata + " RepLine: " + str(self.replylinecount) + " " + self.replydata
+
+class NFSLogAnalyzer:
+
+ def __init__ (self):
+ self.xid_request_map = {}
+ self.orphan_replies = {}
+ self.CALL = 1
+ self.REPLY = 2
+
+ def handle_call_line (self, logline, linecount):
+ newreq = NFSRequest (logline, linecount)
+ xid = newreq.getXID ()
+ self.xid_request_map [xid] = newreq
+
+ def handle_reply_line (self, logline, linecount):
+ tokens = logline.strip ().split (" ")
+
+ xididx = tokens.index ("XID:")
+ xid = tokens [xididx + 1].strip(",")
+ if xid not in self.xid_request_map.keys ():
+ self.orphan_replies [xid] = logline
+ else:
+ self.xid_request_map [xid].setReply (logline, linecount)
+
+ def analyzeLine (self, logline, linecount):
+ tokens = logline.strip ().split (" ")
+ msgtype = 0
+
+ if "XID:" not in tokens:
+ return
+
+ if "args:" in tokens:
+ msgtype = self.CALL
+ elif "NFS:" in tokens:
+ msgtype = self.REPLY
+
+ if msgtype == self.CALL:
+ self.handle_call_line (logline, linecount)
+ elif msgtype == self.REPLY:
+ self.handle_reply_line (logline, linecount)
+
+ def getStats (self):
+ rcount = len (self.xid_request_map.keys ())
+ orphancount = len (self.orphan_replies.keys ())
+ print "Requests: " + str(rcount) + ", Orphans: " + str(orphancount)
+
+ def dump (self):
+ self.getStats ()
+ for rq in self.xid_request_map.values ():
+ rq.dump ()
+
+
+
+
+linecount = 0
+la = NFSLogAnalyzer ()
+
+progmsgcount = 1000
+dumpinterval = 2000000
+
+if "--progress" in sys.argv:
+ idx = sys.argv.index ("--progress")
+ progmsgcount = int(sys.argv[idx+1])
+
+
+if "--dump" in sys.argv:
+ idx = sys.argv.index ("--dump")
+ dumpinterval = int(sys.argv[idx+1])
+
+for line in sys.stdin:
+ linecount = linecount + 1
+ if linecount % dumpinterval == 0:
+ sys.stderr.write ("Dumping data..\n")
+ la.dump ()
+ la = NFSLogAnalyzer ()
+
+ if linecount % progmsgcount == 0:
+ sys.stderr.write ("Integrating line: "+ str(linecount) + "\n")
+ la.analyzeLine (line, linecount)
+
+la.dump ()