TIPS & TRICKS

Splunk > Clara-fication: Customizing SimpleXML Dashboards With Inline CSS

SimpleXML dashboards have been around for quite a while now, and you can do quite a bit with them. They improve with every new version of Splunk. We all know that there are rows and panels and charts and whatnot, but what about when you want to do some customization, like change the font size or add a border? A lot of applications have StyleSteets (.css) and JavaScript (.js) files that can be used for custom visualizations, however you can use inline CSS and HTML within SimpleXML to markup a dashboard as needed! JavaScript can not be done inline and must be done with a SimpleXML extension, however it can be done inline with a Splunk HTML dashboard, however those lose a lot of SimpleXML behavior and is irreversible, so use caution.

Let me fill you in on just a few things about StyleSheets before we get started. 

Editing the dashboard.css file will apply those styles across all dashboards within the app without having to add the stylesheet="dashboard.css" in any dashboard. 

Generic styles come from the bootstrap-enterprise.css file, which you can notice when using the Developer Tools in the browser. 

Using a relative URI, you are able to open a StyleSheet directly in a browser window: http://<hostname>/en-US/static/app/<app>/<css>.css - this is also true for JS files. 

More than one StyleSheet can be applied to the same dashboard. StyleSheets can live within or outside of the app and be referred to using a relative path: stylesheet="<app>:<css>.css"

Also, let’s go over different ways to use CSS within Splunk and the pros and cons: 

  • The most standard way is to create a static stylesheet, similar to what I just described above. These can be used throughout the environment, they’re more generally more organized, and reusable. The downside is that users need to have access to the backend in order to upload these files, and they also require either a debug/refresh, bump, etc. before they’ll be picked up. 

  • Another method is inline CSS using HTML panels, just like my example in this blog! The advantages are that it can be used for testing out CSS, users do not need permission to the backend, and they can be saved as prebuilt panels and used in various dashboards. Prebuilt panels of inline CSS could, however, lead to unwanted CSS overrides and these are restricted to a dashboard, unlike some CSS that can be applied to an entire app.

  • Another way of doing inline CSS is to use the HTML panel element to apply the style itself, like so:

    <html> <div id="div_header" style="background:red;color:white;font-weight:bold;font-size:120%">Header Goes Here</div> </html> 
    


    These have the same pros and cons as the other inline method.
     

I’m going to show a dashboard that I just randomly created with a handful of panels that have HTML and CSS markups. I’ll explain how you go about using the Developer Tools in light details as well as the code this dashboard uses for future reference. 

Ready? Here we go.

What a Snazzy Dashboard

Here is the dashboard that I’ve created. It’s all randomly generated data that has literally no meaning. As you can see, it contains lots of colors, the single value panels have different widths, there’s a border. There are a lot of possibilities within Splunk dashboards to customize them when using CSS.

You can see there’s this cool little thumbs up image in the Definitions panel. Well, to know what icons and colors are native to Splunk, you can check out this link: http://<host>/en-US/static/docs/style/style-guide.html. You can easily save new icons within your environment to reference or use a link to an image in an HTML panel. 

There’s a Tool for This?

To know the element path you need in your style section of your dashboard, it’s easiest to use the Developer Tools in your browser. Give your row, or panel, or chart an ID (<panel id="panel2">), for starters, then, using the Developer Tools, navigate to the section of the dashboard you want to customize in order to find out what class it is.

So let’s get into how to use the Developer Tools to figure out what the element is even called that you want to edit. In the top left corner of the Developer Tools you can click on the little mouse icon to hover around the dashboard and click on an element and it will take you right to where you need to go in the code. As you can see in the image below, I’m hovered over “Secondary Cool Title” and the class name is called “dashboard-element-title”. One thing to remember is that element IDs are notated with # (hash) and classes are notated with . (dot). There are more selectors that can be used, if needed. That’s all I really need to know here. I have an ID attached to this row, so the class is all I need to start editing the title. 

