Dashboards & Visualizations

How to AutoRefresh dashboards only through Javascript

Communicator

I'm trying to set the auto refresh functionality in one of my dashboards trough pure Javascript. In the middle of searching how Splunk does this, I converted my dashboard to Html with and withouth the refresh property in the form element. I noticied the only visible change in both Html's was that the one with the refresh property had one extra line of code named setTimeout('location.reload();', seconds x 1000). I added this line to my JS, but it refreshed me the whole page instead of only the panels like the refresh property does. Anyone know if what I'm trying to do is achievable ?

This is how I was doing it

$('#AutoRefresh').click(function(){
        if($(this).is(':checked')){
            var seconds = 15;
            setTimeout('location.reload();', seconds * 1000);
        }else{
            clearTimeout();
        }
    });
0 Karma
1 Solution

Communicator

So the good news is I came up with an answer for a AutoRefresh timer purely through JavaScript which was my goal with this post, and the bad news is that I haven't gotten a clue of how Splunk code does it.

So with the major help of @niketnilay ♦ I came up with this code that gathers all the searches you have in your SimpleXML being the a PostProcess or a Search:

var intervalId;
$('#AutoRefresh').click(function(){
        if($(this).is(':checked')){
            var seconds = 15;
            intervalId = setInterval(refreshSearches, seconds * 1000);
        }else{
            clearInterval(intervalId);
        }
    });

var searches = getAllSearches();

function getAllSearches(){
        // Find both base and regular searches
        var searches = [];
        var componentsAttributes = mvc.Components._previousAttributes; 
        for(var key in componentsAttributes){
            if(componentsAttributes.hasOwnProperty(key)){
                var attr = componentsAttributes[key];
                if(attr instanceof SearchManager){
                    searches.push(attr.id);
                }
                if(attr instanceof PostProcessManager){
                    searches.push(attr.id);
                }
            }
        }
        return searches;
    }

function refreshSearches(){
        for(var i = 0; i < searches.length; ++i){
            mvc.Components.get(searches[i]).startSearch();
        }
    }

View solution in original post

Communicator

So the good news is I came up with an answer for a AutoRefresh timer purely through JavaScript which was my goal with this post, and the bad news is that I haven't gotten a clue of how Splunk code does it.

So with the major help of @niketnilay ♦ I came up with this code that gathers all the searches you have in your SimpleXML being the a PostProcess or a Search:

var intervalId;
$('#AutoRefresh').click(function(){
        if($(this).is(':checked')){
            var seconds = 15;
            intervalId = setInterval(refreshSearches, seconds * 1000);
        }else{
            clearInterval(intervalId);
        }
    });

var searches = getAllSearches();

function getAllSearches(){
        // Find both base and regular searches
        var searches = [];
        var componentsAttributes = mvc.Components._previousAttributes; 
        for(var key in componentsAttributes){
            if(componentsAttributes.hasOwnProperty(key)){
                var attr = componentsAttributes[key];
                if(attr instanceof SearchManager){
                    searches.push(attr.id);
                }
                if(attr instanceof PostProcessManager){
                    searches.push(attr.id);
                }
            }
        }
        return searches;
    }

function refreshSearches(){
        for(var i = 0; i < searches.length; ++i){
            mvc.Components.get(searches[i]).startSearch();
        }
    }

View solution in original post

SplunkTrust
SplunkTrust

@greggz thanks for posting this. Now I have learnt how to find Splunk component 🙂

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

Communicator

@niketnilay ♦ My pleasure! Btw you migth not need to get the PostProcessManagers, cause I think when you start the Parent Search , the children searches will automattically start aswell. All the best 😉

0 Karma

SplunkTrust
SplunkTrust

@greggz, one Question is #Autorefresh a Splunk Input created via Splunk JS Stack or HTML input forced through jQuery? Since you want this JS script to be independent of the Dashboard, I just wanted to confirm?

You can use startSearch() method for selected Search Manager to forcefully start a search based on button click using JavaScript and SplunkJS Stack.

http://docs.splunk.com/DocumentationStatic/WebFramework/1.0/compref_searchmanager.html
http://docs.splunk.com/DocumentationStatic/WebFramework/1.0/compref_searchbar.html

Can you try adding the following code to your HTML to see? Following assumes, you have not created your own Search IDs (or else you will need to add them manually i.e. for example in post-processing). By default Splunk assigns search ids in incremental order i.e. search1, search2, search3... I am trying to run the loop 10 times but it will exit the moment a search ID is not found.

