Dashboards & Visualizations

How to dynamically populate field names in dropdown input of a dashboard?

bhagyashriyan
Explorer

In my dashboard my search criteria includes UserID(dropdown), Source(dropdown), Destination(dropdown) , a dropdown that populates remaining list of field names for a particular UserID given as input and Field value(text box)

Based on these inputs panel appears.

For example,

UserID =1234 Source = A Destination= B FieldName = ItemCode/PONumber(dropdown) FieldValues = abcd

UserID =5678 Source = C Destination= D FieldName = ItemCode/PONumber/Summary/Records(dropdown) FieldValues = efgh

So, how to dynamically populate remaining search inputs which are field names unique to UserID?

Thanks,
Bhagyashri S

Tags (1)
0 Karma
1 Solution

niketn
Legend

@bhagyashriyan, if your need is to create a dropdown with all the fields based on events for selected Filters, you can try either one of the following two approaches:

1) Use Transpose command ( with | head 1 if all events have same fields)

<YourBaseSearch>
|  head 1
|  fields - _* component log_level
|  transpose column_name="filter_3_name" include_empty=false
|  fields filter_3_name

PS: Using | fields - _* <fieldName1> <fieldName1>, default fields like _time, _raw can be removed and also unwanted fields like in the example component and log_level which already are listed in separate dropdowns are removed.
include_empty=false parameter in transpose command removed null columns.

2) Use fieldsummary command (with count!=0)

 <YourBaseSearch>
|  fieldsummary 
|  search count!=0  field!="component" AND field!="log_level"
|  dedup field
|  fields field

PS: To remove null fields count!=0 check is introduced. Already existing filters i.e. component and log_level have been removed using field!=component and field!=log_level respectively.

alt text

Please try the following run anywhere dashboard based on Splunk's _internal index. You can modify as per your needs.
PS: I have initialized a baseQuery token with the base search filter to be applied on all of the dashboard search just for simplicity. You should use either eventtype or macro instead of this. Two filter fields are component and log_level in the following example. A lot of token dependencies have been created to show/hide elements and set/unset tokens based on token changes.

<form>
  <label>Dynamic Dropdown with Static and Dynamic filters</label>
  <init>
    <!-- For Simplicity Base Query Filter is saved as token. Ideally it should either be eventtype or macro (or both)-->
    <set token="baseQuery">index="_internal" sourcetype="splunkd" log_level!="INFO" component=*</set>
  </init>
  <fieldset submitButton="false"></fieldset>
  <row>
    <panel>
      <input type="time" token="tokTime" searchWhenChanged="true">
        <label>Select Time</label>
        <default>
          <earliest>-60m@m</earliest>
          <latest>now</latest>
        </default>
      </input>
      <input type="dropdown" token="tokFilter1" searchWhenChanged="true">
        <label>Filter 1 - component</label>
        <search>
          <query>$baseQuery$ log_level=$tokFilter2$
  | dedup component
  | sort component
  | table component</query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>component</fieldForLabel>
        <fieldForValue>component</fieldForValue>
        <change>
          <unset token="tokFilter3Name"></unset>
          <unset token="tokFilter3"></unset>
          <unset token="form.tokFilter3Name"></unset>
          <unset token="form.tokFilter3"></unset>
        </change>
        <choice value="*">All</choice>
        <default>*</default>
      </input>
      <input type="dropdown" token="tokFilter2" searchWhenChanged="true">
        <label>Filter 2 - log_level</label>
        <search>
          <query>$baseQuery$ component=$tokFilter1$
  | dedup log_level
  | sort log_level
  | table log_level</query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>log_level</fieldForLabel>
        <fieldForValue>log_level</fieldForValue>
        <change>
          <unset token="tokFilter3Name"></unset>
          <unset token="tokFilter3"></unset>
          <unset token="form.tokFilter3Name"></unset>
          <unset token="form.tokFilter3"></unset>
        </change>
        <choice value="*">All</choice>
        <default>*</default>
      </input>
      <input depends="$tokFilter1$,$tokFilter2$" type="dropdown" token="tokFilter3Name" searchWhenChanged="true">
        <label>Filter 3 - Select Filter Name</label>
        <search>
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$"
|  head 1
|  fields - _* component log_level
|  transpose column_name="filter_3_name" include_empty=false
|  fields filter_3_name</query>
<!-- Following query can also be used. fieldForValue abd fieldForLabel will be field.
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$"
|  fieldsummary 
|  search count!=0 field!="component" AND field!="log_level"
|  dedup field
|  fields field</query>
-->
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>filter_3_name</fieldForLabel>
        <fieldForValue>filter_3_name</fieldForValue>
      </input>
      <input depends="$tokFilter3Name$" type="dropdown" token="tokFilter3" searchWhenChanged="true">
        <label>Filter 3 - Select Filter Value</label>
        <search>
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$" $tokFilter3Name$=*
|  dedup $tokFilter3Name$
|  sort $tokFilter3Name$
|  table $tokFilter3Name$ </query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>$tokFilter3Name$</fieldForLabel>
        <fieldForValue>$tokFilter3Name$</fieldForValue>
        <choice value="*">All</choice>
        <default>*</default>
      </input>
    </panel>
  </row>
  <row depends="$tokFilter3$">
    <panel>
      <title>Splunkd Errors/Warnings</title>
      <chart>
        <search>
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$" $tokFilter3Name$="$tokFilter3$"
|  timechart count</query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="charting.chart">column</option>
        <option name="charting.drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </chart>
    </panel>
  </row>
