1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-01-08 21:18:00 +03:00

Refactoring loggging and log manager, and more linting

This commit is contained in:
Adolfo Gómez García 2023-04-20 03:10:46 +02:00
parent 3a0efbb998
commit 9030ff3ab3
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
43 changed files with 228 additions and 232 deletions

View File

@ -91,10 +91,10 @@ class RESTTestCase(test.UDSTransactionTestCase):
) )
for user in self.users: for user in self.users:
log.doLog(user, log.DEBUG, f'Debug Log for {user.name}') log.doLog(user, log.LogLevel.DEBUG, f'Debug Log for {user.name}')
log.doLog(user, log.INFO, f'Info Log for {user.name}') log.doLog(user, log.LogLevel.INFO, f'Info Log for {user.name}')
log.doLog(user, log.WARNING, f'Warning Log for {user.name}') log.doLog(user, log.LogLevel.WARNING, f'Warning Log for {user.name}')
log.doLog(user, log.ERROR, f'Error Log for {user.name}') log.doLog(user, log.LogLevel.ERROR, f'Error Log for {user.name}')
self.provider = services_fixtures.createProvider() self.provider = services_fixtures.createProvider()

View File

@ -147,7 +147,7 @@ class Dispatcher(View):
logger.debug('Path: %s', full_path) logger.debug('Path: %s', full_path)
logger.debug('Error: %s', e) logger.debug('Error: %s', e)
log.log_operation(handler, 500, log.ERROR) log.logOperation(handler, 500, log.LogLevel.ERROR)
return http.HttpResponseServerError( return http.HttpResponseServerError(
f'Invalid parameters invoking {full_path}: {e}', f'Invalid parameters invoking {full_path}: {e}',
content_type="text/plain", content_type="text/plain",
@ -157,17 +157,17 @@ class Dispatcher(View):
for n in ['get', 'post', 'put', 'delete']: for n in ['get', 'post', 'put', 'delete']:
if hasattr(handler, n): if hasattr(handler, n):
allowedMethods.append(n) allowedMethods.append(n)
log.log_operation(handler, 405, log.ERROR) log.logOperation(handler, 405, log.LogLevel.ERROR)
return http.HttpResponseNotAllowed( return http.HttpResponseNotAllowed(
allowedMethods, content_type="text/plain" allowedMethods, content_type="text/plain"
) )
except AccessDenied: except AccessDenied:
log.log_operation(handler, 403, log.ERROR) log.logOperation(handler, 403, log.LogLevel.ERROR)
return http.HttpResponseForbidden( return http.HttpResponseForbidden(
'access denied', content_type="text/plain" 'access denied', content_type="text/plain"
) )
except Exception: except Exception:
log.log_operation(handler, 500, log.ERROR) log.logOperation(handler, 500, log.LogLevel.ERROR)
logger.exception('error accessing attribute') logger.exception('error accessing attribute')
logger.debug('Getting attribute %s for %s', http_method, full_path) logger.debug('Getting attribute %s for %s', http_method, full_path)
return http.HttpResponseServerError( return http.HttpResponseServerError(
@ -185,28 +185,28 @@ class Dispatcher(View):
for k, val in handler.headers().items(): for k, val in handler.headers().items():
response[k] = val response[k] = val
log.log_operation(handler, response.status_code, log.INFO) log.logOperation(handler, response.status_code, log.LogLevel.INFO)
return response return response
except RequestError as e: except RequestError as e:
log.log_operation(handler, 400, log.ERROR) log.logOperation(handler, 400, log.LogLevel.ERROR)
return http.HttpResponseBadRequest(str(e), content_type="text/plain") return http.HttpResponseBadRequest(str(e), content_type="text/plain")
except ResponseError as e: except ResponseError as e:
log.log_operation(handler, 500, log.ERROR) log.logOperation(handler, 500, log.LogLevel.ERROR)
return http.HttpResponseServerError(str(e), content_type="text/plain") return http.HttpResponseServerError(str(e), content_type="text/plain")
except NotSupportedError as e: except NotSupportedError as e:
log.log_operation(handler, 501, log.ERROR) log.logOperation(handler, 501, log.LogLevel.ERROR)
return http.HttpResponseBadRequest(str(e), content_type="text/plain") return http.HttpResponseBadRequest(str(e), content_type="text/plain")
except AccessDenied as e: except AccessDenied as e:
log.log_operation(handler, 403, log.ERROR) log.logOperation(handler, 403, log.LogLevel.ERROR)
return http.HttpResponseForbidden(str(e), content_type="text/plain") return http.HttpResponseForbidden(str(e), content_type="text/plain")
except NotFound as e: except NotFound as e:
log.log_operation(handler, 404, log.ERROR) log.logOperation(handler, 404, log.LogLevel.ERROR)
return http.HttpResponseNotFound(str(e), content_type="text/plain") return http.HttpResponseNotFound(str(e), content_type="text/plain")
except HandlerError as e: except HandlerError as e:
log.log_operation(handler, 500, log.ERROR) log.logOperation(handler, 500, log.LogLevel.ERROR)
return http.HttpResponseBadRequest(str(e), content_type="text/plain") return http.HttpResponseBadRequest(str(e), content_type="text/plain")
except Exception as e: except Exception as e:
log.log_operation(handler, 500, log.ERROR) log.logOperation(handler, 500, log.LogLevel.ERROR)
# Get ecxeption backtrace # Get ecxeption backtrace
trace_back = traceback.format_exc() trace_back = traceback.format_exc()
logger.error('Exception processing request: %s', full_path) logger.error('Exception processing request: %s', full_path)

View File

@ -32,15 +32,10 @@ Author: Adolfo Gómez, dkmaster at dkmon dot com
import typing import typing
from uds import models from uds import models
from uds.core.util.log import (
REST, # Import for REST using this module can access constants easily
OWNER_TYPE_AUDIT, # pylint: disable=unused-import
DEBUG, from uds.core.util.log import LogLevel, LogSource, doLog
INFO,
WARNING,
ERROR,
CRITICAL,
)
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from .handlers import Handler from .handlers import Handler
@ -68,14 +63,14 @@ def replacePath(path: str) -> str:
uuid = path.split(f'/{type}/')[1].split('/')[0] uuid = path.split(f'/{type}/')[1].split('/')[0]
name = model.objects.get(uuid=uuid).name # type: ignore name = model.objects.get(uuid=uuid).name # type: ignore
path = path.replace(uuid, f'[{name}]') path = path.replace(uuid, f'[{name}]')
except Exception: # nosec: intentionally broad exception except Exception: # nosec: intentionally broad exception
pass pass
return path return path
def log_operation( def logOperation(
handler: typing.Optional['Handler'], response_code: int, level: int = INFO handler: typing.Optional['Handler'], response_code: int, level: LogLevel = LogLevel.INFO
): ):
""" """
Logs a request Logs a request
@ -83,7 +78,7 @@ def log_operation(
if not handler: if not handler:
return # Nothing to log return # Nothing to log
path = handler._request.path path = handler.request.path
# If a common request, and no error, we don't log it because it's useless and a waste of resources # If a common request, and no error, we don't log it because it's useless and a waste of resources
if response_code < 400 and any( if response_code < 400 and any(
@ -93,15 +88,13 @@ def log_operation(
path = replacePath(path) path = replacePath(path)
username = handler._request.user.pretty_name if handler._request.user else 'Unknown' username = handler.request.user.pretty_name if handler.request.user else 'Unknown'
# Global log is used without owner nor type doLog(
models.Log.objects.create( None,
owner_id=0,
owner_type=OWNER_TYPE_AUDIT,
created=models.getSqlDatetime(),
level=level, level=level,
source=REST, message=f'{handler.request.ip} {username}: [{handler.request.method}/{response_code}] {path}'[
data=f'{handler._request.ip} {username}: [{handler._request.method}/{response_code}] {path}'[
:4096 :4096
], ],
source=LogSource.REST,
avoidDuplicates=False,
) )

View File

@ -682,7 +682,7 @@ class Log(ActorV3Action):
userService, userService,
int(self._params['level']) + 10000, int(self._params['level']) + 10000,
self._params['message'], self._params['message'],
log.ACTOR, log.LogSource.ACTOR,
) )
return ActorV3Action.actorResult('ok') return ActorV3Action.actorResult('ok')

View File

@ -110,12 +110,12 @@ class MetaServicesPool(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
("Added" if uuid is None else "Modified") ("Added" if uuid is None else "Modified")
+ " meta pool member {}/{}/{} by {}".format( + " meta pool member {}/{}/{} by {}".format(
pool.name, priority, enabled, self._user.pretty_name pool.name, priority, enabled, self._user.pretty_name
), ),
log.ADMIN, log.LogSource.ADMIN,
) )
return self.success() return self.success()
@ -128,7 +128,7 @@ class MetaServicesPool(DetailHandler):
member.delete() member.delete()
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
class MetaAssignedService(DetailHandler): class MetaAssignedService(DetailHandler):
@ -243,7 +243,7 @@ class MetaAssignedService(DetailHandler):
else: else:
raise self.invalidItemException(_('Item is not removable')) raise self.invalidItemException(_('Item is not removable'))
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
# Only owner is allowed to change right now # Only owner is allowed to change right now
def saveItem(self, parent: MetaPool, item: typing.Optional[str]): def saveItem(self, parent: MetaPool, item: typing.Optional[str]):
@ -276,4 +276,4 @@ class MetaAssignedService(DetailHandler):
service.save() service.save()
# Log change # Log change
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)

View File

@ -116,9 +116,9 @@ class AccessCalendars(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'{"Added" if uuid is None else "Updated"} access calendar {calendar.name}/{access} by {self._user.pretty_name}', f'{"Added" if uuid is None else "Updated"} access calendar {calendar.name}/{access} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
def deleteItem(self, parent: 'ServicePool', item: str) -> None: def deleteItem(self, parent: 'ServicePool', item: str) -> None:
@ -126,7 +126,7 @@ class AccessCalendars(DetailHandler):
logStr = f'Removed access calendar {calendarAccess.calendar.name} by {self._user.pretty_name}' logStr = f'Removed access calendar {calendarAccess.calendar.name} by {self._user.pretty_name}'
calendarAccess.delete() calendarAccess.delete()
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
class ActionsCalendars(DetailHandler): class ActionsCalendars(DetailHandler):
@ -219,7 +219,7 @@ class ActionsCalendars(DetailHandler):
params=params, params=params,
) )
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
def deleteItem(self, parent: 'ServicePool', item: str) -> None: def deleteItem(self, parent: 'ServicePool', item: str) -> None:
calendarAction = CalendarAction.objects.get(uuid=processUuid(self._args[0])) calendarAction = CalendarAction.objects.get(uuid=processUuid(self._args[0]))
@ -232,7 +232,7 @@ class ActionsCalendars(DetailHandler):
calendarAction.delete() calendarAction.delete()
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
def execute(self, parent: 'ServicePool', item: str): def execute(self, parent: 'ServicePool', item: str):
logger.debug('Launching action') logger.debug('Launching action')
@ -247,7 +247,7 @@ class ActionsCalendars(DetailHandler):
f'{calendarAction.params}" by {self._user.pretty_name}' f'{calendarAction.params}" by {self._user.pretty_name}'
) )
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
calendarAction.execute() calendarAction.execute()
return self.success() return self.success()