There’s something important to be noted about all of this: these properties could change with any new release of the product. It is always important to test and validate the changes upon upgrading Splunk. 

For the Love of Splunk, Give Me the Code! 

Below you can see my SimpleXML for the dashboard I created. I have some comments in the CSS sections to explain what it’s doing.

<dashboard>
  <label>customization</label>
  <row depends="$hide$">
    <panel>
      <!--creates an HTML panel in order to create an inline style sheet-->
      <html>
        <style>
      //<!--this creates a solid line border on the top and sides of the element with the id=row1-->{}
          #row1.dashboard-row.dashboard-layout-rowcolumn-row {
              border: solid !important;
              border-bottom: none !important;}
      //<!--this creates a solid line border only on the sides of the element with the id=row2-->{}
          #row2.dashboard-row.dashboard-layout-rowcolumn-row {
              border: solid !important;
              border-top: none !important;
              border-bottom: none !important;}
      //<!--this creates a solid line border on the bottom and sides of the element with the id=row3-->{}
          #row3.dashboard-row.dashboard-layout-rowcolumn-row {
              border: solid !important;
              border-top: none !important;}
      //<!--this makes panel1 have a smaller width than the other panels in the row-->{}  
          #panel1 {
              width: 15% !important}
      //<!--this colors the label of the single value, changes the font size, and changes the font to Courier New for id=panel1-->{}
          #panel1 .under-label {
              fill: #236d9c !important;
              text-align: justify !important;
              font-size: 12px !important;
              font-family: Courier New !important;}
      //<!--this colors the label of the single value, changes the font size, and also makes it bold for id=panel2-->{}
          #panel2 .under-label {
              fill: #f8be33 !important;
              font-size: 16px !important;
              font-weight: bold !important;}
      //<!--this colors the label of the single value, changes the font size, and also makes it italic for id=panel3-->{}
          #panel3 .under-label {
              fill: orange !important;
              font-size: 20px !important;
              font-style: italic !important;}
      //<!--this makes panel4 have a larger width than the other panels in the row-->{}  
          #panel4 {
              width: 35% !important}
      //<!--this changes the label font size and creates a red shadow for id=panel4-->{}   
          #panel4 .under-label {
              font-size: 24px !important;
              text-shadow: 8px 11px red !important;}
      //<!--this colors the 3rd column of the gentimes table as well as aligns the text in the column, changes the font size, and changes the font to Times New Roman-->{}
          #gentimes td:nth-child(3) {
              color: purple !important;
              text-align: justify !important;
              font-size: 15px !important;
              font-family: Times New Roman !important;}
      //<!--this colors and aligns the second panel title in row4-->{}
          #row4 .dashboard-element-title {
              color: blue !important;
              text-align: center !important;}
      //<!--this colors the data labels in the chart (or charts if there happened to be more than one) in row4-->{}        
          #row4 g.highcharts-data-labels text {
              fill: red !important;}
        </style>
      </html>
    </panel>
  </row>
  <row id="row1">
    <panel id="panel1">
      <single>
        <search>
          <query>|makeresults|eval result=100</query>
        </search>
        <option name="rangeColors">["0x006d9c","0xf8be34","0xf1813f","0xdc4e41"]</option>
        <option name="rangeValues">[100,200,300]</option>
        <option name="underLabel">cool number</option>
        <option name="useColors">1</option>
      </single>
    </panel>
    <panel id="panel2">
      <single>
        <search>
          <query>|makeresults|eval result=200</query>
        </search>
        <option name="rangeColors">["0x006d9c","0xf8be34","0xf1813f","0xdc4e41"]</option>
        <option name="rangeValues">[100,200,300]</option>
        <option name="underLabel">cooler number</option>
        <option name="useColors">1</option>
      </single>
    </panel>
    <panel id="panel3">
      <single>
        <search>
          <query>|makeresults|eval result=300</query>
        </search>
        <option name="rangeColors">["0x006d9c","0xf8be34","0xf1813f","0xdc4e41"]</option>
        <option name="rangeValues">[100,200,300]</option>
        <option name="underLabel">coolest number</option>
        <option name="useColors">1</option>
      </single>
    </panel>
    <panel id="panel4">
      <single>
        <search>
          <query>|makeresults|eval result=400</query>
        </search>
        <option name="rangeColors">["0x006d9c","0xf8be34","0xf1813f","0xdc4e41"]</option>
        <option name="rangeValues">[100,200,300]</option>
        <option name="underLabel">less cool number</option>
        <option name="useColors">1</option>
      </single>
    </panel>
  </row>
  <row id="row2">
    <panel>
      <table id="gentimes">
        <search>
          <query>|gentimes start=-20|table starttime starthuman endtime endhuman</query>
          <earliest>$earliest$</earliest>
          <latest>$latest$</latest>
        </search>
        <option name="count">10</option>
        <option name="drilldown">cell</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
  <row id="row3">
    <panel>
      <html>
        <!--this creates a header-->
        <h1>Definitions</h1>
        <style>
    //<!--Creates a left column that takes up 50% of the space-->{}
        #left_col {
           float:left;
           width:50%;
        }
    //<!--Creates a right column that takes up 50% of the space-->{}
        #right_col {
           float:right;
           width:50%;
         }
        </style>
        <!--create a table with two columns using the stylesheet above and insert an image into the last line-->
          <div id="left_col">
            <b>Never gonna give:</b> you up <br/>
            <b>Never gonna let:</b> you down<br/>
            <b>Never gonna run:</b> around and desert you
          </div>
          <div id="right_col">
            <b>Never gonna make:</b> you cry<br/>
            <b>Never gonna say:</b> goodbye<br/>
            <b>Never gonna tell:</b> a lie and hurt you <img src="https://purepng.com/public/uploads/medium/facebook-thumbs-up-arc.png" width="25" height="25"/>
          </div>
        </html>
    </panel>
  </row>
  <row id="row4">
    <panel>
      <title>Count of Cool Things</title>
      <chart>
        <title>Secondary Cool Title</title>
        <search>
          <query>|gentimes start=-15|eval random1=random()|eval _time=starttime|timechart values(random1)</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
        </search>
        <option name="charting.axisTitleX.visibility">collapsed</option>
        <option name="charting.axisTitleY.visibility">collapsed</option>
        <option name="charting.chart">line</option>
        <option name="charting.chart.showDataLabels">minmax</option>
        <option name="charting.drilldown">none</option>
        <option name="charting.legend.placement">none</option>
        <option name="refresh.display">progressbar</option>
      </chart>
    </panel>
  </row>
</dashboard>

 

Go Forth and Customize

Now you know that you can use CSS and HTML within a SimpleXML Splunk dashboard without actually needing to save the CSS file within the app and call it as a stylesheet or a full HTML dashboard. Pretty incredible. There is so much more that CSS is capable of than I have listed above. With the new Splunk Dashboards App available on Splunkbase, there’s some really cool stuff that you can do, as well, out of the box. This new beta does not, however, allow for CSS or JS extensions. If you are still building dashboards with SimpleXML and you want to do some extra customizations, inline CSS and HTML can really provide some quick turnarounds for designing your dashboards.


Additional Resources

 

Clara Merriman
Posted by

Clara Merriman

Clara Merriman is a Senior Splunk Engineer on the Splunk@Splunk team. She began using Splunk back in 2013 for SONIFI Solutions, Inc. as a Business Intelligence Engineer. Her passion really showed for utilizing Splunk to answer questions for more than just IT and Security. She joined Splunk in 2018 to spread her knowledge and her ideas from the source! She's also a huge advocate for the Splunk community and has been part of the SplunkTrust in 2018 and 2019 (honorary) - fingers crossed for 2020! Check me out on Slack or Splunk Answers - I'm GIRL!

Join the Discussion