All Apps and Add-ons

$results[0].xxx$ in HTML module

Path Finder

Hi nick,

I am kurt. Sorry to bother you, but can I you ask a question?

I want to get a time spot(an beginning time of a time span) when users click in a chart and show it on a panel.

It works on Splunk 4.2 but not on Splunk 4.3 when doing the following :

  1. using a Search module to slice $click.timeRange$ from an upstream module.

    a. The search I run is : " index=_internal | head 1 | eval timeToken = split("$click.timeRange$", " ") | eval clickTime = mvindex(timeToken,0 ,4) | eval clickTime = mvjoin(clickTime, " ") | table clickTime

    b. The value of $click.timeRange$ is : Wed Jan 25 2012 15:15:00 GMT+0800 (台北標準時間) Wed Jan 25 2012 15:30:00 GMT+0800 (台北標準時間) 1327475700 1327476600

    c. After the search I get a value of Wed Jan 25 2012 15:15:00 for clickTime

  2. making the Search module followed by a HTML module, and using $results[0].clickTime$ to show

    up on a panel.

Is there anything I do wrong in 4.3 or something changed I don't realize between Splunk 4.2 and Splunk 4.3?

Any help or suggestoin will be very appreciate.

PS : the following is a part of my dashboard to get the time spot :

<module name="Search" autoRun="true" layoutPanel="panelrow2col1">

  <param name="search">index=_internal | head 1 | eval timeToken = split("$click.timeRange$", " ") | eval clickTime = mvindex(timeToken,0 ,4) | eval clickTime = mvjoin(clickTime, " ") | table clickTime </param>

  <module name="HTML">

    <param name="html"><![CDATA[

click time : $results[0].clickTime$

    ]]>
</param>

  </module>
</module>

1 Solution

SplunkTrust
SplunkTrust

OK. You deserve some credit for figuring out this solution, but it's got some problems with it. I don't think anything changed here from 4.2 to 4.3, but I can tell you the main problem.

From your description I gather you have XML like this:

<module name="TimeRangePicker" layoutPanel="panel_row1_col1" autoRun="True">
  <param name="default">last 4 hours</param>
  <module name="Search">
    <param name="search">* | timechart count</param>
    <module name="Pager">
      <module name="SimpleResultsTable">
        <param name="drilldown">row</param>
        <module name="Search">
          <param name="search"> index=_internal | head 1 | eval timeToken = split("$click.timeRange$", " ") | eval clickTime = mvindex(timeToken,0 ,4) | eval clickTimeJoined = mvjoin(clickTime, " ")</param>
          <module name="HTML">
            <param name="html"><![CDATA[
            <b>search:</b><br>
            $search$<br>
            <br>
            <b>clickTime:</b> $results[0].clickTime$
            ]]></param>
          </module>
        </module>
      </module>
    </module>
  </module>
</module>

You're using

index=_internal | head 1 to generate a reliable search result set, with a single row. However, the drilldown click on a timechart table or chart will always use the timerange of the clicked-on-row. So you might not have any internal data right at that second. Furthermore, the user might not be an admin user, and might not have full access to the _internal events, or might not have any access to _internal. Or you might have cleaned the server and reindexed after this "time" value.

In any case, what happens often is your index=_internal search will return zero events for many or most timeranges. So the whole search folds up and you'll get nothing.

The simplest change to get you going again, is to replace your index=internal | head 1, with | stats count. It looks bizarre, but all | stats count does is count the number of rows coming in from the left, and output a single row, with a single field "count". So when | stats count starts off an expression, you start off with a single row, with a "count" field, and the value of "count" is of course "0". | stats count will always output that single row, so you avoid this problem where the whole row dissappears.

However you have another source of complexity here too - you're also doing a lot of work getting the very messy $click.timeRange$ key, and then carving it up with mv expressions. $click.timeRange$ is actually a reference designed for use by internal JS code, and it's actually an object. The fact that it has this big "toString" expansion is more of a side effect. Easier than doing all this work, is to just use an addinfo command after the | stats count. See below:

<module name="TimeRangePicker" layoutPanel="panel_row2_col1" autoRun="True">
  <param name="default">last 4 hours</param>
  <module name="Search">
    <param name="search">* | timechart count</param>
    <module name="Pager">
      <module name="SimpleResultsTable">
        <param name="drilldown">row</param>
        <module name="Search">
          <param name="search">| stats count | addinfo | table info_min_time | convert ctime(info_min_time)</param>
          <module name="HTML">
            <param name="html"><![CDATA[
            <b>search:</b><br>
            $search$<br>
            <br>
            <b>clickTime:</b> $results[0].info_min_time$
            ]]></param>
          </module>
        </module>
      </module>
    </module>
  </module>
</module>

Last but not least, you might go back and look at why you're displaying this time to the user, and you might get better use out of $click.timeRange.label$. $click.timeRange.label$ will output keys like "September 2011", and "from 5:20 AM to 5:25 AM on Thursday, February 16, 2012".

XML that does that is shown below:

