source: CCCC/trunk/ceda_cc/summary.py @ 347

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CCCC/trunk/ceda_cc/summary.py
Revision 347, 8.7 KB checked in by astephen, 5 years ago (diff)

Updated summary.py as follows:

  • renamed class "main" to "LogSummariser?"
  • changed class interactions so "summarise()" method is used to run it
  • added convenience function to wrap initiate class and call "summarise()" method.
  • added comments to allow all FAILED files to be listed in summary
    • this can be added as a command-line switch later.
Line 
1
2import string, sys, glob, os
3import collections
4
5HERE = os.path.dirname(__file__)
6if HERE == '':
7  HERE = '.'
8print '############################ %s' % HERE
9
10NT_esn = collections.namedtuple( 'errorShortName', ['name', 'long_name', 'description' ] )
11class errorShortNames(object):
12
13  def __init__(self, file='config/testStandardNames.txt'):
14    assert os.path.isfile(file), 'File %s not found' % file
15    ii = map( string.strip, open(file).readlines() )
16    ll = [[ii[0],]]
17    for l in ii[1:]:
18      if len(l) > 0 and l[0] == '=':
19        ll.append( [l,] )
20      else:
21        ll[-1].append( l )
22    self.ll = []
23    for l in ll:
24      if len(l) < 2:
25        print l
26      else:
27        self.ll.append( NT_esn( string.strip(l[0],'='), l[1][1:], string.join(l[2:]) ) )
28
29def cmin(x,y):
30  if x < 0:
31        return y
32  else:
33    return min(x,y)
34
35class LogSummariser(object):
36
37  def __init__(self):
38    pass
39
40  def summarise(self):
41    args = sys.argv[1:-1]
42    idir = sys.argv[-1]
43    ndisp = 2
44    dohtml = False
45    while len(args) > 0:
46      x = args.pop(0)
47      if x == '-n':
48        ndisp = int( args.pop(0) )
49      elif x == '-html':
50        dohtml = True
51    assert os.path.isdir( idir ), 'Directory %s not found' % idir
52
53    fb = glob.glob( '%s/qcBatchLog*' % idir )
54    fb.sort()
55    fb = fb[-1]
56    ii = open( fb )
57    jj = []
58
59    for k in range(10):
60      jj.append( string.strip(ii.readline()) )
61    ii.close()
62    i0 = jj[0].index( ' INFO ' )
63    tstart = jj[0][:i0]
64    m1 = jj[0][i0+6:]
65    m2 = jj[1][i0+6:]
66    self.info = (tstart, m1, m2)
67##2014-09-06 18:42:24,109 INFO Starting batch -- number of file: 338
68##2014-09-06 18:42:24,109 INFO Source: /data/work/cordex/early/AFR-44i/SMHI/ECMWF-ERAINT/evaluation//.....
69
70    ee = {}
71
72    fl = glob.glob( '%s/*__qclog_*.txt' % idir )
73    self.write( 'Summarising error reports from %s log file' % len(fl) )
74    nne = 0
75    nerr = 0
76    ff = {}
77
78    for f in fl:
79      nef = 0
80      elist = []
81      for l in open(f).readlines():
82        fn = string.split(f,'/')[-1]
83        if (l[:3] in ('C4.', 'C5.') and l.find('FAILED') > -1) or l.find('CDMSError:') > -1:
84          nef += 1
85          nerr += 1
86          bits = map( string.strip, string.split(l, ':' ) )
87          if 'FAILED' in bits:
88             kb1 = bits.index('FAILED') + 1
89          else:
90             kb1 = 1
91          if len(bits) > kb1:
92            code = bits[0]
93            if kb1 == 3:
94              msg0 = string.join(bits[kb1:], ':' )
95              msg = string.strip( bits[1] + ' ' + msg0 )
96              se = bits[1][1:-1]
97            else:
98              msg = string.strip( string.join(bits[kb1:], ':' ) )
99              msg0 = msg
100              se = None
101            if code not in ee.keys():
102              ee[code] = [0,{msg:[0,[]]},se]
103            elif msg not in ee[code][1].keys():
104              ee[code][1][msg] = [0,[]]
105            ee[code][0] += 1
106            ee[code][1][msg][0] += 1
107            if ee[code][1][msg][0]:
108              ee[code][1][msg][1].append(fn)
109            elist.append( (code,msg,se) )
110          else:
111            self.write( str(bits) )
112      if nef == 0:
113        nne += 1
114      else:
115        ff[fn] = elist
116
117    keys = ee.keys()
118    keys.sort()
119
120    for k in keys:
121      ks = ee[k][1].keys()
122      if len(ks) == 1:
123        self.write( '%s%s  %s' % (k,ee[k][0],ks[0]) )
124
125        # Show first set of files that failed [To show them all change to: range(len(ee[k][1][ks[0]][1])) ]
126        for i in range(cmin(ndisp,ee[k][0])):
127          self.write( '               %s' % ee[k][1][ks[0]][1][i] )
128      else:
129        self.write( '%s: %s' % (k,ee[k][0])  )
130        ks.sort()
131        for k2 in ks:
132          self.write( '  --- %s: %s' % (k2,ee[k][1][k2][0]) )
133
134          # Show first set of files that failed [To show them all change to: range(len(ee[k][1][k2][1]))
135          for i in range(cmin(ndisp,ee[k][1][k2][0])):
136            self.write( '               %s' % ee[k][1][k2][1][i] )
137
138    self.write( 'Number of files with no errors: %s' % nne )
139    esum = (len(fl), nerr, nne )
140    self.testnames()
141    if dohtml:
142      self.htmlout( ee, ff, esum )
143      self.htmlEsn( )
144
145  def testnames(self):
146    tnfile = '%s/config/testStandardNames.txt' % HERE
147    ii = open( tnfile ).readlines()
148    self.tests = []
149    thistest = None
150    for l in ii:
151      if l[0] == '=':
152        name = string.strip(l)[1:-1]
153        if thistest != None:
154          thistest.append(defn)
155          self.tests.append( thistest )
156        thistest = [name,]
157        defn = ''
158      elif l[0] == '*':
159        thistest.append( string.strip(l)[1:] )
160      elif string.strip(l) != '':
161        defn += l
162    thistest.append(defn)
163    self.tests.append( thistest )
164    self.testdict = {}
165    for t in self.tests:
166      self.testdict[t[0]] = (t[1],t[2])
167
168  def write( self, s ):
169    print s
170
171  def htmlEsn( self ):
172    esn = errorShortNames()
173    cnt = '<h1>Error Short Names</h1>\n'
174    for l in esn.ll:
175      cnt += '''<a name="%s"><h2>%s</h2></a>
176            <p><i>%s</i><br/>
177             %s
178             </p>
179             ''' % (l.name,l.name, l.long_name, l.description )
180
181    self.__htmlPageWrite( 'html/ref/errorShortNames.html', cnt )
182
183  def htmlout( self, ee, ff, esum ):
184    if not os.path.isdir( 'html' ):
185      os.mkdir( 'html' )
186      os.mkdir( 'html/ref' )
187      os.mkdir( 'html/files' )
188      os.mkdir( 'html/errors' )
189    about = """<p>Output from CEDA CC</p>
190<p>This report contains a list of errors for each file, and a list of files associated with each error.</p>
191"""
192    data = """<p>%s<br/>
193     %s<br/>
194     Start of checks: %s</p>
195""" % (self.info[1], self.info[2], self.info[0] )
196    results = """<ul><li>Number of files tested: %s: <a href="files/findex.html">index by file</a></li>
197                     <li>Number of errors: %s: <a href="errors/eindex.html">index by error</a></li>
198                     <li>Number of error free files: %s</li></ul>
199""" % esum
200
201    keys = ee.keys()
202    keys.sort()
203    list = []
204    for k in keys:
205      if ee[k][2] == None:
206        list.append( '<li>%s: %s</li>' % (k,ee[k][0]) )
207      else:
208        assert ee[k][2] in self.testdict.keys(), 'unrecognised test name: %s' % ee[k][2]
209        list.append( '<li>%s [%s:%s]: %s</li>' % (self.testdict[ee[k][2]][0],k,ee[k][2],ee[k][0]) )
210    res2 = '<ul>%s</ul>' % string.join(list, '\n' )
211    results += res2
212
213    maincontent = """<h1>The test</h1>
214                         %s
215                     <h1>The data</h1>
216                         %s
217                     <h1>Results</h1>
218                         %s
219""" % (about,data,results)
220    self.__htmlPageWrite( 'html/index.html', maincontent )
221
222    keys = ee.keys()
223    keys.sort()
224
225    eItemTmpl = '<li><a href="rep.%3.3i.html">%s [%s]</a>: %s</li>'
226    list = []
227    nn = 0
228    for k in keys:
229      ks = ee[k][1].keys()
230      ks.sort()
231      sect_esn = None
232      for k2 in ks:
233        nn += 1
234        this_esn = string.split(k2,']')[0][1:]
235        if this_esn != sect_esn:
236          sect_esn = this_esn
237          list.append( '<h2>%s: %s<a href="../ref/errorShortNames.html#%s">(definition)</a></h2>' % (k,this_esn, this_esn) )
238        list.append( eItemTmpl % (nn,k, ee[k][1][k2][0], k2  ) )
239        l2 = []
240        for ss in ee[k][1][k2][1]:
241            i0 = string.index( ss, '__qclog' )
242            fs = ss[:i0]
243            l2.append( '<li><a href="../files/rep.%s.html">%s</a></li>' % (fs,fs) )
244        ePage = """<h1>Error %s </h1> %s <ul>%s</ul> """ % (nn,k2,string.join( l2, '\n' ) )
245        efp = 'html/errors/rep.%3.3i.html' % nn
246        self.__htmlPageWrite( efp, ePage )
247    eIndexContent = """<h1>List of detected errors</h1>
248<p>Code[number of files with error]: result <br/>
249Click on the code to see a list of the files in which each error is detected.
250</p>
251<ul>%s</ul>
252"""  % (string.join(list, '\n' ) )
253    self.__htmlPageWrite( 'html/errors/eindex.html', eIndexContent )
254
255    keys = ff.keys()
256    keys.sort()
257    fItemTmpl = '<li><a href="%s">%s [%s]</a></li>'
258    list = []
259    for k in ff:
260      i0 = string.index( k, '__qclog' )
261      fs = k[:i0]
262      knc = fs + '.nc'
263      hfn = 'rep.%s.html' % fs
264      hfp = 'html/files/%s' % hfn
265      list.append( fItemTmpl % (hfn, knc, len(ff[k]) ) )
266      l2 = []
267      for f in ff[k]:
268        l2.append( '<li>%s: %s</li>' % f[:2] )
269      fPage = """<h1>Errors in %s.nc</h1>
270<ul>%s</ul>
271""" % (fs,string.join( l2, '\n' ) )
272      self.__htmlPageWrite( hfp, fPage )
273    list.sort()
274    fIndexContent = """<h1>List of files with errors</h1>
275        File name [number of errors]
276<ul> %s </ul>
277"""  % string.join( list, '\n' )
278    self.__htmlPageWrite( 'html/files/findex.html', fIndexContent )
279
280
281  def __htmlPageWrite(self, pp, content):
282    ptmpl = """<html><body>%s</body></html>"""
283    oo = open( pp, 'w' )
284    oo.write( ptmpl % content )
285    oo.close()
286
287def summariseLogs():
288    summariser = LogSummariser()
289    summariser.summarise()
290
291if __name__ == '__main__':
292
293  summariseLogs()
Note: See TracBrowser for help on using the repository browser.