Dashboards & Visualizations

What is wrong in this JS and CSS for row color?

ljalvrdz
New Member

Hello,

I'm having issues with Splunk 7.1.1 making this row colour thing to work, this is my dashboard:

<dashboard script="table_row_highlighting.js" stylesheet="table_decorations.css">
  <label>Network Dashboard</label>
  <description>Network Dashboard - Dev01</description>
  <row>
    <panel>
      <title>VPN Client Login</title>
      <table id='highlight'>
        <search>
          <query>index=main login_result=* vpn_user=* vpn_port=XXXX OR XXXX OR XXXX ip_vpn_source=*
          | table  _time vpn_user vpn_port login_result ip_vpn_source
          | lookup vpn_lookup vpn_user OUTPUTNEW vpn_username
          | eval _time=strftime(_time, "%d/%m/%Y %H:%M:%S %p")
          | sort - _time
          | replace "XXXX" WITH XXXX IN vpn_port
          | replace "XXXX" WITH XXXX IN vpn_port
          | replace "XXXX" WITH XXXX IN vpn_port
          | replace "Login failed" WITH DENEGADA IN login_result
          | replace "Login Success" WITH APROBADA IN login_result
          | rename _time AS HORA vpn_user AS USUARIO vpn_port AS CONEXION login_result AS AUTORIZACIÓN ip_vpn_source AS ORIGEN vpn_username AS USUARIO
          </query>
          <earliest>rt-12h</earliest>
          <latest>rtnow</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">false</option>
      </table>
    </panel>
  </row>
</dashboard>

What it basically does is to create a table and provide time, username, port and result of credentials from a VPN client access, so we can monitor approved and unapproved users.

I am using this JS to change the row colour (red) when unapproved users show:

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView) {

     // Row Coloring Example with custom, client-side range interpretation

    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Enable this custom cell renderer for both the active_hist_searches and the active_realtime_searches field
            return _(["login_result"]).contains(cell.field);
        },
        render: function($td, cell) {
            // Add a class to the cell based on the returned value
            var value = cell.value;

            // Apply interpretation for string of autorización
            if (cell.field === "login_result") {
                if (value == "Login failed") {
                    $td.addClass('range-cell').addClass('range-severe');
                }
            }

            // Update the cell content
            $td.text(value).addClass('string');
        }
    });

    mvc.Components.get('highlight').getVisualization(function(tableView) {
        tableView.on('rendered', function() {

            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);
        });
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });

});

I took it from Splunk Dashboard Examples App and also this CSS:

/* Custom Icons */

td.icon {
    text-align: center;
}

td.icon i {
    font-size: 25px;
    text-shadow: 1px 1px #aaa;
}

td.icon .severe {
    color: red;
}

td.icon .elevated {
    color: orangered;
}

td.icon .low {
    color: #006400;
}

/* Row Coloring */

#highlight tr td {
    background-color: #c1ffc3 !important;
}

#highlight tr.range-elevated td {
    background-color: #ffc57a !important;
}

#highlight tr.range-severe td {
    background-color: #d59392 !important;
}


#highlight .table td {
    border-top: 1px solid #fff;
}

#highlight td.range-severe, td.range-elevated {
    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;

The colour is not changing to red, the whole table is green doesn't matter if the column "login_result" shows "Login failed". I would appreciate any ideas.

Gracias,

0 Karma
1 Solution

poete
Builder

Hello @ljalvrdz,
it seems there is a problem of consistency between your js code and your renames and replaces.

