Dashboards & Visualizations

How to call a macro from an intention with adv. XML

jamesdon
Path Finder

I am trying to enhance the *nix app by creating an entirely collapsed list of the available graphs for a host on a single page. Then, a user can just click on the links that they want to load, decreasing the page load time and reducing clutter all at once. I am sure that I will make some of the content static later, but this is just a starting point.

To get the list of hosts, I have a daily search that looks for all of the hosts (| metadata type=hosts index=os | sort host | fields + host). I then parse the results via Perl & API and prints a .csv in my lookup dir. The final printout has columns with hosts and the names of macros to call from the *nix app, which draw pretty graphs. Each host has a complete list of the macro names, which lets me lookup the table from a SearchSelectLister and present the results in a table (also built with future customizations in mind - think dynamic lists per host or host type).

Everything works up to this point, and I am ready for a victory lap. However, my dreams are shattered by this error message - "PARSER: Applying intentions failed Error in 'SearchParser': The name '$click.value2$' is invalid. Macro and argument names may only include alphanumerics, '_' and '-'.".

I thought that this was the proper way to tackle this problem. Do I have to add another field in the .csv that contains the search string (defined by the macro) and have that variable be $click.value2$? I started down this path, but padding all of the special characters in my Perl script is taking me a bit to get straight. It would be even better if there was a way to properly use the $click.value2$ variable when calling the macro.

Any input would be greatly appreciated, I have attached my code and a screen shot for clarity.

Regards,

Jim

https://lh6.googleusercontent.com/_Zgb9nnpHAxA/TZKih8XwwWI/AAAAAAAAAZU/---jOAXmo7I/s1440/Screen%20sh...

<view template="dashboard.html">
  <label>Custom wiring the clicks</label>
  <module name="AccountBar" layoutPanel="appHeader"/>
  <module name="AppBar" layoutPanel="navigationHeader"/>
  <module name="Message" layoutPanel="messaging">
    <param name="filter">*</param>
    <param name="clearOnJobDispatch">False</param>
    <param name="maxSize">1</param>
  </module>
  <module name="TitleBar" layoutPanel="viewHeader">
    <param name="actionsMenuFilter">dashboard</param>
  </module>

  <module name="SearchSelectLister" layoutPanel="panel_row1_col1_grp1">
    <param name="label">Select host</param>
    <param name="settingToCreate">host_setting</param>
    <param name="search">| metadata type=hosts index=os | sort host</param>
    <param name="searchWhenChanged">True</param>
    <param name="selected">mrtg-2.unix.X.edu</param>
    <param name="searchFieldsToDisplay">
      <list>
        <param name="label">host</param>
        <param name="value">host</param>
      </list>
    </param>
    <module name="ConvertToIntention">
      <param name="settingToConvert">host_setting</param>
      <param name="intention">
        <param name="name">addterm</param>
        <param name="arg">
          <param name="host">$target$</param>
        </param>
        <!-- tells the addterm intention to put our term in the first search clause no matter what. -->
        <param name="flags"><list>indexed</list></param>
      </param>

      <module name="GenericHeader">
        <param name="label">Reports</param>
      </module>
      <module name="HiddenSearch">
        <param name="search">| lookup all_hosts host OUTPUT report | head 1 | fields + host report | fields - _time</param>
        <param name="earliest">-1d</param>

        <module name="HiddenChartFormatter">
          <param name="chart">line</param>
          <param name="primaryAxisTitle.text">Interface</param>
          <param name="secondaryAxisTitle.text">bits/sec</param>
          <param name="legend.placement">none</param>
          <module name="JobProgressIndicator"/>

          <!-- here's the SimpleResultsTable that we'll click on -->
          <module name="SimpleResultsTable" layoutPanel="panel_row1_col1_grp1">
            <param name="displayRowNumbers">false</param>
            <param name="drilldown">all</param>
            <param name="entityName">results</param>

            <!-- We throw in a header so we can tell the user what they clicked on. -->
            <module name="SimpleResultsHeader" layoutPanel="panel_row1_col1_grp2">
              <param name="entityName">results</param>
              <param name="headerFormat">CHART for time = $time$, cv=$click.value$, cv2=$click.value2$, cn=$click.name$, cn2=$click.name2$</param>
            </module>

            <!-- we swap out the search to be a timechart.  -->
            <module name="HiddenSearch">
              <param name="search">`$click.value2$($host$)`</param>
              <param name="earliest">-1d</param>

              <!-- this module will grab the value we clicked on and put it in as a searchterm,   element_name="some_element_name".   -->
              <module name="ConvertToIntention">
                <param name="intention">
                  <param name="name">addterm</param>
                  <param name="arg">
                    <param name="element_name">$click.value2$</param>
                  </param>

                  <!-- tells the addterm intention to put our term in the first search clause no matter what. -->
                  <param name="flags"><list>indexed</list></param>
                </param>

                <!-- finally, we render the search in another FlashChart, and we throw in a JobProgressIndicator for good measure. -->
                <module name="JobProgressIndicator" layoutPanel="panel_row1_col1_grp2"></module>
                <module name="HiddenChartFormatter" layoutPanel="panel_row1_col1_grp2">
                  <param name="chart">line</param>
                  <param name="primaryAxisTitle.text">Time</param>
                  <param name="secondaryAxisTitle.text">bits per second</param>
                  <param name="legend.placement">none</param>
                  <module name="FlashChart">
                    <param name="width">100%</param>
                    <param name="height">160px</param>
                  </module>
                </module>
              </module>
            </module>
          </module>
        </module>
      </module>
    </module>
  </module>



