added logging capabilites to Provider & Services Class. Added info on provider log when a machine is not accesible on phisical

This commit is contained in:
Adolfo Gómez García 2020-05-28 02:13:00 +02:00
parent 944bc0041b
commit 7a9dbc3edd
9 changed files with 42 additions and 19 deletions

View File

@ -424,7 +424,8 @@ class Log(ActorV3Action):
def action(self) -> typing.MutableMapping[str, typing.Any]:
logger.debug('Args: %s, Params: %s', self._args, self._params)
userService = self.getUserService()
log.doLog(userService, int(self._params['level']), self._params['message'], log.ACTOR)
# Adjust loglevel to own, we start on 10000 for OTHER, and received is 0 for OTHER
log.doLog(userService, int(self._params['level']) + 10000, self._params['message'], log.ACTOR)
return ActorV3Action.actorResult('ok')

View File

@ -80,13 +80,10 @@ class LogManager:
"""
Logs a message associated to owner
"""
from uds.models import getSqlDatetime
from uds.models import Log
# Ensure message fits on space
message = str(message)[:255]
qs = Log.objects.filter(owner_id=owner_id, owner_type=owner_type)
qs = models.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:]:
@ -94,7 +91,7 @@ class LogManager:
if avoidDuplicates is True:
try:
lg = Log.objects.filter(owner_id=owner_id, owner_type=owner_type, level=level, source=source).order_by('-created', '-id')[0]
lg = models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type, level=level, source=source).order_by('-created', '-id')[0]
if lg.message == message:
# Do not log again, already logged
return
@ -103,7 +100,7 @@ class LogManager:
# now, we add new log
try:
Log.objects.create(owner_type=owner_type, owner_id=owner_id, created=getSqlDatetime(), source=source, level=level, data=message)
models.Log.objects.create(owner_type=owner_type, owner_id=owner_id, created=models.getSqlDatetime(), source=source, level=level, data=message)
except Exception:
# Some objects will not get logged, such as System administrator objects, but this is fine
pass
@ -112,18 +109,14 @@ class LogManager:
"""
Get all logs associated with an user service, ordered by date
"""
from uds.models import Log
qs = Log.objects.filter(owner_id=owner_id, owner_type=owner_type)
qs = models.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', '-id')[:limit])]
def __clearLogs(self, owner_type: int, owner_id: int):
"""
Clears all logs related to user service
"""
from uds.models import Log
Log.objects.filter(owner_id=owner_id, owner_type=owner_type).delete()
models.Log.objects.filter(owner_id=owner_id, owner_type=owner_type).delete()
def doLog(self, wichObject: 'Model', level: int, message: str, source: str, avoidDuplicates: bool = True):
"""

View File

@ -278,6 +278,9 @@ class Module(UserInterface, Environmentable, Serializable):
def getUuid(self) -> str:
return self._uuid
def setUuid(self, uuid: typing.Optional[str]) -> None:
self._uuid = uuid or ''
def destroy(self) -> None:
"""
Invoked before deleting an module from database.

View File

@ -36,6 +36,7 @@ import typing
from uds.core import Module
from uds.core.environment import Environment
from uds.core.util import log
from uds.core.util.config import GlobalConfig
from uds.core.ui import gui
@ -197,6 +198,14 @@ class ServiceProvider(Module):
val = getattr(val, 'value', val)
return val is True or val == gui.TRUE
def doLog(self, level: int, message: str) -> None:
"""
Logs a message with requested level associated with this service
"""
from uds.models import Provider as DBProvider
if self.getUuid():
log.doLog(DBProvider.objects.get(uuid=self.getUuid()), level, message, log.SERVICE)
def __str__(self):
"""
Basic implementation, mostly used for debuging and testing, never used

View File

@ -32,11 +32,13 @@
"""
import typing
import logging
from django.utils.translation import ugettext_noop as _
from uds.core import Module
from uds.core.transports import protocols
from uds.core.util.state import State
from uds.core.util import log
from . import types
from .publication import Publication
@ -51,6 +53,7 @@ if typing.TYPE_CHECKING:
from uds.core.util.unique_gid_generator import UniqueGIDGenerator
from uds import models
logger = logging.getLogger(__name__)
class Service(Module):
"""
@ -70,7 +73,7 @@ class Service(Module):
As you derive from this class, if you provide __init__ in your own class,
remember to call ALWAYS at base class __init__ as this:
super(self.__class__, self).__init__(dbAuth, environment, values)
super().__init__(parent, environment, values)
This is a MUST (if you override __init__), so internal structured gets
filled correctly, so don't forget it!.
@ -286,6 +289,14 @@ class Service(Module):
By default, services does not have a token
"""
return None
def doLog(self, level: int, message: str) -> None:
"""
Logs a message with requested level associated with this service
"""
from uds.models import Service as DBService
if self.getUuid():
log.doLog(DBService.objects.get(uuid=self.getUuid()), level, message, log.SERVICE)
@classmethod
def canAssign(cls) -> bool:

View File

@ -227,7 +227,7 @@ class UserDeployment(Environmentable, Serializable): # pylint: disable=too-many
def doLog(self, level: int, message: str) -> None:
"""
Logs a message with requested level associated with this service
Logs a message with requested level associated with this user deployment
"""
log.doLog(self._dbService, level, message, log.SERVICE)

View File

@ -78,7 +78,10 @@ class Provider(ManagedObjectModel, TaggingMixin): # type: ignore
return services.ServiceProvider # Basic Service implementation. Will fail if we try to use it, but will be ok to reference it
def getInstance(self, values: typing.Optional[typing.Dict[str, str]] = None) -> 'services.ServiceProvider':
return typing.cast('services.ServiceProvider', super().getInstance(values=values))
prov: services.ServiceProvider = typing.cast('services.ServiceProvider', super().getInstance(values=values))
# Set uuid
prov.setUuid(self.uuid)
return prov
def isInMaintenance(self) -> bool:
return self.maintenance_mode

View File

@ -116,7 +116,7 @@ class Service(ManagedObjectModel, TaggingMixin): # type: ignore
sType = prov.getServiceByType(self.data_type)
if sType:
obj = sType(self.getEnvironment(), prov, values)
obj = sType(self.getEnvironment(), prov, values, uuid=self.uuid)
self.deserialize(obj, values)
else:
raise Exception('Service type of {} is not recogniced by provider {}'.format(self.data_type, prov))

View File

@ -37,7 +37,8 @@ import typing
from django.utils.translation import ugettext_lazy as _
from uds.core.ui import gui
from uds.core.util.connection import testServer
from uds.core.util import log
from uds.core.util import connection
from uds.core.services import types as serviceTypes
from .deployment import IPMachineDeployed
@ -139,7 +140,9 @@ class IPMachinesService(IPServiceBase):
self.storage.saveData(theIP, theIP)
# Now, check if it is available on port, if required...
if self._port > 0:
if testServer(theIP, self._port, timeOut=0.5) is False:
if connection.testServer(theIP, self._port, timeOut=0.5) is False:
# Log into logs of provider, so it can be "shown" on services logs
self.parent().doLog(log.WARN, 'Host {} not accesible on port {}'.format(theIP, self._port))
self.storage.remove(theIP) # Return Machine to pool
continue
return theIP