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:
parent
3a0efbb998
commit
9030ff3ab3
@ -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()
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
@ -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')
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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,
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
||||||
|
@ -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] = {
|
||||||
|
@ -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()
|
||||||
|
@ -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')
|
||||||
|
@ -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'])
|
||||||
|
@ -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(
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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':
|
||||||
"""
|
"""
|
||||||
|
@ -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)'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
"""
|
"""
|
@ -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()
|
||||||
|
@ -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',
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
17
server/src/uds/migrations/0045_log_name.py
Normal file
17
server/src/uds/migrations/0045_log_name.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
@ -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(
|
||||||
|
@ -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 (
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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}',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user