I am trying to use this because I do not know if there is a built in mvc.Components function to get all Search IDs from Search Managers in a Dashboard using Splunk JS Stack. @rjthibod, @jeffland are you aware of any such Splunk JS stack function?

    $('#Autorefresh').on("click",function(){
        for(i=1;i<10;i++)
        {
            var search=mvc.Components.get("search"+i);
            if(search===undefined){
                break;
            }   
            else{
                    search.startSearch();
            }
        }
    });

alt text

Following is run anywhere code for Simple XML dashboard with JavaScript Extension:

Simple XML Dashboard

<form script="autorefresh_panels.js">
  <label>Refresh Panel JavaScript and startSearch</label>
  <fieldset submitButton="false">
    <input type="time" token="tokTime" searchWhenChanged="true">
      <label></label>
      <default>
        <earliest>-60m@m</earliest>
        <latest>now</latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <title>Splunk Log Levels</title>
      <html>
        <a id="Autorefresh" class="btn">Refresh &#8635;</a>
      </html>
      <chart>
        <search>
          <query>index=_internal sourcetype=splunkd log_level=*
| timechart count by log_level
| table _time INFO WARN ERROR
| fields - dummy</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
        <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
        <option name="charting.axisTitleX.visibility">visible</option>
        <option name="charting.axisTitleY.visibility">visible</option>
        <option name="charting.axisTitleY2.visibility">visible</option>
        <option name="charting.axisX.abbreviation">none</option>
        <option name="charting.axisX.scale">linear</option>
        <option name="charting.axisY.abbreviation">none</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.axisY2.abbreviation">none</option>
        <option name="charting.axisY2.enabled">1</option>
        <option name="charting.axisY2.scale">inherit</option>
        <option name="charting.chart">column</option>
        <option name="charting.chart.bubbleMaximumSize">50</option>
        <option name="charting.chart.bubbleMinimumSize">10</option>
        <option name="charting.chart.bubbleSizeBy">area</option>
        <option name="charting.chart.nullValueMode">gaps</option>
        <option name="charting.chart.overlayFields">INFO</option>
        <option name="charting.chart.showDataLabels">none</option>
        <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
        <option name="charting.chart.stackMode">stacked</option>
        <option name="charting.chart.style">shiny</option>
        <option name="charting.drilldown">none</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
        <option name="charting.legend.mode">standard</option>
        <option name="charting.legend.placement">bottom</option>
        <option name="charting.lineWidth">2</option>
        <option name="refresh.display">progressbar</option>
        <option name="trellis.enabled">0</option>
        <option name="trellis.scales.shared">1</option>
        <option name="trellis.size">medium</option>
      </chart>
    </panel>
  </row>
  <row>
    <panel>
      <title>Splunk Components</title>
      <chart>
        <search>
          <query>index=_internal sourcetype=splunkd log_level=*
| timechart count by component useother=f usenull=f limit=10</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
        <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
        <option name="charting.axisTitleX.visibility">visible</option>
        <option name="charting.axisTitleY.visibility">visible</option>
        <option name="charting.axisTitleY2.visibility">visible</option>
        <option name="charting.axisX.abbreviation">none</option>
        <option name="charting.axisX.scale">linear</option>
        <option name="charting.axisY.abbreviation">none</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.axisY2.abbreviation">none</option>
        <option name="charting.axisY2.enabled">1</option>
        <option name="charting.axisY2.scale">inherit</option>
        <option name="charting.chart">column</option>
        <option name="charting.chart.bubbleMaximumSize">50</option>
        <option name="charting.chart.bubbleMinimumSize">10</option>
        <option name="charting.chart.bubbleSizeBy">area</option>
        <option name="charting.chart.nullValueMode">gaps</option>
        <option name="charting.chart.overlayFields">Metrics</option>
        <option name="charting.chart.showDataLabels">none</option>
        <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
        <option name="charting.chart.stackMode">stacked</option>
        <option name="charting.chart.style">shiny</option>
        <option name="charting.drilldown">none</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
        <option name="charting.legend.mode">standard</option>
        <option name="charting.legend.placement">bottom</option>
        <option name="charting.lineWidth">2</option>
        <option name="refresh.display">progressbar</option>
        <option name="trellis.enabled">0</option>
        <option name="trellis.scales.shared">1</option>
        <option name="trellis.size">medium</option>
      </chart>
    </panel>
  </row>
</form>

