Splunk Search

How can I integrate the time constraint from my time input token in JavaScript for a table with expandable rows?

sebdamaye
New Member

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.

0 Karma

sebdamaye
New Member

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());
    });

});
0 Karma

sundareshr
Legend

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
0 Karma

sebdamaye
New Member

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....

0 Karma

sebdamaye
New Member

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());
    });
});
0 Karma

sundareshr
Legend

You need to define the TimeRangePicker object. Just like you did for the tableView object. So add this var TimeRangePicker=mvc.Components.getInstance("TimeRangePicker"); , beforevar t=TimeRangePicker.val();`

0 Karma

sebdamaye
New Member

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

0 Karma

sebdamaye
New Member

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$"
0 Karma
Get Updates on the Splunk Community!

Splunk Forwarders and Forced Time Based Load Balancing

Splunk customers use universal forwarders to collect and send data to Splunk. A universal forwarder can send ...

NEW! Log Views in Splunk Observability Dashboards Gives Context From a Single Page

Today, Splunk Observability releases log views, a new feature for users to add their logs data from Splunk Log ...

Last Chance to Submit Your Paper For BSides Splunk - Deadline is August 12th!

Hello everyone! Don't wait to submit - The deadline is August 12th! We have truly missed the community so ...