3 # Copyright 2008, Google Inc.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following disclaimer
14 # in the documentation and/or other materials provided with the
16 # * Neither the name of Google Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived from
18 # this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 Filter service runtime logging output and compute system call statistics.
37 To use this script, define the BENCHMARK symbol to be zero (default)
38 in nacl_syscall_hook.c. Next, run the service runtime with NACLLOG
39 set to an output file name. When the run is complete, run this script
40 with that file as input.
51 Compute basic statistics.
55 self
._sum
_x
_squared
= 0.0
63 val: the new (floating point) value
66 self
._sum
_x
_squared
+= val
* val
71 """Returns the mean of entered values.
73 return self
._sum
_x
/ self
._n
77 """Returns the variance of entered values.
80 return self
._sum
_x
_squared
/ self
._n
- mean
* mean
84 """Returns the standard deviation of entered values.
86 return math
.sqrt(self
.Variance())
90 """Returns the number of data points entered.
98 """Compute min and max for a data set. While far less efficient
99 than using a reduce, this class makes streaming data handling
108 def Enter(self
, val
):
109 """Enter a new datum.
112 val: the new datum to be entered.
123 """Returns the maximum value found so far.
129 """Returns the minimum value found so far.
138 """Class for computing statistics on events based on counting the
139 number of occurrences in a time interval. Statistcs on these
140 bucketed counts are then available.
143 def __init__(self
, duration
):
145 self
._t
_duration
= duration
147 self
._event
_count
= 0
148 self
._rate
_stats
= Stats()
149 self
._peak
_stats
= PeakStats()
153 """Enter in a new event that occurred at time t.
156 t: the time at which an event occurred.
158 if self
._t
_start
== -1:
160 self
._t
_end
= t
+ self
._t
_duration
162 # [ t_start, t_start + duration )
164 self
._event
_count
+= 1
168 self
._event
_count
= 1
169 next_end
= self
._t
_end
171 next_end
+= self
._t
_duration
173 self
._t
_end
= next_end
174 self
._t
_start
= next_end
- self
._t
_duration
178 """Finalize the last bucket.
181 self
._rate
_stats
.Enter(self
._event
_count
)
182 self
._peak
_stats
.Enter(self
._event
_count
)
183 self
._event
_count
= 0
187 """Returns the event rate statistics object.
190 return self
._rate
_stats
194 """Returns the peak event rate statistics object.
197 return self
._peak
_stats
202 class TimestampParser
:
204 A class to parse timestamp strings. This is needed because there is
205 implicit state: the timestamp string is HH:MM:SS.fract and may cross
206 a 24 hour boundary -- we do not log the date since that would make
207 the log file much larger and generally it is not needed (implicit in
208 file modification time) -- so we convert to a numeric representation
209 that is relative to an arbitrary epoch start, and the state enables
210 us to correctly handle midnight.
212 This code assumes that the timestamps are monotonically
220 def Convert(self
, timestamp
):
221 """Converts a timestamp string into a numeric timestamp value.
224 timestamp: A timestamp string in HH:MM:SS.fraction format.
227 a numeric timestamp (arbitrary epoch)
229 (hh
, mm
, ss
) = map(float,timestamp
.split(':'))
230 t
= ((hh
* 60) + mm
) * 60 + ss
231 if self
._min
_time
== -1:
234 while t
< self
._min
_time
:
243 def ReadFileHandle(fh
, duration
):
244 """Reads log data from the provided file handle, and compute and
245 print various statistics on the system call rate based on the log
249 # log format "[pid:timestamp] msg" where the timestamp is
250 log_re
= re
.compile(r
'\[[0-9,]+:([:.0-9]+)\] system call [0-9]+')
251 parser
= TimestampParser()
252 inter_stats
= Stats()
254 windowed
= WindowedRate(duration
)
257 for line
in fh
: # generator
258 m
= log_re
.search(line
)
260 timestamp
= m
.group(1)
261 t
= parser
.Convert(timestamp
)
266 elapsed
= t
- prev_time
267 inter_stats
.Enter(elapsed
)
268 rate_stats
.Enter(1.0/elapsed
)
277 print '\nInter-syscall time'
278 print 'Mean: %g' % inter_stats
.Mean()
279 print 'Stddev: %g' % inter_stats
.Stddev()
280 print '\nInstantaneous Syscall Rate (unweighted!)'
281 print 'Mean : %g' % rate_stats
.Mean()
282 print 'Stddev: %g' % rate_stats
.Stddev()
283 print '\nAvg Syscall Rate: %g' % (rate_stats
.NumEntries()
284 / (prev_time
- start_time
))
286 print '\nSyscalls in %f interval' % duration
287 print 'Mean: %g' % windowed
.RateStats().Mean()
288 print 'Stddev: %g' % windowed
.RateStats().Stddev()
289 print 'Min: %g' % windowed
.PeakStats().Min()
290 print 'Max: %g' % windowed
.PeakStats().Max()
296 print >>sys
.stderr
, 'no arguments expected\n'
299 ReadFileHandle(sys
.stdin
, 0.010)
303 if __name__
== '__main__':
304 sys
.exit(main(sys
.argv
))