Source code for networkapi.eventlog.models

# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import threading
from datetime import datetime
from time import time

from django.db import models
from django.utils.translation import ugettext_lazy as _

from networkapi.queue_tools.rabbitmq import QueueManager

LOG = logging.getLogger(__name__)


[docs]class EventLogError(Exception): """Representa um erro ocorrido durante acesso à tabela event_log.""" def __init__(self, cause, message=None): self.cause = cause self.message = message def __str__(self): msg = u'Causa: %s, Mensagem: %s' % (self.cause, self.message) return msg.encode('utf-8', 'replace')
[docs]class EventLog(models.Model): ADD = 0 CHANGE = 1 DELETE = 2 id = models.AutoField(primary_key=True, db_column='id_evento') usuario = models.ForeignKey( 'usuario.Usuario', db_column='id_user', blank=True, null=True ) hora_evento = models.DateTimeField() acao = models.TextField() funcionalidade = models.TextField() parametro_anterior = models.TextField() parametro_atual = models.TextField() evento = models.TextField() resultado = models.IntegerField() id_objeto = models.IntegerField() audit_request = models.ForeignKey( 'eventlog.AuditRequest', db_column='id_audit_request', blank=True, null=True ) logger = logging.getLogger('EventLog') class Meta: db_table = u'event_log' managed = True
[docs] @classmethod def log(cls, usuario, evento): """ saves the eventlog in the database @params usuario: Usuario object evento: dict in the form { "acao": value, "funcionalidade": value, "parametro_anterior": value, "parametro_atual": value, "id_objeto": value, "audit_request": value } """ parametro_anterior = [ '{0} : {1}'.format(key, evento['parametro_anterior'][key]) for key in evento['parametro_anterior']] parametro_anterior = u'\n'.join(parametro_anterior) parametro_atual = [ '{0} : {1}'.format(key, evento['parametro_atual'][key]) for key in evento['parametro_atual']] parametro_atual = u'\n'.join(parametro_atual) try: functionality = Functionality() event_log = EventLog() event_log.usuario = usuario event_log.hora_evento = datetime.now() event_log.acao = evento['acao'] event_log.funcionalidade = functionality.exist( evento['funcionalidade']) event_log.parametro_anterior = parametro_anterior event_log.parametro_atual = parametro_atual event_log.id_objeto = evento['id_objeto'] event_log.audit_request = evento['audit_request'] event_log.evento = '' event_log.resultado = 0 event_log.save() except Exception, e: cls.logger.error( u'Falha ao salvar o log: evento = %s, id do usuario = %s.' % (evento, usuario)) raise EventLogError( e, u'Falha ao salvar o log: evento = %s, id do usuario = %s.' % (evento, usuario))
[docs]class EventLogQueue(object):
[docs] @classmethod def log(cls, usuario, evento): """Send the eventlog to queues""" usuario_id = 'NoUser' if usuario: usuario_id = usuario.id # Send to Queue queue_manager = QueueManager( broker_vhost='tasks', exchange_name='eventslog', routing_key='eventslog' ) queue_manager.append({ 'action': evento['acao'], 'kind': evento['funcionalidade'], 'timestamp': int(time()), 'data': { 'id_object': evento['id_objeto'], 'user': usuario_id, 'old_value': evento['parametro_anterior'], 'new_value': evento['parametro_atual'] } }) queue_manager.send()
[docs]class AuditRequest(models.Model): """ copied from https://github.com/leandrosouza/django-simple-audit """ THREAD_LOCAL = threading.local() request_id = models.CharField(max_length=255) request_context = models.CharField(max_length=255) ip = models.IPAddressField() path = models.CharField(max_length=1024) date = models.DateTimeField(auto_now_add=True, verbose_name=_('Date')) user = models.ForeignKey('usuario.Usuario') class Meta: db_table = u'audit_request'
[docs] @staticmethod def new_request(path, user, ip, identity, context): """ Create a new request from a path, user and ip and put it on thread context. The new request should not be saved until first use or calling method current_request(True) """ from networkapi.usuario.models import Usuario if not isinstance(user, Usuario): # try to find a Usuario with the same email # Need to do this because we are using django 1.4 and we cannot # change the user model usuario, created = Usuario.objects.get_or_create( user=user.username, defaults={'ativo': user.is_active, 'nome': user.get_full_name(), 'email': user.email, 'user': user.username}) else: usuario = user audit_request = AuditRequest() audit_request.ip = ip audit_request.user = usuario audit_request.path = path audit_request.request_id = identity audit_request.request_context = context AuditRequest.THREAD_LOCAL.current = audit_request return audit_request
[docs] @staticmethod def set_request_from_id(request_id): """ Load an old request from database and put it again in thread context. If request_id doesn'texist, thread context will be cleared """ audit_request = None if request_id is not None: try: audit_request = AuditRequest.objects.get(request_id=request_id) except AuditRequest.DoesNotExist: pass AuditRequest.THREAD_LOCAL.current = audit_request
[docs] @staticmethod def current_request(force_save=False): """ Get current request from thread context (or None doesn't exist). If you specify force_save,current request will be saved on database first. """ audit_request = getattr(AuditRequest.THREAD_LOCAL, 'current', None) if force_save and audit_request is not None and audit_request.pk is None: audit_request.save() return audit_request
[docs] @staticmethod def cleanup_request(): """ Remove audit request from thread context """ AuditRequest.THREAD_LOCAL.current = None
[docs]class Functionality(models.Model): nome = models.CharField( max_length=50, primary_key=True, db_column='functionality') logger = logging.getLogger('Funcionality') class Meta: db_table = u'functionality'
[docs] @classmethod def exist(cls, event_functionality): func = Functionality.objects.filter(nome=event_functionality) if func.exists(): return event_functionality else: functionality = Functionality() functionality.nome = event_functionality functionality.save() return event_functionality