</form>
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

niketn
Legend

@bhagyashriyan, if your need is to create a dropdown with all the fields based on events for selected Filters, you can try either one of the following two approaches:

1) Use Transpose command ( with | head 1 if all events have same fields)

<YourBaseSearch>
|  head 1
|  fields - _* component log_level
|  transpose column_name="filter_3_name" include_empty=false
|  fields filter_3_name

PS: Using | fields - _* <fieldName1> <fieldName1>, default fields like _time, _raw can be removed and also unwanted fields like in the example component and log_level which already are listed in separate dropdowns are removed.
include_empty=false parameter in transpose command removed null columns.

2) Use fieldsummary command (with count!=0)

 <YourBaseSearch>
|  fieldsummary 
|  search count!=0  field!="component" AND field!="log_level"
|  dedup field
|  fields field

PS: To remove null fields count!=0 check is introduced. Already existing filters i.e. component and log_level have been removed using field!=component and field!=log_level respectively.

alt text

Please try the following run anywhere dashboard based on Splunk's _internal index. You can modify as per your needs.
PS: I have initialized a baseQuery token with the base search filter to be applied on all of the dashboard search just for simplicity. You should use either eventtype or macro instead of this. Two filter fields are component and log_level in the following example. A lot of token dependencies have been created to show/hide elements and set/unset tokens based on token changes.

