So, I have a big set of web stats for a given time in a search. Basically, I want it broken down by uri_path and for each uri_path, it tells me the number of hits that were returning status 500.
So, for example, let's say that I only had two uri_path values, as follows:
During the time frame, each of those only returned two status values: 200 and 500.
Let's say there was 100 hits for /fnord/hooray.cfm, out of which 20 were 500 errors. At that same time, there were 200 hits for /dronf/test.cfm, 100 of which were 500 errors. Ideally, the resulting search would show something like this:
/fnord/horray.cfm 20 20%
/fronf/test.cfm 100 50%
Does that make sense? It seem like it would be easy to do this, but I'm not sure how. How get the search and/or report to do that?
There are many different ways of accomplishing this search, but the one I find most intuitive and easily understood is to approach it like this:
... | chart count(eval(status=500)) as internal_errors, count as total_requests by uri_path | eval perc=internal_error/total_requests
Here we use the count function of the chart command first to get counts of the two interesting values.
First, we get the count of all events where status=500 and save that as a new field internal_errors. Second, we count the total number of requests as total_requests. And lastly, we tell Splunk to apply this chart command "by" uri_path (think group by).
Now we just have counts of 500s and the total number of requests, so we add on the eval-command to actually get the percentile of internal_errors in relation to total_requests.
To get the output you are requesting, you can select the interesting fields by use of:
... | fields uri_path, internal_errors, perc
In addition to jwestberg's answer, you can also use things like:
... | top limit=0 status by uri_path
... | stats count by status,uri_path | eventstats sum(count) as uri_total by uri_path | eval percent=count/uri_total
to get all statuses count and percentages. You can then add a
| where status=500 or
| where status==500 OR status==200 if you want to be selective about what statuses you're bringing back.
Combining the two approaches above (thank you both) and experimenting a little, I ended up going with this:
... | stats count by status,uri_path | eventstats sum(count) as total_hits by uri_path | eval percent_errors=(count/total_hits)*100 | where status=500 | fields count, uri_path, percent_errors, total_hits | sort - count