View File

@ -102,8 +102,8 @@ class TunnelTicket(Handler):
now = models.getSqlDatetimeAsUnix() now = models.getSqlDatetimeAsUnix()
totalTime = now - extra.get('b', now - 1) totalTime = now - extra.get('b', now - 1)
msg = f'User {user.name} stopped tunnel {extra.get("t", "")[:8]}... to {host}:{port}: u:{sent}/d:{recv}/t:{totalTime}.' msg = f'User {user.name} stopped tunnel {extra.get("t", "")[:8]}... to {host}:{port}: u:{sent}/d:{recv}/t:{totalTime}.'
log.doLog(user.manager, log.INFO, msg) log.doLog(user.manager, log.LogLevel.INFO, msg)
log.doLog(userService, log.INFO, msg) log.doLog(userService, log.LogLevel.INFO, msg)
# Try to log Close event # Try to log Close event
try: try:
@ -131,8 +131,8 @@ class TunnelTicket(Handler):
tunnel=self._args[0], tunnel=self._args[0],
) )
msg = f'User {user.name} started tunnel {self._args[0][:8]}... to {host}:{port} from {self._args[1]}.' msg = f'User {user.name} started tunnel {self._args[0][:8]}... to {host}:{port} from {self._args[1]}.'
log.doLog(user.manager, log.INFO, msg) log.doLog(user.manager, log.LogLevel.INFO, msg)
log.doLog(userService, log.INFO, msg) log.doLog(userService, log.LogLevel.INFO, msg)
# Generate new, notify only, ticket # Generate new, notify only, ticket
notifyTicket = models.TicketStore.create_for_tunnel( notifyTicket = models.TicketStore.create_for_tunnel(
userService=userService, userService=userService,

View File

@ -191,7 +191,7 @@ class AssignedService(DetailHandler):
else: else:
raise self.invalidItemException(_('Item is not removable')) raise self.invalidItemException(_('Item is not removable'))
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
# Only owner is allowed to change right now # Only owner is allowed to change right now
def saveItem(self, parent: models.ServicePool, item: typing.Optional[str]) -> None: def saveItem(self, parent: models.ServicePool, item: typing.Optional[str]) -> None:
@ -219,7 +219,7 @@ class AssignedService(DetailHandler):
userService.save() userService.save()
# Log change # Log change
log.doLog(parent, log.INFO, logStr, log.ADMIN) log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
def reset(self, parent: 'models.ServicePool', item: str) -> typing.Any: def reset(self, parent: 'models.ServicePool', item: str) -> typing.Any:
userService = parent.userServices.get(uuid=processUuid(item)) userService = parent.userServices.get(uuid=processUuid(item))
@ -340,9 +340,9 @@ class Groups(DetailHandler):
parent.assignedGroups.add(group) parent.assignedGroups.add(group)
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'Added group {group.pretty_name} by {self._user.pretty_name}', f'Added group {group.pretty_name} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
def deleteItem(self, parent: models.ServicePool, item: str) -> None: def deleteItem(self, parent: models.ServicePool, item: str) -> None:
@ -350,9 +350,9 @@ class Groups(DetailHandler):
parent.assignedGroups.remove(group) parent.assignedGroups.remove(group)
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'Removed group {group.pretty_name} by {self._user.pretty_name}', f'Removed group {group.pretty_name} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
@ -399,9 +399,9 @@ class Transports(DetailHandler):
parent.transports.add(transport) parent.transports.add(transport)
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'Added transport {transport.name} by {self._user.pretty_name}', f'Added transport {transport.name} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
def deleteItem(self, parent: models.ServicePool, item: str) -> None: def deleteItem(self, parent: models.ServicePool, item: str) -> None:
@ -411,9 +411,9 @@ class Transports(DetailHandler):
parent.transports.remove(transport) parent.transports.remove(transport)
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'Removed transport {transport.name} by {self._user.pretty_name}', f'Removed transport {transport.name} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
@ -447,9 +447,9 @@ class Publications(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'Initiated publication v{parent.current_pub_revision} by {self._user.pretty_name}', f'Initiated publication v{parent.current_pub_revision} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
return self.success() return self.success()
@ -478,9 +478,9 @@ class Publications(DetailHandler):
log.doLog( log.doLog(
parent, parent,
log.INFO, log.LogLevel.INFO,
f'Canceled publication v{parent.current_pub_revision} by {self._user.pretty_name}', f'Canceled publication v{parent.current_pub_revision} by {self._user.pretty_name}',
log.ADMIN, log.LogSource.ADMIN,
) )
return self.success() return self.success()

View File

@ -525,12 +525,12 @@ def authLogLogin(
] ]
) )
) )
level = log.INFO if logStr == 'Logged in' else log.ERROR level = log.LogLevel.INFO if logStr == 'Logged in' else log.LogLevel.ERROR
log.doLog( log.doLog(
authenticator, authenticator,
level, level,
f'user {userName} has {logStr} from {request.ip} where os is {request.os.os.name}', f'user {userName} has {logStr} from {request.ip} where os is {request.os.os.name}',
log.WEB, log.LogSource.WEB,
) )
try: try:
@ -540,7 +540,7 @@ def authLogLogin(
user, user,
level, level,
f'{logStr} from {request.ip} where OS is {request.os.os.name}', f'{logStr} from {request.ip} where OS is {request.os.os.name}',
log.WEB, log.LogSource.WEB,
) )
except models.User.DoesNotExist: # pylint: disable=no-member except models.User.DoesNotExist: # pylint: disable=no-member
pass pass
@ -550,8 +550,8 @@ def authLogLogout(request: 'ExtendedHttpRequest') -> None:
if request.user: if request.user:
log.doLog( log.doLog(
request.user.manager, request.user.manager,
log.INFO, log.LogLevel.INFO,
f'user {request.user.name} has logged out from {request.ip}', f'user {request.user.name} has logged out from {request.ip}',
log.WEB, log.LogSource.WEB,
) )
log.doLog(request.user, log.INFO, f'has logged out from {request.ip}', log.WEB) log.doLog(request.user, log.LogLevel.INFO, f'has logged out from {request.ip}', log.LogSource.WEB)

