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:
|
||||
log.doLog(user, log.DEBUG, f'Debug Log for {user.name}')
|
||||
log.doLog(user, log.INFO, f'Info Log for {user.name}')
|
||||
log.doLog(user, log.WARNING, f'Warning Log for {user.name}')
|
||||
log.doLog(user, log.ERROR, f'Error Log for {user.name}')
|
||||
log.doLog(user, log.LogLevel.DEBUG, f'Debug Log for {user.name}')
|
||||
log.doLog(user, log.LogLevel.INFO, f'Info Log for {user.name}')
|
||||
log.doLog(user, log.LogLevel.WARNING, f'Warning Log for {user.name}')
|
||||
log.doLog(user, log.LogLevel.ERROR, f'Error Log for {user.name}')
|
||||
|
||||
self.provider = services_fixtures.createProvider()
|
||||
|
||||
|
@ -147,7 +147,7 @@ class Dispatcher(View):
|
||||
logger.debug('Path: %s', full_path)
|
||||
logger.debug('Error: %s', e)
|
||||
|
||||
log.log_operation(handler, 500, log.ERROR)
|
||||
log.logOperation(handler, 500, log.LogLevel.ERROR)
|
||||
return http.HttpResponseServerError(
|
||||
f'Invalid parameters invoking {full_path}: {e}',
|
||||
content_type="text/plain",
|
||||
@ -157,17 +157,17 @@ class Dispatcher(View):
|
||||
for n in ['get', 'post', 'put', 'delete']:
|
||||
if hasattr(handler, n):
|
||||
allowedMethods.append(n)
|
||||
log.log_operation(handler, 405, log.ERROR)
|
||||
log.logOperation(handler, 405, log.LogLevel.ERROR)
|
||||
return http.HttpResponseNotAllowed(
|
||||
allowedMethods, content_type="text/plain"
|
||||
)
|
||||
except AccessDenied:
|
||||
log.log_operation(handler, 403, log.ERROR)
|
||||
log.logOperation(handler, 403, log.LogLevel.ERROR)
|
||||
return http.HttpResponseForbidden(
|
||||
'access denied', content_type="text/plain"
|
||||
)
|
||||
except Exception:
|
||||
log.log_operation(handler, 500, log.ERROR)
|
||||
log.logOperation(handler, 500, log.LogLevel.ERROR)
|
||||
logger.exception('error accessing attribute')
|
||||
logger.debug('Getting attribute %s for %s', http_method, full_path)
|
||||
return http.HttpResponseServerError(
|
||||
@ -185,28 +185,28 @@ class Dispatcher(View):
|
||||
for k, val in handler.headers().items():
|
||||
response[k] = val
|
||||
|
||||
log.log_operation(handler, response.status_code, log.INFO)
|
||||
log.logOperation(handler, response.status_code, log.LogLevel.INFO)
|
||||
return response
|
||||
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")
|
||||
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")
|
||||
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")
|
||||
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")
|
||||
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")
|
||||
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")
|
||||
except Exception as e:
|
||||
log.log_operation(handler, 500, log.ERROR)
|
||||
log.logOperation(handler, 500, log.LogLevel.ERROR)
|
||||
# Get ecxeption backtrace
|
||||
trace_back = traceback.format_exc()
|
||||
logger.error('Exception processing request: %s', full_path)
|
||||
|
@ -32,15 +32,10 @@ Author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
import typing
|
||||
|
||||
from uds import models
|
||||
from uds.core.util.log import (
|
||||
REST,
|
||||
OWNER_TYPE_AUDIT,
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
CRITICAL,
|
||||
)
|
||||
|
||||
# Import for REST using this module can access constants easily
|
||||
# pylint: disable=unused-import
|
||||
from uds.core.util.log import LogLevel, LogSource, doLog
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .handlers import Handler
|
||||
@ -68,14 +63,14 @@ def replacePath(path: str) -> str:
|
||||
uuid = path.split(f'/{type}/')[1].split('/')[0]
|
||||
name = model.objects.get(uuid=uuid).name # type: ignore
|
||||
path = path.replace(uuid, f'[{name}]')
|
||||
except Exception: # nosec: intentionally broad exception
|
||||
except Exception: # nosec: intentionally broad exception
|
||||
pass
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def log_operation(
|
||||
handler: typing.Optional['Handler'], response_code: int, level: int = INFO
|
||||
def logOperation(
|
||||
handler: typing.Optional['Handler'], response_code: int, level: LogLevel = LogLevel.INFO
|
||||
):
|
||||
"""
|
||||
Logs a request
|
||||
@ -83,7 +78,7 @@ def log_operation(
|
||||
if not handler:
|
||||
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 response_code < 400 and any(
|
||||
@ -93,15 +88,13 @@ def log_operation(
|
||||
|
||||
path = replacePath(path)
|
||||
|
||||
username = handler._request.user.pretty_name if handler._request.user else 'Unknown'
|
||||
# Global log is used without owner nor type
|
||||
models.Log.objects.create(
|
||||
owner_id=0,
|
||||
owner_type=OWNER_TYPE_AUDIT,
|
||||
created=models.getSqlDatetime(),
|
||||
username = handler.request.user.pretty_name if handler.request.user else 'Unknown'
|
||||
doLog(
|
||||
None,
|
||||
level=level,
|
||||
source=REST,
|
||||
data=f'{handler._request.ip} {username}: [{handler._request.method}/{response_code}] {path}'[
|
||||
message=f'{handler.request.ip} {username}: [{handler.request.method}/{response_code}] {path}'[
|
||||
:4096
|
||||
],
|
||||
source=LogSource.REST,
|
||||
avoidDuplicates=False,
|
||||
)
|
||||
|
@ -682,7 +682,7 @@ class Log(ActorV3Action):
|
||||
userService,
|
||||
int(self._params['level']) + 10000,
|
||||
self._params['message'],
|
||||
log.ACTOR,
|
||||
log.LogSource.ACTOR,
|
||||
)
|
||||
|
||||
return ActorV3Action.actorResult('ok')
|
||||
|
@ -110,12 +110,12 @@ class MetaServicesPool(DetailHandler):
|
||||
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
("Added" if uuid is None else "Modified")
|
||||
+ " meta pool member {}/{}/{} by {}".format(
|
||||
pool.name, priority, enabled, self._user.pretty_name
|
||||
),
|
||||
log.ADMIN,
|
||||
log.LogSource.ADMIN,
|
||||
)
|
||||
|
||||
return self.success()
|
||||
@ -128,7 +128,7 @@ class MetaServicesPool(DetailHandler):
|
||||
|
||||
member.delete()
|
||||
|
||||
log.doLog(parent, log.INFO, logStr, log.ADMIN)
|
||||
log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
|
||||
|
||||
|
||||
class MetaAssignedService(DetailHandler):
|
||||
@ -243,7 +243,7 @@ class MetaAssignedService(DetailHandler):
|
||||
else:
|
||||
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
|
||||
def saveItem(self, parent: MetaPool, item: typing.Optional[str]):
|
||||
@ -276,4 +276,4 @@ class MetaAssignedService(DetailHandler):
|
||||
service.save()
|
||||
|
||||
# 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(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
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:
|
||||
@ -126,7 +126,7 @@ class AccessCalendars(DetailHandler):
|
||||
logStr = f'Removed access calendar {calendarAccess.calendar.name} by {self._user.pretty_name}'
|
||||
calendarAccess.delete()
|
||||
|
||||
log.doLog(parent, log.INFO, logStr, log.ADMIN)
|
||||
log.doLog(parent, log.LogLevel.INFO, logStr, log.LogSource.ADMIN)
|
||||
|
||||
|
||||
class ActionsCalendars(DetailHandler):
|
||||
@ -219,7 +219,7 @@ class ActionsCalendars(DetailHandler):
|
||||
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:
|
||||
calendarAction = CalendarAction.objects.get(uuid=processUuid(self._args[0]))
|
||||
@ -232,7 +232,7 @@ class ActionsCalendars(DetailHandler):
|
||||
|
||||
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):
|
||||
logger.debug('Launching action')
|
||||
@ -247,7 +247,7 @@ class ActionsCalendars(DetailHandler):
|
||||
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()
|
||||
|
||||
return self.success()
|
||||
|
@ -102,8 +102,8 @@ class TunnelTicket(Handler):
|
||||
now = models.getSqlDatetimeAsUnix()
|
||||
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}.'
|
||||
log.doLog(user.manager, log.INFO, msg)
|
||||
log.doLog(userService, log.INFO, msg)
|
||||
log.doLog(user.manager, log.LogLevel.INFO, msg)
|
||||
log.doLog(userService, log.LogLevel.INFO, msg)
|
||||
|
||||
# Try to log Close event
|
||||
try:
|
||||
@ -131,8 +131,8 @@ class TunnelTicket(Handler):
|
||||
tunnel=self._args[0],
|
||||
)
|
||||
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(userService, log.INFO, msg)
|
||||
log.doLog(user.manager, log.LogLevel.INFO, msg)
|
||||
log.doLog(userService, log.LogLevel.INFO, msg)
|
||||
# Generate new, notify only, ticket
|
||||
notifyTicket = models.TicketStore.create_for_tunnel(
|
||||
userService=userService,
|
||||
|
@ -191,7 +191,7 @@ class AssignedService(DetailHandler):
|
||||
else:
|
||||
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
|
||||
def saveItem(self, parent: models.ServicePool, item: typing.Optional[str]) -> None:
|
||||
@ -219,7 +219,7 @@ class AssignedService(DetailHandler):
|
||||
userService.save()
|
||||
|
||||
# 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:
|
||||
userService = parent.userServices.get(uuid=processUuid(item))
|
||||
@ -340,9 +340,9 @@ class Groups(DetailHandler):
|
||||
parent.assignedGroups.add(group)
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
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:
|
||||
@ -350,9 +350,9 @@ class Groups(DetailHandler):
|
||||
parent.assignedGroups.remove(group)
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
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)
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'Added transport {transport.name} by {self._user.pretty_name}',
|
||||
log.ADMIN,
|
||||
log.LogSource.ADMIN,
|
||||
)
|
||||
|
||||
def deleteItem(self, parent: models.ServicePool, item: str) -> None:
|
||||
@ -411,9 +411,9 @@ class Transports(DetailHandler):
|
||||
parent.transports.remove(transport)
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'Removed transport {transport.name} by {self._user.pretty_name}',
|
||||
log.ADMIN,
|
||||
log.LogSource.ADMIN,
|
||||
)
|
||||
|
||||
|
||||
@ -447,9 +447,9 @@ class Publications(DetailHandler):
|
||||
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'Initiated publication v{parent.current_pub_revision} by {self._user.pretty_name}',
|
||||
log.ADMIN,
|
||||
log.LogSource.ADMIN,
|
||||
)
|
||||
|
||||
return self.success()
|
||||
@ -478,9 +478,9 @@ class Publications(DetailHandler):
|
||||
|
||||
log.doLog(
|
||||
parent,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'Canceled publication v{parent.current_pub_revision} by {self._user.pretty_name}',
|
||||
log.ADMIN,
|
||||
log.LogSource.ADMIN,
|
||||
)
|
||||
|
||||
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(
|
||||
authenticator,
|
||||
level,
|
||||
f'user {userName} has {logStr} from {request.ip} where os is {request.os.os.name}',
|
||||
log.WEB,
|
||||
log.LogSource.WEB,
|
||||
)
|
||||
|
||||
try:
|
||||
@ -540,7 +540,7 @@ def authLogLogin(
|
||||
user,
|
||||
level,
|
||||
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
|
||||
pass
|
||||
@ -550,8 +550,8 @@ def authLogLogout(request: 'ExtendedHttpRequest') -> None:
|
||||
if request.user:
|
||||
log.doLog(
|
||||
request.user.manager,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
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
|
||||
# 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__)
|
||||
|
||||
|
||||
|
||||
class LogManager(metaclass=singleton.Singleton):
|
||||
"""
|
||||
Manager for logging (at database) events
|
||||
@ -61,7 +60,7 @@ class LogManager(metaclass=singleton.Singleton):
|
||||
def manager() -> 'LogManager':
|
||||
return LogManager() # Singleton pattern will return always the same instance
|
||||
|
||||
def __log(
|
||||
def _log(
|
||||
self,
|
||||
owner_type: LogObjectType,
|
||||
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 0 < max_elements <= current_elements:
|
||||
# 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()
|
||||
|
||||
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
|
||||
pass
|
||||
|
||||
def __getLogs(
|
||||
def _getLogs(
|
||||
self, owner_type: LogObjectType, owner_id: int, limit: int
|
||||
) -> 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
|
||||
]
|
||||
|
||||
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
|
||||
"""
|
||||
@ -148,7 +149,7 @@ class LogManager(metaclass=singleton.Singleton):
|
||||
|
||||
if owner_type is not None:
|
||||
try:
|
||||
self.__log(
|
||||
self._log(
|
||||
owner_type, objectId, level, message, source, avoidDuplicates
|
||||
)
|
||||
except Exception:
|
||||
@ -180,7 +181,11 @@ class LogManager(metaclass=singleton.Singleton):
|
||||
logger.debug('Getting log: %s -> %s', wichObject, 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(
|
||||
'Requested getLogs for a type of object not covered: %s', wichObject
|
||||
@ -200,7 +205,7 @@ class LogManager(metaclass=singleton.Singleton):
|
||||
else LogObjectType.SYSLOG
|
||||
)
|
||||
if owner_type:
|
||||
self.__clearLogs(owner_type, getattr(wichObject, 'id', -1))
|
||||
self._clearLogs(owner_type, getattr(wichObject, 'id', -1))
|
||||
else:
|
||||
logger.debug(
|
||||
'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
|
||||
|
||||
if self == LogObjectType.SYSLOG:
|
||||
return GlobalConfig.SYSLOG_MAX_ELEMENTS.getInt()
|
||||
return GlobalConfig.MAX_LOGS_PER_ELEMENT.getInt()
|
||||
|
||||
return GlobalConfig.GENERAL_LOG_MAX_ELEMENTS.getInt()
|
||||
return GlobalConfig.INDIVIDIAL_LOG_MAX_ELEMENTS.getInt()
|
||||
|
||||
# Dict for translations
|
||||
MODEL_TO_TYPE: typing.Mapping[typing.Type['Model'], LogObjectType] = {
|
||||
|
@ -344,7 +344,7 @@ class PublicationManager(metaclass=singleton.Singleton):
|
||||
publication.deployed_service,
|
||||
log.WARN,
|
||||
'Forced cancel on publication, you must check uncleaned resources manually',
|
||||
log.ADMIN,
|
||||
log.LogSource.ADMIN,
|
||||
)
|
||||
publication.setState(State.CANCELED)
|
||||
publication.save()
|
||||
|
@ -566,7 +566,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
servicePool,
|
||||
log.WARN,
|
||||
f'Max number of services reached: {servicePool.max_srvs}',
|
||||
log.INTERNAL,
|
||||
log.LogSource.INTERNAL,
|
||||
)
|
||||
raise MaxServicesReachedError()
|
||||
|
||||
@ -854,9 +854,9 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
serviceNotReadyCode = 0x0002
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
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
|
||||
userServiceInstance = userService.getInstance()
|
||||
@ -872,7 +872,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
userService,
|
||||
log.WARN,
|
||||
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)
|
||||
else:
|
||||
@ -889,7 +889,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
transportInstance = transport.getInstance()
|
||||
if transportInstance.isAvailableFor(userService, ip):
|
||||
# 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(
|
||||
userService,
|
||||
transportInstance.processedUser(userService, user),
|
||||
@ -913,7 +913,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
message = transportInstance.getCustomAvailableErrorMsg(
|
||||
userService, ip
|
||||
)
|
||||
log.doLog(userService, log.WARN, message, log.TRANSPORT)
|
||||
log.doLog(userService, log.WARN, message, log.LogSource.TRANSPORT)
|
||||
logger.debug(
|
||||
'Transport is not ready for user service %s: %s',
|
||||
userService,
|
||||
@ -926,7 +926,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
userService,
|
||||
log.WARN,
|
||||
f'User {user.pretty_name} from {srcIp} tried to access, but service was not ready',
|
||||
log.WEB,
|
||||
log.LogSource.WEB,
|
||||
)
|
||||
|
||||
traceLogger.error(
|
||||
@ -1131,7 +1131,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
||||
meta,
|
||||
log.WARN,
|
||||
f'No user service accessible from device (ip {srcIp}, os: {os.os.name})',
|
||||
log.SERVICE,
|
||||
log.LogSource.SERVICE,
|
||||
)
|
||||
raise InvalidServiceException(
|
||||
_('The service is not accessible from this device')
|
||||
|
@ -67,7 +67,7 @@ class StateUpdater:
|
||||
logger.error('Got error on processor: %s', msg)
|
||||
self.save(State.ERROR)
|
||||
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):
|
||||
if newState:
|
||||
@ -263,7 +263,7 @@ class UserServiceOpChecker(DelayedTask):
|
||||
|
||||
except Exception as e:
|
||||
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.save(update_fields=['data'])
|
||||
|
||||
@ -304,7 +304,7 @@ class UserServiceOpChecker(DelayedTask):
|
||||
# Exception caught, mark service as errored
|
||||
logger.exception("Error %s, %s :", e.__class__, e)
|
||||
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:
|
||||
uService.setState(State.ERROR)
|
||||
uService.save(update_fields=['data'])
|
||||
|
@ -251,9 +251,9 @@ class OSManager(Module):
|
||||
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'User {userName} has logged in',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
|
||||
log.useLog(
|
||||
@ -316,9 +316,9 @@ class OSManager(Module):
|
||||
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'User {userName} has logged out',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
|
||||
log.useLog(
|
||||
|
@ -216,7 +216,7 @@ class ServiceProvider(Module):
|
||||
|
||||
if self.getUuid():
|
||||
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):
|
||||
|
@ -402,7 +402,7 @@ class Service(Module):
|
||||
|
||||
if self.getUuid():
|
||||
log.doLog(
|
||||
DBService.objects.get(uuid=self.getUuid()), level, message, log.SERVICE
|
||||
DBService.objects.get(uuid=self.getUuid()), level, message, log.LogSource.SERVICE
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -234,7 +234,7 @@ class UserDeployment(Environmentable, Serializable):
|
||||
Logs a message with requested level associated with this user deployment
|
||||
"""
|
||||
if self._dbService:
|
||||
log.doLog(self._dbService, level, message, log.SERVICE)
|
||||
log.doLog(self._dbService, level, message, log.LogSource.SERVICE)
|
||||
|
||||
def macGenerator(self) -> 'UniqueMacGenerator':
|
||||
"""
|
||||
|
@ -529,18 +529,18 @@ class GlobalConfig:
|
||||
),
|
||||
)
|
||||
# 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',
|
||||
'100',
|
||||
type=Config.FieldType.NUMERIC,
|
||||
help=_('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(
|
||||
'Max logs for UDS logs',
|
||||
'10000',
|
||||
GENERAL_LOG_MAX_ELEMENTS: Config.Value = Config.section(GLOBAL_SECTION).value(
|
||||
'Max entries for general UDS logs',
|
||||
'32000',
|
||||
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.handlers
|
||||
import typing
|
||||
import enum
|
||||
|
||||
# Not imported at runtime, just for type checking
|
||||
if typing.TYPE_CHECKING:
|
||||
@ -41,64 +42,48 @@ if typing.TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
useLogger = logging.getLogger('useLog')
|
||||
|
||||
# Logging levels
|
||||
OTHER, DEBUG, INFO, WARNING, ERROR, CRITICAL = (
|
||||
10000 * (x + 1) for x in range(6)
|
||||
) # @UndefinedVariable
|
||||
class LogLevel(enum.IntEnum):
|
||||
OTHER = 10000
|
||||
DEBUG = 20000
|
||||
INFO = 30000
|
||||
WARNING = 40000
|
||||
# Alias WARN
|
||||
WARN = 40000
|
||||
ERROR = 50000
|
||||
CRITICAL = 60000
|
||||
# Alias FATAL
|
||||
FATAL = 60000
|
||||
|
||||
WARN = WARNING
|
||||
FATAL = CRITICAL
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
# Logging sources
|
||||
INTERNAL, ACTOR, TRANSPORT, OSMANAGER, UNKNOWN, WEB, ADMIN, SERVICE, REST = (
|
||||
'internal',
|
||||
'actor',
|
||||
'transport',
|
||||
'osmanager',
|
||||
'unknown',
|
||||
'web',
|
||||
'admin',
|
||||
'service',
|
||||
'rest',
|
||||
)
|
||||
def __repr__(self) -> str:
|
||||
return self.name
|
||||
|
||||
OTHERSTR, DEBUGSTR, INFOSTR, WARNSTR, ERRORSTR, FATALSTR = (
|
||||
'OTHER',
|
||||
'DEBUG',
|
||||
'INFO',
|
||||
'WARN',
|
||||
'ERROR',
|
||||
'FATAL',
|
||||
)
|
||||
@classmethod
|
||||
def fromStr(cls: typing.Type['LogLevel'], level: str) -> 'LogLevel':
|
||||
try:
|
||||
return cls[level.upper()]
|
||||
except KeyError:
|
||||
return cls.OTHER
|
||||
|
||||
# Names for defined log levels
|
||||
__nameLevels = {
|
||||
DEBUGSTR: DEBUG,
|
||||
INFOSTR: INFO,
|
||||
WARNSTR: WARN,
|
||||
ERRORSTR: ERROR,
|
||||
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')
|
||||
@classmethod
|
||||
def fromInt(cls: typing.Type['LogLevel'], level: int) -> 'LogLevel':
|
||||
try:
|
||||
return cls(level)
|
||||
except ValueError:
|
||||
return cls.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(
|
||||
type_: str,
|
||||
@ -141,10 +126,10 @@ def useLog(
|
||||
|
||||
|
||||
def doLog(
|
||||
wichObject: 'Model',
|
||||
level: int,
|
||||
wichObject: typing.Optional['Model'],
|
||||
level: LogLevel,
|
||||
message: str,
|
||||
source: str = UNKNOWN,
|
||||
source: LogSource = LogSource.UNKNOWN,
|
||||
avoidDuplicates: bool = True,
|
||||
) -> None:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
@ -155,22 +140,18 @@ def doLog(
|
||||
|
||||
|
||||
def getLogs(
|
||||
wichObject: 'Model', limit: typing.Optional[int] = None
|
||||
wichObject: typing.Optional['Model'], limit: int = -1
|
||||
) -> typing.List[typing.Dict]:
|
||||
"""
|
||||
Get the logs associated with "wichObject", limiting to "limit" (default is GlobalConfig.MAX_LOGS_PER_ELEMENT)
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
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)
|
||||
|
||||
|
||||
def clearLogs(wichObject: 'Model') -> None:
|
||||
def clearLogs(wichObject: typing.Optional['Model']) -> None:
|
||||
"""
|
||||
Clears the logs associated with the object using the logManager
|
||||
"""
|
@ -98,26 +98,26 @@ class HangedCleaner(Job):
|
||||
): # Removing too long, remark it as removable
|
||||
log.doLog(
|
||||
us,
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
'User Service hanged on removal process. Restarting removal.',
|
||||
log.INTERNAL,
|
||||
log.LogSource.INTERNAL,
|
||||
)
|
||||
log.doLog(
|
||||
servicePool,
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
f'User service {us.friendly_name} hanged on removal. Restarting removal.',
|
||||
)
|
||||
us.release() # Mark it again as removable, and let's see
|
||||
else:
|
||||
log.doLog(
|
||||
us,
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
'User Service seems to be hanged. Removing it.',
|
||||
log.INTERNAL,
|
||||
log.LogSource.INTERNAL,
|
||||
)
|
||||
log.doLog(
|
||||
servicePool,
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
f'Removing user service {us.friendly_name} because it seems to be hanged'
|
||||
)
|
||||
us.releaseOrCancel()
|
||||
|
@ -66,7 +66,7 @@ class ServiceCacheUpdater(Job):
|
||||
servicePool,
|
||||
log.WARN,
|
||||
'Service Pool is restrained due to excesive errors',
|
||||
log.INTERNAL,
|
||||
log.LogSource.INTERNAL,
|
||||
)
|
||||
logger.info('%s is restrained, will check this later', servicePool.name)
|
||||
|
||||
@ -259,9 +259,9 @@ class ServiceCacheUpdater(Job):
|
||||
except MaxServicesReachedError:
|
||||
log.doLog(
|
||||
servicePool,
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
'Max number of services reached for this service',
|
||||
log.INTERNAL,
|
||||
log.LogSource.INTERNAL,
|
||||
)
|
||||
logger.warning(
|
||||
'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)
|
||||
log.doLog(
|
||||
servicePool,
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
f'User service {stuck.name} has been hard removed because it\'s stuck',
|
||||
)
|
||||
# stuck.setState(State.ERROR)
|
||||
|
@ -93,8 +93,8 @@ def guacamole(
|
||||
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"
|
||||
msg = f'User {user.name} started HTML5 {protocol} tunnel to {host}.'
|
||||
log.doLog(user.manager, log.INFO, msg)
|
||||
log.doLog(userService, log.INFO, msg)
|
||||
log.doLog(user.manager, log.LogLevel.INFO, msg)
|
||||
log.doLog(userService, log.LogLevel.INFO, msg)
|
||||
|
||||
events.addEvent(
|
||||
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(
|
||||
f'Executed action {CALENDAR_ACTION_DICT.get(self.action, {}).get("description", self.action)} [{self.prettyParams}]',
|
||||
level=log.INFO,
|
||||
level=log.LogLevel.INFO,
|
||||
)
|
||||
except Exception:
|
||||
self.service_pool.log(
|
||||
|
@ -58,6 +58,7 @@ class Log(models.Model):
|
||||
created = models.DateTimeField(db_index=True)
|
||||
source = models.CharField(max_length=16, default='internal', 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='')
|
||||
|
||||
# "fake" declarations for type checking
|
||||
@ -74,9 +75,9 @@ class Log(models.Model):
|
||||
@property
|
||||
def level_str(self) -> str:
|
||||
# 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:
|
||||
return (
|
||||
|
@ -699,8 +699,8 @@ class ServicePool(UUIDModel, TaggingMixin): # type: ignore
|
||||
return bool(self.service) and self.service.testServer(host, port, timeout)
|
||||
|
||||
# Utility for logging
|
||||
def log(self, message: str, level: int = log.INFO) -> None:
|
||||
log.doLog(self, level, message, log.INTERNAL)
|
||||
def log(self, message: str, level: int = log.LogLevel.INFO) -> None:
|
||||
log.doLog(self, level, message, log.LogSource.INTERNAL)
|
||||
|
||||
@staticmethod
|
||||
def beforeDelete(sender, **kwargs) -> None: # pylint: disable=unused-argument
|
||||
|
@ -637,8 +637,8 @@ class UserService(UUIDModel):
|
||||
) or self.publication == self.deployed_service.activePublication()
|
||||
|
||||
# Utility for logging
|
||||
def log(self, message: str, level: int = log.INFO) -> None:
|
||||
log.doLog(self, level, message, log.INTERNAL)
|
||||
def log(self, message: str, level: int = log.LogLevel.INFO) -> None:
|
||||
log.doLog(self, level, message, log.LogSource.INTERNAL)
|
||||
|
||||
def testServer(self, host, port, timeout=4) -> bool:
|
||||
return self.deployed_service.testServer(host, port, timeout)
|
||||
|
@ -134,7 +134,7 @@ class LinuxOsManager(osmanagers.OSManager):
|
||||
"""
|
||||
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
|
||||
try:
|
||||
msg, level = data.split('\t')
|
||||
@ -142,10 +142,10 @@ class LinuxOsManager(osmanagers.OSManager):
|
||||
level = int(level)
|
||||
except Exception:
|
||||
logger.debug('Do not understand level %s', level)
|
||||
level = log.INFO
|
||||
level = log.LogLevel.INFO
|
||||
log.doLog(service, level, msg, origin)
|
||||
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(
|
||||
self, userService: 'UserService'
|
||||
@ -160,9 +160,9 @@ class LinuxOsManager(osmanagers.OSManager):
|
||||
if self.isRemovableOnLogout(userService):
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
'Unused user service for too long. Removing due to OS Manager parameters.',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
userService.remove()
|
||||
|
||||
|
@ -101,9 +101,9 @@ class LinuxRandomPassManager(LinuxOsManager):
|
||||
service.storeValue('linOsRandomPass', randomPass)
|
||||
log.doLog(
|
||||
service,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
"Password set to \"{}\"".format(randomPass),
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
|
||||
return randomPass
|
||||
|
@ -108,7 +108,7 @@ class TestOSManager(osmanagers.OSManager):
|
||||
"""
|
||||
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
|
||||
try:
|
||||
msg, level = data.split('\t')
|
||||
@ -116,10 +116,10 @@ class TestOSManager(osmanagers.OSManager):
|
||||
level = int(level)
|
||||
except Exception:
|
||||
logger.debug('Do not understand level %s', level)
|
||||
level = log.INFO
|
||||
level = log.LogLevel.INFO
|
||||
log.doLog(service, level, msg, origin)
|
||||
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(
|
||||
self, userService: 'UserService'
|
||||
@ -134,9 +134,9 @@ class TestOSManager(osmanagers.OSManager):
|
||||
if self.isRemovableOnLogout(userService):
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
'Unused user service for too long. Removing due to OS Manager parameters.',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
userService.remove()
|
||||
|
||||
|
@ -140,7 +140,7 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
def getName(self, userService: 'UserService') -> str:
|
||||
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
|
||||
try:
|
||||
msg, levelStr = data.split('\t')
|
||||
@ -148,13 +148,13 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
level = int(levelStr)
|
||||
except Exception:
|
||||
logger.debug('Do not understand level %s', levelStr)
|
||||
level = log.INFO
|
||||
level = log.LogLevel.INFO
|
||||
|
||||
log.doLog(userService, level, msg, origin)
|
||||
except Exception:
|
||||
logger.exception('WindowsOs Manager message log: ')
|
||||
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(
|
||||
@ -191,9 +191,9 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
if self.isRemovableOnLogout(userService):
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
'Unused user service for too long. Removing due to OS Manager parameters.',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
userService.remove()
|
||||
|
||||
|
@ -311,7 +311,7 @@ class WinDomainOsManager(WindowsOsManager):
|
||||
userService,
|
||||
log.WARN,
|
||||
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)
|
||||
# Already added this machine to this group, pass
|
||||
@ -325,7 +325,7 @@ class WinDomainOsManager(WindowsOsManager):
|
||||
# logger.exception('Ldap Exception caught')
|
||||
|
||||
if error:
|
||||
log.doLog(userService, log.WARN, error, log.OSMANAGER)
|
||||
log.doLog(userService, log.WARN, error, log.LogSource.OSMANAGER)
|
||||
logger.error(error)
|
||||
|
||||
def release(self, userService: 'UserService') -> None:
|
||||
@ -339,9 +339,9 @@ class WinDomainOsManager(WindowsOsManager):
|
||||
# logger.info('Releasing from a not FQDN domain is not supported')
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
"Removing a domain machine form a non FQDN domain is not supported.",
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
return
|
||||
|
||||
@ -353,7 +353,7 @@ class WinDomainOsManager(WindowsOsManager):
|
||||
userService,
|
||||
log.WARN,
|
||||
f'Could not remove machine from domain (_ldap._tcp.{self._domain} not found)',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
return
|
||||
except ldaputil.LDAPError as e:
|
||||
@ -362,7 +362,7 @@ class WinDomainOsManager(WindowsOsManager):
|
||||
userService,
|
||||
log.WARN,
|
||||
f'Could not remove machine from domain ({e})',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
return
|
||||
except Exception as e:
|
||||
@ -371,7 +371,7 @@ class WinDomainOsManager(WindowsOsManager):
|
||||
userService,
|
||||
log.WARN,
|
||||
f'Could not remove machine from domain ({e})',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
return
|
||||
|
||||
|
@ -128,9 +128,9 @@ class WinRandomPassManager(WindowsOsManager):
|
||||
userService.storeValue('winOsRandomPass', randomPass)
|
||||
log.doLog(
|
||||
userService,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
f'Password set to "{randomPass}"',
|
||||
log.OSMANAGER,
|
||||
log.LogSource.OSMANAGER,
|
||||
)
|
||||
return randomPass
|
||||
|
||||
|
@ -218,7 +218,7 @@ class OVirtLinkedDeployment(services.UserDeployment):
|
||||
|
||||
self.cache.put('ready', '1')
|
||||
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
|
||||
|
||||
return State.FINISHED
|
||||
@ -335,7 +335,7 @@ if sys.platform == 'win32':
|
||||
"""
|
||||
reason = str(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
|
||||
OVirtDeferredRemoval.remove(self.service().parent(), self._vmid)
|
||||
|
@ -228,7 +228,7 @@ class OGDeployment(UserDeployment):
|
||||
State.ERROR, so we can do "return self.__error(reason)"
|
||||
"""
|
||||
logger.debug('Setting error state, reason: %s', reason)
|
||||
self.doLog(log.ERROR, reason)
|
||||
self.doLog(log.LogLevel.ERROR, reason)
|
||||
|
||||
if self._machineId:
|
||||
try:
|
||||
@ -311,7 +311,7 @@ class OGDeployment(UserDeployment):
|
||||
self._stamp = getSqlDatetimeAsUnix()
|
||||
|
||||
self.doLog(
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
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')
|
||||
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
|
||||
|
||||
return State.FINISHED
|
||||
@ -242,7 +242,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
|
||||
"""
|
||||
reason = str(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
|
||||
try:
|
||||
|
@ -157,7 +157,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
|
||||
|
||||
self.cache.put('ready', '1')
|
||||
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
|
||||
|
||||
return State.FINISHED
|
||||
@ -247,7 +247,7 @@ class LiveDeployment(UserDeployment): # pylint: disable=too-many-public-methods
|
||||
self._queue = [opError]
|
||||
self._reason = str(reason)
|
||||
|
||||
self.doLog(log.ERROR, self._reason)
|
||||
self.doLog(log.LogLevel.ERROR, self._reason)
|
||||
|
||||
if self._vmid: # Powers off & delete it
|
||||
try:
|
||||
|
@ -297,7 +297,7 @@ if sys.platform == 'win32':
|
||||
"""
|
||||
reason = str(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
|
||||
ProxmoxDeferredRemoval.remove(self.service().parent(), int(self._vmid))
|
||||
@ -532,7 +532,7 @@ if sys.platform == 'win32':
|
||||
if getSqlDatetimeAsUnix() - shutdown_start > GUEST_SHUTDOWN_WAIT:
|
||||
logger.debug('Time is consumed, falling back to stop')
|
||||
self.doLog(
|
||||
log.ERROR,
|
||||
log.LogLevel.ERROR,
|
||||
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
|
||||
|
@ -154,7 +154,7 @@ class XenLinkedDeployment(UserDeployment):
|
||||
self.cache.put('ready', '1', 30)
|
||||
except Exception as e:
|
||||
# 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 State.FINISHED
|
||||
@ -224,7 +224,7 @@ class XenLinkedDeployment(UserDeployment):
|
||||
|
||||
def __error(self, reason: typing.Any) -> str:
|
||||
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
|
||||
try:
|
||||
|
@ -210,11 +210,11 @@ def action(
|
||||
rebuild = True
|
||||
log.doLog(
|
||||
userService.deployed_service,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
"Removing User Service {} as requested by {} from {}".format(
|
||||
userService.friendly_name, request.user.pretty_name, request.ip
|
||||
),
|
||||
log.WEB,
|
||||
log.LogSource.WEB,
|
||||
)
|
||||
UserServiceManager().requestLogoff(userService)
|
||||
userService.release()
|
||||
@ -226,11 +226,11 @@ def action(
|
||||
rebuild = True
|
||||
log.doLog(
|
||||
userService.deployed_service,
|
||||
log.INFO,
|
||||
log.LogLevel.INFO,
|
||||
"Reseting User Service {} as requested by {} from {}".format(
|
||||
userService.friendly_name, request.user.pretty_name, request.ip
|
||||
),
|
||||
log.WEB,
|
||||
log.LogSource.WEB,
|
||||
)
|
||||
# UserServiceManager().requestLogoff(userService)
|
||||
UserServiceManager().reset(userService)
|
||||
|
Loading…
Reference in New Issue
Block a user