Splunk Search

How to change color of row after column has a certain value?

bmendez0428
Explorer

I'm somewhat new to Splunk.

I have a dashboard displaying a table with data. I have code that fills in the columns with 4 different values.
For example, the NA values underneath the column(ex QA4, QA5, PVE) should cause the whole row to have a red outline in the corresponding boxes.
The green checkmark comes from a DB and the value that causes that is "low", yellow icon is "moderate", and the red circle is caused by a "severe" value from the table. How can I get the "NA" to change the whole row to a red outline?
With CSS/Javascript?

alt text

0 Karma
1 Solution

niketn
Legend

@bmendez0428 please use the following run anywhere example on similar lines as per your question. It gets the ERROR, INFO and WARN log levels for Splunk's _internal logs and converts the range of count of each over time to SLAs i.e. low, moderate and severe. Whenever any row has a column with NA, it adds a red border to the same.

PS: I have extended the DARK mode customer table rendering for this example. So if you are on more recent versions of Splunk i.e. 7.x+ , you can take advantage of the Dark Mode for as your dashboard theme.

alt text

Following is the run anywhere Simple XML Code:

<form script="table_row_highlighting_with_icons.js">
  <label>Table with icon and NA</label>
  <fieldset submitButton="false">
    <input type="time" token="field1" searchWhenChanged="true">
      <label></label>
      <default>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <html>
        <style>
          /* Custom Icons */
          #highlight td {
              text-align: center;
          }
          #highlight td.icon i {
              font-size: 25px;
              text-shadow: 1px 1px #aaa;
          }
          #highlight td.icon .severe {
              color: #DC4E41;
          }
          #highlight td.icon .moderate {
              color: #F8BE34;
          }
          #highlight td.icon .low {
              color: #006400;
          }
          #highlight tr.range-red td {
              border-top: 1px solid #DC4E41!important;
              border-bottom: 1px solid #DC4E41!important;
          }
          #highlight .table td {
              border-top: 1px solid #fff;
          }
          #highlight td.range-red {
              font-weight: bold;
          }
          .icon-inline i {
              font-size: 18px;
              margin-left: 5px;
          }
          .icon-inline i.icon-alert-circle {
              color: #ef392c;
          }
          .icon-inline i.icon-alert {
              color: #ff9c1a;
          }
          .icon-inline i.icon-check {
              color: #5fff5e;
          }
          /* Dark Theme */
          td.icon i.dark {
              text-shadow: none;
          }
          /* Row Coloring */
          #highlight tr.dark td {
              background-color: #5BA383 !important;
          }
          #highlight tr.range-red.dark td {
              border-top: 1px solid #AF575A!important;
              border-bottom: 1px solid #AF575A!important;
          }
          #highlight .table .dark td {
              border-top: 1px solid #000000;
              color: #F2F4F5;
          }
        </style>
      </html>
      <table id="highlight">
        <search id="myTableSearch">
          <query>index=_internal sourcetype=splunkd 
| eval Time=strftime(_time,"%Y-%m-%d %H").":00" 
| chart count by log_level Time span=1h limit=10 useother=f 
| foreach "*:00" 
    [| eval "<<FIELD>>"=case('<<FIELD>>'>=0 AND '<<FIELD>>'<100,"low",'<<FIELD>>'>=100 AND '<<FIELD>>'<5000,"moderate",'<<FIELD>>'>=5000 AND '<<FIELD>>'<10000,"severe",true(),"NA")] 
| foreach "*:00" 
    [| eval "<<FIELD>>"=replace('<<FIELD>>',"^0$","NA")]</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="refresh.display">progressbar</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</form>

Following is the required JS table_row_highlighting_with_icons.js

/* TODO: jink to replace theme_utils with that from core */
require.config({
  paths: {
    theme_utils: "../app/simple_xml_examples/theme_utils"
  }
});