JavaScript file - autorefresh_panels.js
This file needs to be placed under the Splunk App's static folder which is typically: $SPLUNK_HOME$/etc/apps/<YourAppName>/appserver/static
Also, adding static file implies, for the changes to reflect, Splunk needs to be restarted/refreshed/bumped and also browser history may need to be cleaned up.

require([
    "splunkjs/mvc",
    "jquery",
    "splunkjs/mvc/searchmanager",
    "splunkjs/mvc/simplexml/ready!"
], function(
            mvc,
            $
            ){
        $('#Autorefresh').on("click",function(){
            for(i=1;i<10;i++)
            {
                var search=mvc.Components.get("search"+i);
                if(search===undefined){
                    break;
                }   
                else{
                        search.startSearch();
                }
            }
        });
});
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

Communicator

@niketnilay ♦ Thank you again for your replies! Regarding your first question, I'm forcing it via Html and reference it with Jquery, but I think that won't be a problem with this implementation. This seems to be able to work indeed, but this is a single refresh. To mimic the Auto refresh, I guess I should add the

setInterval( search.startSearch() , numberOfSeconds);

But yes I think this is the way! I'll mark it as the right answer as soon as I'll be able to test it.

0 Karma

SplunkTrust
SplunkTrust

@greggz, I purposely made it single time refresh, because in your post you had created it for click event. So, I assumed you want Panels to be refreshed each time a button is clicked. Thanks for your explanation that it was only for your testing 🙂

Try with setTimeout()and confirm! All the best!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

SplunkTrust
SplunkTrust

@greggz, I think the reason is with JavaScript function location.reload() which is forcing a POST rather than receiving dashboard from cache.

Since you want only panel searches to re-run not the entire dashboard, you will either have to use Splunk JS Stack to set the refresh attribute for all Search Managers.

But looking at your code seems like you want refresh to execute on click of a button. Can you try the following run anywhere Simple XML dashboard based on Splunk's _internal index.

This dashboard initializes a dummy token forceRefreshPanel in the <init> section (for page load. PS: It will not work with HTML dashboard)

Then I have included it in all searches as token as dummy value | eval dummy="$forceRefreshPanel$" | fields - dummy

There is a Checkbox which unset's the dummy token to reset search query and then sets is back for query to complete. You can use HTML Panel to add button to do this and implement token set/unset in JavaScript for neat solution. I have kept it Simple XML for demo/clarification 🙂

alt text

<form>
  <label>Refresh Panel</label>
  <init>
    <set token="forceRefreshPanel">true</set>
  </init>
  <fieldset submitButton="false">
    <input type="time" token="tokTime" searchWhenChanged="true">
      <label></label>
      <default>
        <earliest>-60m@m</earliest>
        <latest>now</latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <title>Splunk Log Levels</title>
      <input type="checkbox" token="tokRefresh" id="refreshCheck">
        <label></label>
        <choice value="refresh">Refresh</choice>
        <change>
          <condition value="refresh">
            <unset token="forceRefreshPanel"></unset>
            <unset token="form.tokRefresh"></unset>
            <set token="forceRefreshPanel">true</set>
          </condition>
        </change>
      </input>
      <chart>
        <search>
          <query>index=_internal sourcetype=splunkd log_level=*
| timechart count by log_level
| table _time INFO WARN ERROR
| eval dummy="$forceRefreshPanel$"
| fields - dummy</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
        <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
        <option name="charting.axisTitleX.visibility">visible</option>
        <option name="charting.axisTitleY.visibility">visible</option>
        <option name="charting.axisTitleY2.visibility">visible</option>
        <option name="charting.axisX.abbreviation">none</option>
        <option name="charting.axisX.scale">linear</option>
        <option name="charting.axisY.abbreviation">none</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.axisY2.abbreviation">none</option>
        <option name="charting.axisY2.enabled">1</option>
        <option name="charting.axisY2.scale">inherit</option>
        <option name="charting.chart">column</option>
        <option name="charting.chart.bubbleMaximumSize">50</option>
        <option name="charting.chart.bubbleMinimumSize">10</option>
        <option name="charting.chart.bubbleSizeBy">area</option>
        <option name="charting.chart.nullValueMode">gaps</option>
        <option name="charting.chart.overlayFields">INFO</option>
        <option name="charting.chart.showDataLabels">none</option>
        <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
        <option name="charting.chart.stackMode">stacked</option>
        <option name="charting.chart.style">shiny</option>
        <option name="charting.drilldown">none</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
        <option name="charting.legend.mode">standard</option>
        <option name="charting.legend.placement">bottom</option>
        <option name="charting.lineWidth">2</option>
        <option name="refresh.display">progressbar</option>
        <option name="trellis.enabled">0</option>
        <option name="trellis.scales.shared">1</option>
        <option name="trellis.size">medium</option>
      </chart>
    </panel>
  </row>
  <row>
    <panel>
      <title>Splunk Components</title>
      <chart>
        <search>
          <query>index=_internal sourcetype=splunkd log_level=*
