1
- # ------------------------------------------------------------------------------------------------------------------------------------------------
2
- # helper function to generate color based on the job statu
3
- # this may need renaming to Get-DbaTimelineStatusColor or similar
4
- # ------------------------------------------------------------------------------------------------------------------------------------------------
5
- Function Get-StatusColor ([string ]$Status ) {
6
- $out = switch ($Status ){
7
- " Failed" {" #FF3D3D" }
8
- " Succeeded" {" #36B300" }
9
- " Retry" {" #FFFF00" }
10
- " Canceled" {" #C2C2C2" }
11
- " In Progress" {" #00CCFF" }
12
- default {" #FF00CC" }
13
- }
14
- return $out
15
- }
1
+ function ConvertTo-DbaTimeline {
2
+ <#
3
+ . SYNOPSIS
4
+ Converts InputObject to a html timeline using Google Chart
5
+
6
+ . DESCRIPTION
7
+ This function accepts input as pipeline from the following psdbatools functions:
8
+ Get-DbaAgentJobHistory
9
+ Get-DbaBackupHistory
10
+ (more to come...)
11
+ And generates Bootstrap based, HTML file with Google Chart Timeline
12
+
13
+ . PARAMETER InputObject
14
+
15
+ Pipe input, must an output from the above functions.
16
+
17
+ . NOTES
18
+ Tags: Internal
19
+ Author: Marcin Gminski (@marcingminski)
20
+
21
+ Dependency: ConvertTo-JsDate, Convert-DbaTimelineStatusColor
22
+ Requirements: None
23
+
24
+ Website: https://dbatools.io
25
+ Copyright: (C) Chrissy LeMaire, clemaire@gmail.com
26
+ - License: MIT https://opensource.org/licenses/MIT
27
+
28
+ . LINK
29
+ https://dbatools.io/ConvertTo-DbaTimeline
16
30
17
- # ------------------------------------------------------------------------------------------------------------------------------------------------
18
- # helper function to convert human time to java script time format: new Date( Year, Month, Day, Hour, Minute, Second)
19
- # Java script time is zero base which means January = 0 and December = 11
20
- # ------------------------------------------------------------------------------------------------------------------------------------------------
21
- Function ConvertTo-JsDate ([datetime ]$InputDate ) {
22
- $out = " new Date($ ( Get-Date $InputDate - format " yyyy" ) , $ ( $ (Get-Date $InputDate - format " MM" )-1 ) , $ ( Get-Date $InputDate - format " dd" ) , $ ( Get-Date $InputDate - format " HH" ) , $ ( Get-Date $InputDate - format " mm" ) , $ ( Get-Date $InputDate - format " ss" ) )"
23
- return $out
24
- }
31
+ . EXAMPLE
32
+ Get-DbaAgentJobHistory -SqlInstance sql-1 -StartDate ‘2018年08月13日 00:00’ -EndDate ‘2018年08月13日 23:59’ -NoJobSteps | ConvertTo-DbaTimeline | Out-File C:\temp\DbaAgentJobHistory.html -Encoding ASCII
33
+ Get-DbaBackupHistory -SqlInstance sql-1 -Since ‘2018年08月13日 00:00’ | ConvertTo-DbaTimeline | Out-File C:\temp\DbaBackupHistory.html -Encoding ASCII
25
34
26
- # ------------------------------------------------------------------------------------------------------------------------------------------------
27
- # function to convert to timeline
28
- # ------------------------------------------------------------------------------------------------------------------------------------------------
29
- Function ConvertTo-DbaTimeline {
35
+ #>
36
+
37
+ [CmdletBinding ()]
30
38
Param (
31
39
[parameter (Mandatory = $true , ValueFromPipeline = $true )]
32
40
[object []]$InputObject
33
41
)
34
-
35
42
begin {
36
43
# need to capture calling process to know what we are being asked for i.e. JobHistory, BackupHistory etc?
37
44
# I dont know of any way apart from Get-PSCallStack but that return the whole stack but in order to the last
@@ -42,23 +49,18 @@ Function ConvertTo-DbaTimeline {
42
49
<html>
43
50
<head>
44
51
<!-- Developed by Marcin Gminski, https://marcin.gminski.net, 2018 -->
45
-
46
52
<!-- Load jQuery required to autosize timeline -->
47
53
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
48
-
49
54
<!-- Load Bootstrap -->
50
55
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
51
56
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
52
57
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
53
-
54
58
<!-- Load Google Charts library -->
55
59
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
56
-
57
60
<!-- a bit of custom styling to work with bootstrap grid -->
58
61
<style>
59
62
60
63
html,body{height:100%;background-color:#c2c2c2;}
61
-
62
64
.viewport {height:100%}
63
65
64
66
.chart{
@@ -71,18 +73,15 @@ Function ConvertTo-DbaTimeline {
71
73
box-shadow:1px 1px 3px 0 rgba(0,0,0,.45)
72
74
}
73
75
.badge-custom{background-color:#939}
74
-
75
76
.container {
76
77
height:100%;
77
78
}
78
-
79
79
.fill{
80
80
width:100%;
81
81
height:100%;
82
82
min-height:100%;
83
83
padding:10px;
84
84
}
85
-
86
85
.timeline-tooltip{
87
86
border:1px solid #E0E0E0;
88
87
font-family:Arial,Helvetica;
@@ -91,12 +90,10 @@ Function ConvertTo-DbaTimeline {
91
90
}
92
91
.timeline-tooltip div{padding:6px}
93
92
.timeline-tooltip span{font-weight:700}
94
-
95
93
</style>
96
94
<script type="text/javascript">
97
95
google.charts.load('43', {'packages':['timeline']});
98
96
google.charts.setOnLoadCallback(drawChart);
99
-
100
97
function drawChart() {
101
98
var container = document.getElementById('Chart');
102
99
var chart = new google.visualization.Timeline(container);
@@ -117,7 +114,7 @@ Function ConvertTo-DbaTimeline {
117
114
# This is where do column mapping:
118
115
if ($caller.Position -Like " *Get-DbaAgentJobHistory*" ) {
119
116
$CallerName = " Get-DbaAgentJobHistory"
120
- $data = $input | Select @ { Name = " SqlInstance" ; Expression = {$_.SqlInstance }}, @ { Name = " InstanceName" ; Expression = {$_.InstanceName }}, @ { Name = " vLabel" ; Expression = {$_.Job } }, @ { Name = " hLabel" ; Expression = {$_.Status } }, @ { Name = " Style" ; Expression = {$ (Get-StatusColor ($_.Status ))} }, @ { Name = " StartDate" ; Expression = {$ (ConvertTo-JsDate ($_.StartDate ))} }, @ { Name = " EndDate" ; Expression = {$ (ConvertTo-JsDate ($_.EndDate ))} }
117
+ $data = $input | Select @ { Name = " SqlInstance" ; Expression = {$_.SqlInstance }}, @ { Name = " InstanceName" ; Expression = {$_.InstanceName }}, @ { Name = " vLabel" ; Expression = {$_.Job } }, @ { Name = " hLabel" ; Expression = {$_.Status } }, @ { Name = " Style" ; Expression = {$ (Convert-DbaTimelineStatusColor ($_.Status ))} }, @ { Name = " StartDate" ; Expression = {$ (ConvertTo-JsDate ($_.StartDate ))} }, @ { Name = " EndDate" ; Expression = {$ (ConvertTo-JsDate ($_.EndDate ))} }
121
118
122
119
}
123
120
@@ -133,41 +130,33 @@ Function ConvertTo-DbaTimeline {
133
130
var paddingHeight = 20;
134
131
var rowHeight = dataTable.getNumberOfRows() * 41;
135
132
var chartHeight = rowHeight + paddingHeight;
136
-
137
133
dataTable.insertColumn(2, {type: 'string', role: 'tooltip', p: {html: true}});
138
-
139
134
var dateFormat = new google.visualization.DateFormat({
140
135
pattern: 'dd/MM/yy HH:mm:ss'
141
136
});
142
-
143
137
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
144
138
var duration = (dataTable.getValue(i, 5).getTime() - dataTable.getValue(i, 4).getTime()) / 1000;
145
139
var hours = parseInt( duration / 3600 ) % 24;
146
140
var minutes = parseInt( duration / 60 ) % 60;
147
141
var seconds = duration % 60;
148
-
149
142
var tooltip = '<div class="timeline-tooltip"><span>' +
150
143
dataTable.getValue(i, 1).split(",").join("<br />") + '</span></div><div class="timeline-tooltip"><span>' +
151
144
dataTable.getValue(i, 0) + '</span>: ' +
152
145
dateFormat.formatValue(dataTable.getValue(i, 4)) + ' - ' +
153
146
dateFormat.formatValue(dataTable.getValue(i, 5)) + '</div>' +
154
147
'<div class="timeline-tooltip"><span>Duration: </span>' +
155
148
hours + 'h ' + minutes + 'm ' + seconds + 's ';
156
-
157
149
dataTable.setValue(i, 2, tooltip);
158
150
}
159
-
160
151
var options = {
161
152
timeline: {
162
153
rowLabelStyle: { },
163
154
barLabelStyle: { },
164
155
},
165
156
hAxis: {
166
157
format: 'dd/MM HH:mm',
167
-
168
158
},
169
159
}
170
-
171
160
// Autosize chart. It would not be enough to just count rows and expand based on row height as there can be overlappig rows.
172
161
// this will draw the chart, get the size of the underlying div and apply that size to the parent container and redraw:
173
162
chart.draw(dataTable, options);
@@ -177,7 +166,6 @@ Function ConvertTo-DbaTimeline {
177
166
options.height=realheight
178
167
// draw again:
179
168
chart.draw(dataTable, options);
180
-
181
169
}
182
170
</script>
183
171
</head>
@@ -196,7 +184,3 @@ Function ConvertTo-DbaTimeline {
196
184
"@
197
185
}
198
186
}
199
-
200
- # execution
201
- # Get-DbaAgentJobHistory -SqlInstance sql-1 -StartDate ‘2018年08月13日 00:00’ -EndDate ‘2018年08月13日 23:59’ -NoJobSteps | ConvertTo-DbaTimeline | Out-File C:\temp\DbaAgentJobHistory.html -Encoding ASCII
202
- # Get-DbaBackupHistory -SqlInstance sql-1 -Since ‘2018年08月13日 00:00’ | ConvertTo-DbaTimeline | Out-File C:\temp\DbaBackupHistory.html -Encoding ASCII
0 commit comments