From a740207b8e76b42a2726da1625d90a767f0317b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez?= Date: Thu, 31 Jan 2013 14:24:29 +0000 Subject: [PATCH] Added log for all initial loggable objects Added removing logs at object destroy (models) --- server/src/uds/core/managers/LogManager.py | 83 ++++++++++++++++------ server/src/uds/models.py | 43 ++++++++--- server/src/uds/xmlrpc/auths/AdminAuth.py | 2 +- 3 files changed, 98 insertions(+), 30 deletions(-) diff --git a/server/src/uds/core/managers/LogManager.py b/server/src/uds/core/managers/LogManager.py index d7ed3590..be7051cc 100644 --- a/server/src/uds/core/managers/LogManager.py +++ b/server/src/uds/core/managers/LogManager.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # # Copyright (c) 2013 Virtual Cable S.L. # All rights reserved. @@ -31,6 +30,15 @@ @author: Adolfo Gómez, dkmaster at dkmon dot com ''' +from uds.models import UserService +from uds.models import DeployedServicePublication +from uds.models import DeployedService +from uds.models import Service +from uds.models import Provider +from uds.models import User +from uds.models import Group +from uds.models import Authenticator + from uds.models import Log from uds.core.util import log from uds.core.util.Config import GlobalConfig @@ -40,6 +48,18 @@ logger = logging.getLogger(__name__) OT_USERSERVICE, OT_PUBLICATION, OT_DEPLOYED_SERVICE, OT_SERVICE, OT_PROVIDER, OT_USER, OT_GROUP, OT_AUTHENTICATOR = xrange(8) +# Dict for translations +transDict = { + UserService : OT_USERSERVICE, + DeployedServicePublication : OT_PUBLICATION, + DeployedService : OT_DEPLOYED_SERVICE, + Service : OT_SERVICE, + Provider : OT_PROVIDER, + User : OT_USER, + Group : OT_GROUP, + Authenticator : OT_AUTHENTICATOR +} + class LogManager(object): ''' Manager for logging (at database) events @@ -54,31 +74,36 @@ class LogManager(object): if LogManager._manager == None: LogManager._manager = LogManager() return LogManager._manager - - - # User Service log section - def __logUserService(self, userService, level, message, source): + + def __log(self, owner_type, owner_id, level, message, source): ''' - Logs a message associated to an user service + Logs a message associated to owner ''' from uds.models import getSqlDatetime - - qs = Log.objects.filter(owner_id = userService.id, owner_type = OT_USERSERVICE) + qs = Log.objects.filter(owner_id = owner_id, owner_type = owner_type) # First, ensure we do not have more than requested logs, and we can put one more log item if qs.count() >= GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt(): for i in qs.order_by('-created',)[GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()-1:]: i.delete() # now, we add new log - Log.objects.create(owner_type = OT_USERSERVICE, owner_id = userService.id, created = getSqlDatetime(), source = source, level = level, data = message) - - def __getUserServiceLogs(self, userService, limit): + Log.objects.create(owner_type = owner_type, owner_id = owner_id, created = getSqlDatetime(), source = source, level = level, data = message) + + + def __getLogs(self, owner_type, owner_id, limit): ''' Get all logs associated with an user service, ordered by date ''' - qs = Log.objects.filter(owner_id = userService.id, owner_type = OT_USERSERVICE) - return [{'date': x.created, 'level': x.level, 'source': x.source, 'message': x.data} for x in qs.order_by('created')][:limit] - + qs = Log.objects.filter(owner_id = owner_id, owner_type = owner_type) + return [{'date': x.created, 'level': x.level, 'source': x.source, 'message': x.data} for x in reversed(qs.order_by('-created')[:limit])] + + def __clearLogs(self, owner_type, owner_id): + ''' + Clears all logs related to user service + ''' + Log.objects.filter(owner_id = owner_id, owner_type = owner_type).delete() + + def doLog(self, wichObject, level, message, source = log.UNKNOWN): ''' @@ -86,21 +111,39 @@ class LogManager(object): If the object provided do not accepts associated loggin, it simply ignores the request ''' - from uds.models import UserService if type(level) is not int: level = log.logLevelFromStr(level) - if type(wichObject) is UserService: - self.__logUserService(wichObject, level, message, source) + owner_type = transDict.get(type(wichObject), None) + if owner_type is not None: + self.__log(owner_type, wichObject.id, level, message, source) else: logger.debug('Requested doLog for a type of object not covered: {0}'.format(wichObject)) def getLogs(self, wichObject, limit = GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()): - from uds.models import UserService + ''' + Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT) + ''' - if type(wichObject) is UserService: - return self.__getUserServiceLogs(wichObject, limit) + owner_type = transDict.get(type(wichObject), None) + + if owner_type is not None: + return self.__getLogs(owner_type, wichObject.id, limit) else: logger.debug('Requested getLogs for a type of object not covered: {0}'.format(wichObject)) + return [] + + def clearLogs(self, wichObject): + ''' + Clears all logs related to wichObject + + Used mainly at object database removal (parent object) + ''' + + owner_type = transDict.get(type(wichObject), None) + if owner_type is not None: + self.__clearLogs(owner_type, wichObject.id) + else: + logger.debug('Requested clearLogs for a type of object not covered: {0}'.format(wichObject)) diff --git a/server/src/uds/models.py b/server/src/uds/models.py index 15f07c74..67bece9a 100644 --- a/server/src/uds/models.py +++ b/server/src/uds/models.py @@ -40,6 +40,7 @@ from uds.core.util.State import State from uds.core.util import log from uds.core.services.Exceptions import InvalidServiceException from datetime import datetime, timedelta +from uds.core.managers import logManager import logging @@ -128,7 +129,7 @@ class Provider(models.Model): return services.factory().lookup(self.data_type) def __unicode__(self): - return "{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) + return u"{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) @staticmethod def beforeDelete(sender, **kwargs): @@ -146,6 +147,9 @@ class Provider(models.Model): s = toDelete.getInstance() s.destroy() s.env().clearRelatedData() + + # Clears related logs + logManager().clearLogs(toDelete) logger.debug('Before delete service provider '.format(toDelete)) @@ -215,7 +219,7 @@ class Service(models.Model): return self.provider.getType().getServiceByType(self.data_type) def __unicode__(self): - return "{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) + return u"{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) @staticmethod def beforeDelete(sender, **kwargs): @@ -234,6 +238,9 @@ class Service(models.Model): s.destroy() s.env().clearRelatedData() + # Clears related logs + logManager().clearLogs(toDelete) + logger.debug('Before delete service '.format(toDelete)) #: Connects a pre deletion signal to Service @@ -302,7 +309,7 @@ class OSManager(models.Model): def __unicode__(self): - return "{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) + return u"{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) def remove(self): ''' @@ -590,7 +597,7 @@ class Authenticator(models.Model): return falseIfNotExists def __unicode__(self): - return "{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) + return u"{0} of type {1} (id:{2})".format(self.name, self.data_type, self.id) @staticmethod def all(): @@ -616,6 +623,9 @@ class Authenticator(models.Model): s.destroy() s.env().clearRelatedData() + # Clears related logs + logManager().clearLogs(toDelete) + logger.debug('Before delete auth '.format(toDelete)) # Connects a pre deletion signal to Authenticator @@ -701,7 +711,7 @@ class User(models.Model): return self.getManager().logout(self.name) def __unicode__(self): - return "User {0} from auth {1}".format(self.name, self.manager.name) + return u"User {0} from auth {1}".format(self.name, self.manager.name) @staticmethod @@ -720,6 +730,9 @@ class User(models.Model): # be removed toDelete.getManager().removeUser(toDelete.name) + # Remove related logs + logManager().clearLogs(toDelete) + # Removes all user services assigned to this user (unassign it and mark for removal) for us in toDelete.userServices.all(): us.assignToUser(None) @@ -756,7 +769,7 @@ class Group(models.Model): return self.manager.getInstance() def __unicode__(self): - return "Group {0} from auth {1}".format(self.name, self.manager.name) + return u"Group {0} from auth {1}".format(self.name, self.manager.name) @staticmethod def beforeDelete(sender, **kwargs): @@ -774,6 +787,8 @@ class Group(models.Model): # be removed toDelete.getManager().removeGroup(toDelete.name) + # Clears related logs + logManager().clearLogs(toDelete) logger.debug('Deleted group {0}'.format(toDelete)) @@ -1013,10 +1028,13 @@ class DeployedService(models.Model): toDelete = kwargs['instance'] toDelete.getEnvironment().clearRelatedData() + # Clears related logs + logManager().clearLogs(toDelete) + logger.debug('Deleting Deployed Service {0}'.format(toDelete)) def __unicode__(self): - return "Deployed service {0}({1}) with {2} as initial, {3} as L1 cache, {4} as L2 cache, {5} as max".format( + return u"Deployed service {0}({1}) with {2} as initial, {3} as L1 cache, {4} as L2 cache, {5} as max".format( self.name, self.id, self.initial_srvs, self.cache_l1_srvs, self.cache_l2_srvs, self.max_srvs) @@ -1143,9 +1161,13 @@ class DeployedServicePublication(models.Model): toDelete = kwargs['instance'] toDelete.getEnvironment().clearRelatedData() - # Destroy method is invoked directly by PublicationManager, + # Delete method is invoked directly by PublicationManager, # Destroying a publication is not obligatory an 1 step action. - # It's handled as "publish", and as so, it + # It's handled as "publish", and as so, it can be a multi-step process + + # Clears related logs + logManager().clearLogs(toDelete) + logger.debug('Deleted publication {0}'.format(toDelete)) @@ -1498,6 +1520,9 @@ class UserService(models.Model): toDelete = kwargs['instance'] toDelete.getEnvironment().clearRelatedData() + # Clear related logs to this user service + logManager().clearLogs(toDelete) + # TODO: Check if this invokation goes here #toDelete.getInstance() diff --git a/server/src/uds/xmlrpc/auths/AdminAuth.py b/server/src/uds/xmlrpc/auths/AdminAuth.py index 44a44787..d32a7e3f 100644 --- a/server/src/uds/xmlrpc/auths/AdminAuth.py +++ b/server/src/uds/xmlrpc/auths/AdminAuth.py @@ -158,7 +158,7 @@ def login(username, password, idAuth, locale, request): logger.info("Validating user {0} with authenticator {1} with locale {2}".format(username, idAuth, locale)) activate(locale) if idAuth == ADMIN_AUTH: - if GlobalConfig.SUPER_USER_LOGIN.get() == username and GlobalConfig.SUPER_USER_PASS.get(True) == password: + if GlobalConfig.SUPER_USER_LOGIN.get(True) == username and GlobalConfig.SUPER_USER_PASS.get(True) == password: return makeCredentials(idAuth, username, locale, True) else: raise AuthException(_('Invalid credentials'))