In Chapter 4, Simple XML Dashboards, we covered building dashboards using simple XML. We first used the wizards provided in Splunk, and then edited the resultant XML. When you reach the limits of what can be accomplished with simple XML, one option is to dive into Splunk's advanced XML.
Here are a few reasons to use advanced XML:
More control over layout: With advanced XML, you have better control over where form elements and chrome appear, and somewhat improved control over the placement of the output.
Custom drilldowns: It is only possible to create custom drilldowns from tables and charts using advanced XML.
Access to more parameters: The modules in simple XML actually use advanced XML modules, but many parameters are not exposed. Sometimes the desire is actually to disable features, and this is only possible by using advanced XML.
Access to more modules: There are many modules not available when using simple XML, for example the search bar itself. All extra modules provided by the apps at Splunkbase, for example Google Maps, are for use in advanced XML.
There are also a number of reasons to not work with advanced XML:
Steep learning curve: Depending on what technologies you are comfortable working with, and possibly on how well the rest of this chapter is written, the learning curve for advanced XML can be steep.
No direct control over HTML: If there is a particular HTML you want to produce from search results, this may not be as simple as you had hoped. Short of writing your own module, you must work within the bounds of the options provided to the existing modules, modify CSS with
application.css
, or modify the HTML using JavaScript.No direct control over logic: If you need specific things to happen when you click on specific table cells, particularly based on other values in the same row, this can only be accomplished by modifying the document using JavaScript. This is possible, but it is not well documented. Examples can be found at http://splunkbase.com both in answers posts and sample applications...
When building dashboards, my approach is generally as follows:
Create the needed queries.
Add the queries to a simple XML dashboard. Use the GUI tools to tweak the dashboard as much as possible. Finish all graphical changes at this stage, if possible.
Convert the simple XML dashboard to a form if form elements are needed. Make all logic work with simple XML if possible.
Convert the simple XML dashboard to an advanced XML dashboard. There is no reverse conversion possible, so this should be done as late as possible, and only if needed.
Edit the advanced XML dashboard accordingly.
The idea is to take advantage of the Splunk GUI tools as much as possible, letting the simple XML conversion process add all of the advanced XML that you would have to otherwise find yourself. We covered steps 1-3 in the previous chapters. Step 4 is covered in the Converting simple XML to advanced XML section.
Before we dig into the modules provided, let's look at the structure of the XML itself and cover a couple of concepts.
The tag structure of an advanced XML document is essentially:
view module param ... module ...
The main concept of Splunk's XML structure is that the effects of modules flow downstream to child modules. This is a vital concept to understand. The XML structure has almost nothing to do with layout, and everything to do with the flow of data.
Let's look at a simple example like this:
<view template="dashboard.html"> <label>Chapter 8, Example 1</label> <module name="HiddenSearch" layoutPanel="panel_row1_col1" autoRun="True"> <param name="earliest">-1d</param> <param name="search">error | top user</param> <module name="SimpleResultsTable"></module> </module> </view>
This document produces a sparse dashboard with one panel like...
Let's go back to
one of the dashboards we created in Chapter 4, Simple XML Dashboards, errors_user_form
. We built this before our app, so it still lives in the Search app. In my instance, this URL is http://mysplunkserver:8000/en-US/app/search/errors_user_form
.
Just to refresh, the simple XML behind this dashboard looks like:
<?xml version='1.0' encoding='utf-8'?> <form> <fieldset> <input type="text" token="user"> <label>User</label> </input> <input type="time" /> </fieldset> <label>Errors User Form</label> <row> <chart> <searchString> sourcetype="impl_splunk_gen" loglevel=error user="$user$" | timechart count as "Error count" by network </searchString> <title> Dashboard - Errors - errors by network timechart </title> <option name="charting.chart">line<...
The main concept of nested modules is that parent (upstream) modules affect child (downstream) modules. Looking at the first panel, the full module flow is:
<module name="ExtendedFieldSearch"> <module name="TimeRangePicker"> <module name="SubmitButton"> <module name="HiddenSearch"> <module name="ViewstateAdapter"> <module name="HiddenFieldPicker"> <module name="JobProgressIndicator"> <module name="EnablePreview"> <module name="HiddenChartFormatter"> <module name="JSChart"> <module name="ConvertToDrilldownSearch"> <module name="ViewRedirector"> <module name="ViewRedirectorLink">
Note
A reference for the modules installed in your instance of Splunk is available at /modules
. In my case, the full URL is http://mysplunkserver:8000/modules
.
Let's step through...
In an advanced XML dashboard, which panel a module is drawn to is determined by the value of the layoutPanel
attribute. This separation of logic and layout can be useful—for instance, allowing you to reuse data generated by a query with multiple modules—but displays the results on different parts of the page.
A few rules about this attribute are as follows:
The
layoutPanel
attribute must appear on all immediate children of<view>
.The
layoutPanel
attribute can appear ondescendant
child module tags.If a module does not have a
layoutPanel
attribute, it will inherit the value from the closest upstream module that does.Modules that have visible output are added to their respective
layoutPanel
attribute in the order they appear in the XML.Modules "flow" in the panel they are placed. Most modules take the entire width of the panel, but some do not, and flow left to right before wrapping.
Looking through our XML, we find these elements with the layoutPanel
attribute...
One example of separating layout from data would be using a single query to populate both a table and a chart. The advanced XML for this could look like the following:
<view template="dashboard.html"> <label>Chapter 8 - Reusing a query</label> <module name="StaticContentSample" layoutPanel="panel_row1_col1"> <param name="text">Text above</param> </module> <module name="HiddenSearch" layoutPanel="panel_row1_col1" autoRun="True"> <param name="search"> sourcetype="impl_splunk_gen" loglevel=error | top user </param> <param name="earliest">-24h</param> <module name="HiddenChartFormatter"> <param name="charting.chart">pie</param> <module name="JSChart"></module> <module name="StaticContentSample" layoutPanel="panel_row1_col1"> <!-- this layoutPanel is...
Intentions allow you to affect downstream searches, using values provided by other modules, for instance, form fields or the results of a click. There are a number of available intention types, but we will cover the two most common, stringreplace
and addterm
. You can see examples of other types of intentions in the UI Examples app available at http://splunkbase.com.
This is the most common intention to use, and maps directly to the only available action in simple XML—variable replacement. Let's look at our search field from our advanced XML example:
<module name="ExtendedFieldSearch" layoutPanel="viewHeader"> <param name="replacementMap"> <param name="arg"> <param name="user"/> </param> </param> <param name="field">User</param> <param name="intention"> <param name="name">stringreplace</param> <param name="arg"> <param name="user"> <param...
A drilldown is a query built using values from a previous query. The module ConvertToDrilldownSearch
will build a query automatically from the table or graph that it is nested inside. Unfortunately, this only works well when the query is fairly simple, and when you want to see raw events. To build a custom drilldown, we combine intentions and the nested nature of modules.
Looking back at our chart in the Reusing a query section, let's build a custom drilldown that shows the top instances of another field when it is clicked on.
Here is an example dashboard that draws a chart and then runs a custom query when clicked on:
<view template="dashboard.html"> <label>Chapter 8 - Drilldown to custom query</label> <!-- chrome --> <module name="HiddenSearch" layoutPanel="panel_row1_col1" autoRun="True" group="Errors by user"> <param name="search"> sourcetype="impl_splunk_gen...
There are many excellent apps available at http://splunkbase.com, a number of which provide custom modules. We will cover two of the most popular, Google Maps and Sideview Utils.
As we saw in Chapter 7, Working with Apps, the Google Maps app provides a dashboard and lookup for drawing results on a map. The underlying module is also available to use in your own dashboards.
Here is a very simple dashboard that uses the GoogleMaps
module:
<?xml version="1.0"?> <view template="search.html"> <!-- chrome --> <label>Chapter 8 - Google Maps Search</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> <!-- search --> <...
We have covered an enormous amount of ground in this chapter. The toughest concepts we touched on were module nesting, the meaning of layoutPanel
, intentions, and an alternative to intentions with SideView Utils. As with many skills, the best way to become proficient is to dig in, and hopefully have some fun along the way! The examples in this chapter should give you a head start.
In the next chapter, we will cover summary indexing, a powerful part of Splunk that can improve the efficiency of your queries greatly.