Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generating a timeline from a log file
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization',
'version':'1','packages':['timeline']}]}"></script>
<script type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Thread' });
dataTable.addColumn({ type: 'string', id: 'Task' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
<% threads.each_with_index do |thread, index| %>
<% thread.tasks.each do |task| %>
[ 'Thread <%= index %>', '<%= task.name %>', <%= task.started_at.strftime("new Date(%Y,%m,%d,%H,%M,%S)") %>, <%= task.completed_at.strftime("new Date(%Y,%m,%d,%H,%M,%S)") %> ],
<% end %>
<% end %>
]);
var colors = ["#318CE7", "#FAF0BE", "#0000FF", "#DE5D83", "#79443B", "#CC0000", "#B5A642", "#BF94E4", "#C32148", "#FF007F", "#08E8DE", "#D19FE8", "#004225", "#CD7F32", "#964B00", "#FFC1CC", "#E7FEFF", "#F0DC82", "#800020", "#DEB887", "#CC5500", "#E97451", "#8A3324", "#BD33A4", "#702963", "#536878", "#5D3954", "#A40000", "#08457E", "#986960", "#CD5B45", "#008B8B", "#B8860B", "#013220", "#1A2421", "#BDB76B", "#483C32", "#734F96", "#8B008B", "#003366", "#556B2F", "#FF8C00", "#779ECB", "#03C03C", "#966FD6", "#C23B22", "#E75480", "#003399", "#872657", "#E9967A", "#560319"];
var options = { colors: colors };
chart.draw(dataTable, options);
}
</script>
</head>
<body>
<div id="timeline" style="width: 1000px; height: 600px;"></div>
</body>
</html>
require 'date'
require 'erb'
log_file = ARGV[0]
class Task < Struct.new(:name, :started_at, :completed_at)
end
class EtlThread
def tasks
@tasks ||= []
end
def completed_before?(timestamp)
tasks.all? { |t| t.completed_at <= timestamp }
end
end
log_lines = File.readlines(log_file).reject { |l| l =~ /^#/ }
tasks = log_lines.each_with_object([]) do |line, array|
if line =~ /([\d\s:-]{19}) \[.{5}\] \[([\w:]+)\] Task (starting|completed)/
timestamp, task_name, event = [ DateTime.parse($1), $2.split('::').last, $3 ]
case event
when "starting"
array << Task.new(task_name, timestamp, nil)
when "completed"
array.find { |t| t.name == task_name }.completed_at = timestamp
end
end
end
tasks.find_all { |t| t.completed_at.nil? }.each { |t| puts "No end date: #{t.name}" }
tasks.reject! { |t| t.completed_at.nil? }
threads = 12.times.map { EtlThread.new }
tasks.sort_by(&:started_at).each do |task|
thread = threads.find { |th| th.completed_before?(task.started_at) }
thread.tasks << task
end
html = ERB.new(File.read("timeline.html.erb")).result(binding)
File.open("#{log_file}.html", "w") { |f| f.write(html) }
@mdeutsch

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.