All Apps and Add-ons

Sideview Utils: How to embed a button into each row of a table?

IngloriousSplun
Communicator

Following examples for Sideview Utils, I'm attempting to display a table of results where a Button is embedded into each row. This button executes a custom search or action when clicked, such as acknowledging an event.

If I create the Table and a static search, the Table and Buttons display properly with the results. If I add in a TextField to allow users to modify the query for filtering, the Button disappears. It's likely something stupid with my XML, but after looking repeatedly I can't figure out what the issue is.

XML I'm using is below. Note this XML does work for displaying results and filtering those results using the TextField, it just removes the Button for some reason. Also, sorry if formatting is off, I had to manually type it since Splunk is on a system where I can't copy and paste from.

<view autoCancelInterval="90" isSticky="False" onunloadCancelJobs="true" template="dashboard.html">
  <label>Testing Sideview</label>

  <module name="AccountBar" layoutPanel="appHeader" />
    <module name="AppBar" layoutPanel="appHeader" />
      <module name="SideviewUtils" layoutPanel="appHeader" />

      <module name="Message" layoutPanel="messaging">
        <param name=”filter”>*</param>
        <param name=”maxSize”>2</param>
        <param name=”clearOnJobDispatch”>False</param>
      </module>

      <module name=”Search” layoutPanel=”panel_row1_col1” autoRun=”True”>
        <param name=”search”>`Test_Macro(wild=”*”)`</param>
        <param name=”earliest”>-1d</param>
        <param name=”latest”>now</param>
        <module name=TextField” layoutPanel=”panel_row1_col1” autoRun=”True”>
          <param name=”name”>wild</param>
          <param name=”float”>left</param>
          <param name=”label”>Search</param>
          <param name=”default”>*</param>
          <module name=”Search” layoutPanel=”panel_row1_col1” autoRun=”True”>
            <param name=”search”>`Test_Macro(wild=”$wild$”)`</param>
            <module name=”Pager”>
              <module name=”Table”>
                <module name=”Button” group=”row.fields.actions”>
                  <param name=”label”>Ack</param>
                    <module name=”Search”>
                      <param name=”search”>search series=$row.fields.series$ | eval event_ack=”Yes”</param>
                        <module name=”CustomBehavior”>
                          <param name=”requiresDispatch”>True</param>
                        </module>
                    </module>
                  </module>
                </module>
            </module>
       </module>
     </module>
   </module>
</view>

Also, if anyone has developed a method for acknowledging events using Sideview, this is what I'm pursuing. The idea I have thus far is a tag each event with an "acknowledged" field default set to "no", and upon clicking of the button that field gets set to "yes", and vice versa if its already set to "yes".

Thanks.

1 Solution

sideview
SplunkTrust
SplunkTrust

Most likely it is that the results of Test_Macro(wild=”$wild$”) do not include a field called "actions". A blank field has to exist unfortunately, although I can fix this in a future release (and make it so that the Table builds extra column "foo" when it sees it has a child with group="row.fields.foo")

Another serious problem here is all the autoRun="True". Remove all those except for the very topmost one. They aren't doing what you think they are, and in fact they are probably causing a lot of harm. At best they'll be slowing down the page load a lot.

The best and simplest path I think, is to have a lookup based on some key or id in the main results, whose rows indicate which of the id's have been acknowledged, or more generally what state they are in.

