Geo IP API lookup provider for Sitecore

As an alternative to the geo IP lookup provider that ships with Sitecore I have created my own provider using IP-API which is a free web service a while back and I have used it already for a couple years.

IP-API offers free lookup’s using their web services for up to 150 requests per minute. That means it will be good enough for your Sitecore setup if you have 150 or less new user sessions created per minute as there is some caching implemented that will ensure that each IP look up will only be done once. The caching is using the Sitecore built-in GeoIpCacheManager.GeoIpCache.

There is also a paid subscription for 160 Euro per year if you want unlimited amount of lookup’s which is a good value for money.

The IP-API based lookup provider is now available on Github as well as a Sitecore module on the market place.

If you want to create your own lookup provider you can start by creating a new class that derives from Sitecore.Analytics.Lookups.LookupProviderBase. Don’t forget that you also need to add a project reference to the Sitecore.Analytics library. For that I am using the Sitecore nuget server which is pretty cool.

Then you can use your own logic to lookup geo location information based on IP address by overriding the¬†GetInformationByIp(string ip) from the base class. Don’t forget to use the caching provided by Sitecore so you will not lookup the same IP address multiple times:

    GeoIpCache geoIpCache = GeoIpCacheManager.GeoIpCache;
    WhoIsInformation information = geoIpCache.Get(ip);
    if (information != null)
        return information;

Also, make sure you handle errors gracefully in case your logic fails:

       // Your logic to lookup
    catch (Exception ex)
       HandleLookupErrorArgs handleLookupErrorArgs = new HandleLookupErrorArgs(ex);
       CorePipeline.Run("ces.geoIp.handleLookupError", handleLookupErrorArgs);
       if (handleLookupErrorArgs.Fallback == null)

       if (handleLookupErrorArgs.CacheFallback)
           geoIpCache.Add(ip, handleLookupErrorArgs.Fallback);

       return handleLookupErrorArgs.Fallback;

Last but not least you will also need to create a Sitecore config patch to replace the built-in Sitecore lookup provider which can be done like this:

    <lookupManager defaultProvider="default">
          <patch:attribute name="type">Swissworx.Modules.Analytics.Lookups.IpApi.LookupProvider, Swissworx.Modules.Analytics.Lookups.IpApi</patch:attribute>

Sitecore 8.1 SolrConnectionException – the operation timed out

Lately I have noticed a lot of the following exceptions in our client’s Sitecore log:

Exception: SolrNet.Exceptions.SolrConnectionException
 Message: The operation has timed out

This started to happen as our dedicated processing server is going through a few months of data as it was not running properly for a while.

I have spent some time trying to tweak the Solr server’s parameters such as the request time out without seeing any improvement in regards to the number of logged time out exceptions.

Eventually I approached Sitecore support and they told me that this is a known bug in Sitecore 8.1 which has been fixed for 8.2.

If you are running 8.1 same as us and you experience this problems, I recommend you reach out to Sitecore support as they have a patch for each of their support DI containers which will allow you to configure the Solr time out in the settings.

I hope this helps others to save the time investigating this issue.

Sitecore 8 MongoCommandException using Mongo Db as a service (mLab)

In essence Andy Cohen has already described the solution to overcome the MongoCommandException in one of his blog posts.

However, when I connected to my Mongo database hosted with mLab and attempted to run the db.grantRolesToUser command I got an exception that my user was not authorized on my database to execute the command.

If you experience the same issue the following steps might help you to overcome it:

  1. On your admin database add a new admin user
  2. Use command prompt to login to admin database using the newly created admin user
  3. Switch to your analytics database
  4. Run db.grantRolesToUser command