# -*- coding: utf-8 -*- # Author: Konstantinos Livieratos <livieratos.konstantinos@gmail.com> # https://github.com/koslibpro/django-traffic/ import logging from django.conf import settings from django.utils import timezone from django.utils.deprecation import MiddlewareMixin from django.contrib.gis.geoip2 import GeoIP2 from elasticsearch import Elasticsearch def _load_geo_db(): geo_db_path = getattr(settings, 'GEO_DB_PATH', None) if geo_db_path is None: if hasattr(settings, 'GEOIP_PATH'): g = GeoIP2() return g logging.error('[django-traffic] GEOIP_PATH or GEO_DB_PATH should be present in settings.py') return None return GeoIP2(path=geo_db_path) class ESTrafficInfoMiddleware(MiddlewareMixin): def __init__(self, get_response=None): self.get_response = get_response if hasattr(settings, 'TRAFFIC_INDEX_NAME'): self.index_name = getattr(settings, 'TRAFFIC_INDEX_NAME') else: self.index_name = "django-traffic" # if settings.ES_CLIENT: if hasattr(settings, 'ES_CLIENT'): self.es = settings.ES_CLIENT else: assert settings.ES_HOST, 'ES_HOST definition in settings.py is required' self.es = Elasticsearch( hosts=[settings.ES_HOST] ) super(ESTrafficInfoMiddleware, self).__init__(get_response=get_response) def process_request(self, request, *args, **kwargs): self.es_upstream(request) return None def ip_to_cordinates(self, device_ip): g = _load_geo_db() try: lat, lng = g.lat_lon(device_ip) except Exception as e: logging.error("[django-traffic] Error while getting lan/lon from GEOIP2: %s " % e) return None, None else: return lat, lng def es_upstream(self, request): device_ip = request.META.get('HTTP_X_FORWARDED_FOR') or request.META.get('REMOTE_ADDR') device_ip = str(device_ip).split(',')[0] logging.info("[django-traffic] Device IP: %s" % device_ip) if not self.es.indices.exists(index=self.index_name): mapping = { "mappings": { "request-info": { "properties": { "timestamp": { "type": "date" }, "text": { "type": "string" }, "location": { "type": "geo_point" }, "method": { "type": "string" }, "body": { "type": "string" }, "path": { "type": "string" }, "path_info": { "type": "string" }, "scheme": { "type": "string" }, "encoding": { "type": "string" }, "encoding_type": { "type": "string" }, "ip_addr": { "type": "ip" } } } } } logging.info("[django-traffic] Creating new elasticsearch indice...") self.es.indices.create(index=self.index_name, body=mapping) doc = { "timestamp": timezone.now(), "text": "django-traffic geo-point object", "method": request.method, "body": request.body, "path": request.path, "path_info": request.path_info, "scheme": request.scheme, "encoding": request.encoding, "encoding_type": getattr(request, 'encoding_type', ''), "ip_addr": device_ip } lat, lng = self.ip_to_cordinates(device_ip) if lat and lng: doc["location"] = { "lat": lat, "lon": lng } else: if not getattr(settings, 'LOG_WITHOUT_LOCATION', False): return res = self.es.index(index=self.index_name, doc_type='request-info', body=doc) if res['created']: logging.info("[django-traffic] request indexed")