Skip to content

Instantly share code, notes, and snippets.

@mdeutsch
Created May 4, 2015 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdeutsch/dab1acc1e4c22ddeea09 to your computer and use it in GitHub Desktop.
Save mdeutsch/dab1acc1e4c22ddeea09 to your computer and use it in GitHub Desktop.
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
Copy link
Author

mdeutsch commented May 4, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment