I've been working and searching for the answer to this question for about a week. I need some help.
I use a summary index query to populate a timechart. I want to do an inline drill down to a single time period as a result of clicking the first timechart.
I have tried many different ways of passing the click time range, but so far no luck. This is what I have.
<module name="Search">
<param name="search"><![CDATA[index=summary search_name="$query.rawValue$" | timechart $function.rawValue$(delay) as seconds span=$span.rawValue$]]></param>
<module name="HiddenChartFormatter">
<param name="legend.placement">none</param>
<param name="charting.axisTitleX.visibility">collapsed</param>
<param name="charting.axisY.minimumNumber">0</param>
<param name="charting.axisY.maximumNumber">100</param>
<param name="charting.axisLabelsY.majorUnit">20</param>
<param name="chartTitle">$query.Value$</param>
<param name="chart">column</param>
<module name="JSChart" layoutPanel="panel_row2_col1"/>
</module>
</module>
<module name="Search">
<param name="search"><![CDATA[sourcetype=access_combined uri="*link?navSystem*" | timechart $function.rawValue$(delay) as seconds span=$span.rawValue$]]></param>
<param name="earliest">$earliest$</param>
<param name="latest">$latest$</param>
<module name="HiddenChartFormatter">
<param name="legend.placement">none</param>
<param name="charting.axisTitleX.visibility">collapsed</param>
<param name="charting.axisY.minimumNumber">0</param>
<param name="charting.axisY.maximumNumber">100</param>
<param name="charting.axisLabelsY.majorUnit">20</param>
<param name="chartTitle">Navigation Response Time</param>
<param name="chart">column</param>
<module name="JSChart" layoutPanel="panel_row2_col2"/>
</module>
</module>
1) The main problem here, is that the second search and chart modules are not downstream from the chart being clicked on. In the Sideview XML, the only way a module gets any information from another module is if it is downstream from that module. So as this XML is written, these two charts are completely independent.
Solution: Nest the Search + HiddenChartFormatter + JSChart inside (ie downstream) from the first JSChart.
2) After that though, there's a second mistake being made here. In inline drilldown, the timerange is actually calculated from the timechart click for you automatically, so you don't have to do anything at all. In fact if we only fixed prolem #1, then the way you are setting earliest/latest here is actually going to replace the valid earliest and latest bounds of the automatically-determined timerange, and instead set them to null values.
Solution: delete these lines:
<param name="earliest">$earliest$</param>
<param name="latest">$latest$</param>
and the drilldown timerange will get passed down.
Some other minor items
3) it's weird to be using the $foo.rawValue$ tokens here instead of simply using the $foo$ tokens. The docs discuss the rawValue tokens, and say that they are only for when you are passing the token into a URL with the Redirector module, constructing a URL manually with the HTML module, or displaying the value to the user on screen. For all other uses, you really do want the $query$ and $function$ tokens here, not $query.rawValue$ and $function.rawValue$. It's probably doing no harm but it doesn't take long to hit a case where there's a problem using a rawValue unnecessarily.
4) Once the drilldown modules are properly nested, you can actually factor most of this HiddenChartFormatter keys up a level so you only specify them once and thus save some XML. You can also use the Sideview ValueSetter module to replace HiddenChartFormatter. I find HiddenChartFormatter very confusing, as some keys like "legend.placement" allow you to omit the "charting." prefix, and other keys do not. With ValueSetter you need an extra "arg." on the front, but at least you can set all charting keys the same with "arg.charting.". The ValueSetter is also a very useful module for lots of other corner cases, whereas the HiddenChartFormatter is useful only for charting.
Doing all of this, here is modified XML. I also have some conventions for whitespace and indentation that I find keeps views somewhat more readable. Note if you use the Sideview Editor to create and edit your views, it will follow these same conventions when it writes out the XML for you, so poking at a view with the Editor a little bit is a simple way to instantly "clean up" the whole view.
<module name="Search">
<param name="search"><![CDATA[
index=summary search_name="$query$" | timechart $function$(delay) as seconds span=$span$
]]></param>
<module name="ValueSetter">
<param name="arg.charting.legend.placement">none</param>
<param name="arg.charting.axisTitleX.visibility">collapsed</param>
<param name="arg.charting.axisY.minimumNumber">0</param>
<param name="arg.charting.axisY.maximumNumber">100</param>
<param name="arg.charting.axisLabelsY.majorUnit">20</param>
<param name="arg.charting.chartTitle">$query.Value$</param>
<param name="arg.charting.chart">column</param>
<module name="JSChart" layoutPanel="panel_row2_col1">
<module name="Search">
<param name="search"><![CDATA[
sourcetype=access_combined uri="*link?navSystem*" | timechart $function$(delay) as seconds span=$span$
]]></param>
<module name="ValueSetter">
<param name="arg.charting.chartTitle">$query.Value$</param>
<module name="JSChart" layoutPanel="panel_row2_col2"/>
</module>
</module>
</module>
</module>
</module>
Beyond that, you might want to look at the "template" param that all of the Sideview form element modules have. These allow you to have just $span$ in your search instead of span="$span$", where you have to worry about null token values creating malformed search syntax. The template param allow you to pull the foo= part up into the form element logic and this is a cleaner and simpler way to go.
1) The main problem here, is that the second search and chart modules are not downstream from the chart being clicked on. In the Sideview XML, the only way a module gets any information from another module is if it is downstream from that module. So as this XML is written, these two charts are completely independent.
Solution: Nest the Search + HiddenChartFormatter + JSChart inside (ie downstream) from the first JSChart.
2) After that though, there's a second mistake being made here. In inline drilldown, the timerange is actually calculated from the timechart click for you automatically, so you don't have to do anything at all. In fact if we only fixed prolem #1, then the way you are setting earliest/latest here is actually going to replace the valid earliest and latest bounds of the automatically-determined timerange, and instead set them to null values.
Solution: delete these lines:
<param name="earliest">$earliest$</param>
<param name="latest">$latest$</param>
and the drilldown timerange will get passed down.
Some other minor items
3) it's weird to be using the $foo.rawValue$ tokens here instead of simply using the $foo$ tokens. The docs discuss the rawValue tokens, and say that they are only for when you are passing the token into a URL with the Redirector module, constructing a URL manually with the HTML module, or displaying the value to the user on screen. For all other uses, you really do want the $query$ and $function$ tokens here, not $query.rawValue$ and $function.rawValue$. It's probably doing no harm but it doesn't take long to hit a case where there's a problem using a rawValue unnecessarily.
4) Once the drilldown modules are properly nested, you can actually factor most of this HiddenChartFormatter keys up a level so you only specify them once and thus save some XML. You can also use the Sideview ValueSetter module to replace HiddenChartFormatter. I find HiddenChartFormatter very confusing, as some keys like "legend.placement" allow you to omit the "charting." prefix, and other keys do not. With ValueSetter you need an extra "arg." on the front, but at least you can set all charting keys the same with "arg.charting.". The ValueSetter is also a very useful module for lots of other corner cases, whereas the HiddenChartFormatter is useful only for charting.
Doing all of this, here is modified XML. I also have some conventions for whitespace and indentation that I find keeps views somewhat more readable. Note if you use the Sideview Editor to create and edit your views, it will follow these same conventions when it writes out the XML for you, so poking at a view with the Editor a little bit is a simple way to instantly "clean up" the whole view.
<module name="Search">
<param name="search"><![CDATA[
index=summary search_name="$query$" | timechart $function$(delay) as seconds span=$span$
]]></param>
<module name="ValueSetter">
<param name="arg.charting.legend.placement">none</param>
<param name="arg.charting.axisTitleX.visibility">collapsed</param>
<param name="arg.charting.axisY.minimumNumber">0</param>
<param name="arg.charting.axisY.maximumNumber">100</param>
<param name="arg.charting.axisLabelsY.majorUnit">20</param>
<param name="arg.charting.chartTitle">$query.Value$</param>
<param name="arg.charting.chart">column</param>
<module name="JSChart" layoutPanel="panel_row2_col1">
<module name="Search">
<param name="search"><![CDATA[
sourcetype=access_combined uri="*link?navSystem*" | timechart $function$(delay) as seconds span=$span$
]]></param>
<module name="ValueSetter">
<param name="arg.charting.chartTitle">$query.Value$</param>
<module name="JSChart" layoutPanel="panel_row2_col2"/>
</module>
</module>
</module>
</module>
</module>
Beyond that, you might want to look at the "template" param that all of the Sideview form element modules have. These allow you to have just $span$ in your search instead of span="$span$", where you have to worry about null token values creating malformed search syntax. The template param allow you to pull the foo= part up into the form element logic and this is a cleaner and simpler way to go.
Wow. That was way more information than I expected in way less time that I imagined. Thank you for your kind tutelage!
Hi @leathej1
If @sideview's answer solved your question, don't forget to accept their answer by clicking on "Accept" directly below their response to resolve this post. This will award them karma points and you as well 🙂
Sidenote: Also for future reference, please be sure when responding to someone's answer, click on "Add comment" directly below their answer or, if responding to someone's comment, type in the "Add your comment..." box directly below their comment. You typed your response in the "Enter your answer here..." box at the very bottom of the page which, instead, posts a brand new answer when it was really meant as a comment. This will help with a clean continuous flow of the conversation. I already converted your answer to a comment, so just something to keep in mind from here on out. Thanks! And glad you got an awesome answer 🙂 Happy Splunking!
Patrick
Whoops. Sorry!
no worries! When you get used to the upstream/downstream thing, much that seemed arbitrary and confusing falls into place. It might be a good time to re-read the page in the Sideview Utils docs "Introduction to the Advanced XML". The explanations of a few key things on that page will help you fully understand almost all of what's weird about the XML.
I think I understand fairly well. But I still don't seem to be able to pass the time range downstream:
<module name="Search">
<param name="search"><![CDATA[index=summary search_name="$query$" | timechart $function$(delay) as seconds span=$span$]]></param>
<module name="ValueSetter">
<param name="arg.charting.legend.placement">none</param>
<param name="arg.charting.axisTitleX.visibility">collapsed</param>
<param name="arg.charting.axisY.minimumNumber">0</param>
<param name="arg.charting.axisY.maximumNumber">100</param>
<param name="arg.charting.axisLabelsY.majorUnit">20</param>
<param name="arg.charting.chartTitle">$query$</param>
<param name="arg.charting.chart">column</param>
<module name="JSChart" layoutPanel="panel_row2_col1" />
<module name="Search">
<param name="search"><![CDATA[sourcetype=access_combined uri="*link?navSystem*" | timechart $function$(delay) as seconds span=$span$]]></param>
<module name="ValueSetter">
<param name="arg.charting.chartTitle">$earliest$ - $latest$</param>
<module name="JSChart" layoutPanel="panel_row2_col2" />
</module>
</module>
</module>
I can't tell from this snippet - the problem with your last attempt was that the first JSChart looked like this:
<module name="JSChart" layoutPanel="panel_row2_col1"/>
That little "/" at the end of the tag, means the tag is instantly closed. So that module has no modules downstream. Therefore the drilldown click on that JSChart will go nowhere.
Instead you need to nest the subsequent Search + ValueSetter + JSChart inside ie downstream from that first JSChart tag. I think this is still the problem here, although you're posted XML showing that error has been removed in the interim.
The comment box is indeed clunky - I've learned not to trust the "preview" text it generates, and you might consider pastebin for longer code blocks.
Yes, you're right - I closed the tag. How embarrassing. Thanks for humoring me...
One last question: I still can't get these variables to evaluate:
<param name="arg.charting.chartTitle">$earliest$ - $latest$</param>
Oh goodness, yes there is no $earliest$ and $latest$ key. If you want to display the timerange, you could in theory do
$search.timeRange.earliest$ - $search.timeRange.latest$, but I doubt that you actually want this, since it will display things in epochtime (ie seconds since 1/1/1970) and "1420761600 - 1420848000" doesn't do any humans any good at all.
Instead you probably want to use the Sideview key
$search.timeRange.label$ which will give you a nice localized string like "January 9th, 2015", or "12am to 12pm January 9th", or if the timerange in question is a relative one, a helpful string like "last 24 hours" or "Yesterday".
Note that this illustrates another big advantage of ValueSetter over HiddenChartFormatter, in that HiddenChartFormatter can't work with $foo$ tokens at all.
OK, I see what is going on. Searching within the Sideview app help is not getting me hits, so I am Googling to get help and foo keys. I kinda wish the Sideview documentation was easier to work with. Once I found this deep down in the walkthroughs, it became self explanatory.
I can't seem to comment with code.