</view>

New code:

Custom wiring the clicks * False 1 dashboard

Select host host_setting | metadata type=hosts index=os | sort host True mrtg-2.unix.X.edu host host host_setting addterm $target$ indexed

  <module name="GenericHeader">
    <param name="label">Reports</param>
  </module>
  <module name="HiddenSearch">
    <param name="search">| lookup all_hosts host OUTPUT report | head 1 | fields + host report | fields - _time</param>
    <param name="earliest">-1d</param>

    <!-- here's the SimpleResultsTable that we'll click on -->
    <module name="SimpleResultsTable" layoutPanel="panel_row1_col1_grp1">
      <param name="displayRowNumbers">false</param>
      <param name="drilldown">all</param>
      <param name="entityName">results</param>

      <!-- We throw in a header so we can tell the user what they clicked on. -->
      <module name="SimpleResultsHeader" layoutPanel="panel_row1_col1_grp2">
        <param name="entityName">results</param>
        <param name="headerFormat">CHART for time = $time$, cv=$click.value$, cv2=$click.value2$, cn=$click.name$, cn2=$click.name2$</param>
      </module>

        <!-- this module will grab the value we clicked on and put it in as a searchterm, element_name="some_element_name".   -->
        <module name="ConvertToIntention">
          <param name="intention">
            <param name="settingToConvert">click.value2</param>
            <param name="name">stringreplace</param>
            <param name="arg">
              <param name="element_name">
                <param name="value">$click.value2$</param>
              </param>
            </param>
          </param>

        <!-- this module will grab the value we clicked on and put it in as a searchterm, element_name="some_element_name".   -->
        <module name="ConvertToIntention">
          <param name="intention">
            <param name="settingToConvert">click.value</param>
            <param name="name">stringreplace</param>
            <param name="arg">
              <param name="host">
                <param name="value">$click.value$</param>
              </param>
            </param>
          </param>

          <!-- we swap out the search to be a timechart.  -->
          <module name="HiddenSearch">
            <param name="search">`$element_name$($host$)`</param>
            <param name="earliest">-1d</param>

            <!-- finally, we render the search in another FlashChart, and we throw in a JobProgressIndicator for good measure. -->
            <module name="JobProgressIndicator" layoutPanel="panel_row1_col1_grp2"></module>
            <module name="HiddenChartFormatter" layoutPanel="panel_row1_col1_grp2">
              <param name="chart">line</param>
              <param name="primaryAxisTitle.text">Time</param>
              <param name="secondaryAxisTitle.text">bits per second</param>
              <param name="legend.placement">none</param>
              <module name="FlashChart">
                <param name="width">100%</param>
                <param name="height">160px</param>
              </module>
            </module>
          </module>
        </module>
      </module>
    </module>
  </module>
