Esempio n. 1
0
class KronosLoggingMiddleware(object):
  FORWARDED_IP_FIELDS = {'HTTP_X_FORWARDED_FOR',
                         'HTTP_X_FORWARDED_HOST',
                         'HTTP_X_FORWARDED_SERVER'}

  def __init__(self):
    from django.conf import settings
    from django.core.exceptions import ImproperlyConfigured

    if not hasattr(settings, 'KRONOS_MIDDLEWARE'):
      raise ImproperlyConfigured
    kronos_config = settings.KRONOS_MIDDLEWARE
    if not isinstance(kronos_config, dict):
      raise ImproperlyConfigured
    if 'host' not in kronos_config:
      raise ImproperlyConfigured
    if 'stream' not in kronos_config:
      raise ImproperlyConfigured
    self.client = KronosClient(
      kronos_config['host'],
      blocking=kronos_config.get('blocking', False),
      sleep_block=kronos_config.get('sleep_block', 0.1))
    self.stream = kronos_config['stream']
    self.namespace = kronos_config.get('namespace')
    self.log_exception_stack_trace = kronos_config.get(
        'log_exception_stack_trace', False)
    self.fail_silently = kronos_config.get('fail_silently', True)

  def _get_ip(self, request):
    if not KronosLoggingMiddleware.FORWARDED_IP_FIELDS & set(request.META):
      return request.META.get('REMOTE_ADDR', '').strip()
    for field in KronosLoggingMiddleware.FORWARDED_IP_FIELDS:
      if field in request.META:
        return request.META[field].split(',')[-1].strip()

  def process_request(self, request):
    request._kronos_event = {
      'start_time': time.time(),
      '@time': kronos_time_now(),
      'method': request.method.upper(),
      'path': request.path,
      'client_ip': self._get_ip(request)
    }
    get_dict = request.GET.dict()
    if get_dict:
      request._kronos_event['get_params'] = get_dict
    try:
      if not request.body:
        return
    except:
      # The following exception is thrown if the body could not be read.
      # Exception("You cannot access body after reading from request's data
      #           stream")
      return
    post_dict = request.POST.dict()
    if (len(post_dict) == 1 and
        post_dict.values()[0] == '' and
        post_dict.keys()[0] == request.body):
      # There is no real *form* POST.
      try:
        request._kronos_event['body'] = json.loads(request.body)
      except ValueError:
        request._kronos_event['body'] = request.body
    else:
      request._kronos_event['post_params'] = post_dict

  def process_exception(self, request, exception):
    self.client._log_exception(
      request._kronos_event, exception,
      sys.exc_info()[2] if self.log_exception_stack_trace else None)

  def process_response(self, request, response):
    start_time = request._kronos_event.pop('start_time')
    request._kronos_event['duration'] = time.time() - start_time
    try:
      self.client.put({self.stream: [request._kronos_event]},
                      namespace=self.namespace)
    except:
      if self.fail_silently:
        log.error('Failed to log event to Kronos.', exc_info=True)
      else:
        raise

    return response
Esempio n. 2
0
class KronosLoggingMiddleware(object):
    FORWARDED_IP_FIELDS = {
        'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST',
        'HTTP_X_FORWARDED_SERVER'
    }

    def __init__(self):
        from django.conf import settings
        from django.core.exceptions import ImproperlyConfigured

        if not hasattr(settings, 'KRONOS_MIDDLEWARE'):
            raise ImproperlyConfigured
        kronos_config = settings.KRONOS_MIDDLEWARE
        if not isinstance(kronos_config, dict):
            raise ImproperlyConfigured
        if 'host' not in kronos_config:
            raise ImproperlyConfigured
        if 'stream' not in kronos_config:
            raise ImproperlyConfigured
        self.client = KronosClient(
            kronos_config['host'],
            blocking=kronos_config.get('blocking', False),
            sleep_block=kronos_config.get('sleep_block', 0.1))
        self.stream = kronos_config['stream']
        self.namespace = kronos_config.get('namespace')
        self.log_exception_stack_trace = kronos_config.get(
            'log_exception_stack_trace', False)
        self.fail_silently = kronos_config.get('fail_silently', True)

    def _get_ip(self, request):
        if not KronosLoggingMiddleware.FORWARDED_IP_FIELDS & set(request.META):
            return request.META.get('REMOTE_ADDR', '').strip()
        for field in KronosLoggingMiddleware.FORWARDED_IP_FIELDS:
            if field in request.META:
                return request.META[field].split(',')[-1].strip()

    def process_request(self, request):
        request._kronos_event = {
            'start_time': time.time(),
            '@time': kronos_time_now(),
            'method': request.method.upper(),
            'path': request.path,
            'client_ip': self._get_ip(request)
        }
        get_dict = request.GET.dict()
        if get_dict:
            request._kronos_event['get_params'] = get_dict
        try:
            if not request.body:
                return
        except:
            # The following exception is thrown if the body could not be read.
            # Exception("You cannot access body after reading from request's data
            #           stream")
            return
        post_dict = request.POST.dict()
        if (len(post_dict) == 1 and post_dict.values()[0] == ''
                and post_dict.keys()[0] == request.body):
            # There is no real *form* POST.
            try:
                request._kronos_event['body'] = json.loads(request.body)
            except ValueError:
                request._kronos_event['body'] = request.body
        else:
            request._kronos_event['post_params'] = post_dict

    def process_exception(self, request, exception):
        self.client._log_exception(
            request._kronos_event, exception,
            sys.exc_info()[2] if self.log_exception_stack_trace else None)

    def process_response(self, request, response):
        start_time = request._kronos_event.pop('start_time')
        request._kronos_event['duration'] = time.time() - start_time
        try:
            self.client.put({self.stream: [request._kronos_event]},
                            namespace=self.namespace)
        except:
            if self.fail_silently:
                log.error('Failed to log event to Kronos.', exc_info=True)
            else:
                raise

        return response