PageRenderTime 36ms CodeModel.GetById 2ms app.highlight 28ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/lib/python/indra/util/simperf_oprof_interface.py

https://bitbucket.org/lindenlab/viewer-beta/
Python | 167 lines | 157 code | 0 blank | 10 comment | 0 complexity | 437fdedf0a1cc9c9921f35cf0b098892 MD5 | raw file
  1#!/usr/bin/env python
  2"""\
  3@file simperf_oprof_interface.py
  4@brief Manage OProfile data collection on a host
  5
  6$LicenseInfo:firstyear=2008&license=mit$
  7
  8Copyright (c) 2008-2009, Linden Research, Inc.
  9
 10Permission is hereby granted, free of charge, to any person obtaining a copy
 11of this software and associated documentation files (the "Software"), to deal
 12in the Software without restriction, including without limitation the rights
 13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 14copies of the Software, and to permit persons to whom the Software is
 15furnished to do so, subject to the following conditions:
 16
 17The above copyright notice and this permission notice shall be included in
 18all copies or substantial portions of the Software.
 19
 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 26THE SOFTWARE.
 27$/LicenseInfo$
 28"""
 29
 30import sys, os, getopt
 31import simplejson
 32
 33
 34def usage():
 35    print "Usage:"
 36    print sys.argv[0] + " [options]"
 37    print "  Digest the OProfile report forms that come out of the"
 38    print "  simperf_oprof_ctl program's -r/--report command.  The result"
 39    print "  is an array of dictionaires with the following keys:"
 40    print 
 41    print "     symbol        Name of sampled, calling, or called procedure"
 42    print "     file          Executable or library where symbol resides"
 43    print "     percentage    Percentage contribution to profile, calls or called"
 44    print "     samples       Sample count"
 45    print "     calls         Methods called by the method in question (full only)"
 46    print "     called_by     Methods calling the method (full only)"
 47    print 
 48    print "  For 'full' reports the two keys 'calls' and 'called_by' are"
 49    print "  themselves arrays of dictionaries based on the first four keys."
 50    print
 51    print "Return Codes:"
 52    print "  None.  Aggressively digests everything.  Will likely mung results"
 53    print "  if a program or library has whitespace in its name."
 54    print
 55    print "Options:"
 56    print "  -i, --in      Input settings filename.  (Default:  stdin)"
 57    print "  -o, --out     Output settings filename.  (Default:  stdout)"
 58    print "  -h, --help    Print this message and exit."
 59    print
 60    print "Interfaces:"
 61    print "   class SimPerfOProfileInterface()"
 62    
 63class SimPerfOProfileInterface:
 64    def __init__(self):
 65        self.isBrief = True             # public
 66        self.isValid = False            # public
 67        self.result = []                # public
 68
 69    def parse(self, input):
 70        in_samples = False
 71        for line in input:
 72            if in_samples:
 73                if line[0:6] == "------":
 74                    self.isBrief = False
 75                    self._parseFull(input)
 76                else:
 77                    self._parseBrief(input, line)
 78                self.isValid = True
 79                return
 80            try:
 81                hd1, remain = line.split(None, 1)
 82                if hd1 == "samples":
 83                    in_samples = True
 84            except ValueError:
 85                pass
 86
 87    def _parseBrief(self, input, line1):
 88        try:
 89            fld1, fld2, fld3, fld4 = line1.split(None, 3)
 90            self.result.append({"samples" : fld1,
 91                                "percentage" : fld2,
 92                                "file" : fld3,
 93                                "symbol" : fld4.strip("\n")})
 94        except ValueError:
 95            pass
 96        for line in input:
 97            try:
 98                fld1, fld2, fld3, fld4 = line.split(None, 3)
 99                self.result.append({"samples" : fld1,
100                                    "percentage" : fld2,
101                                    "file" : fld3,
102                                    "symbol" : fld4.strip("\n")})
103            except ValueError:
104                pass
105
106    def _parseFull(self, input):
107        state = 0       # In 'called_by' section
108        calls = []
109        called_by = []
110        current = {}
111        for line in input:
112            if line[0:6] == "------":
113                if len(current):
114                    current["calls"] = calls
115                    current["called_by"] = called_by
116                    self.result.append(current)
117                state = 0
118                calls = []
119                called_by = []
120                current = {}
121            else:
122                try:
123                    fld1, fld2, fld3, fld4 = line.split(None, 3)
124                    tmp = {"samples" : fld1,
125                           "percentage" : fld2,
126                           "file" : fld3,
127                           "symbol" : fld4.strip("\n")}
128                except ValueError:
129                    continue
130                if line[0] != " ":
131                    current = tmp
132                    state = 1       # In 'calls' section
133                elif state == 0:
134                    called_by.append(tmp)
135                else:
136                    calls.append(tmp)
137        if len(current):
138            current["calls"] = calls
139            current["called_by"] = called_by
140            self.result.append(current)
141
142
143def main(argv=None):
144    opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"])
145    input_file = sys.stdin
146    output_file = sys.stdout
147    for o, a in opts:
148        if o in ("-i", "--in"):
149            input_file = open(a, 'r')
150        if o in ("-o", "--out"):
151            output_file = open(a, 'w')
152        if o in ("-h", "--help"):
153            usage()
154            sys.exit(0)
155
156    oprof = SimPerfOProfileInterface()
157    oprof.parse(input_file)
158    if input_file != sys.stdin:
159        input_file.close()
160
161    # Create JSONable dict with interesting data and format/print it
162    print >>output_file, simplejson.dumps(oprof.result)
163
164    return 0
165
166if __name__ == "__main__":
167    sys.exit(main())