In case you keep | replace "Login failed" WITH DENEGADA IN login_result in the query, then you need to modify your js accordingly
if (value == "Login failed") { then becomes if (value == "DENEGADA") {
Accordingly,
In case you keep | rename ... login_result AS AUTORIZACIÓN, then you need to modify if (cell.field === "login_result") { to if (cell.field === "AUTORIZACIÓN") {.

Do not forget to '_bump' in order to make sure the changes are taken into account.

View solution in original post

0 Karma

poete
Builder

Hello @ljalvrdz,
it seems there is a problem of consistency between your js code and your renames and replaces.

In case you keep | replace "Login failed" WITH DENEGADA IN login_result in the query, then you need to modify your js accordingly
if (value == "Login failed") { then becomes if (value == "DENEGADA") {
Accordingly,
In case you keep | rename ... login_result AS AUTORIZACIÓN, then you need to modify if (cell.field === "login_result") { to if (cell.field === "AUTORIZACIÓN") {.

Do not forget to '_bump' in order to make sure the changes are taken into account.

View solution in original post

0 Karma

ljalvrdz
New Member

I tried in another web browser and it worked. Maybe something to do with my caché.

Thank you for the help! @poete

0 Karma

ljalvrdz
New Member

Hi @poete,

Thanks for the answer but I'm still unable to make it work. I keep the XML code of the dashboard like this:


Network Dashboard - Dev01


VPN Client Login



index=main login_result=* vpn_user=* vpn_port=9050 OR 9010 OR 9100 ip_vpn_source=*
| table _time vpn_user vpn_port login_result ip_vpn_source
| lookup vpn_lookup vpn_user OUTPUTNEW vpn_username
| eval _time=strftime(_time, "%d/%m/%Y %H:%M:%S %p")
| sort - _time
| replace "9010" WITH EOS-CFE IN vpn_port
| replace "9100" WITH ELSTER IN vpn_port
| replace "9050" WITH EOS-SAP IN vpn_port
| replace "Login failed" WITH DENEGADA IN login_result
| replace "Login Success" WITH APROBADA IN login_result
| rename _time AS HORA vpn_user AS USUARIO vpn_port AS CONEXION login_result as AUTORIZACIÓN ip_vpn_source AS ORIGEN vpn_username AS USUARIO

rt-12hrs
rtnow
1

none
none
false
false
false
false



And modify the JS code like this:

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView) {

     // Row Coloring Example with custom, client-side range interpretation

    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Enable this custom cell renderer for both the active_hist_searches and the active_realtime_searches field
            return _(["AUTORIZACIÓN"]).contains(cell.field);
        },
        render: function($td, cell) {
            // Add a class to the cell based on the returned value
            var value = cell.value;

            // Apply interpretation for string of autorización
            if (cell.field === "AUTORIZACIÓN") {
                if (value == "DENEGADA") {
                    $td.addClass('range-cell').addClass('range-severe');
                }
            }

            // Update the cell content
            $td.text(value).addClass('string');
        }
    });

    mvc.Components.get('highlight').getVisualization(function(tableView) {
        tableView.on('rendered', function() {

            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);
        });
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });

});

Did the _bump, splunk restart splunkweb and even restart all splunk service but no success.

0 Karma

niketnilay
Legend

@ljalvrdz have you removed the following rename pipe to test?

login_result AS AUTORIZACIÓN

Also can you check with historical search instead of real-time (maybe refresh panel every 30 seconds instead)?

       <earliest>-12h</earliest>
       <latest>now</latest>
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

ljalvrdz
New Member

@niketnilay I removed the rename:
index=main login_result=* vpn_user=* vpn_port=9050 OR 9010 OR 9100 ip_vpn_source=*
| table _time vpn_user vpn_port login_result ip_vpn_source
| lookup vpn_lookup vpn_user OUTPUTNEW vpn_username
| eval _time=strftime(_time, "%d/%m/%Y %H:%M:%S %p")
| sort - _time
| replace "9010" WITH EOS-CFE IN vpn_port
| replace "9100" WITH ELSTER IN vpn_port
| replace "9050" WITH EOS-SAP IN vpn_port
| replace "Login failed" WITH DENEGADA IN login_result
| replace "Login Success" WITH APROBADA IN login_result
| rename _time AS HORA vpn_user AS USUARIO vpn_port AS CONEXION ip_vpn_source AS ORIGEN vpn_username AS USUARIO

And changed the historical search with no luck:
-12hrs
now

0 Karma

poete
Builder

Hello @ljalvrdz,

did you on purpose rename to different fields into USUARIO?

I see form the last rename : vpn_user AS USUARIO ... vpn_username AS USUARIO

This seems a bit strange to me. Can you please confirm?

0 Karma

ljalvrdz
New Member

Hello @poete,

Yes I did that on purpose.

0 Karma
Did you miss .conf21 Virtual?

Good news! The event's keynotes and many of its breakout sessions are now available online, and still totally FREE!