-
Notifications
You must be signed in to change notification settings - Fork 0
Logs
The Plotly Plugin for Grafana allows the user to make dynamic graphs. In this page we will explore how to make the table graph to display the logs.
severity = data.series[0].fields[2].values;
code = data.series[0].fields[0].values;
message = data.series[0].fields[1].values;
subsystem = data.series[0].fields[3].values;
ts = data.series[0].fields[4].values;
We obtain the data that grafana (and our queries provide), for example on the line
severity = data.series[0].fields[2].values;
the list named data is a reserved value, that stores all the data obtained by the data selector (our queries), then the sub-list series stores all the queries avaible on the data source, the sub-sub-list fields stores all the fields avaible on said query, finally the values stores a list with all the avaible values from the query.
allSubsystems = subsystem.filter(function (v, i, self) {
return i == self.indexOf(v);
});
timeStamp = ts.map(function (value, index){
timeFormatted = (new Date(value)).toUTCString()
return timeFormatted
});
Firstly we obtain all unique data from the subsystems for later filtering. Then we sanitize the time stamp, by returning a string value that is readable.
In order to filter, we first need something to filter and update, that is why we store a table with no filtered values. Since we want a table, we format the values as a multi-dimensional List, that we later add to the table.
var valuesAll = [code,
message,
severity,
subsystem,
timeStamp
];
var tableAll = {
type: 'table',
visible: 'true',
header: {
values: [["<b>Code</b>"], ["<b>Message</b>"],
["<b>Severity</b>"], ["<b>Subsystem</b>"], ["<b>ts</b>"]],
align: "center",
line: {width: 1, color: 'black'},
fill: {color: "grey"},
font: {family: "Arial", size: 12, color: "white"}
},
cells: {
values: valuesAll,
align: "center",
fill: {
color: [getColor(severity)]
},
line: {color: "black", width: 1},
font: {family: "Arial", size: 11, color: ["black"]}
},
}
In order to get the colors right for each row, we run the following function:
function getColor(arr)
{ var colors = arr.map(function(val, index){
var color = '';
switch(val){
case 'info':
color = 'skyblue';
break;
case 'warning':
color = 'orange';
break;
case 'error':
color = 'red';
break;
default:
color = 'white';
break;
}
return color
})
return colors
}
where the data required (arr), must be the severity column.
function getSpecificSubsystem(arr, subsystemV){
vals = arr.map(function (val, index){
if(subsystem[index].includes(subsystemV)){
return val
}
});
return vals.filter(function( element ) {
return element !== undefined;
});
}
We use the previous function to determine which rows of the complete data belong to a given subsystem.
In order to update the table we must first choose which part of the table declaration we need to update, in this case is cells, to avoid complications, we will update the entire cells dictionary. Then we apply the given subsystem(stored in subsystemV), and store all the columns on a list, to then input it on the values attribute. Finally we update the colors.
function generateData(subsystemV){
codeS = getSpecificSubsystem(code, subsystemV)
messageS = getSpecificSubsystem(message, subsystemV)
severityS = getSpecificSubsystem(severity, subsystemV)
subsystemS = getSpecificSubsystem(subsystem, subsystemV)
timeStampS = getSpecificSubsystem(timeStamp, subsystemV)
valuesS = [codeS, messageS, severityS, subsystemS, timeStampS]
cells = {
values: valuesS,
align: "center",
fill: {
color: [getColor(severityS)]
},
line: {color: "black", width: 1},
font: {family: "Arial", size: 11, color: ["black"]}
}
customdata = selected_severity
return [cells,customdata]
}
On the Plotly framework, we must declare what each button does, and how it affects the main table. So we use the following function, that returns a list of formatted buttons, that were populated according to a given array.
function getButtons(arr){
var buttons = []
for(var i = 0; i < arr.length; i++){
button = {
method: 'update',
args: [{'cells': generateData(arr[i])}],
label: arr[i]
}
buttons.push(button)
}
return buttons
}
To finish the filtering process we declare the variable updatemenus, that contains the button set, and we add it to the layout variable.
updatemenus = [ {
yanchor: 'bottom',
buttons: getButtons(allSubsystems)
},
]
layoutTable = {
updatemenus : updatemenus,
}
var data = [tableAll];
return{data: data, layout: layoutTable}
We add the rendered table to the data variable, to finally return it into the required by the plugin dictionary, along with the layout.