require([
    "underscore",
    "jquery",
    "splunkjs/mvc",
    "splunkjs/mvc/searchmanager",
    "splunkjs/mvc/tableview",
    "theme_utils",
    "splunkjs/mvc/simplexml/ready!"
], function(_, $, mvc, SearchManager, TableView, themeUtils) {

    console.log("Inside Table Render JS");

    var isDarkTheme = themeUtils.getCurrentTheme && themeUtils.getCurrentTheme() === "dark";

    var mySearch = splunkjs.mvc.Components.getInstance("myTableSearch");
    var myResults = mySearch.data("results", {count:0});
    var allFields,filteredFields;

    // Translations from rangemap results to CSS class
    var ICONS = {
        severe: 'alert-circle',
        moderate: 'alert',
        low: 'check-circle'
    };

    myResults.on("data", function(){
        allFields=myResults.data().fields;
        filteredFields=allFields.filter(filterFields);
    });
    function filterFields(field) {
        return field !== "log_level";
    }

     // Row Coloring Example with custom, client-side range interpretation
     var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
         canRender: function(cell) {
             // Enable this custom cell renderer for all fields except log_level
             return _(filteredFields).contains(cell.field);
         },
         render: function($td, cell) {

             // Apply interpretation based on count of errors per _time for each field
             if(cell.field!=="log_level"){
                var icon = 'question';
                var isDarkTheme = themeUtils.getCurrentTheme && themeUtils.getCurrentTheme() === 'dark';
                // Fetch the icon for the value
                if(cell.value!=="NA"){
                    if (ICONS.hasOwnProperty(cell.value)) {
                        icon = ICONS[cell.value];
                    }
                    // Create the icon element and add it to the table cell
                    $td.addClass('icon').html(_.template('<i class="icon-<%-icon%> <%- range %> <%- isDarkTheme %>" title="<%- range %>"></i>', {
                        icon: icon,
                        range: cell.value,
                        isDarkTheme: isDarkTheme ? 'dark' : ''
                    }));
                }else{
                    // Update the cell content
                    $td.text("NA").addClass("string");
                    $td.addClass("range-cell").addClass("range-red");
                }
             }
         }
     });

    mvc.Components.get('highlight').getVisualization(function(tableView) {
        tableView.on('rendered', function() {
            // Add a delay to ensure Custom Render applies to row without getting overridden with built in reder.            
            setTimeout(function(){  
                // Apply class of the cells to the parent row in order to color the whole row
                tableView.$el.find('td.range-cell').each(function() {
                    $(this).parents('tr').addClass(this.className);
                });
            },100);
            if(isDarkTheme){
              tableView.$el.find('td.timestamp').each(function() {
                 $(this).parents('tr').addClass('dark');
              });
            }
        });
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });
});

PS: CSS Style override has been directly added in the SImple XML dashboard as <html> panel. You can move the same to css file as per your use case.

Please try out and confirm.

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

niketn
Legend

@bmendez0428 please use the following run anywhere example on similar lines as per your question. It gets the ERROR, INFO and WARN log levels for Splunk's _internal logs and converts the range of count of each over time to SLAs i.e. low, moderate and severe. Whenever any row has a column with NA, it adds a red border to the same.

PS: I have extended the DARK mode customer table rendering for this example. So if you are on more recent versions of Splunk i.e. 7.x+ , you can take advantage of the Dark Mode for as your dashboard theme.

alt text

Following is the run anywhere Simple XML Code:

<form script="table_row_highlighting_with_icons.js">
  <label>Table with icon and NA</label>
  <fieldset submitButton="false">
    <input type="time" token="field1" searchWhenChanged="true">
      <label></label>
      <default>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <html>
        <style>
          /* Custom Icons */
          #highlight td {
              text-align: center;
          }
          #highlight td.icon i {
              font-size: 25px;
              text-shadow: 1px 1px #aaa;
          }
          #highlight td.icon .severe {
              color: #DC4E41;
          }
          #highlight td.icon .moderate {
              color: #F8BE34;
          }
          #highlight td.icon .low {
              color: #006400;
          }
          #highlight tr.range-red td {
              border-top: 1px solid #DC4E41!important;
              border-bottom: 1px solid #DC4E41!important;
          }
          #highlight .table td {
              border-top: 1px solid #fff;
          }
          #highlight td.range-red {
              font-weight: bold;
          }
          .icon-inline i {
              font-size: 18px;
              margin-left: 5px;
          }
          .icon-inline i.icon-alert-circle {
              color: #ef392c;
          }
          .icon-inline i.icon-alert {
              color: #ff9c1a;
          }
          .icon-inline i.icon-check {
              color: #5fff5e;
          }
          /* Dark Theme */
          td.icon i.dark {
              text-shadow: none;
          }
          /* Row Coloring */
          #highlight tr.dark td {
              background-color: #5BA383 !important;
          }
          #highlight tr.range-red.dark td {
              border-top: 1px solid #AF575A!important;
              border-bottom: 1px solid #AF575A!important;
          }
          #highlight .table .dark td {
              border-top: 1px solid #000000;
              color: #F2F4F5;
          }
        </style>
      </html>
      <table id="highlight">
        <search id="myTableSearch">
          <query>index=_internal sourcetype=splunkd 
