Saturday, December 10, 2011

Sitecore GeoIP Country Resolving - Jump to Lightspeed

There is always a trade-off between the website performance and the number of features you want to provide to the visitors. With MaxMind GeoIP services, which are tightly integrated with Sitecore DMS you can get the detailed info about each website user, but sometimes it can take a while to retrieve all requested information.
In this article, I'll show how to customize Sitecore, to use GeoLite database for instant country resolving.


GeoLite Country is a free country GeoIP database provided by MaxMind. It's just a one megabyte of data in a binary format, and it has a C# API which can be downloaded here.

The following classes are required for using the API:








At the Sitecore side, customization point is a CountryCondition class, which can be replaced with your own implementation in the following item:
/sitecore/system/Settings/Rules/Conditional Renderings/Conditions/Geo IP/Country Condition

And override "GetColumnValue" method, see the code below, it is so simple, that does not require comments.

        private static readonly LookupService lookupService =
            new LookupService(
                HttpContext.Current.Server.MapPath(
                    Sitecore.Configuration.Settings.GetSetting("Sitecore.SharedSource.GeoLiteResolver.DataFile")),
                LookupService.GEOIP_MEMORY_CACHE);

        protected override string GetColumnValue(VisitorDataSet.VisitsRow visit)
        {
            Country country = lookupService.getCountry(HttpContext.Current.Request.UserHostAddress);
            return country.getCode();
        }


So, this is it, you're done with customization, and country resolving is now almost instant. How fast is it? Well, it takes 7-10 ms to load the data file (~1 megabyte) to the memory during first request (after the AppPool recycle, etc.), and then - less then 1ms to perform look-up.

One more thing - I've created package which will be soon published to the Shared Source. It contains compiled binaries, updated item, and the database. All you need to get started without coding at all.
You can download the package here (This product includes GeoLite data created by MaxMind, available from http://maxmind.com/). It can be used with Sitecore 6.5 only, but it is rather easy to update the code to work with previous versions, let me know if you need help with it.


5 comments:

  1. Good insight into the condition resolving. But would it not be more convenient and useful to override the Sitecore.Analytics.Lookups.MaxMindProvider to use the local file lookup instead of the service one?

    ReplyDelete
  2. It just seemed easier to me to override the condition. Also, such approach guarantees that country information will be available on first visit.

    ReplyDelete
  3. Any tips on how to spoof location during local development? I need to simulate an EU user to test that my code is properly showing a control and not sure how to do that locally.

    ReplyDelete
  4. There is even a blog post about it - http://sitecoresnippets.blogspot.com/2012/04/update-geoip-info-in-dms-database.html :)

    ReplyDelete
  5. Any suggestion for upgrading the code to sitecore 9 ?

    ReplyDelete