| timechart count by component useother=f usenull=f limit=10
| eval dummy="$forceRefreshPanel$"
| fields - dummy</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
        <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
        <option name="charting.axisTitleX.visibility">visible</option>
        <option name="charting.axisTitleY.visibility">visible</option>
        <option name="charting.axisTitleY2.visibility">visible</option>
        <option name="charting.axisX.abbreviation">none</option>
        <option name="charting.axisX.scale">linear</option>
        <option name="charting.axisY.abbreviation">none</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.axisY2.abbreviation">none</option>
        <option name="charting.axisY2.enabled">1</option>
        <option name="charting.axisY2.scale">inherit</option>
        <option name="charting.chart">column</option>
        <option name="charting.chart.bubbleMaximumSize">50</option>
        <option name="charting.chart.bubbleMinimumSize">10</option>
        <option name="charting.chart.bubbleSizeBy">area</option>
        <option name="charting.chart.nullValueMode">gaps</option>
        <option name="charting.chart.overlayFields">Metrics</option>
        <option name="charting.chart.showDataLabels">none</option>
        <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
        <option name="charting.chart.stackMode">stacked</option>
        <option name="charting.chart.style">shiny</option>
        <option name="charting.drilldown">none</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
        <option name="charting.legend.mode">standard</option>
        <option name="charting.legend.placement">bottom</option>
        <option name="charting.lineWidth">2</option>
        <option name="refresh.display">progressbar</option>
        <option name="trellis.enabled">0</option>
        <option name="trellis.scales.shared">1</option>
        <option name="trellis.size">medium</option>
      </chart>
    </panel>
  </row>
</form>

Please try out and confirm.

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

Communicator

@niketnilay ♦ Thank you for taking time to answer me!! but I don't think this solution is pratical enough for my case. My case scenario is one which I can't modify the simpleXML. We want to be able to include a .Js file in a set of dashboards, therefore our solution must be generic to be able to run in every dashboard. I can't go around and change the query's by adding the eval dummy = $refresh$ option. Can't I just run trough every SearchManager in the dashboard and add them the "refresh" property ? I'm trying to find any docs on it but I've had no success.

0 Karma

SplunkTrust
SplunkTrust

@greggz, What you are looking at is form or dashboard refresh which refreshes the entire dashboard.

If you want to refresh just a single panel, you will have to set <refresh> option for the search powering the respective panel

Following is a run anywhere search example in Simple XML with 1 minute refresh <refresh>1m</refresh>:

        <search>
          <query>index=_internal sourcetype=splunkd log_level=*
| timechart count by log_level
| table _time INFO WARN ERROR
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
          <refresh>1m</refresh>
          <refreshType>delay</refreshType>
        </search>

Following is corresponding HTML code with "refresh": "1m"

var search1 = new SearchManager({
            "id": "search1",
            "refresh": "1m",
            "earliest_time": "-24h@h",
            "sample_ratio": 1,
            "status_buckets": 0,
            "cancelOnUnload": true,
            "refreshType": "delay",
            "latest_time": "now",
            "search": "index=_internal sourcetype=splunkd log_level=* | timechart count by log_level | table _time INFO WARN ERROR",
            "app": utils.getCurrentApp(),
            "auto_cancel": 90,
            "preview": true,
            "tokenDependencies": {
            },
            "runWhenTimeIsUndefined": false
        }, {tokens: true, tokenNamespace: "submitted"});
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

Communicator

Thanks for your answer, so for me to make this work in Javascript, I would need to iterate trough every SearchManager in the dashboard and add them a refresh option ?

0 Karma

SplunkTrust
SplunkTrust

If you want to refresh all your Panels then your previous solution of entire dashboard refresh would be better. Could you please confirm whether you want individual panel or all?

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

Communicator

@niketnilay ♦ How to prevent the page from reloading ? Splunk prop "refresh" in only refreshes the searches, it does not reload the entire page

0 Karma

Communicator

I want all to be refreshed. My first solution was reloading the entire page, like a normal refresh would. Splunk's refresh by some magic only refreshes the panels.

0 Karma