Author: dmacvicar Date: Tue Oct 30 16:51:46 2007 New Revision: 7705 URL: http://svn.opensuse.org/viewcvs/zypp?rev=7705&view=rev Log: graph a timeline of zypp log Added: trunk/scripts/zypp-log-timeline.rb Added: trunk/scripts/zypp-log-timeline.rb URL: http://svn.opensuse.org/viewcvs/zypp/trunk/scripts/zypp-log-timeline.rb?rev=7705&view=auto ============================================================================== --- trunk/scripts/zypp-log-timeline.rb (added) +++ trunk/scripts/zypp-log-timeline.rb Tue Oct 30 16:51:46 2007 @@ -0,0 +1,247 @@ +require 'cairo' +require 'date' +require 'rubygems' +require 'getoptlong' +require 'logger' + +opts = GetoptLong.new( + [ '--help', '-h', GetoptLong::NO_ARGUMENT ] +# [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ], +# [ '--input', '-i', GetoptLong::REQUIRED_ARGUMENT ], +# [ '--name', GetoptLong::OPTIONAL_ARGUMENT ] +) + +opts.each do |opt, arg| + case opt + when '--help' + #RDoc::usage + when '--input' + puts "input #{arg}" + when '--repeat' + repetitions = arg.to_i + when '--name' + if arg == '' + name = 'John' + else + name = arg + end + end +end + + +if ARGV.length != 1 + puts "Missing log file argument (try --help)" + exit 0 +end + +logfile = ARGV.shift + + +PALETTE = [ + [0.12, 0.29, 0.49], + [0.36, 0.51, 0.71], + [0.75, 0.31, 0.30], + [0.62, 0.73, 0.38], + [0.50, 0.40, 0.63], + [0.29, 0.67, 0.78], + [0.96, 0.62, 0.34], + [1.0 - 0.12, 1.0 - 0.29, 1.0 - 0.49], + [1.0 - 0.36, 1.0 - 0.51, 1.0 - 0.71], + [1.0 - 0.75, 1.0 - 0.31, 1.0 - 0.30], + [1.0 - 0.62, 1.0 - 0.73, 1.0 - 0.38], + [1.0 - 0.50, 1.0 - 0.40, 1.0 - 0.63], + [1.0 - 0.29, 1.0 - 0.67, 1.0 - 0.78], + [1.0 - 0.96, 1.0 - 0.62, 1.0 - 0.34] + ] + +### CUSTOMIZATION BEGINS HERE +FONT_NAME = "Bitstream Vera Sans" +FONT_SIZE = 8 +PIXELS_PER_SECOND = 40 +PIXELS_PER_LINE = 45 +PLOT_WIDTH = 1400 +TIME_SCALE_WIDTH = 25 +SYSCALL_MARKER_WIDTH = 20 +LOG_TEXT_XPOS = 200 +LOG_MARKER_WIDTH = 20 +BACKGROUND_COLOR = :black + +class Event + attr_accessor :time + attr_accessor :text + attr_accessor :time_ypos + attr_accessor :text_ypos + attr_accessor :color + + def initialize(time, text) + @color = :white + @time = time + @text = text + @time_ypos = 0 + @text_ypos = 0 + end + + def to_s + "#{time.strftime('%H:%M:%S')} #{text}" + end +end + +class Metrics + attr_accessor :height, :width + + def initialize(events) + num_events = events.size + @width = PLOT_WIDTH + num_seconds = (events.last.time - events.first.time).to_i + @height = [num_seconds * PIXELS_PER_SECOND, num_events * PIXELS_PER_LINE].max + + text_ypos = 0 + + events.each do |event| + event.time_ypos = event.time.to_i * PIXELS_PER_SECOND + event.text_ypos = text_ypos + FONT_SIZE + + text_ypos += PIXELS_PER_LINE + end + end + +end + +def plot_time_scale(surface, ctx, metrics) + num_seconds = (metrics.height + PIXELS_PER_SECOND - 1) / PIXELS_PER_SECOND + + ctx.set_source_color(:yellow) + ctx.set_line_width(1.0) + + for i in 0..num_seconds + ypos = i * PIXELS_PER_SECOND + + ctx.move_to(0, ypos + 0.5) + ctx.line_to(TIME_SCALE_WIDTH, ypos + 0.5) + ctx.stroke() + + ctx.move_to(0, ypos + 2 + FONT_SIZE) + ctx.show_text("%d s" % i) + end +end + +def plot_event(surface, ctx, event) + ctx.set_source_color(event.color) + + # Line + ctx.move_to(TIME_SCALE_WIDTH, event.time_ypos) + ctx.line_to(TIME_SCALE_WIDTH + SYSCALL_MARKER_WIDTH, event.time_ypos) + ctx.line_to(LOG_TEXT_XPOS - LOG_MARKER_WIDTH, event.text_ypos - FONT_SIZE / 2 + 0.5) + ctx.line_to(LOG_TEXT_XPOS, event.text_ypos - FONT_SIZE / 2 + 0.5) + ctx.stroke + + # Log text + ctx.move_to(LOG_TEXT_XPOS, event.text_ypos) + #ctx.show_text(format("%8.5f: %s", event.time.to_i, event.text)) + ctx.show_text(event.text) +end + +def plot_events_to_surface(events, metrics) + num_events = events.size + #surface = Cairo::ImageSurface.new(Cairo::FORMAT_RGB24, + # metrics.width, metrics.height) + + surface = Cairo::SVGSurface.new("out.svg", + metrics.width, metrics.height) + + #surface = Cairo::PDFSurface.new("out.pdf", + # metrics.width, metrics.height) + + ctx = Cairo::Context.new(surface) + ctx.select_font_face(FONT_NAME) + ctx.set_font_size(FONT_SIZE) + + # Background + ctx.set_source_color(BACKGROUND_COLOR) + ctx.rectangle(0, 0, metrics.width, metrics.height) + ctx.fill() + + # Time scale + + plot_time_scale(surface, ctx, metrics) + + # Contents + + ctx.set_line_width(1.0) + + events.each do |event| + plot_event(surface, ctx, event) + end + + return surface +end + +# scalable_surface_output("PSSurface", "ps") +# scalable_surface_output("PDFSurface", "pdf") +# scalable_surface_output("SVGSurface", "svg") + + +events = Array.new + +f = File.open(logfile, 'r') +f.each_line do | l | + if ( l =~ /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d) <\d> (.+)\(\d+\) \[.+\] (.+)/ ) + time = Time.local($1, $2, $3, $4, $5, $6) + host = $7 + event = Event.new(time, $8) + + begin + break if (events.last.time.to_i - events.first.time.to_i) > 10 + rescue + puts l + end + + if not events.empty? + + if ( event.text =~ /update-status/ ) + event.color = :green + events << event + next + end + + if (event.time.to_i - events.last.time.to_i) > 1 + events.last.color = :red + # if there is difference, just add it + events << event + next + elsif (event.time.to_i - events.last.time.to_i) == 0 + # mark this as a collection of lot of events + events.last.color = :yellow + events.last.text = "(...) #{event.text}" + next + # last element is the same time to this one so remove it + #events.pop + else + event.color = :white + end + end + + events << event + else + raise "invalid log line [#{l}]" + end +end + +$log = Logger.new(STDOUT) +$log.datetime_format = "%Y-%m-%d %H:%M:%S" +$log.level = Logger::INFO + +first = events.first.time +events.each do |e| + e.time = e.time - first +end + +metrics = Metrics.new(events) +$log.info metrics.height +$log.info "events: #{events.size} seconds: #{(events.last.time - events.first.time).to_i}" +surface = plot_events_to_surface(events, metrics) +surface.write_to_png("out.pdf") +surface.finish + + + -- To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org For additional commands, e-mail: zypp-commit+help@opensuse.org