How to use tokens from 2 time range inputs in single Splunk dashboard query? - splunk

I'm using Splunk classic dashboards where I have 2 time range inputs. I want to compare data for 2 time frames in a single table. Essentially, I want to perform query which counts errors by type for period A and B, then join the searches by error type so that I can see how many errors of each type there were in period A as opposed to period B.
I added a panel as follows:
because I want to use tokens from both time inputs for the query:
(index=myindex) earliest="$runATimeInput.earliest$" latest="$runATimeInput.latest$" environment="$runAEnvironment$" level=ERROR
| spath input=message
| stats count by logIdentifier
| sort count desc
| join left=L right=R where L.logIdentifier = R.logIdentifier
[| search (index=myindex) earliest="$runBTimeInput.earliest$" latest="$runBTimeInput.latest$" environment="$runBEnvironment$" level=ERROR
| spath input=message
| stats count by logIdentifier ]
The problem is that the query doesn't return any results although it should. The main query returns results:
(index=myindex) earliest="$runATimeInput.earliest$" latest="$runATimeInput.latest$" environment="$runAEnvironment$" level=ERROR
| spath input=message
| stats count by logIdentifier
| sort count desc
However the subsearch query doesn't return any results (although a separate search for the same period in a new tab returns results):
[| search (index=myindex) earliest="$runBTimeInput.earliest$" latest="$runBTimeInput.latest$" environment="$runBEnvironment$" level=ERROR
| spath input=message
| stats count by logIdentifier ]
When I click on Run Search in Splunk panel in order to open the search in a new tab I see strange values for earliest/latest tokens. For the main query the values are: earliest="1669500000" latest="1669506493.677" where 1669500000 is the Tue Jan 20 1970 09:45:00 and 1669506493.677 is Sun Nov 27 2022 01:48:13 whereas the timeframe for period 1 was Sun Nov 27 2022 00:00:00 - Sun Nov 27 2022 01:48:13. That being said the main query works and it respects the original time frame.
The values for the second query are earliest="1669813200" latest="1669816444.909" where 1669813200 is Tue Jan 20 1970 09:45:00 and 1669816444.909 is Wed Nov 30 2022 15:54:04 whereas the period 2 timeframe was Wed Nov 30 2022 15:00:04 - Wed Nov 30 2022 15:54:04`.
Am I doing something wrong in the panel settings or the query? Or maybe there's another way to do this in Splunk?
Below is the dashboard XML:
<form>
<label>My Dashboard</label>
<description>My Dashboard</description>
<fieldset submitButton="false" autoRun="true">
<input type="time" token="runATimeInput" searchWhenChanged="true">
<label>Run A</label>
<default>
<earliest>-24h#h</earliest>
<latest>now</latest>
</default>
</input>
<input type="dropdown" token="runAEnvironment" searchWhenChanged="true">
<label>Run A Environment</label>
<choice value="prod">prod</choice>
<default>prod</default>
</input>
<input type="time" token="runBTimeInput" searchWhenChanged="true">
<label>Run B</label>
<default>
<earliest>-24h#h</earliest>
<latest>now</latest>
</default>
</input>
<input type="dropdown" token="runBEnvironment" searchWhenChanged="true">
<label>Run B Environment</label>
<choice value="prod">prod</choice>
<default>prod</default>
</input>
</fieldset>
<row>
<panel>
<title>Top Exceptions</title>
<table>
<title>Top Exceptions</title>
<search>
<query>(index=distapps) earliest="$runATimeInput.earliest$" latest="$runATimeInput.latest$" environment="$runAEnvironment$" level=ERROR | spath input=message
| stats count by logIdentifier
| sort count desc
| join left=L right=R where L.logIdentifier = R.logIdentifier
[| search (index=myindex) earliest="$runBTimeInput.earliest$" latest="$runBTimeInput.latest$" environment="$runBEnvironment$" level=ERROR
| spath input=message
| stats count by logIdentifier ]</query>
<earliest>$runATimeInput.earliest$</earliest>
<latest>$runBTimeInput.latest$</latest>
</search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
</form>

Here's a test dashboard I created that uses two timepickers. It produces results for both time periods. How is yours different? Could it be the count field is used in both the main and subsearches?
<form version="1.1">
<label>test</label>
<fieldset submitButton="false">
<input type="time" token="runATimeInput">
<label>A</label>
<default>
<earliest>-24h#h</earliest>
<latest>now</latest>
</default>
</input>
<input type="time" token="runBTimeInput">
<label>B</label>
<default>
<earliest>-48h#h</earliest>
<latest>-24h#h</latest>
</default>
</input>
</fieldset>
<row>
<panel>
<table>
<search>
<query>(index=_internal) earliest="$runATimeInput.earliest$" latest="$runATimeInput.latest$"
| stats count as countA by component
| join component [| search (index=_internal) earliest="$runBTimeInput.earliest$" latest="$runBTimeInput.latest$"
| stats count as countB by component ]</query>
<earliest>$runATimeInput.earliest$</earliest>
<latest>$runATimeInput.latest$</latest>
<sampleRatio>1</sampleRatio>
</search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
</table>
</panel>
</row>
</form>

Don't use any tokens or time selector on the panel itself
You should be able to reference your two time tokens' .earliest and .latest just fine in any searches on the dashboard

Related

How to show the time difference between two events in a Splunk join query?

Consider the following log data,
{"level":"info","msg":"Enqueued a recurring task","time":"2022-04-01T18:46:22.854684-07:00","uuid":"4e9fc098-f611-4128-ae0b-2e6b9cb232c8"}
{"level":"info","msg":"Reported a result","path":"/results","time":"2022-04-01T18:46:22.955999-07:00","uuid":"4e9fc098-f611-4128-ae0b-2e6b9cb232c8"}
{"level":"info","msg":"Reported a result","path":"/results","time":"2022-04-01T18:46:23.056295-07:00","uuid":"4e9fc098-f611-4128-ae0b-2e6b9cb232c8"}
{"level":"info","msg":"Enqueued a recurring task","time":"2022-04-01T18:46:23.056376-07:00","uuid":"28e9bea9-5d0c-4dd5-af4f-c22944fc4fcd"}
It represents enqueuing a recurring task with a certain uuid, the results of which can be reported multiple times (or not at all) with the same uuid. I'm interested in determining the interval elapsed between when the task was enqueued and when the result was reported for the first time. So far, I can display the results this outer join table,
msg="Enqueued a recurring task"
| join type=outer left=L right=R where L.uuid = R.uuid
[ search msg="Reported a result" | dedup uuid sortby +_time]
| fillnull value=""
| table _time, L.msg, L.uuid, R.msg, L.time, R.time
What I'd like for convenience is to add an additional column with the difference between R.time and L.time. As far as I can tell from how to calculate duration between two events Splunk, one way to do this is to use strptime to convert those time fields into time values and then determine their difference. However, the time of the events was already parsed when importing the data (as seen from the built-in _time field) so this seems inefficient to me. Is there a more efficient way?
Update
Even the 'inefficient' method using strptime is proving tricky; I've added eval fields t to each of the searches,
msg="Enqueued a recurring task"
| eval t=strptime(time, "%Y-%m-%dT%H:%M:%S.%6N%:z")
| join type=outer left=L right=R where L.uuid = R.uuid
[ search msg="Reported a result"
| dedup uuid sortby +_time
| eval t=strptime(time, "%Y-%m-%dT%H:%M:%S.%6N%:z")]
| fillnull value=""
| table _time, L.msg, L.uuid, R.msg, L.time, R.time, L.t, R.t, R.t-L.t
and it appears to parse the time correctly, yet the difference R.t-L.t shows up empty in the table:
Any idea why it's not showing the difference?
Update 2
I've tried both of RichG's answers, but they both lead to the following error in Splunk:
Error in 'eval' command: Type checking failed. '-' only takes numbers.
(See screenshots below). The way I'm running Splunk is with a Docker container,
docker run -p 8000:8000 -e "SPLUNK_START_ARGS=--accept-license" -e "SPLUNK_PASSWORD=supersecret" --name splunk splunk/splunk:latest
Update 3
I finally got this to work using RichG's updated answer, combining both an evaluated strftime field with a diff field where R.t and L.t are quoted:
msg="Enqueued a recurring task"
| eval t=strptime(time, "%Y-%m-%dT%H:%M:%S.%6N%:z")
| join type=outer left=L right=R where L.uuid = R.uuid
[ search msg="Reported a result"
| dedup uuid sortby +_time
| eval t=strptime(time, "%Y-%m-%dT%H:%M:%S.%6N%:z")]
| fillnull value=""
| eval diff='R.t'-'L.t'
| table _time, L.msg, L.uuid, R.msg, L.time, R.time, L.t, R.t, diff
The time difference is empty in the table because the table command does not perform arithmetic. You must calculate the difference in a separate eval and display the result in the table.
index=foo msg="Enqueued a recurring task"
| eval t=strptime(time, "%Y-%m-%dT%H:%M:%S.%6N%:z")
| join type=outer left=L right=R where L.uuid = R.uuid
[ search index=foo msg="Reported a result"
| dedup uuid sortby +_time
| eval t=strptime(time, "%Y-%m-%dT%H:%M:%S.%6N%:z")]
| fillnull value=""
| eval diff='R.t' - 'L.t'
| table _time, L.msg, L.uuid, R.msg, L.time, R.time, L.t, R.t, diff
You should be able to use each event's _time field to avoid having to parse the time field.
index=foo msg="Enqueued a recurring task"
| join type=outer left=L right=R where L.uuid = R.uuid
[ search index=foo msg="Reported a result"
| dedup uuid sortby +_time ]
| fillnull value=""
| eval diff='R._time' - 'L._time'
| table _time, L.msg, L.uuid, R.msg, L.time, R.time, L.t, R.t, diff
Fairly confident something akin to this should work (without using join:
index=ndx sourtype=srctp uuid=* msg=*
| stats min(_time) as first_time max(_time) as last_time earliest(msg) as first_msg latest(msg) as last_msg by uuid
| eval diff_seconds=last_time-first_time
| eval first_time=strftime(first_time,"%c"), last_time=strftime(last_time,"%c")
This approach will presume that _time has been set properly in the sourcetype's props.conf, but if it has, this gets you what you're looking for in one pass.

How do I added a token to the query of a dashboard in Splunk?

I recreated the dashboard using the report query and have the search returning all of the table results. I have an input for the reference number as a text box. The token name is: purchCostReferenceToken
I want to limit the table results based on this token. This is the query:
<form>
<label>Thru Train Dashboard</label>
<fieldset submitButton="false" autoRun="true">
<input type="text" token="purchCostReferenceToken" searchWhenChanged="true">
<label>Enter a TMS Reference Number to Filter Table</label>
<default>*</default>
<initialValue>*</initialValue>
</input>
</fieldset>
<row>
<panel>
<title>Thru Train Data</title>
<table>
<search>
<query>index=... "<billingMethod>RULE</billingMethod>" "createMessage MsgSource" | xmlkv | rex max_match=0 "\<purchasedCostTripSegment\>(?P<segment>[^\<]+)" |eval Segments = mvrange(1,mvcount(mvindex(segment, 0, 2))+1,1) | rex max_match=0 "\<carrier\>(?P<Carriers>[^\<]+)" | rex max_match=0 "\<billingMethod\>(?P<BillingMethod>[^\<]+)" | rex max_match=0 "<purchasedCostTripSegment>[\s\S]*?<origin>\s*<ns2:numberCode>(?P<Origin>\d+)" | rex max_match=0 "<purchasedCostTripSegment>[\s\S]*?<destination>\s*<ns2:numberCode>(?P<Destination>\d+)" | rex max_match=0 "<purchasedCostTripSegment>[\s\S]*?<stopOff>\s*<ns2:stopOffLocation>\s*<ns2:numberCode>(?P<StopOffLocation>\d+)" | eval Time =_time | convert timeformat="%m-%d-%Y %H:%M:%S" ctime(Time) | table purchCostReference, eventType, Time, Segments, Carriers, BillingMethod, Origin, Destination, StopOffLocation | sort Time</query>
<earliest>-30d#d</earliest>
<latest>now</latest>
</search>
<option name="drilldown">none</option>
</table>
</panel>
</row>
</form>
Where do I add the token to limit the search?
I tried adding this to the end of the query before the table command:
... | eval Time =_time | convert timeformat="%m-%d-%Y %H:%M:%S" ctime(Time) purchCostReference=$purchCostReferenceToken$ | table purchCostReference, eventType, Time, Segments, Carriers, BillingMethod, Origin, Destination, StopOffLocation | sort Time
I get an error...error in convert command: the argument purchCostReference- is invalid
I would like to add filters in several of the table columns. The purchCostReference value is an extracted field in the query using xmlkv
Technically, a token can be placed anywhere in a query, but the query has to be valid when the token is replaced with its value. convert timeformat="%m-%d-%Y %H:%M:%S" ctime(Time) purchCostReference=4 is not valid SPL.
If the field referenced by the token is extracted automatically then it's usually best to put the token in the base search. That's not the case here.
You should use a search or where command to filter events based on the token value. Something like xmlkv | search purchCostReference=$purchCostReferenceToken$.

How to select dropdown if it is not have id and label in selenium

Here is my HTML
<option ng-selected="user.id == userDetail.assignedTo.id" ng-repeat="user in assignableUsers | orderBy:user.name" value="9,5304" class="ng-binding ng-scope">
User1
</option>
<option ng-selected="user.id == userDetail.assignedTo.id" ng-repeat="user in assignableUsers | orderBy:user.name" value="19,5304" class="ng-binding ng-scope">
User2
</option>
It has list of dropdown values. I wanted to select say eg., User2.
If I give select by Label is not working since it does not have label and
value also it has id not text (which is dynamic number build to build).
Only option is selectByIndex by 2. If incase, User11 exists then it takes User11 as the dropdown list orders by alpahbetically ascending..
I have option to take getText for Each Index and match it User2 then select that index.. Is that only way or any other solution?

Is there a way to colspan a table header with GitHub flavored markdown?

HTML allows extending a table's header row across multiple columns using colspan:
<table>
<tr><th colspan=2>Logical Operators</th></tr>
<tr><td>&&</td><td>Logical and</td></tr>
<tr><td>||</td><td>Logical or</td></tr>
<tr><td>!</td><td>Logical not</td></tr>
<tr><td>? :</td><td>Logical ternary</td></tr>
</table>
On GitHub, when this HTML is rendered in a readme.md file it looks like this:
...but using markdown syntax to create a table, I can't span the table's header row across columns, e.g. I can only split up the header text:
| Logical | Operators |
|:---:| --- |
| `&&` | Logical and |
| `\|\|` | Logical or |
| `!` | Logical not |
| `? :` | Logical ternary |
...and rendering the GFM table on GitHub looks like:
I tried emulating this solution for using colspan in the table's data rows, but I could not get it to work with the header row. Is there a way to span the GFM table's header row across more than one column with GitHub flavored Markdown?
I've posted the question to the folks at the GH MD repo.
I did it this way in order to generate a table with 5 columns with headers spanning respectively over 3 and 2 columns:
<table>
<tr>
<td colspan=3>a <td colspan=2>b
<tr>
<td colspan=1>col1 <td colspan=1>col2 <td colspan=1>col3<td colspan=1>col4 <td colspan=1>col5
</table>
My two cents.

Choosing and keeping multiple radio button value inside a table

I am using radio button for choosing employee type such as part-time , full-time etc.I could choose only one item according followed table structure.How can i select multiple radio button and keep these inside a table.For instance such as keeping inside an array?
+--------------+----------------+
| EmployeeId | EmployeeType |
+--------------+----------------+
| 2 | 2 |
+--------------+----------------+
| 3 | 1 |
+--------------+----------------+
EmployeeTypes :
0 Part-time
1 Full-time
2 Consultant
3 Trainer
In HTML, radio buttons work by posting different values to the same name - the value of the item selected.
<form action="">
<input type="radio" name="sex" value="male">Male
<input type="radio" name="sex" value="female">Female
</form>
http://www.w3schools.com/html/tryit.asp?filename=tryhtml_radio
However, if you have a table of data, and you need to be able to edit multiple rows at the same time, there will be the need to differentiate between EmployeeType for User 2 and EmployeeType for User 3. So the radio buttons with various values might now instead post to names such as EmployeeType_2 and EmployeeType_3.
This is essentially what will happen behind the scenes when you try to do code like the following.
How can I post a list of items in MVC
At some point here you may want to actually consider using a grid control, but I'm not trying to plug Telerik or DevExpress controls. So, instead I'll mention the following that came up in my search. Perhaps other users can suggest other controls.
http://www.codeproject.com/Tips/720348/MVC-Grid-Inline-Edit
http://www.codeproject.com/Articles/165410/ASP-NET-MVC-Editable-DataTable-jQuery-DataTables-a