| eval Time=strftime(_time,"%Y-%m-%d %H").":00" 
| chart count by log_level Time span=1h limit=10 useother=f 
| foreach "*:00" 
    [| eval "<<FIELD>>"=case('<<FIELD>>'>=0 AND '<<FIELD>>'<100,"low",'<<FIELD>>'>=100 AND '<<FIELD>>'<5000,"moderate",'<<FIELD>>'>=5000 AND '<<FIELD>>'<10000,"severe",true(),"NA")] 
| foreach "*:00" 
    [| eval "<<FIELD>>"=replace('<<FIELD>>',"^0$","NA")]</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="refresh.display">progressbar</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</form>

Following is the required JS table_row_highlighting_with_icons.js

/* TODO: jink to replace theme_utils with that from core */
require.config({
  paths: {
    theme_utils: "../app/simple_xml_examples/theme_utils"
  }
});

require([
    "underscore",
    "jquery",
    "splunkjs/mvc",
    "splunkjs/mvc/searchmanager",
    "splunkjs/mvc/tableview",
    "theme_utils",
    "splunkjs/mvc/simplexml/ready!"
], function(_, $, mvc, SearchManager, TableView, themeUtils) {

    console.log("Inside Table Render JS");

    var isDarkTheme = themeUtils.getCurrentTheme && themeUtils.getCurrentTheme() === "dark";

    var mySearch = splunkjs.mvc.Components.getInstance("myTableSearch");
    var myResults = mySearch.data("results", {count:0});
    var allFields,filteredFields;

    // Translations from rangemap results to CSS class
    var ICONS = {
        severe: 'alert-circle',
        moderate: 'alert',
        low: 'check-circle'
    };

    myResults.on("data", function(){
        allFields=myResults.data().fields;
        filteredFields=allFields.filter(filterFields);
    });
    function filterFields(field) {
        return field !== "log_level";
    }

     // Row Coloring Example with custom, client-side range interpretation
     var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
         canRender: function(cell) {
             // Enable this custom cell renderer for all fields except log_level
             return _(filteredFields).contains(cell.field);
         },
         render: function($td, cell) {

             // Apply interpretation based on count of errors per _time for each field
             if(cell.field!=="log_level"){
                var icon = 'question';
                var isDarkTheme = themeUtils.getCurrentTheme && themeUtils.getCurrentTheme() === 'dark';
                // Fetch the icon for the value
                if(cell.value!=="NA"){
                    if (ICONS.hasOwnProperty(cell.value)) {
                        icon = ICONS[cell.value];
                    }
                    // Create the icon element and add it to the table cell
                    $td.addClass('icon').html(_.template('<i class="icon-<%-icon%> <%- range %> <%- isDarkTheme %>" title="<%- range %>"></i>', {
                        icon: icon,
                        range: cell.value,
                        isDarkTheme: isDarkTheme ? 'dark' : ''
                    }));
                }else{
                    // Update the cell content
                    $td.text("NA").addClass("string");
                    $td.addClass("range-cell").addClass("range-red");
                }
             }
         }
     });

    mvc.Components.get('highlight').getVisualization(function(tableView) {
        tableView.on('rendered', function() {
            // Add a delay to ensure Custom Render applies to row without getting overridden with built in reder.            
            setTimeout(function(){  
                // Apply class of the cells to the parent row in order to color the whole row
                tableView.$el.find('td.range-cell').each(function() {
                    $(this).parents('tr').addClass(this.className);
                });
            },100);
            if(isDarkTheme){
              tableView.$el.find('td.timestamp').each(function() {
                 $(this).parents('tr').addClass('dark');
              });
            }
        });
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });
});

PS: CSS Style override has been directly added in the SImple XML dashboard as <html> panel. You can move the same to css file as per your use case.

Please try out and confirm.

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

vnravikumar
Champion
0 Karma
Get Updates on the Splunk Community!

What’s New in Splunk App for PCI Compliance 5.3.1?

The Splunk App for PCI Compliance allows customers to extend the power of their existing Splunk solution with ...

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...

What's new in Splunk Cloud Platform 9.1.2312?

Hi Splunky people! We are excited to share the newest updates in Splunk Cloud Platform 9.1.2312! Analysts can ...