View File

@ -26,4 +26,4 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # 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. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from manager import LogManager from .manager import LogManager

View File

@ -48,7 +48,6 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class LogManager(metaclass=singleton.Singleton): class LogManager(metaclass=singleton.Singleton):
""" """
Manager for logging (at database) events Manager for logging (at database) events
@ -61,7 +60,7 @@ class LogManager(metaclass=singleton.Singleton):
def manager() -> 'LogManager': def manager() -> 'LogManager':
return LogManager() # Singleton pattern will return always the same instance return LogManager() # Singleton pattern will return always the same instance
def __log( def _log(
self, self,
owner_type: LogObjectType, owner_type: LogObjectType,
owner_id: int, owner_id: int,
@ -83,7 +82,9 @@ class LogManager(metaclass=singleton.Singleton):
# If max_elements is greater than 0, database contains equals or more than max_elements, we will delete the oldest ones to ensure we have max_elements - 1 # If max_elements is greater than 0, database contains equals or more than max_elements, we will delete the oldest ones to ensure we have max_elements - 1
if 0 < max_elements <= current_elements: if 0 < max_elements <= current_elements:
# We will delete the oldest ones # We will delete the oldest ones
for x in qs.order_by('created', 'id')[:current_elements - max_elements + 1]: for x in qs.order_by('created', 'id')[
: current_elements - max_elements + 1
]:
x.delete() x.delete()
if avoidDuplicates: if avoidDuplicates:
@ -108,7 +109,7 @@ class LogManager(metaclass=singleton.Singleton):
# Some objects will not get logged, such as System administrator objects, but this is fine # Some objects will not get logged, such as System administrator objects, but this is fine
pass pass
def __getLogs( def _getLogs(
self, owner_type: LogObjectType, owner_id: int, limit: int self, owner_type: LogObjectType, owner_id: int, limit: int
) -> typing.List[typing.Dict]: ) -> typing.List[typing.Dict]:
""" """
@ -120,7 +121,7 @@ class LogManager(metaclass=singleton.Singleton):
for x in reversed(qs.order_by('-created', '-id')[:limit]) # type: ignore # Slicing is not supported by pylance right now for x in reversed(qs.order_by('-created', '-id')[:limit]) # type: ignore # Slicing is not supported by pylance right now
] ]
def __clearLogs(self, owner_type: LogObjectType, owner_id: int): def _clearLogs(self, owner_type: LogObjectType, owner_id: int):
""" """
Clears ALL logs related to user service Clears ALL logs related to user service
""" """
@ -148,7 +149,7 @@ class LogManager(metaclass=singleton.Singleton):
if owner_type is not None: if owner_type is not None:
try: try:
self.__log( self._log(
owner_type, objectId, level, message, source, avoidDuplicates owner_type, objectId, level, message, source, avoidDuplicates
) )
except Exception: except Exception:
@ -180,7 +181,11 @@ class LogManager(metaclass=singleton.Singleton):
logger.debug('Getting log: %s -> %s', wichObject, owner_type) logger.debug('Getting log: %s -> %s', wichObject, owner_type)
if owner_type: # 0 is valid owner type if owner_type: # 0 is valid owner type
return self.__getLogs(owner_type, getattr(wichObject, 'id', -1), limit if limit != -1 else owner_type.get_max_elements()) return self._getLogs(
owner_type,
getattr(wichObject, 'id', -1),
limit if limit != -1 else owner_type.get_max_elements(),
)
logger.debug( logger.debug(
'Requested getLogs for a type of object not covered: %s', wichObject 'Requested getLogs for a type of object not covered: %s', wichObject
@ -200,7 +205,7 @@ class LogManager(metaclass=singleton.Singleton):
else LogObjectType.SYSLOG else LogObjectType.SYSLOG
) )
if owner_type: if owner_type:
self.__clearLogs(owner_type, getattr(wichObject, 'id', -1)) self._clearLogs(owner_type, getattr(wichObject, 'id', -1))
else: else:
logger.debug( logger.debug(
'Requested clearLogs for a type of object not covered: %s: %s', 'Requested clearLogs for a type of object not covered: %s: %s',

View File

@ -27,9 +27,8 @@ class LogObjectType(enum.IntEnum):
from uds.core.util.config import GlobalConfig # pylint: disable=import-outside-toplevel from uds.core.util.config import GlobalConfig # pylint: disable=import-outside-toplevel
if self == LogObjectType.SYSLOG: if self == LogObjectType.SYSLOG:
return GlobalConfig.SYSLOG_MAX_ELEMENTS.getInt() return GlobalConfig.GENERAL_LOG_MAX_ELEMENTS.getInt()
return GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt() return GlobalConfig.INDIVIDIAL_LOG_MAX_ELEMENTS.getInt()
# Dict for translations # Dict for translations
MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = { MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = {

View File

@ -344,7 +344,7 @@ class PublicationManager(metaclass=singleton.Singleton):
publication.deployed_service, publication.deployed_service,
log.WARN, log.WARN,
'Forced cancel on publication, you must check uncleaned resources manually', 'Forced cancel on publication, you must check uncleaned resources manually',
log.ADMIN, log.LogSource.ADMIN,
) )
publication.setState(State.CANCELED) publication.setState(State.CANCELED)
publication.save() publication.save()

View File

@ -566,7 +566,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
servicePool, servicePool,
log.WARN, log.WARN,
f'Max number of services reached: {servicePool.max_srvs}', f'Max number of services reached: {servicePool.max_srvs}',
log.INTERNAL, log.LogSource.INTERNAL,
) )
raise MaxServicesReachedError() raise MaxServicesReachedError()
@ -854,9 +854,9 @@ class UserServiceManager(metaclass=singleton.Singleton):
serviceNotReadyCode = 0x0002 serviceNotReadyCode = 0x0002
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
f"User {user.pretty_name} from {srcIp} has initiated access", f"User {user.pretty_name} from {srcIp} has initiated access",
log.WEB, log.LogSource.WEB,
) )
# If ready, show transport for this service, if also ready ofc # If ready, show transport for this service, if also ready ofc
userServiceInstance = userService.getInstance() userServiceInstance = userService.getInstance()
@ -872,7 +872,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
userService, userService,
log.WARN, log.WARN,
f'User service is not accessible due to invalid UUID (user: {user.pretty_name}, ip: {ip})', f'User service is not accessible due to invalid UUID (user: {user.pretty_name}, ip: {ip})',
log.TRANSPORT, log.LogSource.TRANSPORT,
) )
logger.debug('UUID check failed for user service %s', userService) logger.debug('UUID check failed for user service %s', userService)
else: else:
@ -889,7 +889,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
transportInstance = transport.getInstance() transportInstance = transport.getInstance()
if transportInstance.isAvailableFor(userService, ip): if transportInstance.isAvailableFor(userService, ip):
# userService.setConnectionSource(srcIp, 'unknown') # userService.setConnectionSource(srcIp, 'unknown')
log.doLog(userService, log.INFO, "User service ready", log.WEB) log.doLog(userService, log.LogLevel.INFO, "User service ready", log.LogSource.WEB)
self.notifyPreconnect( self.notifyPreconnect(
userService, userService,
transportInstance.processedUser(userService, user), transportInstance.processedUser(userService, user),
@ -913,7 +913,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
message = transportInstance.getCustomAvailableErrorMsg( message = transportInstance.getCustomAvailableErrorMsg(
userService, ip userService, ip
) )
log.doLog(userService, log.WARN, message, log.TRANSPORT) log.doLog(userService, log.WARN, message, log.LogSource.TRANSPORT)
logger.debug( logger.debug(
'Transport is not ready for user service %s: %s', 'Transport is not ready for user service %s: %s',
userService, userService,
@ -926,7 +926,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
userService, userService,
log.WARN, log.WARN,
f'User {user.pretty_name} from {srcIp} tried to access, but service was not ready', f'User {user.pretty_name} from {srcIp} tried to access, but service was not ready',
log.WEB, log.LogSource.WEB,
) )
traceLogger.error( traceLogger.error(
@ -1131,7 +1131,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
meta, meta,
log.WARN, log.WARN,
f'No user service accessible from device (ip {srcIp}, os: {os.os.name})', f'No user service accessible from device (ip {srcIp}, os: {os.os.name})',
log.SERVICE, log.LogSource.SERVICE,
) )
raise InvalidServiceException( raise InvalidServiceException(
_('The service is not accessible from this device') _('The service is not accessible from this device')

View File

@ -67,7 +67,7 @@ class StateUpdater:
logger.error('Got error on processor: %s', msg) logger.error('Got error on processor: %s', msg)
self.save(State.ERROR) self.save(State.ERROR)
if msg is not None: if msg is not None:
log.doLog(self.userService, log.ERROR, msg, log.INTERNAL) log.doLog(self.userService, log.LogLevel.ERROR, msg, log.LogSource.INTERNAL)
def save(self, newState: typing.Optional[str] = None): def save(self, newState: typing.Optional[str] = None):
if newState: if newState:
@ -263,7 +263,7 @@ class UserServiceOpChecker(DelayedTask):
except Exception as e: except Exception as e:
logger.exception('Checking service state') logger.exception('Checking service state')
log.doLog(userService, log.ERROR, f'Exception: {e}', log.INTERNAL) log.doLog(userService, log.LogLevel.ERROR, f'Exception: {e}', log.LogSource.INTERNAL)
userService.setState(State.ERROR) userService.setState(State.ERROR)
userService.save(update_fields=['data']) userService.save(update_fields=['data'])
@ -304,7 +304,7 @@ class UserServiceOpChecker(DelayedTask):
# Exception caught, mark service as errored # Exception caught, mark service as errored
logger.exception("Error %s, %s :", e.__class__, e) logger.exception("Error %s, %s :", e.__class__, e)
if uService: if uService:
log.doLog(uService, log.ERROR, f'Exception: {e}', log.INTERNAL) log.doLog(uService, log.LogLevel.ERROR, f'Exception: {e}', log.LogSource.INTERNAL)
try: try:
uService.setState(State.ERROR) uService.setState(State.ERROR)
uService.save(update_fields=['data']) uService.save(update_fields=['data'])

View File

@ -251,9 +251,9 @@ class OSManager(Module):
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
f'User {userName} has logged in', f'User {userName} has logged in',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
log.useLog( log.useLog(
@ -316,9 +316,9 @@ class OSManager(Module):
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
f'User {userName} has logged out', f'User {userName} has logged out',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
log.useLog( log.useLog(

View File

@ -216,7 +216,7 @@ class ServiceProvider(Module):
if self.getUuid(): if self.getUuid():
log.doLog( log.doLog(
DBProvider.objects.get(uuid=self.getUuid()), level, message, log.SERVICE DBProvider.objects.get(uuid=self.getUuid()), level, message, log.LogSource.SERVICE
) )
def __str__(self): def __str__(self):

View File

@ -402,7 +402,7 @@ class Service(Module):
if self.getUuid(): if self.getUuid():
log.doLog( log.doLog(
DBService.objects.get(uuid=self.getUuid()), level, message, log.SERVICE DBService.objects.get(uuid=self.getUuid()), level, message, log.LogSource.SERVICE
) )
@classmethod @classmethod

View File

@ -234,7 +234,7 @@ class UserDeployment(Environmentable, Serializable):
Logs a message with requested level associated with this user deployment Logs a message with requested level associated with this user deployment
""" """
if self._dbService: if self._dbService:
log.doLog(self._dbService, level, message, log.SERVICE) log.doLog(self._dbService, level, message, log.LogSource.SERVICE)
def macGenerator(self) -> 'UniqueMacGenerator': def macGenerator(self) -> 'UniqueMacGenerator':
""" """

View File

@ -529,18 +529,18 @@ class GlobalConfig:
), ),
) )
# Maximum logs per every log-capable administration element # Maximum logs per every log-capable administration element
MAX_LOGS_PER_ELEMENT: Config.Value = Config.section(GLOBAL_SECTION).value( INDIVIDIAL_LOG_MAX_ELEMENTS: Config.Value = Config.section(GLOBAL_SECTION).value(
'maxLogPerElement', 'maxLogPerElement',
'100', '100',
type=Config.FieldType.NUMERIC, type=Config.FieldType.NUMERIC,
help=_('Maximum logs per every log-capable administration element'), help=_('Maximum logs per every log-capable administration element'),
) )
# Maximum logs per every log-capable administration element # Maximum logs per every log-capable administration element
SYSLOG_MAX_ELEMENTS: Config.Value = Config.section(GLOBAL_SECTION).value( GENERAL_LOG_MAX_ELEMENTS: Config.Value = Config.section(GLOBAL_SECTION).value(
'Max logs for UDS logs', 'Max entries for general UDS logs',
'10000', '32000',
type=Config.FieldType.NUMERIC, type=Config.FieldType.NUMERIC,
help=_('Maximum logs entries to keep in database for UDS logs (0 = unlimited, use with care)'), help=_('Maximum logs entries for general UDS logs (0 = unlimited, use with care)'),
) )

View File

@ -33,6 +33,7 @@
import logging import logging
import logging.handlers import logging.handlers
import typing import typing
import enum
# Not imported at runtime, just for type checking # Not imported at runtime, just for type checking
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
@ -41,64 +42,48 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
useLogger = logging.getLogger('useLog') useLogger = logging.getLogger('useLog')
# Logging levels class LogLevel(enum.IntEnum):
OTHER, DEBUG, INFO, WARNING, ERROR, CRITICAL = ( OTHER = 10000
10000 * (x + 1) for x in range(6) DEBUG = 20000
) # @UndefinedVariable INFO = 30000
WARNING = 40000
# Alias WARN
WARN = 40000
ERROR = 50000
CRITICAL = 60000
# Alias FATAL
FATAL = 60000
WARN = WARNING def __str__(self) -> str:
FATAL = CRITICAL return self.name
# Logging sources def __repr__(self) -> str:
INTERNAL, ACTOR, TRANSPORT, OSMANAGER, UNKNOWN, WEB, ADMIN, SERVICE, REST = ( return self.name
'internal',
'actor',
'transport',
'osmanager',
'unknown',
'web',
'admin',
'service',
'rest',
)
OTHERSTR, DEBUGSTR, INFOSTR, WARNSTR, ERRORSTR, FATALSTR = ( @classmethod
'OTHER', def fromStr(cls: typing.Type['LogLevel'], level: str) -> 'LogLevel':
'DEBUG', try:
'INFO', return cls[level.upper()]
'WARN', except KeyError:
'ERROR', return cls.OTHER
'FATAL',
)
# Names for defined log levels @classmethod
__nameLevels = { def fromInt(cls: typing.Type['LogLevel'], level: int) -> 'LogLevel':
DEBUGSTR: DEBUG, try:
INFOSTR: INFO, return cls(level)
WARNSTR: WARN, except ValueError:
ERRORSTR: ERROR, return cls.OTHER
FATALSTR: FATAL,
OTHERSTR: OTHER,
}
# Reverse dict of names
__valueLevels = {v: k for k, v in __nameLevels.items()}
# Global log owner types:
OWNER_TYPE_GLOBAL = -1
OWNER_TYPE_AUDIT = -2
def logLevelFromStr(level: str) -> int:
"""
Gets the numeric log level from an string.
"""
return __nameLevels.get(level.upper(), OTHER)
def logStrFromLevel(level: int) -> str:
return __valueLevels.get(level, 'OTHER')
class LogSource(enum.StrEnum):
INTERNAL = 'internal'
ACTOR = 'actor'
TRANSPORT = 'transport'
OSMANAGER = 'osmanager'
UNKNOWN = 'unknown'
WEB = 'web'
ADMIN = 'admin'
SERVICE = 'service'
REST = 'rest'
def useLog( def useLog(
type_: str, type_: str,
@ -141,10 +126,10 @@ def useLog(
def doLog( def doLog(
wichObject: 'Model', wichObject: typing.Optional['Model'],
level: int, level: LogLevel,
message: str, message: str,
source: str = UNKNOWN, source: LogSource = LogSource.UNKNOWN,
avoidDuplicates: bool = True, avoidDuplicates: bool = True,
) -> None: ) -> None:
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
@ -155,22 +140,18 @@ def doLog(
def getLogs( def getLogs(
wichObject: 'Model', limit: typing.Optional[int] = None wichObject: typing.Optional['Model'], limit: int = -1
) -> typing.List[typing.Dict]: ) -> typing.List[typing.Dict]:
""" """
Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT) Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT)
""" """
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from uds.core.managers.log import LogManager from uds.core.managers.log import LogManager
from uds.core.util.config import GlobalConfig
if limit is None:
limit = GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
return LogManager().getLogs(wichObject, limit) return LogManager().getLogs(wichObject, limit)
def clearLogs(wichObject: 'Model') -> None: def clearLogs(wichObject: typing.Optional['Model']) -> None:
""" """
Clears the logs associated with the object using the logManager Clears the logs associated with the object using the logManager
""" """

View File

@ -98,26 +98,26 @@ class HangedCleaner(Job):
): # Removing too long, remark it as removable ): # Removing too long, remark it as removable
log.doLog( log.doLog(
us, us,
log.ERROR, log.LogLevel.ERROR,
'User Service hanged on removal process. Restarting removal.', 'User Service hanged on removal process. Restarting removal.',
log.INTERNAL, log.LogSource.INTERNAL,
) )
log.doLog( log.doLog(
servicePool, servicePool,
log.ERROR, log.LogLevel.ERROR,
f'User service {us.friendly_name} hanged on removal. Restarting removal.', f'User service {us.friendly_name} hanged on removal. Restarting removal.',
) )
us.release() # Mark it again as removable, and let's see us.release() # Mark it again as removable, and let's see
else: else:
log.doLog( log.doLog(
us, us,
log.ERROR, log.LogLevel.ERROR,
'User Service seems to be hanged. Removing it.', 'User Service seems to be hanged. Removing it.',
log.INTERNAL, log.LogSource.INTERNAL,
) )
log.doLog( log.doLog(
servicePool, servicePool,
log.ERROR, log.LogLevel.ERROR,
f'Removing user service {us.friendly_name} because it seems to be hanged' f'Removing user service {us.friendly_name} because it seems to be hanged'
) )
us.releaseOrCancel() us.releaseOrCancel()

View File

@ -66,7 +66,7 @@ class ServiceCacheUpdater(Job):
servicePool, servicePool,
log.WARN, log.WARN,
'Service Pool is restrained due to excesive errors', 'Service Pool is restrained due to excesive errors',
log.INTERNAL, log.LogSource.INTERNAL,
) )
logger.info('%s is restrained, will check this later', servicePool.name) logger.info('%s is restrained, will check this later', servicePool.name)
@ -259,9 +259,9 @@ class ServiceCacheUpdater(Job):
except MaxServicesReachedError: except MaxServicesReachedError:
log.doLog( log.doLog(
servicePool, servicePool,
log.ERROR, log.LogLevel.ERROR,
'Max number of services reached for this service', 'Max number of services reached for this service',
log.INTERNAL, log.LogSource.INTERNAL,
) )
logger.warning( logger.warning(
'Max user services reached for %s: %s. Cache not created', 'Max user services reached for %s: %s. Cache not created',

View File

@ -95,7 +95,7 @@ class StuckCleaner(Job):
logger.debug('Found stuck user service %s', stuck) logger.debug('Found stuck user service %s', stuck)
log.doLog( log.doLog(
servicePool, servicePool,
log.ERROR, log.LogLevel.ERROR,
f'User service {stuck.name} has been hard removed because it\'s stuck', f'User service {stuck.name} has been hard removed because it\'s stuck',
) )
# stuck.setState(State.ERROR) # stuck.setState(State.ERROR)

View File

@ -93,8 +93,8 @@ def guacamole(
protocol = 'RDS' if 'remote-app' in val else val['protocol'].upper() protocol = 'RDS' if 'remote-app' in val else val['protocol'].upper()
host = val.get('hostname', '0.0.0.0') # nosec: Not a bind, just a placeholder for "no host" host = val.get('hostname', '0.0.0.0') # nosec: Not a bind, just a placeholder for "no host"
msg = f'User {user.name} started HTML5 {protocol} tunnel to {host}.' msg = f'User {user.name} started HTML5 {protocol} tunnel to {host}.'
log.doLog(user.manager, log.INFO, msg) log.doLog(user.manager, log.LogLevel.INFO, msg)
log.doLog(userService, log.INFO, msg) log.doLog(userService, log.LogLevel.INFO, msg)
events.addEvent( events.addEvent(
userService.deployed_service, userService.deployed_service,

View File

@ -0,0 +1,17 @@
# Generated by Django 4.2 on 2023-04-20 03:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("uds", "0044_notification_notifier_servicetokenalias_and_more"),
]
operations = [
migrations.AddField(
model_name="log",
name="name",
field=models.CharField(default="", max_length=64),
),
]

View File

@ -449,7 +449,7 @@ class CalendarAction(UUIDModel):
self.service_pool.log( self.service_pool.log(
f'Executed action {CALENDAR_ACTION_DICT.get(self.action, {}).get("description", self.action)} [{self.prettyParams}]', f'Executed action {CALENDAR_ACTION_DICT.get(self.action, {}).get("description", self.action)} [{self.prettyParams}]',
level=log.INFO, level=log.LogLevel.INFO,
) )
except Exception: except Exception:
self.service_pool.log( self.service_pool.log(

View File

@ -58,6 +58,7 @@ class Log(models.Model):
created = models.DateTimeField(db_index=True) created = models.DateTimeField(db_index=True)
source = models.CharField(max_length=16, default='internal', db_index=True) source = models.CharField(max_length=16, default='internal', db_index=True)
level = models.PositiveIntegerField(default=0, db_index=True) level = models.PositiveIntegerField(default=0, db_index=True)
name = models.CharField(max_length=64, default='') # If syslog, log name, else empty
data = models.CharField(max_length=4096, default='') data = models.CharField(max_length=4096, default='')
# "fake" declarations for type checking # "fake" declarations for type checking
@ -74,9 +75,9 @@ class Log(models.Model):
@property @property
def level_str(self) -> str: def level_str(self) -> str:
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from uds.core.util.log import logStrFromLevel from uds.core.util.log import LogLevel
return logStrFromLevel(self.level) return LogLevel.fromInt(self.level).name
def __str__(self) -> str: def __str__(self) -> str:
return ( return (

View File

@ -699,8 +699,8 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
return bool(self.service) and self.service.testServer(host, port, timeout) return bool(self.service) and self.service.testServer(host, port, timeout)
# Utility for logging # Utility for logging
def log(self, message: str, level: int = log.INFO) -> None: def log(self, message: str, level: int = log.LogLevel.INFO) -> None:
log.doLog(self, level, message, log.INTERNAL) log.doLog(self, level, message, log.LogSource.INTERNAL)
@staticmethod @staticmethod
def beforeDelete(sender, **kwargs) -> None: # pylint: disable=unused-argument def beforeDelete(sender, **kwargs) -> None: # pylint: disable=unused-argument

View File

@ -637,8 +637,8 @@ class UserService(UUIDModel):
) or self.publication == self.deployed_service.activePublication() ) or self.publication == self.deployed_service.activePublication()
# Utility for logging # Utility for logging
def log(self, message: str, level: int = log.INFO) -> None: def log(self, message: str, level: int = log.LogLevel.INFO) -> None:
log.doLog(self, level, message, log.INTERNAL) log.doLog(self, level, message, log.LogSource.INTERNAL)
def testServer(self, host, port, timeout=4) -> bool: def testServer(self, host, port, timeout=4) -> bool:
return self.deployed_service.testServer(host, port, timeout) return self.deployed_service.testServer(host, port, timeout)

View File

@ -134,7 +134,7 @@ class LinuxOsManager(osmanagers.OSManager):
""" """
return service.getName() return service.getName()
def doLog(self, service, data, origin=log.OSMANAGER): def doLog(self, service, data, origin=log.LogSource.OSMANAGER):
# Stores a log associated with this service # Stores a log associated with this service
try: try:
msg, level = data.split('\t') msg, level = data.split('\t')
@ -142,10 +142,10 @@ class LinuxOsManager(osmanagers.OSManager):
level = int(level) level = int(level)
except Exception: except Exception:
logger.debug('Do not understand level %s', level) logger.debug('Do not understand level %s', level)
level = log.INFO level = log.LogLevel.INFO
log.doLog(service, level, msg, origin) log.doLog(service, level, msg, origin)
except Exception: except Exception:
log.doLog(service, log.ERROR, "do not understand {0}".format(data), origin) log.doLog(service, log.LogLevel.ERROR, "do not understand {0}".format(data), origin)
def actorData( def actorData(
self, userService: 'UserService' self, userService: 'UserService'
@ -160,9 +160,9 @@ class LinuxOsManager(osmanagers.OSManager):
if self.isRemovableOnLogout(userService): if self.isRemovableOnLogout(userService):
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
'Unused user service for too long. Removing due to OS Manager parameters.', 'Unused user service for too long. Removing due to OS Manager parameters.',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
userService.remove() userService.remove()

View File

@ -101,9 +101,9 @@ class LinuxRandomPassManager(LinuxOsManager):
service.storeValue('linOsRandomPass', randomPass) service.storeValue('linOsRandomPass', randomPass)
log.doLog( log.doLog(
service, service,
log.INFO, log.LogLevel.INFO,
"Password set to \"{}\"".format(randomPass), "Password set to \"{}\"".format(randomPass),
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
return randomPass return randomPass

View File

@ -108,7 +108,7 @@ class TestOSManager(osmanagers.OSManager):
""" """
return userService.getName() return userService.getName()
def doLog(self, service, data, origin=log.OSMANAGER): def doLog(self, service, data, origin=log.LogSource.OSMANAGER):
# Stores a log associated with this service # Stores a log associated with this service
try: try:
msg, level = data.split('\t') msg, level = data.split('\t')
@ -116,10 +116,10 @@ class TestOSManager(osmanagers.OSManager):
level = int(level) level = int(level)
except Exception: except Exception:
logger.debug('Do not understand level %s', level) logger.debug('Do not understand level %s', level)
level = log.INFO level = log.LogLevel.INFO
log.doLog(service, level, msg, origin) log.doLog(service, level, msg, origin)
except Exception: except Exception:
log.doLog(service, log.ERROR, "do not understand {0}".format(data), origin) log.doLog(service, log.LogLevel.ERROR, "do not understand {0}".format(data), origin)
def actorData( def actorData(
self, userService: 'UserService' self, userService: 'UserService'
@ -134,9 +134,9 @@ class TestOSManager(osmanagers.OSManager):
if self.isRemovableOnLogout(userService): if self.isRemovableOnLogout(userService):
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
'Unused user service for too long. Removing due to OS Manager parameters.', 'Unused user service for too long. Removing due to OS Manager parameters.',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
userService.remove() userService.remove()

View File

@ -140,7 +140,7 @@ class WindowsOsManager(osmanagers.OSManager):
def getName(self, userService: 'UserService') -> str: def getName(self, userService: 'UserService') -> str:
return userService.getName() return userService.getName()
def doLog(self, userService: 'UserService', data: str, origin=log.OSMANAGER): def doLog(self, userService: 'UserService', data: str, origin=log.LogSource.OSMANAGER):
# Stores a log associated with this service # Stores a log associated with this service
try: try:
msg, levelStr = data.split('\t') msg, levelStr = data.split('\t')
@ -148,13 +148,13 @@ class WindowsOsManager(osmanagers.OSManager):
level = int(levelStr) level = int(levelStr)
except Exception: except Exception:
logger.debug('Do not understand level %s', levelStr) logger.debug('Do not understand level %s', levelStr)
level = log.INFO level = log.LogLevel.INFO
log.doLog(userService, level, msg, origin) log.doLog(userService, level, msg, origin)
except Exception: except Exception:
logger.exception('WindowsOs Manager message log: ') logger.exception('WindowsOs Manager message log: ')
log.doLog( log.doLog(
userService, log.ERROR, "do not understand {0}".format(data), origin userService, log.LogLevel.ERROR, "do not understand {0}".format(data), origin
) )
def actorData( def actorData(
@ -191,9 +191,9 @@ class WindowsOsManager(osmanagers.OSManager):
if self.isRemovableOnLogout(userService): if self.isRemovableOnLogout(userService):
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
'Unused user service for too long. Removing due to OS Manager parameters.', 'Unused user service for too long. Removing due to OS Manager parameters.',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
userService.remove() userService.remove()

View File

@ -311,7 +311,7 @@ class WinDomainOsManager(WindowsOsManager):
userService, userService,
log.WARN, log.WARN,
f'Could not remove machine from domain (_ldap._tcp.{self._domain} not found)', f'Could not remove machine from domain (_ldap._tcp.{self._domain} not found)',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
except ldap.ALREADY_EXISTS: # type: ignore # (valid) except ldap.ALREADY_EXISTS: # type: ignore # (valid)
# Already added this machine to this group, pass # Already added this machine to this group, pass
@ -325,7 +325,7 @@ class WinDomainOsManager(WindowsOsManager):
# logger.exception('Ldap Exception caught') # logger.exception('Ldap Exception caught')
if error: if error:
log.doLog(userService, log.WARN, error, log.OSMANAGER) log.doLog(userService, log.WARN, error, log.LogSource.OSMANAGER)
logger.error(error) logger.error(error)
def release(self, userService: 'UserService') -> None: def release(self, userService: 'UserService') -> None:
@ -339,9 +339,9 @@ class WinDomainOsManager(WindowsOsManager):
# logger.info('Releasing from a not FQDN domain is not supported') # logger.info('Releasing from a not FQDN domain is not supported')
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
"Removing a domain machine form a non FQDN domain is not supported.", "Removing a domain machine form a non FQDN domain is not supported.",
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
return return
@ -353,7 +353,7 @@ class WinDomainOsManager(WindowsOsManager):
userService, userService,
log.WARN, log.WARN,
f'Could not remove machine from domain (_ldap._tcp.{self._domain} not found)', f'Could not remove machine from domain (_ldap._tcp.{self._domain} not found)',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
return return
except ldaputil.LDAPError as e: except ldaputil.LDAPError as e:
@ -362,7 +362,7 @@ class WinDomainOsManager(WindowsOsManager):
userService, userService,
log.WARN, log.WARN,
f'Could not remove machine from domain ({e})', f'Could not remove machine from domain ({e})',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
return return
except Exception as e: except Exception as e:
@ -371,7 +371,7 @@ class WinDomainOsManager(WindowsOsManager):
userService, userService,
log.WARN, log.WARN,
f'Could not remove machine from domain ({e})', f'Could not remove machine from domain ({e})',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
return return

View File

@ -128,9 +128,9 @@ class WinRandomPassManager(WindowsOsManager):
userService.storeValue('winOsRandomPass', randomPass) userService.storeValue('winOsRandomPass', randomPass)
log.doLog( log.doLog(
userService, userService,
log.INFO, log.LogLevel.INFO,
f'Password set to "{randomPass}"', f'Password set to "{randomPass}"',
log.OSMANAGER, log.LogSource.OSMANAGER,
) )
return randomPass return randomPass

View File

@ -218,7 +218,7 @@ class OVirtLinkedDeployment(services.UserDeployment):
self.cache.put('ready', '1') self.cache.put('ready', '1')
except Exception as e: except Exception as e:
self.doLog(log.ERROR, f'Error on setReady: {e}') self.doLog(log.LogLevel.ERROR, f'Error on setReady: {e}')
# Treat as operation done, maybe the machine is ready and we can continue # Treat as operation done, maybe the machine is ready and we can continue
return State.FINISHED return State.FINISHED
@ -335,7 +335,7 @@ if sys.platform == 'win32':
""" """
reason = str(reason) reason = str(reason)
logger.debug('Setting error state, reason: %s', reason) logger.debug('Setting error state, reason: %s', reason)
self.doLog(log.ERROR, reason) self.doLog(log.LogLevel.ERROR, reason)
if self._vmid != '': # Powers off if self._vmid != '': # Powers off
OVirtDeferredRemoval.remove(self.service().parent(), self._vmid) OVirtDeferredRemoval.remove(self.service().parent(), self._vmid)

View File

@ -228,7 +228,7 @@ class OGDeployment(UserDeployment):
State.ERROR, so we can do "return self.__error(reason)" State.ERROR, so we can do "return self.__error(reason)"
""" """
logger.debug('Setting error state, reason: %s', reason) logger.debug('Setting error state, reason: %s', reason)
self.doLog(log.ERROR, reason) self.doLog(log.LogLevel.ERROR, reason)
if self._machineId: if self._machineId:
try: try:
@ -311,7 +311,7 @@ class OGDeployment(UserDeployment):
self._stamp = getSqlDatetimeAsUnix() self._stamp = getSqlDatetimeAsUnix()
self.doLog( self.doLog(
log.INFO, log.LogLevel.INFO,
f'Reserved machine {self._name}: id: {self._machineId}, mac: {self._mac}, ip: {self._ip}', f'Reserved machine {self._name}: id: {self._machineId}, mac: {self._mac}, ip: {self._ip}',
) )

View File

@ -141,7 +141,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
self.cache.put('ready', '1') self.cache.put('ready', '1')
except Exception as e: except Exception as e:
self.doLog(log.ERROR, 'Error on setReady: {}'.format(e)) self.doLog(log.LogLevel.ERROR, 'Error on setReady: {}'.format(e))
# Treat as operation done, maybe the machine is ready and we can continue # Treat as operation done, maybe the machine is ready and we can continue
return State.FINISHED return State.FINISHED
@ -242,7 +242,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
""" """
reason = str(reason) reason = str(reason)
logger.debug('Setting error state, reason: %s', reason) logger.debug('Setting error state, reason: %s', reason)
self.doLog(log.ERROR, reason) self.doLog(log.LogLevel.ERROR, reason)
if self._vmid: # Powers off & delete it if self._vmid: # Powers off & delete it
try: try:

View File

@ -157,7 +157,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
self.cache.put('ready', '1') self.cache.put('ready', '1')
except Exception as e: except Exception as e:
self.doLog(log.ERROR, 'Error on setReady: {}'.format(e)) self.doLog(log.LogLevel.ERROR, 'Error on setReady: {}'.format(e))
# Treat as operation done, maybe the machine is ready and we can continue # Treat as operation done, maybe the machine is ready and we can continue
return State.FINISHED return State.FINISHED
@ -247,7 +247,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
self._queue = [opError] self._queue = [opError]
self._reason = str(reason) self._reason = str(reason)
self.doLog(log.ERROR, self._reason) self.doLog(log.LogLevel.ERROR, self._reason)
if self._vmid: # Powers off & delete it if self._vmid: # Powers off & delete it
try: try:

View File

@ -297,7 +297,7 @@ if sys.platform == 'win32':
""" """
reason = str(reason) reason = str(reason)
logger.debug('Setting error state, reason: %s', reason) logger.debug('Setting error state, reason: %s', reason)
self.doLog(log.ERROR, reason) self.doLog(log.LogLevel.ERROR, reason)
if self._vmid != '': # Powers off if self._vmid != '': # Powers off
ProxmoxDeferredRemoval.remove(self.service().parent(), int(self._vmid)) ProxmoxDeferredRemoval.remove(self.service().parent(), int(self._vmid))
@ -532,7 +532,7 @@ if sys.platform == 'win32':
if getSqlDatetimeAsUnix() - shutdown_start > GUEST_SHUTDOWN_WAIT: if getSqlDatetimeAsUnix() - shutdown_start > GUEST_SHUTDOWN_WAIT:
logger.debug('Time is consumed, falling back to stop') logger.debug('Time is consumed, falling back to stop')
self.doLog( self.doLog(
log.ERROR, log.LogLevel.ERROR,
f'Could not shutdown machine using soft power off in time ({GUEST_SHUTDOWN_WAIT} seconds). Powering off.', f'Could not shutdown machine using soft power off in time ({GUEST_SHUTDOWN_WAIT} seconds). Powering off.',
) )
# Not stopped by guest in time, but must be stopped normally # Not stopped by guest in time, but must be stopped normally

View File

@ -154,7 +154,7 @@ class XenLinkedDeployment(UserDeployment):
self.cache.put('ready', '1', 30) self.cache.put('ready', '1', 30)
except Exception as e: except Exception as e:
# On case of exception, log an an error and return as if the operation was executed # On case of exception, log an an error and return as if the operation was executed
self.doLog(log.ERROR, 'Error setting machine state: {}'.format(e)) self.doLog(log.LogLevel.ERROR, 'Error setting machine state: {}'.format(e))
# return self.__error('Machine is not available anymore') # return self.__error('Machine is not available anymore')
return State.FINISHED return State.FINISHED
@ -224,7 +224,7 @@ class XenLinkedDeployment(UserDeployment):
def __error(self, reason: typing.Any) -> str: def __error(self, reason: typing.Any) -> str:
logger.debug('Setting error state, reason: %s', reason) logger.debug('Setting error state, reason: %s', reason)
self.doLog(log.ERROR, reason) self.doLog(log.LogLevel.ERROR, reason)
if self._vmid != '': # Powers off and delete VM if self._vmid != '': # Powers off and delete VM
try: try:

View File

@ -210,11 +210,11 @@ def action(
rebuild = True rebuild = True
log.doLog( log.doLog(
userService.deployed_service, userService.deployed_service,
log.INFO, log.LogLevel.INFO,
"Removing User Service {} as requested by {} from {}".format( "Removing User Service {} as requested by {} from {}".format(
userService.friendly_name, request.user.pretty_name, request.ip userService.friendly_name, request.user.pretty_name, request.ip
), ),
log.WEB, log.LogSource.WEB,
) )
UserServiceManager().requestLogoff(userService) UserServiceManager().requestLogoff(userService)
userService.release() userService.release()
@ -226,11 +226,11 @@ def action(
rebuild = True rebuild = True
log.doLog( log.doLog(
userService.deployed_service, userService.deployed_service,
log.INFO, log.LogLevel.INFO,
"Reseting User Service {} as requested by {} from {}".format( "Reseting User Service {} as requested by {} from {}".format(
userService.friendly_name, request.user.pretty_name, request.ip userService.friendly_name, request.user.pretty_name, request.ip
), ),
log.WEB, log.LogSource.WEB,
) )
# UserServiceManager().requestLogoff(userService) # UserServiceManager().requestLogoff(userService)
UserServiceManager().reset(userService) UserServiceManager().reset(userService)