Hi,
I have created a table with expandable rows:
Code for the table:
<form script="expand_alerts.js">
<label>SIEM</label>
<fieldset submitButton="false" autoRun="false">
<input type="time" token="TimeRangePicker" searchWhenChanged="true">
<label>TimeRange</label>
<default>
<earliest>@d</earliest>
<latest>now</latest>
</default>
</input>
</fieldset>
<row>
<panel>
<table id="expand_with_events">
<title>Alerts</title>
<search>
<query>source="*suricata*" | stats distinct_count(src_ip) AS src_ip distinct_count(dest_ip) AS dest_ip sparkline count by alert.signature_id alert.signature alert.category | sort -count | table alert.signature_id alert.signature alert.category count src_ip dest_ip sparkline</query>
<earliest>$TimeRangePicker.earliest$</earliest>
<latest>$TimeRangePicker.latest$</latest>
</search>
<option name="wrap">true</option>
<option name="rowNumbers">false</option>
<option name="drilldown">cell</option>
<option name="dataOverlayMode">none</option>
<option name="count">10</option>
</table>
</panel>
</row>
</form>
When expanded, it shows related events using EventsViewer
, as follows:
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/eventsviewerview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
EventsViewer,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
preview: false
});
this._eventsViewer = new EventsViewer({
managerid: 'details-search-manager'
});
},
canRender: function(rowData) {
// Since more than one row expansion renderer can be registered we let each decide if they can handle that
// data
// Here we will always handle it.
return true;
},
render: function($container, rowData) {
// rowData contains information about the row that is expanded. We can see the cells, fields, and values
// We will find the sourcetype cell to use its value
var alertSignatureIdCell = _(rowData.cells).find(function (cell) {
return cell.field === 'alert.signature_id';
});
//update the search with the sourcetype that we are interested in
this._searchManager.set({ search: 'source="*suricata*" event_type="alert" alert.signature_id=' + alertSignatureIdCell.value });
// $container is the jquery object where we can put out content.
// In this case we will render our chart and add it to the $container
$container.append(this._eventsViewer.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
As you can see, the table depends on a time input (token TimeRangePicker
) that I am also trying to integrate in the javascript. I have already tried to write something like this:
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/eventsviewerview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
EventsViewer,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
preview: false
});
this._eventsViewer = new EventsViewer({
managerid: 'details-search-manager'
});
},
canRender: function(rowData) {
// Since more than one row expansion renderer can be registered we let each decide if they can handle that
// data
// Here we will always handle it.
return true;
},
render: function($container, rowData) {
// rowData contains information about the row that is expanded. We can see the cells, fields, and values
// We will find the sourcetype cell to use its value
var alertSignatureIdCell = _(rowData.cells).find(function (cell) {
return cell.field === 'alert.signature_id';
});
//update the search with the sourcetype that we are interested in
this._searchManager.set({
search: 'source="*suricata*" event_type="alert" alert.signature_id=' + alertSignatureIdCell.value,
earliest_time: $TimeRangePicker.earliest$,
latest_time: $TimeRangePicker.latest$
});
// $container is the jquery object where we can put out content.
// In this case we will render our chart and add it to the $container
$container.append(this._eventsViewer.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
But now, rows don't expand and the web console says $TimeRangePicker
is not defined.
How can I integrate the time constraint from my time input in the javascript?
Thank you in advance for your help.
I HAVE DONE IT!!! After 2 days of struggling with JavaScript debugging, I've finally found the solution. Here is how I did: I converted my dashboard from XML to HTML and analyzed how the search was impacted by the time picker. I noticed that the earliest_time
and latest_time
fields were actually fed with $form.TimeRangePicker.earliest$
and $form.TimeRangePicker.latest
with tokens
set to true
. Below is my final code:
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/eventsviewerview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'
],function(
TableView,
EventsViewer,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
preview: false
});
this._eventsViewer = new EventsViewer({
managerid: 'details-search-manager'
});
},
canRender: function(rowData) {
// Since more than one row expansion renderer can be registered we let each decide if
// they can handle that data
// Here we will always handle it.
return true;
},
render: function($container, rowData) {
// rowData contains information about the row that is expanded. We can see the cells, fields, and values
// We will find the sourcetype cell to use its value
var alertSignatureIdCell = _(rowData.cells).find(function (cell) {
return cell.field === 'alert.signature_id';
});
//update the search with the sourcetype that we are interested in
this._searchManager.set({
earliest_time: "$form.TimeRangePicker.earliest$",
latest_time: "$form.TimeRangePicker.latest$",
search: 'source="*suricata*" event_type="alert" alert.signature_id=' + alertSignatureIdCell.value
}, {tokens: true});
// $container is the jquery object where we can put out content.
// In this case we will render our chart and add it to the $container
$container.append(this._eventsViewer.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
You could try this instead
var t=TimeRangePicker.val();
var te=t.earliest_time;
var tl=t.latest_time;
earliest_time: te
latest_time: tl
Looks like I'm missing something here... 😞
I've tried the following code with tokenSafe
. It does not produce any error but does not filter on time selected from the TimeRangePicker
input.
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/eventsviewerview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'
],function(
TableView,
EventsViewer,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
preview: false
});
this._eventsViewer = new EventsViewer({
managerid: 'details-search-manager'
});
},
canRender: function(rowData) {
// Since more than one row expansion renderer can be registered we let each decide if they can handle that
// data
// Here we will always handle it.
return true;
},
render: function($container, rowData) {
// rowData contains information about the row that is expanded. We can see the cells, fields, and values
// We will find the sourcetype cell to use its value
var alertSignatureIdCell = _(rowData.cells).find(function (cell) {
return cell.field === 'alert.signature_id';
});
//update the search with the sourcetype that we are interested in
this._searchManager.set({
search: 'source="*suricata*" event_type="alert" alert.signature_id=' + alertSignatureIdCell.value,
earliest_time: mvc.tokenSafe('$TimeRangePicker.earliest_time$'),
latest_time: mvc.tokenSafe('$TimeRangePicker.latest_time$')
});
// $container is the jquery object where we can put out content.
// In this case we will render our chart and add it to the $container
$container.append(this._eventsViewer.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
Help....
Thank you for helping @sundareshr. I have tried as follows but it now claims TimeRangePicker is not defined. Maybe I haven't placed your code at the appropriate place?
require([
'splunkjs/mvc/tableview',
'splunkjs/mvc/eventsviewerview',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc',
'underscore',
'splunkjs/mvc/simplexml/ready!'],function(
TableView,
EventsViewer,
SearchManager,
mvc,
_
){
var EventSearchBasedRowExpansionRenderer = TableView.BaseRowExpansionRenderer.extend({
initialize: function(args) {
// initialize will run once, so we will set up a search and a chart to be reused.
this._searchManager = new SearchManager({
id: 'details-search-manager',
preview: false
});
this._eventsViewer = new EventsViewer({
managerid: 'details-search-manager'
});
},
canRender: function(rowData) {
// Since more than one row expansion renderer can be registered we let each decide if they can handle that
// data
// Here we will always handle it.
return true;
},
render: function($container, rowData) {
// rowData contains information about the row that is expanded. We can see the cells, fields, and values
// We will find the sourcetype cell to use its value
var alertSignatureIdCell = _(rowData.cells).find(function (cell) {
return cell.field === 'alert.signature_id';
});
//update the search with the sourcetype that we are interested in
var t=TimeRangePicker.val();
var te=t.earliest_time;
var tl=t.latest_time;
this._searchManager.set({
search: 'source="*suricata*" event_type="alert" alert.signature_id=' + alertSignatureIdCell.value,
earliest_time: te,
latest_time: tl
});
// $container is the jquery object where we can put out content.
// In this case we will render our chart and add it to the $container
$container.append(this._eventsViewer.render().el);
}
});
var tableElement = mvc.Components.getInstance("expand_with_events");
tableElement.getVisualization(function(tableView) {
// Add custom cell renderer, the table will re-render automatically.
tableView.addRowExpansionRenderer(new EventSearchBasedRowExpansionRenderer());
});
});
You need to define the TimeRangePicker
object. Just like you did for the tableView
object. So add this var TimeRangePicker=mvc.Components.getInstance("TimeRangePicker"); , before
var t=TimeRangePicker.val();`
Very weird.... wherever I add var TimeRangePicker=mvc.Components.getInstance("TimeRangePicker");
it says that TimeRangePicker is undefined. I also tried to use PostProcessManager
as described here (http://dev.splunk.com/view/webframework-developapps/SP-CAAAEM8) to filter results based on time constraint after the search but it's not working either. It seems that the issue is actually that the javascript is not able to get the value from the TimeRangePicker
token. However my input has the correct token name. Now trying to use tokenSafe
as described here: http://dev.splunk.com/view/SP-CAAAEVR
On line 40 and 41, surrounding variables with quotes removes the error but it still does not filter events with time selected from my input:
earliest_time: "$TimeRangePicker.earliest$",
latest_time: "$TimeRangePicker.latest$"