<module name="TimeRangePicker" layoutPanel="panel_row4_col1" autoRun="True">
  <param name="default">last 4 hours</param>
  <module name="Search">
    <param name="search">* | timechart count</param>
    <module name="Pager">
      <module name="SimpleResultsTable">
        <param name="drilldown">row</param>
        <module name="HTML">
          <param name="html"><![CDATA[
          <b>natural language description of the timerange:</b> $search.timeRange.label$<br>
          <br>
          <b>earliest side of the timerange:</b>- $search.timeRange.earliest$
          ]]></param>
        </module>
      </module>
    </module>
  </module>

</module>

View solution in original post

SplunkTrust
SplunkTrust

OK. You deserve some credit for figuring out this solution, but it's got some problems with it. I don't think anything changed here from 4.2 to 4.3, but I can tell you the main problem.

From your description I gather you have XML like this:

<module name="TimeRangePicker" layoutPanel="panel_row1_col1" autoRun="True">
  <param name="default">last 4 hours</param>
  <module name="Search">
    <param name="search">* | timechart count</param>
    <module name="Pager">
      <module name="SimpleResultsTable">
        <param name="drilldown">row</param>
        <module name="Search">
          <param name="search"> index=_internal | head 1 | eval timeToken = split("$click.timeRange$", " ") | eval clickTime = mvindex(timeToken,0 ,4) | eval clickTimeJoined = mvjoin(clickTime, " ")</param>
          <module name="HTML">
            <param name="html"><![CDATA[
            <b>search:</b><br>
            $search$<br>
            <br>
            <b>clickTime:</b> $results[0].clickTime$
            ]]></param>
          </module>
        </module>
      </module>
    </module>
  </module>
</module>

You're using

index=_internal | head 1 to generate a reliable search result set, with a single row. However, the drilldown click on a timechart table or chart will always use the timerange of the clicked-on-row. So you might not have any internal data right at that second. Furthermore, the user might not be an admin user, and might not have full access to the _internal events, or might not have any access to _internal. Or you might have cleaned the server and reindexed after this "time" value.

In any case, what happens often is your index=_internal search will return zero events for many or most timeranges. So the whole search folds up and you'll get nothing.

The simplest change to get you going again, is to replace your index=internal | head 1, with | stats count. It looks bizarre, but all | stats count does is count the number of rows coming in from the left, and output a single row, with a single field "count". So when | stats count starts off an expression, you start off with a single row, with a "count" field, and the value of "count" is of course "0". | stats count will always output that single row, so you avoid this problem where the whole row dissappears.

However you have another source of complexity here too - you're also doing a lot of work getting the very messy $click.timeRange$ key, and then carving it up with mv expressions. $click.timeRange$ is actually a reference designed for use by internal JS code, and it's actually an object. The fact that it has this big "toString" expansion is more of a side effect. Easier than doing all this work, is to just use an addinfo command after the | stats count. See below:

<module name="TimeRangePicker" layoutPanel="panel_row2_col1" autoRun="True">
  <param name="default">last 4 hours</param>
  <module name="Search">
    <param name="search">* | timechart count</param>
    <module name="Pager">
      <module name="SimpleResultsTable">
        <param name="drilldown">row</param>
        <module name="Search">
          <param name="search">| stats count | addinfo | table info_min_time | convert ctime(info_min_time)</param>
          <module name="HTML">
            <param name="html"><![CDATA[
            <b>search:</b><br>
            $search$<br>
            <br>
            <b>clickTime:</b> $results[0].info_min_time$
            ]]></param>
          </module>
        </module>
      </module>
    </module>
  </module>
</module>

Last but not least, you might go back and look at why you're displaying this time to the user, and you might get better use out of $click.timeRange.label$. $click.timeRange.label$ will output keys like "September 2011", and "from 5:20 AM to 5:25 AM on Thursday, February 16, 2012".

XML that does that is shown below:

<module name="TimeRangePicker" layoutPanel="panel_row4_col1" autoRun="True">
  <param name="default">last 4 hours</param>
  <module name="Search">
    <param name="search">* | timechart count</param>
    <module name="Pager">
      <module name="SimpleResultsTable">
        <param name="drilldown">row</param>
        <module name="HTML">
          <param name="html"><![CDATA[
          <b>natural language description of the timerange:</b> $search.timeRange.label$<br>
          <br>
          <b>earliest side of the timerange:</b>- $search.timeRange.earliest$
          ]]></param>
        </module>
      </module>
    </module>
  </module>

</module>

View solution in original post

Path Finder

Thanks for your reply, nick!

I have to say that you're very cool.

There is indeed a TimeRanger module in the most upside.

You remind me that when doing drilldown, it passes a time range to the downstream module and there is no data in that time range. Now I know why I can get it working on Splunk 4.2(with data including internal ones) but not in Splunk4.3(a new installation with just some test log).

I learn a lot from the above post and I have my dashboard work.

By the way, displaying the time is an information of time range for a drilldown panel.

Thanks, nick!