</module>

Tags (1)
0 Karma
1 Solution

sideview
SplunkTrust
SplunkTrust

There's one big thing awry here and a couple smallish things.

1) there's a stringreplace intention omitted, to make that $click.value$ get substituted:

in core Splunk UI you actually need a ConvertToIntention module above this guy:

<module name="HiddenSearch">
  <param name="search">`$click.value2$($host$)`</param>
  <param name="earliest">-1d</param>

or else nothing creates the stringreplace intention to slot into $click.value2$. Consult the UI Examples app for an example of stringreplace intention config. It's a bit ugly.

So what's happening is that the literal string $click.value$ is going up to the search parser and the code that looks at the macro name isnt having any of it.

Yes this is bizarre. You have to take the token '$click.value$' and pass it to a 'ConvertToIntention module' so that it can become a 'stringreplace intention', so that the 'stringreplace intention' can get substituted into a string that has '$click.value$' in it.

You're not crazy. You have to jump through hoops to turn $click.value$ back into itself (Once you get tired of this you may want to check out the sideview_utils app and the new modules therein. Among other things this app offers a world without intentions, where you just put $foo$ tokens directly into anything you want).

2) Same deal but with the $host$ key. you use the $host$ key to create an 'addterm' intention further up, and it looks like this works. This addterm intention gets consumed and (snuck in front of your | lookup ... search). The problem is that further on down you have $host$ appearing in the macro search, but without a stringreplace intention this will again not get converted. So you need to reconvert the $host$ key with another ConvertToIntention, not into an addterm intention this time but into a stringreplace intention.

3) Minor, but you have a HiddenChartFormatter above your SimpleResultsTable that appears to do nothing.

View solution in original post

jamesdon
Path Finder

Awesome stuff! I will add the code above. I had problems getting host assigned to more than one intention, but click.value was the same thing, so I just used that.

0 Karma

sideview
SplunkTrust
SplunkTrust

There's one big thing awry here and a couple smallish things.

1) there's a stringreplace intention omitted, to make that $click.value$ get substituted:

in core Splunk UI you actually need a ConvertToIntention module above this guy:

<module name="HiddenSearch">
  <param name="search">`$click.value2$($host$)`</param>
  <param name="earliest">-1d</param>

or else nothing creates the stringreplace intention to slot into $click.value2$. Consult the UI Examples app for an example of stringreplace intention config. It's a bit ugly.

So what's happening is that the literal string $click.value$ is going up to the search parser and the code that looks at the macro name isnt having any of it.

Yes this is bizarre. You have to take the token '$click.value$' and pass it to a 'ConvertToIntention module' so that it can become a 'stringreplace intention', so that the 'stringreplace intention' can get substituted into a string that has '$click.value$' in it.

You're not crazy. You have to jump through hoops to turn $click.value$ back into itself (Once you get tired of this you may want to check out the sideview_utils app and the new modules therein. Among other things this app offers a world without intentions, where you just put $foo$ tokens directly into anything you want).

2) Same deal but with the $host$ key. you use the $host$ key to create an 'addterm' intention further up, and it looks like this works. This addterm intention gets consumed and (snuck in front of your | lookup ... search). The problem is that further on down you have $host$ appearing in the macro search, but without a stringreplace intention this will again not get converted. So you need to reconvert the $host$ key with another ConvertToIntention, not into an addterm intention this time but into a stringreplace intention.

3) Minor, but you have a HiddenChartFormatter above your SimpleResultsTable that appears to do nothing.

Get Updates on the Splunk Community!

More Ways To Control Your Costs With Archived Metrics | Register for Tech Talk

Tuesday, May 14, 2024  |  11AM PT / 2PM ET Register to Attend Join us for this Tech Talk and learn how to ...

.conf24 | Personalize your .conf experience with Learning Paths!

Personalize your .conf24 Experience Learning paths allow you to level up your skill sets and dive deeper ...

Threat Hunting Unlocked: How to Uplevel Your Threat Hunting With the PEAK Framework ...

WATCH NOWAs AI starts tackling low level alerts, it's more critical than ever to uplevel your threat hunting ...