Learn How To Create a Custom Threat Map in Splunk: Part 2

In Part 1 of this screencast series, Ian went over the basics of setting up our Splunk app using the Splunk Web Framework. He also went through the steps of setting up a basic Google Map in Splunk. In this second part of the series, he is going to cover how customize our map.

In Part 1 of this screencast series, I went over the basics of setting up our Splunk app using the Splunk Web Framework. I also went through the steps of setting up a basic Google Map in Splunk. In this second part of the series, I am going to cover how customize our map.

Here, we are extending the GoogleMapView to create our CustomGoogleMapView in order to override the way the default GoogleMapView works, specifically inside of it’s render() method.

THE NITTY GRITTY

You don’t need to read this section in order to continue to following along, but this provides a little more in-depth detail into how this all works. If you go to $SPLUNK_HOME/<appname>/share/splunk/search_mrsparkle/exposed/js/build/simplexml.min/mvc/ this is where Splunk keeps all of its views, so there’s one for a table, a chart and others including Google Maps, specifically within the googlemapview.js file. If you look at this file you will see that GoogleMapView is extending from BaseSplunkView, which all Splunk views extend from. The beauty of these views is that they allow for us to handle the data Splunk provides us from our Search Managers with ease. If you scroll down to the bottom of googlemapview.js you will see the render method – this is what we will be overriding. Of course, we aren’t limited to just overriding our render method, we could override other methods in here as well, but there’s no need to for our purposes here.

What we’ve added here is actually what the default render() method looks like in googlemapview.js, from which we are extending. The part we’ll be concentrating on is the method. Here, Splunk is looping through each row of results from our search and outputting the data to the map. For example, its pulling the latitude and longitude values with >span class="theme:twilight font:consolas font-size:16 line-height:25 lang:default decode:true crayon-inline " rel="font-size: 14px; line-height: 1.6em; background-color: initial;" data-verified="redactor" data-redactor-tag="span" data-redactor-style="font-size: 14px; line-height: 1.6em; background-color: initial;">var lat = parseFloat(row.get("lat")); and var lng = parseFloat(row.get("lng")); The parseFloat method is used because the latitude and longitude come back as float values. Normally, we can just dovar foo = row.get("bar");

Now, before going any further, go back to where you defined your googleMapView and change:

Simply enough, we are pulling the "count", "Source IP", "Category" and "City" values from our search.

Next, we’re going to define a JavaScript object called iconSrc and add properties pertaining to specific categories we defined in our search. Each of these properties will link to the a specific skull image. When we are all done, s1.png will show if the count is categorized as ‘low’ so on and so forth:

This uses the iconSrc object we defined above and inserts the category thats pulled out from our category variable: var category = row.get("Category");

As it loops through each row it will check the category and, for example, if the category pulled out of the specific row is ‘low’ the icon will then be iconSrc['low'] which maps to the image that we defined above in iconSrc['low'] = '/dj/static/<appname>/skulls/s1.png';

If you go back to your page at http://localhost:8000/dj/en-us/<appname>/home/ you should see something like this:

Threat Map

Next, we want to make it so we get popovers to provide us with additional information when we click on a specific skull.

What we are doing here is first checking whether or not infoWindowsOpenCurrently is undefined - if it’s not undefined then close it. The first time we click on an icon, infoWindowsOpenCurrently will be undefined. Then the overlay is opened for the specific marker we clicked on. Finally, we attach that infowindow to infoWindowsOpenCurrently, so it is no longer undefined.

On any subsequent clicks, infoWindowsOpenCurrently will no longer be undefined, so our first statementtypeof infoWindowsOpenCurrently !== 'undefined' will be true so the second part && infoWindowsOpenCurrently.close(); will be triggered to close infoWindowsOpenCurrently, which by this point is actual the previously opened infowindow.

Now, if you go back to the browser, you’ll see that it only opens one popover window at a time.

This is the end of Part 2, in Part 3 I go over how to add an area chart and pass the IP value from the map to the area chart.