#!/usr/bin/python # written by philo vivero - 2007 # released under the terms of the GNU GPL import sys import commands import logging logFile = "/var/log/dbmon/dbmon.log" sqlFile = "/var/log/dbmon/dbmon.sql" logLvl=logging.INFO # process input arguments from optparse import OptionParser parser = OptionParser() parser.add_option("-k", "--killed", dest="queriesKilled", action="store_true", default=False, help="List queries that were killed") parser.add_option("-m", "--min", dest="minQueries", default="", help="Minimum number of queries to worry about") parser.add_option("-s", "--sec", dest="querySeconds", default="", help="Number of seconds query must run to be worried about") parser.add_option("-a", "--allloglines", dest="allLogLines", action="store_true", default=False, help="Process the entire log, not just the first 500,000 lines") (options, args) = parser.parse_args() logging.basicConfig( datefmt="%Y-%m-%d %H:%M:%S", level=logLvl, format="%(levelname)s %(asctime)s %(message)s") filePtr = file(logFile, 'r') # read off the initial "" queryLine = filePtr.readline().rstrip() linesProcessed = 0 eofReached = 0 queryCounts = {} queryTimings = {} while (eofReached == 0): queryLine = filePtr.readline().rstrip() # if line starts with " - " it's just info if (len(queryLine) > 4 and queryLine[0:3] == " - "): logging.debug(queryLine) # this is (probably) a query, deal with it elif (len(queryLine) > 34): # first 32 chars only letters/numbers, likely an MD5 hash queryHash = queryLine[0:32] if (queryHash.isalnum()): # if it's a Finish line, it'll have a timing on the query splitLine = queryLine.split('\t') if (splitLine[1] == "Finish"): # the timing looks like "0.987 sec" so break out the "sec" part timingSplit = splitLine[6].split(' ') countThisQuery = False # if they passed in "-k" only show queries that were killed if (options.queriesKilled == True): if (splitLine[4] == "Killed"): countThisQuery = True else: countThisQuery = False else: countThisQuery = True # by some code path above, countThisQuery became true, so we # count this query if (countThisQuery == True): # how many times the query was seen if (queryCounts.has_key(queryHash)): queryCounts[queryHash] += 1 else: queryCounts[queryHash] = 1 # also interested in timings for the queries if (queryTimings.has_key(queryHash)): queryTimings[queryHash] += float(timingSplit[0]) else: queryTimings[queryHash] = float(timingSplit[0]) # we don't know what happened here else: logging.debug("Hash %s is not alphanumeric." % (queryHash)) elif (queryLine == ""): logging.debug("Hit end of file. Quitting") eofReached = 1 # give a bit of status linesProcessed += 1 if (linesProcessed % 100000 == 0): logging.info("Processed %d lines..." % (linesProcessed)) if (options.allLogLines == False and linesProcessed >= 500000): logging.info("Quitting at 500000 lines. Pass -a if you want to process the entire log file.") break # output the keys found for testing for key in queryCounts: printThisKey = False if (options.minQueries <> ""): if (queryCounts[key] > float(options.minQueries)): printThisKey = True else: printThisKey = True if (printThisKey): avg = queryTimings[key]/queryCounts[key] print ("%8.1f %s occurrences: %7d totalTime: %8.1f avgTime: %0.5f" % (queryTimings[key], key, queryCounts[key], queryTimings[key], avg))