Pipe the main results through that lookup so as to add one or more fields (eg state whose value is perhaps either null or "acknowledged" Do this either with an automatic lookup, or with an explicit pipe to the lookup command in the search syntax.

Then the Table Embedding part looks just like you have it here, but the search would look something like

| inputlookup mylookup | append [| stats count | fields - count | eval myIdField="$row.fields.myIdField$" | eval state="acknowledged"] | stats last(state) as state by myIdField | outputlookup mylookup

A bit weird, but when the button is clicked, get the existing rows of the lookup, tack on a new row indicating that this value of myIdField has state="acknowledged", then use stats to dedup on that idField again, copying over the previous state for our given row, if there was one.

Other small things - you had a redundant Search module, and several redundant layoutPanel attributes which I removed.

Here's an end-to-end example to illustrate.

<view autoCancelInterval="90" isSticky="False" onunloadCancelJobs="true" template="dashboard.html">
   <label>Testing Sideview</label>

   <module name="AccountBar" layoutPanel="appHeader" />
   <module name="AppBar" layoutPanel="appHeader" />
   <module name="SideviewUtils" layoutPanel="appHeader" />

   <module name="Message" layoutPanel="messaging">
     <param name="filter">*</param>
     <param name="maxSize">2</param>
     <param name="clearOnJobDispatch">False</param>
   </module>

   <module name="TextField"  layoutPanel="panel_row1_col1" autoRun="True">
     <param name="name">wild</param>
     <param name="float">left</param>
     <param name="label">Search</param>
     <param name="default">*</param>

     <module name="Search">
       <param name="search">`Test_Macro(wild="*")` | eval actions="" | lookup mylookup myIdField OUTPUT state</param>
       <param name="earliest">-1d</param>
       <param name="latest">now</param>

       <module name="Pager">

         <module name="Table">

           <module name="Button" group="row.fields.actions">
             <param name="label">Ack</param>

             <module name="Search">
               <param name="search">| inputlookup mylookup | append [| stats count | fields - count | eval myIdField="$row.fields.myIdField$" | eval state="acknowledged"] | stats last(state) as state by myIdField | outputlookup mylookup</param>

               <module name="CustomBehavior">
                 <param name="requiresDispatch">True</param>
               </module>
             </module>
           </module>
         </module>
       </module>
     </module>
   </module>
 </view>

View solution in original post

sideview
SplunkTrust
SplunkTrust

Most likely it is that the results of Test_Macro(wild=”$wild$”) do not include a field called "actions". A blank field has to exist unfortunately, although I can fix this in a future release (and make it so that the Table builds extra column "foo" when it sees it has a child with group="row.fields.foo")

Another serious problem here is all the autoRun="True". Remove all those except for the very topmost one. They aren't doing what you think they are, and in fact they are probably causing a lot of harm. At best they'll be slowing down the page load a lot.

The best and simplest path I think, is to have a lookup based on some key or id in the main results, whose rows indicate which of the id's have been acknowledged, or more generally what state they are in.

Pipe the main results through that lookup so as to add one or more fields (eg state whose value is perhaps either null or "acknowledged" Do this either with an automatic lookup, or with an explicit pipe to the lookup command in the search syntax.

Then the Table Embedding part looks just like you have it here, but the search would look something like

| inputlookup mylookup | append [| stats count | fields - count | eval myIdField="$row.fields.myIdField$" | eval state="acknowledged"] | stats last(state) as state by myIdField | outputlookup mylookup

A bit weird, but when the button is clicked, get the existing rows of the lookup, tack on a new row indicating that this value of myIdField has state="acknowledged", then use stats to dedup on that idField again, copying over the previous state for our given row, if there was one.

Other small things - you had a redundant Search module, and several redundant layoutPanel attributes which I removed.

Here's an end-to-end example to illustrate.

<view autoCancelInterval="90" isSticky="False" onunloadCancelJobs="true" template="dashboard.html">
   <label>Testing Sideview</label>

   <module name="AccountBar" layoutPanel="appHeader" />
   <module name="AppBar" layoutPanel="appHeader" />
   <module name="SideviewUtils" layoutPanel="appHeader" />

   <module name="Message" layoutPanel="messaging">
     <param name="filter">*</param>
     <param name="maxSize">2</param>
     <param name="clearOnJobDispatch">False</param>
   </module>

   <module name="TextField"  layoutPanel="panel_row1_col1" autoRun="True">
     <param name="name">wild</param>
     <param name="float">left</param>
     <param name="label">Search</param>
     <param name="default">*</param>

     <module name="Search">
       <param name="search">`Test_Macro(wild="*")` | eval actions="" | lookup mylookup myIdField OUTPUT state</param>
       <param name="earliest">-1d</param>
       <param name="latest">now</param>

       <module name="Pager">

         <module name="Table">

           <module name="Button" group="row.fields.actions">
             <param name="label">Ack</param>

             <module name="Search">
               <param name="search">| inputlookup mylookup | append [| stats count | fields - count | eval myIdField="$row.fields.myIdField$" | eval state="acknowledged"] | stats last(state) as state by myIdField | outputlookup mylookup</param>

               <module name="CustomBehavior">
                 <param name="requiresDispatch">True</param>
               </module>
             </module>
           </module>
         </module>
       </module>
     </module>
   </module>
 </view>

IngloriousSplun
Communicator

After cleaning up my XML based on your suggestion the Button still does not display in the "actions" field. The field is displayed, but it's empty. If I remove the TextField and just use a static search using the Search module, the Button shows up without an issue, it's only when adding in the TextField for some reason.

0 Karma

IngloriousSplun
Communicator

Nevermind, I had the field renamed and that's what caused the button to disappear.

0 Karma

IngloriousSplun
Communicator

Thanks for such a quick reply. I think you might be right that because Test_Macro(wild=”$wild$”) does not contain a field titled 'actions', that could be why the table isn't displaying it. Odd thing is before I added in the TextField to allow users to filter the table results, the Button was populating as it should have with the default results of Test_Macro(wild=”*”), which doesn't have a field titled 'actions'. Tomorrow when I get back into the office I'll update the macro to have an "actions" field, and see if that triggers the button to populate. I may also look to replace the button with the Checkbox module. Once I get a chance to check at the office I'll mark this as resolved.

I also appreciate you cleaning up the XML. Today is the first day I've used Sideview, and it was specific to resolving this acknowledgement issue, so I'm a bit ignorant and still peeling through all the documentation.

I appreciate the suggestion about lookup tables for the "acknowledge" feature. I'm concerned about its scalability. This system could potentially have millions of IDS events, and I'm not sure how well a lookup table will hold up against that. In your example,

| inputlookup mylookup | append [| stats count | fields - count | eval myIdField="$row.fields.myIdField$" | eval state="acknowledged"] | stats last(state) as state by myIdField | output lookup mylookup

can you clarify the line myIdField="$row.fields.myIdField$? Where is it pulling the token myIdField from?

0 Karma
Get Updates on the Splunk Community!

Adoption of RUM and APM at Splunk

    Unleash the power of Splunk Observability   Watch Now In this can't miss Tech Talk! The Splunk Growth ...

Routing logs with Splunk OTel Collector for Kubernetes

The Splunk Distribution of the OpenTelemetry (OTel) Collector is a product that provides a way to ingest ...

Welcome to the Splunk Community!

(view in My Videos) We're so glad you're here! The Splunk Community is place to connect, learn, give back, and ...