At some level time on this blog can be marked by when I'm having a car worked on. Today isn't an exception. While that means the overall frequency is low the upshot is I get to spend my morning working in Chick-fil-A with some good breakfast in mah belly and good music in the background.
A couple days ago I wanted to get a feel for where users were going/how they were using Splunk. This is one of those things that seems easy but the further you go down this path the more offshoots there are. At any rate I was wanting to focus on UI navigation so knew I was going to be looking at the web access logs vs searches performed. There is a couple screens in SoS but they weren't working. There are also a couple screens in the search app (in 6x that is in Activity > System Activity) but those views, while working, didn't display what I was really after.
In looking at the queries behind all of these screens I ended up with the following:
index=_internal source=*web_access.log* uri=*/app/* uri!=*/images/* status=200 | rex field=uri_path "app/(?<app>[^/]+)/(?<view>.+)" | where app!="launcher" AND view!="Home" AND view!="home" AND view!="landing" | table _time host app view user _raw
It is somewhat interesting sometimes the nuances between the search and where commands which is why in this case I chose where (I think - it was 2 days ago /shrug). I'm pretty lazy at heart so I've pretty much kept this base query regardless of the stats command used. In my dashboard I could have all the panels refer back to a base search but note again the previous sentence and the reality is I will have this dashboard emailed to me once a week. At any rate you might need to adjust the query based on how many and uses of your search heads (if you have more than one) or whitelist your Splunk admins so the numbers aren't skewed. Remember this is simply for navigation within the UI and does not capture the types and number of searches. In other words if someone navigates to dashboard X in app Y and then uses that dashboard 150 times in one day it will only show up in the context of this search 1 time (unless their session times out and they log back in causing the page to refresh).
To skip ahead just a bit one of the things you will likely want to do, especially depending on audience, is to translate the app into the something people can read using the app's label. I accomplished this with a join to a REST search like this
... base search ... | stats ... | join app [| rest splunk_server=local /services/apps/local/ | rename title as app | table app label] | ...clean up ...
When you go to answer questions like which apps are the most popular you have at least 2 ways of addressing that. The first is by looking at the app with the highest number of unique people hitting it (this query trims the list to the top 5)
index=_internal source=*web_access.log* uri=*/app/* uri!=*/images/* status=200 | rex field=uri_path "app/(?<app>[^/]+)/(?<view>.+)" | where app!="launcher" AND view!="Home" AND view!="home" AND view!="landing" | table _time host app view user _raw | stats dc(user) as "Unique Users" by app | join app [| rest splunk_server=local /services/apps/local/ | rename title as app | table app label] | table label "Unique Users" | sort -"Unique Users" | rename label as App | head 5
The other way to answer the question is by the most views - again this query is looking at the top 5
index=_internal source=*web_access.log* uri=*/app/* uri!=*/images/* status=200 | rex field=uri_path "app/(?<app>[^/]+)/(?<view>.+)" | where app!="launcher" AND view!="Home" AND view!="home" AND view!="landing" | table _time host app view user _raw | stats count as "Total Views" by app | join app [| rest splunk_server=local /services/apps/local/ | rename title as app | table app label] | table label "Total Views" | sort -"Total Views" | rename label as App | head 5
The resulting data is pretty small so I have those as dashboard panels side by side. The next query shows a number of stats by app: total views, unique users, and number of unique dashboards accessed w/in the app. I also wanted to bake in a little bit of a trend over time w/o using timechart so used the sparkline command.
index=_internal source=*web_access.log* uri=*/app/* uri!=*/images/* status=200 | rex field=uri_path "app/(?<app>[^/]+)/(?<view>.+)" | where app!="launcher" AND view!="Home" AND view!="home" AND view!="landing" | table _time host app view user _raw | stats sparkline as "Usage Trend by Day" dc(user) as "Unique Users" dc(view) as "Unique Dashboards" count as "Total Views" by app | join app [| rest splunk_server=local /services/apps/local/ | rename title as app | table app label] | table label "Usage Trend by Day" "Unique Users" "Unique Dashboards" "Total Views" | rename label as App| sort -"Total Views"
The last query is one that shows which dashboard was accessed by app. The display is one I favor from a logical grouping perspective and is accomplished by using multiple stats commands. As an aside - multiple stats commands are also useful from a drill down perspective.
index=_internal source=*web_access.log* uri=*/app/* uri!=*/images/* status=200 | rex field=uri_path "app/(?<app>[^/]+)/(?<view>.+)" | where app!="launcher" AND view!="Home" AND view!="home" AND view!="landing" | table _time host app view user _raw | stats count by app view user | stats sum(count) as total_views dc(user) as distinct_users by app view | sort -total_views | stats list(view) as Dashboard list(total_views) as Views list(distinct_users) as "Distinct Users" by app | join app [| rest splunk_server=local /services/apps/local/ | rename title as app | table app label] | table label Dashboard Views "Distinct Users" | rename label as App| sort label
Hopefully this is helpful. I feel like I should incorporate user names somehow but haven't gotten that far. Might add that from a drill down perspective or as additional panels. In 6x it is easy to add a time range picker to a dashboard which is what I've done for the above with the default of 7 days. Anyone doing something similar? Would be interested in seeing what you are doing and comparing notes.
Mark
No comments:
Post a Comment