* Updated log system to manage it though a manager

* Updated default settings so tables are created using myisam (for speed) by default
* Updated model to remove doLog from UserService
* Added log manager
* Added log config parameter
* Updated components so they use the new log manager
* Updated virt client so if it can't connect, it raise an exception and do not initializes ovirt cached connection
* Updated plugin detect
* Added xmlrpc methods to access UserService logs
This commit is contained in:
Adolfo Gómez 2013-01-28 09:51:38 +00:00
parent 462cfe9391
commit fc92b3edaa
16 changed files with 197 additions and 28 deletions

View File

@ -52,6 +52,7 @@ encoding//src/uds/core/jobs/Scheduler.py=utf-8
encoding//src/uds/core/jobs/__init__.py=utf-8
encoding//src/uds/core/managers/CryptoManager.py=utf-8
encoding//src/uds/core/managers/DownloadsManager.py=utf-8
encoding//src/uds/core/managers/LogManager.py=utf-8
encoding//src/uds/core/managers/PublicationManager.py=utf-8
encoding//src/uds/core/managers/TaskManager.py=utf-8
encoding//src/uds/core/managers/UserPrefsManager.py=utf-8
@ -184,6 +185,7 @@ encoding//src/uds/xmlrpc/auths/Authenticators.py=utf-8
encoding//src/uds/xmlrpc/auths/Groups.py=utf-8
encoding//src/uds/xmlrpc/auths/UserPreferences.py=utf-8
encoding//src/uds/xmlrpc/auths/Users.py=utf-8
encoding//src/uds/xmlrpc/log/logs.py=utf-8
encoding//src/uds/xmlrpc/osmanagers/OSManagers.py=utf-8
encoding//src/uds/xmlrpc/services/DeployedServices.py=utf-8
encoding//src/uds/xmlrpc/services/Publications.py=utf-8

View File

@ -31,7 +31,7 @@ DATABASES = {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'OPTIONS': {
#'init_command': 'SET storage_engine=INNODB, SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
'init_command' : 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
'init_command' : 'SET storage_engine=MYISAM, SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
},
'NAME': 'dbuds', # Or path to database file if using sqlite3.
'USER': 'dbuds', # Not used with sqlite3.

View File

@ -69,17 +69,17 @@ class DownloadsManager(object):
@param path: path to file
@params zip: If download as zip
'''
id = str(uuid.uuid5(self._namespace, name))
self._downloadables[id] = { 'name': name, 'comment' : comment, 'path' : path, 'mime' : mime }
_id = str(uuid.uuid5(self._namespace, name))
self._downloadables[_id] = { 'name': name, 'comment' : comment, 'path' : path, 'mime' : mime }
def getDownloadables(self):
return self._downloadables
def send(self, request, id):
if self._downloadables.has_key(id) is False:
def send(self, request, _id):
if self._downloadables.has_key(_id) is False:
return Http404()
return self.__send_file(request, self._downloadables[id]['name'], self._downloadables[id]['path'], self._downloadables[id]['mime']);
return self.__send_file(request, self._downloadables[_id]['name'], self._downloadables[_id]['path'], self._downloadables[_id]['mime']);
def __send_file(self, request, name, filename, mime):
"""

View File

@ -0,0 +1,100 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from uds.core.util import log
from uds.core.util.Config import GlobalConfig
import logging
logger = logging.getLogger(__name__)
class LogManager(object):
'''
Manager for logging (at database) events
'''
_manager = None
def __init__(self):
pass
@staticmethod
def manager():
if LogManager._manager == None:
LogManager._manager = LogManager()
return LogManager._manager
# User Service log section
def __logUserService(self, userService, level, message, source):
'''
Logs a message associated to an user service
'''
from uds.models import getSqlDatetime
# First, ensure we do not have more than requested logs, and we can put one more log item
if userService.log.count() >= GlobalConfig.MAX_USERSERVICE_LOGS.getInt():
for i in userService.log.all().order_by('-created',)[GlobalConfig.MAX_USERSERVICE_LOGS.getInt()-1:]: i.delete()
# now, we add new log
userService.log.create(created = getSqlDatetime(), source = source, level = level, data = message)
def __getUserServiceLogs(self, userService):
'''
Get all logs associated with an user service, ordered by date
'''
return [{'date': x.created, 'level': x.level, 'source': x.source, 'message': x.data} for x in userService.log.all().order_by('created')]
def doLog(self, wichObject, level, message, source = log.INTERNAL):
'''
Do the logging for the requested 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)
else:
logger.debug('Requested doLog for a type of object not covered: {0}'.format(wichObject))
def getLogs(self, wichObject):
from uds.models import UserService
if type(wichObject) is UserService:
return self.__getUserServiceLogs(wichObject)
else:
logger.debug('Requested getLogs for a type of object not covered: {0}'.format(wichObject))

View File

@ -46,3 +46,7 @@ def taskManager():
def downloadsManager():
from DownloadsManager import DownloadsManager
return DownloadsManager.manager()
def logManager():
from LogManager import LogManager
return LogManager.manager()

View File