<form>
  <label>Dynamic Dropdown with Static and Dynamic filters</label>
  <init>
    <!-- For Simplicity Base Query Filter is saved as token. Ideally it should either be eventtype or macro (or both)-->
    <set token="baseQuery">index="_internal" sourcetype="splunkd" log_level!="INFO" component=*</set>
  </init>
  <fieldset submitButton="false"></fieldset>
  <row>
    <panel>
      <input type="time" token="tokTime" searchWhenChanged="true">
        <label>Select Time</label>
        <default>
          <earliest>-60m@m</earliest>
          <latest>now</latest>
        </default>
      </input>
      <input type="dropdown" token="tokFilter1" searchWhenChanged="true">
        <label>Filter 1 - component</label>
        <search>
          <query>$baseQuery$ log_level=$tokFilter2$
  | dedup component
  | sort component
  | table component</query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>component</fieldForLabel>
        <fieldForValue>component</fieldForValue>
        <change>
          <unset token="tokFilter3Name"></unset>
          <unset token="tokFilter3"></unset>
          <unset token="form.tokFilter3Name"></unset>
          <unset token="form.tokFilter3"></unset>
        </change>
        <choice value="*">All</choice>
        <default>*</default>
      </input>
      <input type="dropdown" token="tokFilter2" searchWhenChanged="true">
        <label>Filter 2 - log_level</label>
        <search>
          <query>$baseQuery$ component=$tokFilter1$
  | dedup log_level
  | sort log_level
  | table log_level</query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>log_level</fieldForLabel>
        <fieldForValue>log_level</fieldForValue>
        <change>
          <unset token="tokFilter3Name"></unset>
          <unset token="tokFilter3"></unset>
          <unset token="form.tokFilter3Name"></unset>
          <unset token="form.tokFilter3"></unset>
        </change>
        <choice value="*">All</choice>
        <default>*</default>
      </input>
      <input depends="$tokFilter1$,$tokFilter2$" type="dropdown" token="tokFilter3Name" searchWhenChanged="true">
        <label>Filter 3 - Select Filter Name</label>
        <search>
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$"
|  head 1
|  fields - _* component log_level
|  transpose column_name="filter_3_name" include_empty=false
|  fields filter_3_name</query>
<!-- Following query can also be used. fieldForValue abd fieldForLabel will be field.
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$"
|  fieldsummary 
|  search count!=0 field!="component" AND field!="log_level"
|  dedup field
|  fields field</query>
-->
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>filter_3_name</fieldForLabel>
        <fieldForValue>filter_3_name</fieldForValue>
      </input>
      <input depends="$tokFilter3Name$" type="dropdown" token="tokFilter3" searchWhenChanged="true">
        <label>Filter 3 - Select Filter Value</label>
        <search>
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$" $tokFilter3Name$=*
|  dedup $tokFilter3Name$
|  sort $tokFilter3Name$
|  table $tokFilter3Name$ </query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
        </search>
        <fieldForLabel>$tokFilter3Name$</fieldForLabel>
        <fieldForValue>$tokFilter3Name$</fieldForValue>
        <choice value="*">All</choice>
        <default>*</default>
      </input>
    </panel>
  </row>
  <row depends="$tokFilter3$">
    <panel>
      <title>Splunkd Errors/Warnings</title>
      <chart>
        <search>
          <query>$baseQuery$ component="$tokFilter1$" log_level="$tokFilter2$" $tokFilter3Name$="$tokFilter3$"
|  timechart count</query>
          <earliest>$tokTime.earliest$</earliest>
          <latest>$tokTime.latest$</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="charting.chart">column</option>
        <option name="charting.drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </chart>
    </panel>
  </row>
</form>
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

bhagyashriyan
Explorer

Great !! It worked. Thanks 🙂

0 Karma

bhagyashriyan
Explorer

@niketn,

Continuation..

Based on the given inputs, the query i have given for panel is.
index=""| eval name="$fieldname_tok$"| eval name= if(name="", , name)|search Interface="$interface_tok$" AND SourceApplication="$source_tok$" AND name="$value_tok$"| rename name as "FreeField"| table Interface, SourceApplication, FreeField

This query works for "*" condition, however it fails when input field is selected from drop down as,

| eval name="$fieldname_tok$"| -------- token is taken as string rather than field name.

So I am stuck with satisfying both conditions. Please help

Thanks,
Bhagyashri S

0 Karma

niketn
Legend

@bhagyashriyan, just take out double quotes from eval expression i.e.

| eval name=$fieldname_tok$

I think you should get

| eval name=*

Or with specific value

| eval name="<YourSelectedDropdownChoice>"

PS: On a different note,
1) You can use Prefix and Suffix options for dropdown to format Dropdown selected value in specific way you want.
2) If you want to use the value from dropdown however, change them to different formats as per your need you can code the <change> Event Handler for dropdown and set and pass different tokens as per the need. For example

If the dropdown tokSourceType value/label is "splunkd", you can code the change event as follows:

sourcetype="$value$"

This way the token $tokSourceType$ will have value "splunkd" and $tokSourceTypeFull$ will have value sourcetype="splunkd". Please try out and confirm.

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

anjambha
Communicator

Hi bhagyashriyan,

You can do this by passing token of UserID input to other fields input .. like

  1. For UserID input , under Dynamic option write a search query for eg. ... | dedup UserID | table UserID
  2. Now pass this UserID input token (userid) to your next field input. So your search query for the next field input under Dynamic option would be like : ... UserID=$userid$ | dedup field1 | table field1

Let me know if it works..

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 ...