Dashboards & Visualizations

Cluster map dot clicks not returning correct info

hawkeyesc72
Engager

Hi all, 

I'm hoping someone can help me with this. I've been working on it for a few weeks and can't figure it out. Thank you in advance for any assistance you may be willing/able to offer.

OK, here's the situation:

I've got a 2 panel dashboard: statistics table on left and cluster map on right. The table side seems to be working great. The map is populating, but when I click on a dot to open a new tab and get more details I keep running into a "phantom IP'-type of issue.

Dashboard XML:

<form version="1.1" theme="light">
<label>Impossible Travel (ALL USERS)</label>
<fieldset submitButton="true" autoRun="true">
<input type="time" token="time_tok" searchWhenChanged="false">
<label>Time Range</label>
<default>
<earliest>-96h@h</earliest>
<latest>now</latest>
</default>
</input>
<input type="text" token="user_search_tok" searchWhenChanged="false">
<label>Search User (Email or First Last)</label>
<default>*</default>
</input>
</fieldset>
<row>
<panel>
<table>
<search>
<query>index=okta outcome.result IN ("SUCCESS", "ALLOW")
NOT (client.ipAddress="34.192.0.0/12" OR client.ipAddress="34.194.*")
NOT (*Guest* OR *Bontemps* OR "Okta System*" OR "Okta Dashboard*" OR "Okta Browser Plugin" OR "Pharos Beacon" OR "EchoVideo" OR "Omnigo Identity Server" OR "Drata" OR "Okta Administration" OR "Active Directory Agent")
| iplocation client.ipAddress
| eval City = if(cidrmatch("149.150.0.0/16", client.ipAddress), "SHU Campus", City)
| sort 0 actor.alternateId _time
| streamstats window=2 current=f last(lat) as prev_lat last(lon) as prev_lon last(City) as prev_city last(Country) as prev_country last(Region) as prev_state last(_time) as prev_time by actor.alternateId
| where isnotnull(prev_city) AND City != prev_city

| eval duration = _time - prev_time
| eval h = floor(duration/3600)
| eval m = floor((duration%3600)/60)
| eval Time_Between = case(h &gt; 0, h."hr ".m."min", m &gt; 0, m."min", 1=1, "0min")

| where duration &lt;= 7200
| eval user_name = coalesce('actor.displayName', display_name, "Unknown")

| eval lat1 = lat*pi()/180, lon1 = lon*pi()/180, lat2 = prev_lat*pi()/180, lon2 = prev_lon*pi()/180
| eval dlat = lat2 - lat1, dlon = lon2 - lon1
| eval a = pow(sin(dlat/2),2) + cos(lat1) * cos(lat2) * pow(sin(dlon/2),2)
| eval c = 2 * atan2(sqrt(a), sqrt(1-a))
| eval distance_miles = round(3958.8 * c, 2)

| eval City = mvappend(prev_city, City)
| eval State = if(prev_state == Region, Region, mvappend(prev_state, Region))
| eval Country = if(prev_country == Country, Country, mvappend(prev_country, Country))
| fieldformat _time = strftime(_time, "%d %b %Y %l:%M%p")
| sort - _time
| table _time, user_name, actor.alternateId, City, State, Country, distance_miles, Time_Between
| rename user_name as "User", actor.alternateId as "Email", distance_miles as "Mileage", Time_Between as "Time Between Entries"</query>
<earliest>$time_tok.earliest$</earliest>
<latest>$time_tok.latest$</latest>
</search>
<option name="drilldown">none</option>
<option name="refresh.display">progressbar</option>
<format type="color" field="Country">
<colorPalette type="expression">if(value != "United States" AND isnotnull(value) AND value != "" AND value != "Internal/NJ" AND value != "SHU Campus", "#27F2F5", "")</colorPalette>
</format>
<format type="color" field="Mileage">
<colorPalette type="expression">case(value &gt; 1000, "#FFFF00")</colorPalette>
</format>
</table>
</panel>
<panel>
<title>Impossible Travel Map</title>
<map>
<search>
<query>index=okta outcome.result IN ("SUCCESS", "ALLOW")
NOT (client.ipAddress="34.192.0.0/12" OR client.ipAddress="34.194.*")
NOT (*Guest* OR *Bontemps* OR "Okta System*" OR "Okta Dashboard*" OR "Okta Browser Plugin" OR "Pharos Beacon" OR "EchoVideo")
| iplocation client.ipAddress
| eval City = if(cidrmatch("149.150.0.0/16", client.ipAddress), "SHU Campus", City)
| sort 0 actor.alternateId _time
| streamstats window=2 current=f last(City) as prev_city last(_time) as prev_time by actor.alternateId
| where isnotnull(prev_city) AND City != prev_city
| eval duration = _time - prev_time
| where duration &lt;= 7200
| geostats latfield=lat longfield=lon globallimit=0 maxzoomlevel=18 count by client.ipAddress</query>
<earliest>$time_tok.earliest$</earliest>
<latest>$time_tok.latest$</latest>
</search>
<option name="height">600</option>
<option name="mapping.seriesColors">[0x00FF00, 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF, 0xFF9900]</option>
<option name="mapping.type">marker</option>
<option name="refresh.display">progressbar</option>
<drilldown>
<link target="_blank">
<![CDATA[/app/search/search?q=search index=okta | iplocation client.ipAddress | where (lat > ($click.lat$ - 0.1) AND lat < ($click.lat$ + 0.1)) AND (lon > ($click.lon$ - 0.1) AND lon < ($click.lon$ + 0.1)) | eval City = if(cidrmatch("149.150.0.0/16", client.ipAddress), "SHU Campus", City) | table _time, actor.alternateId, City, client.ipAddress, outcome.result&earliest=$time_tok.earliest$&latest=$time_tok.latest$]]>
</link>
</drilldown>
</map>
</panel>
</row>
</form>

Dot click SPL returned in new tab:

The SPL returned varies a bit. The overall general format is 
index=okta | iplocation client.ipAddress | search City="*104.28.56.1*" OR client.ipAddress="*104.28.56.1*" | eval City = if(cidrmatch("149.150.0.0/16", client.ipAddress), "SHU Campus", City) | table _time, actor.alternateId, City, client.ipAddress, outcome.result

However, the IP address in City="IP"  OR client.ipAddress = "IP" varies depending on the search timeframe. I get different IPs returned for 4, 8, 12 and 24 hour searches.

What I'm trying to get to is when I click the dot a new tab opens and I see details about the user, IP address and location coming from and (if possible) IP address and location going to in that dot region.

I feel like everything is good except for the dot click details that get returned.

 

Labels (1)
0 Karma
Got questions? Get answers!

Join the Splunk Community Slack to learn, troubleshoot, and make connections with fellow Splunk practitioners in real time!

Meet up IRL or virtually!

Join Splunk User Groups to connect and learn in-person by region or remotely by topic or industry.

Get Updates on the Splunk Community!

Index This | What travels the world but is also stuck in place?

April 2026 Edition  Hayyy Splunk Education Enthusiasts and the Eternally Curious!   We’re back with this ...

Discover New Use Cases: Unlock Greater Value from Your Existing Splunk Data

Realizing the full potential of your Splunk investment requires more than just understanding current usage; it ...

Continue Your Journey: Join Session 2 of the Data Management and Federation Bootcamp ...

As data volumes continue to grow and environments become more distributed, managing and optimizing data ...