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