@ -217,6 +217,8 @@ class GlobalConfig:
MAX_INITIALIZING_TIME = Config.section(GLOBAL_SECTION).value('maxInitTime', '3600')
# Custom HTML for login page
CUSTOM_HTML_LOGIN = Config.section(GLOBAL_SECTION).valueLong('customHtmlLogin', '')
# Maximum logs per user service
MAX_USERSERVICE_LOGS = Config.section(GLOBAL_SECTION).value('maxLogPerUserService', '100')
initDone = False
@ -247,6 +249,7 @@ class GlobalConfig:
GlobalConfig.REDIRECT_TO_HTTPS.get()
GlobalConfig.MAX_INITIALIZING_TIME.get()
GlobalConfig.CUSTOM_HTML_LOGIN.get()
GlobalConfig.MAX_USERSERVICE_LOGS.get()
except:
logger.debug('Config table do not exists!!!, maybe we are installing? :-)')

View File

@ -1324,13 +1324,6 @@ class UserService(models.Model):
'''
return [self.src_ip, self.src_hostname]
def doLog(self, level, message, source = log.INTERNAL):
if type(level) is not int:
level = log.logLevelFromStr(level)
self.log.create(created = getSqlDatetime(), source = source, level = level, data = message)
def transformsUserOrPasswordForService(self):
'''
If the os manager changes the username or the password, this will return True
@ -1539,7 +1532,7 @@ class UserServiceLog(models.Model):
def __unicode__(self):
return "Log of {0}: {1} - {2} - {3} - {4}".format(self.user_service.name, self.created, self.source, self.level, self.data)
return "Log of {0}({1}): {2} - {3} - {4} - {5}".format(self.user_service.friendly_name, self.user_service.id, self.created, self.source, self.level, self.data)
# General utility models, such as a database cache (for caching remote content of slow connections to external services providers for example)

View File

@ -88,11 +88,13 @@ class WindowsOsManager(osmanagers.OSManager):
def doLog(self, service, data, origin = log.OSMANAGER):
# Stores a log associated with this service
from uds.core.managers import logManager
try:
msg, level = data.split('\t')
service.doLog(level, msg, origin)
logManager().doLog(service, level, msg, origin)
except:
service.doLog(log.ERROR, "do not understand {0}".format(data), log.TRANSPORT)
logManager().doLog(service, log.ERROR, "do not understand {0}".format(data), origin)
def process(self,service,msg, data):

View File

@ -60,10 +60,14 @@ class Client(object):
except:
# Nothing happens, may it was already disconnected
pass
cached_api_key = aKey
cached_api = API(url='https://'+self._host, username=self._username, password=self._password, timeout=self._timeout, insecure=True, debug=True)
return cached_api
try:
cached_api_key = aKey
cached_api = API(url='https://'+self._host, username=self._username, password=self._password, timeout=self._timeout, insecure=True, debug=True)
return cached_api
except:
cached_api_key = None
raise Exception("Can't connet to server at {0}".format(self._host))
def __init__(self, host, username, password, timeout, cache):
self._host = host

File diff suppressed because one or more lines are too long

View File

@ -98,6 +98,7 @@ def login(request):
# Add the "java supported" flag to session
request.session['java'] = java
request.session['OS'] = os
logger.debug('Navigator supports java? {0}'.format(java))
__authLog(request, authenticator, user.name, java, os, 'Logged in')
return response
else:
@ -265,8 +266,10 @@ def sernotify(request, idUserService, notification):
level = request.GET.get('level', None)
if message is not None and level is not None:
from uds.core.util import log
from uds.core.managers import logManager
us = UserService.objects.get(pk=idUserService)
us.doLog(level, message, log.TRANSPORT)
logManager().doLog(us, level, message, log.TRANSPORT)
else:
return HttpResponse('Invalid request!', 'text/plain')
except Exception as e:

View File

View File

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from django.utils.translation import ugettext as _
from ..auths.AdminAuth import needs_credentials
from ..util.Exceptions import FindException
from uds.core.managers import logManager
from uds.models import UserService
import logging
logger = logging.getLogger(__name__)
@needs_credentials
def getUserServiceLogs(credentials, id):
logger.debug('getUserServiceLogs called')
try:
us = UserService.objects.get(pk=id)
return logManager().getLogs(us)
except Exception:
raise FindException(_('Service does not exists'))
# Registers XML RPC Methods
def registerLogFunctions(dispatcher):
dispatcher.register_function(getUserServiceLogs, 'getUserServiceLogs')

View File

@ -39,9 +39,10 @@ from ..util.Exceptions import DeleteException, FindException, ValidationExceptio
from ..util.Helpers import dictFromData
from ..auths.AdminAuth import needs_credentials
from uds.core.Environment import Environment
import logging
from uds.core import osmanagers
import logging
logger = logging.getLogger(__name__)
@needs_credentials

View File

@ -52,6 +52,7 @@ from auths.Users import registerUserFunctions
from auths.UserPreferences import registerPreferencesFunctions
from tools.Cache import registerCacheFunctions
from tools.Config import registerConfigurationFunctions
from log.logs import registerLogFunctions
import logging
@ -142,3 +143,4 @@ registerActorFunctions(dispatcher)
registerPreferencesFunctions(dispatcher)
registerCacheFunctions(dispatcher)
registerConfigurationFunctions(dispatcher)
registerLogFunctions(dispatcher)