debian/0000755000000000000000000000000011545413221007164 5ustar debian/pyversions0000644000000000000000000000000511410225057011322 0ustar 2.5- debian/changelog0000644000000000000000000000746511545413221011052 0ustar pybootchartgui (0+r141-0ubuntu3) natty; urgency=low * Add patch adding-smart-array-block-devices.patch to allow pybootchartgui to run on devices with an HP smart array. (LP: #723663) -- Brian Murray Fri, 01 Apr 2011 11:15:10 -0700 pybootchartgui (0+r141-0ubuntu2) maverick; urgency=low * Adding adding-mmcblk-block-devices.patch to make pybootchartgui run in devices like beagleboard. (LP: #619026) -- Ricardo Salveti de Araujo Mon, 16 Aug 2010 22:56:36 -0300 pybootchartgui (0+r141-0ubuntu1) maverick; urgency=low [ Jean-Louis Dupond ] * Update to Subversion HEAD (LP: #596475): - Use mousewheel to scroll up/down, unless ctrl is pressed in which case mousewheeling is used for zoom. [ Benjamin Drung ] * Switch to dpkg-source 3.0 (quilt) format. * Bump Standards-Version to 3.9.1 (no changes required). * Refer to versioned copyright file. * Change build dependency from python-all-dev to python-all. -- Benjamin Drung Sun, 15 Aug 2010 02:05:49 +0200 pybootchartgui (0+r139-3) maverick; urgency=low * pybootchartgui/draw.py, get_proc_state(): Don't crash on an undefined state. Patch taken from upstream svn r140. (LP: #512172) -- Martin Pitt Tue, 22 Jun 2010 23:24:54 +0200 pybootchartgui (0+r139-2) lucid; urgency=low * debian/control: Don't provide bootchart-java, otherwise we can't actually be installed. -- Scott James Remnant Tue, 01 Dec 2009 20:47:09 +0000 pybootchartgui (0+r139-1) lucid; urgency=low * debian/control: Also provide and replace bootchart-java, since this package is now the preferred version. -- Scott James Remnant Sun, 29 Nov 2009 14:38:14 +0000 pybootchartgui (0+r139) lucid; urgency=low * Update to Subversion HEAD: - Implemented --quiet and --verbose options. - Some performance improvements. - Output format guessing based on suffix. - Option to print pid numbers next to proecss names. - Added setup.py. - Default to /var/log/bootchart.tgz if no filename given. - Parsing also matches virtual disks. * Add --crop-after option; takes a comma-separated list of processes. The chart is cropped at the end of the first 3s idle period after the first of the named processes is started. The time displayed on the chart is that of the start of the idle period. * Add --annotate option, permitted multiple times; takes a comma-separated list of processes and draws a dashed red line vertically across the chart at the point the first of the named processes is started. * Add --annotate-file option, writes the times found with --annotate to the given filename with a blank line for any missing annotations. -- Scott James Remnant Wed, 25 Nov 2009 23:43:23 +0000 pybootchartgui (0+r124) jaunty; urgency=low * New upstream revision: - Fix some drawing issues (lp: #342593) - Fix drawing bug (lp: #343215) - Empty bootcharts are now discovered (lp: #355952) - Fix incorrect seconds value for 60+ second boots (lp: #355954) - Fix parsing issue for process lines with spaces (lp: #356537) - Update slider position when zooming (lp: #358364) - Fix some drawing issue (lp: #360943, thanks to Hernando Torque) (thanks to biehl and Henning Niss for their active development) * debian/control: - Add depencies to 'python-gtk2' and 'python-cairo' (lp: #353699) -- Martin Mai Sat, 18 Apr 2009 22:48:24 +0200 pybootchartgui (0+r102-2) jaunty; urgency=low * Conflict bootchart-java -- Scott James Remnant Wed, 11 Mar 2009 11:47:43 +0000 pybootchartgui (0+r102) jaunty; urgency=low * Initial Release. -- Scott James Remnant Mon, 09 Mar 2009 19:16:46 +0000 debian/compat0000644000000000000000000000000211410225057010361 0ustar 7 debian/patches/0000755000000000000000000000000011545425240010617 5ustar debian/patches/series0000644000000000000000000000014211545425240012031 0ustar additional-options.patch adding-mmcblk-block-devices.patch adding-smart-array-block-devices.patch debian/patches/additional-options.patch0000644000000000000000000002515311431627512015447 0ustar Description: Add options * Add --crop-after option; takes a comma-separated list of processes. The chart is cropped at the end of the first 3s idle period after the first of the named processes is started. The time displayed on the chart is that of the start of the idle period. * Add --annotate option, permitted multiple times; takes a comma-separated list of processes and draws a dashed red line vertically across the chart at the point the first of the named processes is started. * Add --annotate-file option, writes the times found with --annotate to the given filename with a blank line for any missing annotations. Author: Scott James Remnant --- pybootchartgui-0+r141.orig/pybootchartgui/main.py +++ pybootchartgui-0+r141/pybootchartgui/main.py @@ -44,6 +44,12 @@ def _mk_options_parser(): help="profile rendering of chart (only useful when in batch mode indicated by -f)") parser.add_option("--show-pid", action="store_true", dest="show_pid", default=False, help="show process ids in the bootchart as 'processname [pid]'") + parser.add_option("--crop-after", dest="crop_after", metavar="PROCESS", default=None, + help="crop chart when idle after PROCESS is started") + parser.add_option("--annotate", action="append", dest="annotate", metavar="PROCESS", default=None, + help="annotate position where PROCESS is started") + parser.add_option("--annotate-file", dest="annotate_file", metavar="FILENAME", default=None, + help="filename to write annotation points to") return parser class Writer: @@ -101,11 +107,22 @@ def main(argv=None): args = [ "/var/log/bootchart.tgz" ] - res = parsing.parse(writer, args, options.prune) + res = parsing.parse(writer, args, options.prune, + options.crop_after, options.annotate) if options.interactive or options.output == None: gui.show(res, options) else: + if options.annotate_file: + f = open(options.annotate_file, "w") + try: + for time in res[-1]: + if time is not None: + print >>f, time + else: + print >>f + finally: + f.close() filename = _get_filename(args, options) def render(): batch.render(writer, res, options, filename) --- pybootchartgui-0+r141.orig/pybootchartgui/process_tree.py +++ pybootchartgui-0+r141/pybootchartgui/process_tree.py @@ -37,7 +37,7 @@ class ProcessTree: LOGGER_PROC = 'bootchartd' EXPLODER_PROCESSES = set(['hwup']) - def __init__(self, writer, psstats, monitoredApp, prune, for_testing = False): + def __init__(self, writer, psstats, monitoredApp, prune, idle, for_testing = False): self.writer = writer self.process_tree = [] self.psstats = psstats @@ -50,6 +50,7 @@ class ProcessTree: self.start_time = self.get_start_time(self.process_tree) self.end_time = self.get_end_time(self.process_tree) self.duration = self.end_time - self.start_time + self.idle = idle if for_testing: return --- pybootchartgui-0+r141.orig/pybootchartgui/draw.py +++ pybootchartgui-0+r141/pybootchartgui/draw.py @@ -28,6 +28,8 @@ BORDER_COLOR = (0.63, 0.63, 0.63, 1.0) TICK_COLOR = (0.92, 0.92, 0.92, 1.0) # 5-second tick line color. TICK_COLOR_BOLD = (0.86, 0.86, 0.86, 1.0) +# Annotation colour +ANNOTATION_COLOR = (0.63, 0.0, 0.0, 0.5) # Text color. TEXT_COLOR = (0.0, 0.0, 0.0, 1.0) @@ -169,6 +171,22 @@ def draw_box_ticks(ctx, rect, sec_w): ctx.set_line_cap(cairo.LINE_CAP_BUTT) +def draw_annotations(ctx, proc_tree, times, rect, sec_w): + ctx.set_line_cap(cairo.LINE_CAP_SQUARE) + ctx.set_source_rgba(*ANNOTATION_COLOR) + ctx.set_dash([4,4]) + + for time in times: + if time is not None: + x = ((time - proc_tree.start_time) * rect[2] / proc_tree.duration) + + ctx.move_to(rect[0] + x, rect[1] + 1) + ctx.line_to(rect[0] + x, rect[1] + rect[3] - 1) + ctx.stroke() + + ctx.set_line_cap(cairo.LINE_CAP_BUTT) + ctx.set_dash([]) + def draw_chart(ctx, color, fill, chart_bounds, data, proc_tree): ctx.set_line_width(0.5) x_shift = proc_tree.start_time @@ -211,7 +229,7 @@ MIN_IMG_W = 800 OPTIONS = None -def extents(headers, cpu_stats, disk_stats, proc_tree): +def extents(headers, cpu_stats, disk_stats, proc_tree, times): w = (proc_tree.duration * sec_w / 100) + 2*off_x h = proc_h * proc_tree.num_proc + header_h + 2*off_y return (w,h) @@ -219,8 +237,8 @@ def extents(headers, cpu_stats, disk_sta # # Render the chart. # -def render(ctx, options, headers, cpu_stats, disk_stats, proc_tree): - (w, h) = extents(headers, cpu_stats, disk_stats, proc_tree) +def render(ctx, options, headers, cpu_stats, disk_stats, proc_tree, times): + (w, h) = extents(headers, cpu_stats, disk_stats, proc_tree, times) global OPTIONS OPTIONS = options @@ -231,7 +249,11 @@ def render(ctx, options, headers, cpu_st draw_fill_rect(ctx, WHITE, (0, 0, max(w, MIN_IMG_W), h)) w -= 2*off_x # draw the title and headers - curr_y = draw_header(ctx, headers, off_x, proc_tree.duration) + if proc_tree.idle: + duration = proc_tree.idle + else: + duration = proc_tree.duration + curr_y = draw_header(ctx, headers, off_x, duration) # render bar legend ctx.set_font_size(LEGEND_FONT_SIZE) @@ -242,6 +264,7 @@ def render(ctx, options, headers, cpu_st # render I/O wait chart_rect = (off_x, curr_y+30, w, bar_h) draw_box_ticks(ctx, chart_rect, sec_w) + draw_annotations(ctx, proc_tree, times, chart_rect, sec_w) draw_chart(ctx, IO_COLOR, True, chart_rect, [(sample.time, sample.user + sample.sys + sample.io) for sample in cpu_stats], proc_tree) # render CPU load draw_chart(ctx, CPU_COLOR, True, chart_rect, [(sample.time, sample.user + sample.sys) for sample in cpu_stats], proc_tree) @@ -255,6 +278,7 @@ def render(ctx, options, headers, cpu_st # render I/O utilization chart_rect = (off_x, curr_y+30, w, bar_h) draw_box_ticks(ctx, chart_rect, sec_w) + draw_annotations(ctx, proc_tree, times, chart_rect, sec_w) draw_chart(ctx, IO_COLOR, True, chart_rect, [(sample.time, sample.util) for sample in disk_stats], proc_tree) # render disk throughput @@ -272,12 +296,12 @@ def render(ctx, options, headers, cpu_st # draw process boxes - draw_process_bar_chart(ctx, proc_tree, curr_y + bar_h, w, h) + draw_process_bar_chart(ctx, proc_tree, times, curr_y + bar_h, w, h) ctx.set_font_size(SIG_FONT_SIZE) draw_text(ctx, SIGNATURE, SIG_COLOR, off_x + 5, h - off_y - 5) -def draw_process_bar_chart(ctx, proc_tree, curr_y, w, h): +def draw_process_bar_chart(ctx, proc_tree, times, curr_y, w, h): draw_legend_box(ctx, "Running (%cpu)", PROC_COLOR_R, off_x , curr_y + 45, leg_s) draw_legend_box(ctx, "Unint.sleep (I/O)", PROC_COLOR_D, off_x+120, curr_y + 45, leg_s) draw_legend_box(ctx, "Sleeping", PROC_COLOR_S, off_x+240, curr_y + 45, leg_s) @@ -288,7 +312,8 @@ def draw_process_bar_chart(ctx, proc_tre draw_box_ticks(ctx, chart_rect, sec_w) draw_5sec_labels(ctx, chart_rect, sec_w) - + draw_annotations(ctx, proc_tree, times, chart_rect, sec_w) + y = curr_y+60 for root in proc_tree.process_tree: draw_processes_recursively(ctx, root, proc_tree, y, proc_h, chart_rect) --- pybootchartgui-0+r141.orig/pybootchartgui/parsing.py +++ pybootchartgui-0+r141/pybootchartgui/parsing.py @@ -244,10 +244,96 @@ def parse_paths(writer, state, paths): state = parse_file(writer, state, path) return state -def parse(writer, paths, prune): +def parse(writer, paths, prune, crop_after, annotate): state = parse_paths(writer, ParserState(), paths) if not state.valid(): raise ParseError("empty state: '%s' does not contain a valid bootchart" % ", ".join(paths)) + # Crop the chart to the end of the first idle period after the given + # process + if crop_after: + idle = crop(writer, crop_after, state) + else: + idle = None + # Annotate other times as the first start point of given process lists + times = [ idle ] + if annotate: + for procnames in annotate: + names = [x[:15] for x in procnames.split(",")] + for proc in state.ps_stats.process_list: + if proc.cmd in names: + times.append(proc.start_time) + break + else: + times.append(None) monitored_app = state.headers.get("profile.process") - proc_tree = ProcessTree(writer, state.ps_stats, monitored_app, prune) - return (state.headers, state.cpu_stats, state.disk_stats, proc_tree) + proc_tree = ProcessTree(writer, state.ps_stats, monitored_app, prune, idle) + return (state.headers, state.cpu_stats, state.disk_stats, proc_tree, times) + + +def crop(writer, crop_after, state): + names = [x[:15] for x in crop_after.split(",")] + for proc in state.ps_stats.process_list: + if proc.cmd in names: + writer.info("selected proc '%s' from list (start %d)" + % (proc.cmd, proc.start_time)) + break + else: + writer.info("no selected proc in list") + return + + def is_idle_at(util, start, j): + k = j + 1 + while k < len(util) and util[k][0] < start + 300: + k += 1 + k = min(k, len(util)-1) + + if util[j][1] >= 0.25: + return False + + avgload = sum(u[1] for u in util[j:k+1]) / (k-j+1) + if avgload < 0.25: + return True + else: + return False + def is_idle(util, start): + for j in range(0, len(util)): + if util[j][0] < start: + continue + return is_idle_at(util, start, j) + else: + return False + + cpu_util = [(sample.time, sample.user + sample.sys + sample.io) for sample in state.cpu_stats] + disk_util = [(sample.time, sample.util) for sample in state.disk_stats] + + for i in range(0, len(cpu_util)): + if cpu_util[i][0] < proc.start_time: + continue + if is_idle_at(cpu_util, cpu_util[i][0], i) \ + and is_idle(disk_util, cpu_util[i][0]): + idle = cpu_util[i][0] + break + else: + writer.info("selected proc not found in tree") + return + + crop = idle + 300 + writer.info("cropping at time %d" % crop) + while len(state.cpu_stats) \ + and state.cpu_stats[-1].time > crop: + state.cpu_stats.pop() + while len(state.disk_stats) \ + and state.disk_stats[-1].time > crop: + state.disk_stats.pop() + + state.ps_stats.end_time = crop + while len(state.ps_stats.process_list) \ + and state.ps_stats.process_list[-1].start_time > crop: + state.ps_stats.process_list.pop() + for proc in state.ps_stats.process_list: + proc.duration=min(proc.duration,crop-proc.start_time) + while len(proc.samples) \ + and proc.samples[-1].time >crop: + proc.samples.pop() + + return idle debian/patches/adding-mmcblk-block-devices.patch0000644000000000000000000000202611432540642017040 0ustar From: Ricardo Salveti de Araujo Date: Mon, 16 Aug 2010 22:21:10 -0300 Subject: [PATCH] pybootchartgui/parsing.py: adding block devices /dev/mmcblk to DISK_REGEX With this we're able to run pybootchartgui at devices that only have /dev/mmcblk. block devices, like Beagleboard. Signed-off-by: Ricardo Salveti de Araujo --- pybootchartgui/parsing.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/pybootchartgui/parsing.py b/pybootchartgui/parsing.py index fe8d97a..9e0080b 100644 --- a/pybootchartgui/parsing.py +++ b/pybootchartgui/parsing.py @@ -133,7 +133,7 @@ def _parse_proc_disk_stat_log(file, numCpu): not sda1, sda2 etc. The format of relevant lines should be: {major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq} """ - DISK_REGEX = 'hd.$|sd.$|vd.$' + DISK_REGEX = 'hd.$|sd.$|vd.$|mmcblk.$' def is_relevant_line(linetokens): return len(linetokens) == 14 and re.match(DISK_REGEX, linetokens[2]) -- 1.7.1 debian/patches/adding-smart-array-block-devices.patch0000644000000000000000000000155411545425132020043 0ustar From: Brian Murray Description: handle HP Smart Array drives Bug: Bug-Ubuntu: http://launchpad.net/bugs/723663 Origin: upstream developer Forwarded: no Author: Anders Norgaard Index: pybootchartgui-0+r141/pybootchartgui/parsing.py =================================================================== --- pybootchartgui-0+r141.orig/pybootchartgui/parsing.py 2011-04-01 11:17:03.000000000 -0700 +++ pybootchartgui-0+r141/pybootchartgui/parsing.py 2011-04-01 12:02:15.000000000 -0700 @@ -133,7 +133,7 @@ not sda1, sda2 etc. The format of relevant lines should be: {major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq} """ - DISK_REGEX = 'hd.$|sd.$|vd.$|mmcblk.$' + DISK_REGEX = 'hd.$|sd.$|vd.$|mmcblk.$|cciss/c0d0$' def is_relevant_line(linetokens): return len(linetokens) == 14 and re.match(DISK_REGEX, linetokens[2]) debian/rules0000755000000000000000000000103011410225057010235 0ustar #!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk install/pybootchartgui:: install -D -o root -g root -m 755 pybootchartgui.py \ $(DEB_DESTDIR)/usr/bin/pybootchartgui ln -s pybootchartgui $(DEB_DESTDIR)/usr/bin/bootchart install -d -o root -g root -m 755 \ $(DEB_DESTDIR)/usr/share/python-support/pybootchartgui cp -a pybootchartgui \ $(DEB_DESTDIR)/usr/share/python-support/pybootchartgui binary-install/pybootchartgui:: dh_pysupport -p$(cdbs_curpkg) # Add here any variable or target overrides you need. debian/docs0000644000000000000000000000001711410225057010034 0ustar README AUTHORS debian/copyright0000644000000000000000000000242311431625026011122 0ustar This package was debianized by Scott James Remnant on Mon, 09 Mar 2009 19:16:46 +0000. It was downloaded from Upstream Author(s): Anders Norgaard Henning Niss Contributors: Brian Ewins Based on work by: Ziga Mahkovec Copyright: Copyright (C) 2009 Anders Norgaard Copyright (C) 2009 Henning Niss License: This package 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; version 3 of the License. This package 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 package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-3'. debian/source/0000755000000000000000000000000011431624614010470 5ustar debian/source/format0000644000000000000000000000001411432540571011676 0ustar 3.0 (quilt) debian/control0000644000000000000000000000242211431627100010564 0ustar Source: pybootchartgui Section: admin Priority: extra Maintainer: Scott James Remnant Build-Depends: cdbs (>= 0.4.49), debhelper (>= 7), python-all (>= 2.3.5-11), python-support (>= 0.5.3) Standards-Version: 3.9.1 Homepage: http://code.google.com/p/pybootchartgui/ Package: pybootchartgui Architecture: any Depends: python-cairo, python-gtk2, ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} Provides: ${python:Provides} Suggests: bootchart Conflicts: bootchart-java Replaces: bootchart-java XB-Python-Version: ${python:Versions} Description: boot sequence visualisation pybootchartgui is a tool for visualization and analysis of the GNU/Linux boot process. It renders the output of the boot-logger tool bootchart interactively or to files of various formats. . Bootchart collects information about the processes, their dependencies, and resource consumption during boot of a GNU/Linux system. The pybootchartgui tools visualizes the process tree and overall resource utilization. . pybootchartgui is a port of the original visualization part of bootchart from Java to Python and Cairo. . In Ubuntu, the tools to collect the information can be found in the bootchart package.