Skip to content

Instantly share code, notes, and snippets.

@josecanciani
Last active February 27, 2019 22:48
Show Gist options
  • Save josecanciani/9ba6f7a8a0577cbd09ceaa87b18247d5 to your computer and use it in GitHub Desktop.
Save josecanciani/9ba6f7a8a0577cbd09ceaa87b18247d5 to your computer and use it in GitHub Desktop.
It takes a -kibana for example- CSV file and creates an HTML page with a time chart. See usage in first comment.
#!/usr/bin/php
<?php
$file = fopen('php://stdin', 'r');
$stdout = fopen('php://stdin', 'r');
$lineNumber = 0;
$code = new Code();
while (!feof($file) && ($line = fgetcsv($file)) !== false) {
if ($lineNumber) { // ignore header
$logTime = strtotime($line[0]);
$startTime = $logTime - (float) $line[2];
$code->add($line[1], $startTime, $logTime);
}
$lineNumber++;
}
fclose($file);
echo $code->get();
class Code {
private $data = [];
private $categories = [];
private $colors = ['#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6', '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11', '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6'];
private $categoryColors = [];
function add(string $category, float $start, float $end) {
$this->categories[] = $category;
$this->data[] = [$start, $end];
}
function get() {
$this->buildColors();
return str_replace(
['{$categories}', '{$data}', '{$height}'],
[json_encode($this->categories), $this->getEncodedData(), max(count($this->categories) * 20, 600)],
$this->src
);
}
private function buildColors() {
$categories = array_unique($this->categories);
foreach ($categories as $idx => $category) {
if ($idx < count($this->colors)) {
$this->categoryColors[$category] = $this->colors[$idx];
} else {
$this->categoryColors[$category] = '#000000';
}
}
}
private function getEncodedData() {
$data = '[';
foreach ($this->data as $idx => $row) {
$data .= ($idx ? ', ' : '') . '{low: ' . ($row[0] * 1000) . ', high: ' . ($row[1] * 1000) . ', color: "' . $this->categoryColors[$this->categories[$idx]] . '"}';
}
$data .= ']' . PHP_EOL;
return $data;
}
private $src = "
<html>
<head>
<script src='https://code.highcharts.com/highcharts.js'></script>
<script src='https://code.highcharts.com/highcharts-more.js'></script>
<script src='https://code.highcharts.com/modules/exporting.js'></script>
<script src='https://code.highcharts.com/modules/export-data.js'></script>
<script>
Number.prototype.padLeft = function (n, str) {
var len = String(this).length;
return (len < n ? Array(n - len + 1).join(str || '0') : '') + this;
};
Date.prototype.formatForTooltip = function () {
return this.getFullYear().padLeft(4) + '-' + (this.getMonth() + 1).padLeft(2) + '-' + this.getDate().padLeft(2) + ' ' +
this.getHours().padLeft(2) + ':' + this.getMinutes().padLeft(2) + ':' + this.getSeconds().padLeft(2) + '.' + this.getMilliseconds().padLeft(3)
;
};
window.addEventListener('load', function() {
Highcharts.chart('container', {
chart: {
type: 'columnrange',
inverted: true,
height: {\$height}
},
title: {
text: ''
},
plotOptions: {
series: {
pointPadding: 0.1,
groupPadding: 0,
borderWidth: 0,
shadow: false,
animation: false
},
columnrange: {
dataLabels: {
formatter: function () {
var low = this.point.low;
var high = this.point.high;
return this.y === low ? '' : ((high - low)/1000) + 's';
},
enabled: true
}
}
},
yAxis: {
labels: {
enabled: false
},
type: 'datetime'
},
xAxis: {
labels: {
enabled: false
},
categories: {\$categories}
},
legend: {
enabled: false
},
tooltip: {
formatter: function() {
var low = new Date(this.points[0].point.low);
var high = new Date(this.points[0].point.high);
return '<b>'+ this.x +'</b><br/>' + '<p style=\"font-family: monospace; font-size: 12px;\">' + low.formatForTooltip() + '</p><br/><p style=\"font-family: monospace; font-size: 12px;\">' + high.formatForTooltip() + '</p><br/>Elapsed time: <b>' + ((high - low)/1000) + '</b> secs';
},
shared: true
},
series: [{
name: 'Call time',
data: {\$data}
}]
});
});
</script>
</head>
<body>
<div id='container'></div>
</body>
</html>
";
}
@josecanciani
Copy link
Author

josecanciani commented Feb 27, 2019

Usage:
cat kibanaExport.csv | kibanaToTimeTable.php > chart.html; firefox chart.html

The csv file must have at least three columns with this order:

  1. call name
  2. log time
  3. elaped time

The chart will show horizontal bars starting in (logTime-elapsedTime) and ending in (logTime), so you can see what overlaps.

Sample output:

image

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