diff --git a/packages/service-library/src/servicelib/aiohttp/rest_middlewares.py b/packages/service-library/src/servicelib/aiohttp/rest_middlewares.py index fe05ae9a55d4..fdb5df09d93c 100644 --- a/packages/service-library/src/servicelib/aiohttp/rest_middlewares.py +++ b/packages/service-library/src/servicelib/aiohttp/rest_middlewares.py @@ -17,7 +17,7 @@ from models_library.basic_types import IDStr from models_library.rest_error import ErrorGet, ErrorItemType, LogMessageType -from ..logging_errors import create_troubleshootting_log_kwargs +from ..logging_errors import create_troubleshooting_log_kwargs from ..mimetype_constants import MIMETYPE_APPLICATION_JSON from ..rest_constants import RESPONSE_MODEL_POLICY from ..rest_responses import is_enveloped_from_text @@ -72,7 +72,7 @@ def _log_5xx_server_error( error_code, error_context = _create_error_context(request, exception) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exception, error_context=error_context, diff --git a/packages/service-library/src/servicelib/exception_utils.py b/packages/service-library/src/servicelib/exception_utils.py index 6481a9746e9b..7893763d13ba 100644 --- a/packages/service-library/src/servicelib/exception_utils.py +++ b/packages/service-library/src/servicelib/exception_utils.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, Field, NonNegativeFloat, PrivateAttr -from .logging_errors import create_troubleshootting_log_kwargs +from .logging_errors import create_troubleshooting_log_kwargs _logger = logging.getLogger(__name__) @@ -93,7 +93,7 @@ def _should_suppress_exception( # the predicate function raised an exception # log it and do not suppress the original exception _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Predicate function raised exception {type(predicate_exc).__name__}:{predicate_exc} in {func_name}. " f"Original exception will be re-raised: {type(exc).__name__}", error=predicate_exc, diff --git a/packages/service-library/src/servicelib/fastapi/http_error.py b/packages/service-library/src/servicelib/fastapi/http_error.py index b8fd0e511908..9fbf2910811d 100644 --- a/packages/service-library/src/servicelib/fastapi/http_error.py +++ b/packages/service-library/src/servicelib/fastapi/http_error.py @@ -11,7 +11,7 @@ from fastapi.responses import JSONResponse from pydantic import ValidationError -from ..logging_errors import create_troubleshootting_log_kwargs +from ..logging_errors import create_troubleshooting_log_kwargs from ..status_codes_utils import is_5xx_server_error validation_error_response_definition["properties"] = { @@ -57,7 +57,7 @@ async def _http_error_handler(request: Request, exc: Exception) -> JSONResponse: if is_5xx_server_error(status_code): _logger.exception( - create_troubleshootting_log_kwargs( + create_troubleshooting_log_kwargs( f"A 5XX server error happened in current service. Responding with {error_content} and {status_code} status code", error=exc, error_context={ diff --git a/packages/service-library/src/servicelib/fastapi/long_running_tasks/_context_manager.py b/packages/service-library/src/servicelib/fastapi/long_running_tasks/_context_manager.py index 75df739e5142..2af4ca5aa582 100644 --- a/packages/service-library/src/servicelib/fastapi/long_running_tasks/_context_manager.py +++ b/packages/service-library/src/servicelib/fastapi/long_running_tasks/_context_manager.py @@ -7,7 +7,7 @@ from pydantic import PositiveFloat -from ...logging_errors import create_troubleshootting_log_message +from ...logging_errors import create_troubleshooting_log_message from ...long_running_tasks.errors import TaskClientTimeoutError, TaskExceptionError from ...long_running_tasks.models import ( ProgressCallback, @@ -137,7 +137,7 @@ async def _wait_for_task_result() -> Any: ) from e except Exception as e: _logger.warning( - create_troubleshootting_log_message( + create_troubleshooting_log_message( user_error_msg=f"{task_id=} raised an exception", error=e, tip=f"Check the logs of the service responding to '{client.base_url}'", diff --git a/packages/service-library/src/servicelib/logging_base.py b/packages/service-library/src/servicelib/logging_base.py new file mode 100644 index 000000000000..5f74661ad5b7 --- /dev/null +++ b/packages/service-library/src/servicelib/logging_base.py @@ -0,0 +1,22 @@ +from typing import NotRequired, TypedDict + + +class LogExtra(TypedDict): + log_uid: NotRequired[str] + log_oec: NotRequired[str] + + +def get_log_record_extra( + *, + user_id: int | str | None = None, + error_code: str | None = None, +) -> LogExtra | None: + extra: LogExtra = {} + + if user_id: + assert int(user_id) > 0 # nosec + extra["log_uid"] = f"{user_id}" + if error_code: + extra["log_oec"] = error_code + + return extra or None diff --git a/packages/service-library/src/servicelib/logging_errors.py b/packages/service-library/src/servicelib/logging_errors.py index 938a4c3f62dd..0a251966a430 100644 --- a/packages/service-library/src/servicelib/logging_errors.py +++ b/packages/service-library/src/servicelib/logging_errors.py @@ -5,12 +5,12 @@ from common_library.errors_classes import OsparcErrorMixin from common_library.json_serialization import json_dumps, representation_encoder -from .logging_utils import LogExtra, get_log_record_extra +from .logging_base import LogExtra, get_log_record_extra _logger = logging.getLogger(__name__) -def create_troubleshootting_log_message( +def create_troubleshooting_log_message( user_error_msg: str, *, error: BaseException, @@ -31,9 +31,14 @@ def create_troubleshootting_log_message( def _collect_causes(exc: BaseException) -> str: causes = [] current = exc.__cause__ - while current is not None: + seen = set() # Prevent infinite loops + while current is not None and id(current) not in seen: + seen.add(id(current)) causes.append(f"[{type(current).__name__}]'{current}'") current = getattr(current, "__cause__", None) + if len(causes) > 10: # Prevent excessive chains + causes.append("[... truncated]") + break return " <- ".join(causes) debug_data = json_dumps( @@ -57,7 +62,7 @@ class LogKwargs(TypedDict): extra: LogExtra | None -def create_troubleshootting_log_kwargs( +def create_troubleshooting_log_kwargs( user_error_msg: str, *, error: BaseException, @@ -74,7 +79,7 @@ def create_troubleshootting_log_kwargs( ... except MyException as exc _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg=frontend_msg, error=exc, error_context={ @@ -92,7 +97,7 @@ def create_troubleshootting_log_kwargs( context.update(error.error_context()) # compose as log message - log_msg = create_troubleshootting_log_message( + log_msg = create_troubleshooting_log_message( user_error_msg, error=error, error_code=error_code, diff --git a/packages/service-library/src/servicelib/logging_utils.py b/packages/service-library/src/servicelib/logging_utils.py index 5cead04bffaa..613cf236a2ba 100644 --- a/packages/service-library/src/servicelib/logging_utils.py +++ b/packages/service-library/src/servicelib/logging_utils.py @@ -17,11 +17,13 @@ from datetime import datetime from inspect import getframeinfo, stack from pathlib import Path -from typing import Any, Final, NotRequired, TypeAlias, TypedDict, TypeVar +from typing import Any, Final, TypeAlias, TypedDict, TypeVar from common_library.json_serialization import json_dumps from settings_library.tracing import TracingSettings +from .logging_base import LogExtra +from .logging_errors import create_troubleshooting_log_kwargs from .logging_utils_filtering import GeneralLogFilter, LoggerName, MessageSubstring from .tracing import setup_log_tracing from .utils_secrets import mask_sensitive_data @@ -60,27 +62,6 @@ } -class LogExtra(TypedDict): - log_uid: NotRequired[str] - log_oec: NotRequired[str] - - -def get_log_record_extra( - *, - user_id: int | str | None = None, - error_code: str | None = None, -) -> LogExtra | None: - extra: LogExtra = {} - - if user_id: - assert int(user_id) > 0 # nosec - extra["log_uid"] = f"{user_id}" - if error_code: - extra["log_oec"] = error_code - - return extra or None - - class CustomFormatter(logging.Formatter): """Custom Formatter does these 2 things: 1. Overrides 'funcName' with the value of 'func_name_override', if it exists. @@ -97,7 +78,8 @@ def format(self, record) -> str: if hasattr(record, "file_name_override"): record.filename = record.file_name_override - optional_keys = LogExtra.__optional_keys__ | frozenset( # pylint: disable=no-member + # pylint: disable=no-member + optional_keys = LogExtra.__optional_keys__ | frozenset( ["otelTraceID", "otelSpanID"] ) for name in optional_keys: @@ -572,7 +554,12 @@ def log_catch(logger: logging.Logger, *, reraise: bool = True) -> Iterator[None] logger.debug("call was cancelled") raise except Exception as exc: # pylint: disable=broad-except - logger.exception("Unhandled exception:") + logger.exception( + **create_troubleshooting_log_kwargs( + "Caught unhandled exception", + error=exc, + ) + ) if reraise: raise exc from exc diff --git a/packages/service-library/src/servicelib/long_running_tasks/task.py b/packages/service-library/src/servicelib/long_running_tasks/task.py index e3f9346106cc..d549f38f911e 100644 --- a/packages/service-library/src/servicelib/long_running_tasks/task.py +++ b/packages/service-library/src/servicelib/long_running_tasks/task.py @@ -20,7 +20,7 @@ ) from ..background_task import create_periodic_task -from ..logging_errors import create_troubleshootting_log_kwargs +from ..logging_errors import create_troubleshooting_log_kwargs from ..logging_utils import log_catch, log_context from ..redis import RedisClientSDK, exclusive from ..utils import limited_gather @@ -353,7 +353,7 @@ async def _tasks_monitor(self) -> None: # noqa: C901 ) if type(e) not in allowed_errors: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( ( f"Execution of {task_id=} finished with unexpected error, " f"only the following {allowed_errors=} are permitted" @@ -372,7 +372,7 @@ async def _tasks_monitor(self) -> None: # noqa: C901 Exception # pylint:disable=broad-except ) as serialization_error: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( ( f"Execution of {task_id=} finished with an error " f"which could not be serialized" diff --git a/packages/service-library/src/servicelib/rabbitmq/_rpc_router.py b/packages/service-library/src/servicelib/rabbitmq/_rpc_router.py index a81f84ad4efc..6de24904577e 100644 --- a/packages/service-library/src/servicelib/rabbitmq/_rpc_router.py +++ b/packages/service-library/src/servicelib/rabbitmq/_rpc_router.py @@ -8,7 +8,7 @@ from common_library.error_codes import create_error_code from models_library.rabbitmq_basic_types import RPCMethodName -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ..logging_utils import log_context from ._errors import RPCServerError @@ -74,7 +74,7 @@ async def _wrapper(*args, **kwargs): error_code = create_error_code(exc) _logger.exception( # NOTE: equivalent to a 500 http status code error - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Unhandled exception on the rpc-server side for '{func.__name__}'", error=exc, error_code=error_code, diff --git a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/director_v2/errors.py b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/director_v2/errors.py index 31e8dfb90bb4..7d58603d1522 100644 --- a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/director_v2/errors.py +++ b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/director_v2/errors.py @@ -1,9 +1,9 @@ from ..._errors import RPCInterfaceError -class BaseRpcError(RPCInterfaceError): +class BaseRpcError(RPCInterfaceError): # pylint: disable=too-many-ancestors pass -class ComputationalTaskMissingError(BaseRpcError): +class ComputationalTaskMissingError(BaseRpcError): # pylint: disable=too-many-ancestors msg_template = "Computational run not found for project {project_id}" diff --git a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/errors.py b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/errors.py index e0c3fc2419a2..a5f494191aec 100644 --- a/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/errors.py +++ b/packages/service-library/src/servicelib/rabbitmq/rpc_interfaces/webserver/errors.py @@ -1,7 +1,11 @@ from ..._errors import RPCInterfaceError -class ProjectNotFoundRpcError(RPCInterfaceError): ... +class ProjectNotFoundRpcError( # pylint: disable=too-many-ancestors + RPCInterfaceError +): ... -class ProjectForbiddenRpcError(RPCInterfaceError): ... +class ProjectForbiddenRpcError( # pylint: disable=too-many-ancestors + RPCInterfaceError +): ... diff --git a/packages/service-library/src/servicelib/redis/_decorators.py b/packages/service-library/src/servicelib/redis/_decorators.py index 92e1208164d2..e1e724e05013 100644 --- a/packages/service-library/src/servicelib/redis/_decorators.py +++ b/packages/service-library/src/servicelib/redis/_decorators.py @@ -12,7 +12,7 @@ from redis.asyncio.lock import Lock from ..background_task import periodic -from ..logging_errors import create_troubleshootting_log_kwargs +from ..logging_errors import create_troubleshooting_log_kwargs from ._client import RedisClientSDK from ._constants import DEFAULT_LOCK_TTL from ._errors import CouldNotAcquireLockError, LockLostError @@ -143,7 +143,7 @@ async def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R: await lock.release() except redis.exceptions.LockNotOwnedError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Unexpected error while releasing lock '{redis_lock_key}'", error=exc, error_context={ diff --git a/packages/service-library/src/servicelib/redis/_semaphore_decorator.py b/packages/service-library/src/servicelib/redis/_semaphore_decorator.py index 8ae687dd4416..c2650251fe16 100644 --- a/packages/service-library/src/servicelib/redis/_semaphore_decorator.py +++ b/packages/service-library/src/servicelib/redis/_semaphore_decorator.py @@ -10,7 +10,7 @@ from common_library.async_tools import cancel_wait_task from ..background_task import periodic -from ..logging_errors import create_troubleshootting_log_kwargs +from ..logging_errors import create_troubleshooting_log_kwargs from ._client import RedisClientSDK from ._constants import ( DEFAULT_SEMAPHORE_TTL, @@ -87,7 +87,7 @@ async def _periodic_renewer() -> None: await semaphore.release() except SemaphoreNotAcquiredError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Unexpected error while releasing semaphore '{semaphore_key}'", error=exc, error_context={ diff --git a/packages/service-library/tests/test_background_task.py b/packages/service-library/tests/test_background_task.py index 715aaec92b6b..9a33ed6a62c1 100644 --- a/packages/service-library/tests/test_background_task.py +++ b/packages/service-library/tests/test_background_task.py @@ -26,8 +26,8 @@ ] -_FAST_POLL_INTERVAL: Final[int] = 1 -_VERY_SLOW_POLL_INTERVAL: Final[int] = 100 +_FAST_POLL_INTERVAL: Final[float] = 0.01 +_VERY_SLOW_POLL_INTERVAL: Final[float] = 1 @pytest.fixture @@ -207,12 +207,16 @@ async def _func() -> None: assert mock_func.call_count > 1 +class CustomError(Exception): + pass + + async def test_periodic_task_logs_error( mock_background_task: mock.AsyncMock, task_interval: datetime.timedelta, caplog: pytest.LogCaptureFixture, ): - mock_background_task.side_effect = RuntimeError("Test error") + mock_background_task.side_effect = CustomError("Test error") with caplog.at_level(logging.ERROR): async with periodic_task( diff --git a/packages/service-library/tests/test_logging_errors.py b/packages/service-library/tests/test_logging_errors.py index ca9b669f0edc..8bc1ef70aed8 100644 --- a/packages/service-library/tests/test_logging_errors.py +++ b/packages/service-library/tests/test_logging_errors.py @@ -6,8 +6,8 @@ from common_library.error_codes import create_error_code, parse_error_code_parts from common_library.errors_classes import OsparcErrorMixin from servicelib.logging_errors import ( - create_troubleshootting_log_kwargs, - create_troubleshootting_log_message, + create_troubleshooting_log_kwargs, + create_troubleshooting_log_message, ) @@ -29,7 +29,7 @@ class MyError(OsparcErrorMixin, RuntimeError): msg = f"Nice message to user [{error_code}]" - log_msg = create_troubleshootting_log_message( + log_msg = create_troubleshooting_log_message( msg, error=exc, error_code=error_code, @@ -37,7 +37,7 @@ class MyError(OsparcErrorMixin, RuntimeError): tip="This is a test error", ) - log_kwargs = create_troubleshootting_log_kwargs( + log_kwargs = create_troubleshooting_log_kwargs( msg, error=exc, error_code=error_code, diff --git a/packages/service-library/tests/test_logging_utils.py b/packages/service-library/tests/test_logging_utils.py index 60085b687358..39bb854b7dea 100644 --- a/packages/service-library/tests/test_logging_utils.py +++ b/packages/service-library/tests/test_logging_utils.py @@ -11,6 +11,7 @@ import pytest from faker import Faker +from servicelib.logging_base import get_log_record_extra from servicelib.logging_utils import ( _DEFAULT_FORMATTING, CustomFormatter, @@ -618,7 +619,6 @@ def _create_test_log_record( span_id: str | None = None, ) -> logging.LogRecord: """Create a test LogRecord with optional extra fields.""" - from servicelib.logging_utils import get_log_record_extra record = logging.LogRecord( name=name, diff --git a/packages/simcore-sdk/src/simcore_sdk/node_ports_common/_filemanager_utils.py b/packages/simcore-sdk/src/simcore_sdk/node_ports_common/_filemanager_utils.py index 484380fded76..043b763764ad 100644 --- a/packages/simcore-sdk/src/simcore_sdk/node_ports_common/_filemanager_utils.py +++ b/packages/simcore-sdk/src/simcore_sdk/node_ports_common/_filemanager_utils.py @@ -82,7 +82,9 @@ async def complete_upload( state_url = _get_https_link_if_storage_secure( f"{file_upload_complete_response.data.links.state}" ) - _logger.info("completed upload of %s", f"{len(parts)} parts, received {state_url}") + _logger.info( + "required upload completion of %s", f"{len(parts)} parts, received {state_url}" + ) async for attempt in AsyncRetrying( reraise=True, @@ -101,14 +103,14 @@ async def complete_upload( ).validate_python(await resp.json()) assert future_enveloped.data # nosec if future_enveloped.data.state == FileUploadCompleteState.NOK: - msg = "upload not ready yet" + msg = "upload not ready yet (FileUploadCompleteState.NOK)" raise ValueError(msg) if is_directory: assert future_enveloped.data.e_tag is None # nosec return None assert future_enveloped.data.e_tag # nosec - _logger.debug( + _logger.info( "multipart upload completed in %s, received %s", attempt.retry_state.retry_object.statistics, f"{future_enveloped.data.e_tag=}", diff --git a/services/api-server/src/simcore_service_api_server/api/routes/tasks.py b/services/api-server/src/simcore_service_api_server/api/routes/tasks.py index 7b4951fab28b..f29b30a585ef 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/tasks.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/tasks.py @@ -16,7 +16,7 @@ from models_library.users import UserID from servicelib.celery.models import TaskState, TaskUUID from servicelib.fastapi.dependencies import get_app -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from simcore_service_api_server.models.domain.celery_models import ApiWorkerTaskFilter from ...models.schemas.base import ApiServerEnvelope @@ -203,7 +203,7 @@ async def get_task_result( user_error_msg = f"The execution of task {task_id} failed" support_id = create_error_code(task_result) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=task_result, error_code=support_id, diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py index 9d852b472ad0..dccfe3ff114a 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_backend_errors.py @@ -1,7 +1,7 @@ import logging from common_library.error_codes import create_error_code -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.status_codes_utils import is_5xx_server_error from starlette.requests import Request from starlette.responses import JSONResponse @@ -20,7 +20,7 @@ async def backend_error_handler(request: Request, exc: Exception) -> JSONRespons if is_5xx_server_error(exc.status_code): support_id = create_error_code(exc) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exc, error_code=support_id, diff --git a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_factory.py b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_factory.py index 0e081557145a..dc5e7b618e29 100644 --- a/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_factory.py +++ b/services/api-server/src/simcore_service_api_server/exceptions/handlers/_handlers_factory.py @@ -3,7 +3,7 @@ from common_library.error_codes import create_error_code from fastapi.requests import Request from fastapi.responses import JSONResponse -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ._utils import ExceptionHandler, create_error_json_response @@ -40,7 +40,7 @@ async def _http_error_handler( user_error_msg += f" [{error_code}]" _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exception, error_code=error_code, diff --git a/services/api-server/src/simcore_service_api_server/services_http/log_streaming.py b/services/api-server/src/simcore_service_api_server/services_http/log_streaming.py index 5781659d1c74..b30eb5fc5125 100644 --- a/services/api-server/src/simcore_service_api_server/services_http/log_streaming.py +++ b/services/api-server/src/simcore_service_api_server/services_http/log_streaming.py @@ -8,7 +8,7 @@ from models_library.rabbitmq_messages import LoggerRabbitMessage from models_library.users import UserID from pydantic import NonNegativeInt -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_catch from servicelib.rabbitmq import QueueName, RabbitMQClient @@ -139,7 +139,7 @@ async def log_generator(self) -> AsyncIterable[str]: error_msg = MSG_INTERNAL_ERROR_USER_FRIENDLY_TEMPLATE + f" [{error_code}]" _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( error_msg, error=exc, error_code=error_code, diff --git a/services/catalog/src/simcore_service_catalog/service/catalog_services.py b/services/catalog/src/simcore_service_catalog/service/catalog_services.py index 95ced884a26a..f4f0573440ee 100644 --- a/services/catalog/src/simcore_service_catalog/service/catalog_services.py +++ b/services/catalog/src/simcore_service_catalog/service/catalog_services.py @@ -23,7 +23,7 @@ from models_library.users import UserID from pydantic import HttpUrl from servicelib.logging_errors import ( - create_troubleshootting_log_kwargs, + create_troubleshooting_log_kwargs, ) from servicelib.rabbitmq.rpc_interfaces.catalog.errors import ( CatalogForbiddenError, @@ -239,7 +239,7 @@ async def _get_services_manifests( if missing_services: msg = f"Found {len(missing_services)} services that are in the database but missing in the registry manifest" _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( msg, error=CatalogInconsistentError( missing_services=missing_services, diff --git a/services/director-v2/src/simcore_service_director_v2/api/errors/http_error.py b/services/director-v2/src/simcore_service_director_v2/api/errors/http_error.py index fc671e073b05..8f630b7bfac1 100644 --- a/services/director-v2/src/simcore_service_director_v2/api/errors/http_error.py +++ b/services/director-v2/src/simcore_service_director_v2/api/errors/http_error.py @@ -3,7 +3,7 @@ from fastapi import HTTPException from fastapi.encoders import jsonable_encoder -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.status_codes_utils import is_5xx_server_error from starlette.requests import Request from starlette.responses import JSONResponse @@ -34,7 +34,7 @@ async def _http_error_handler(request: Request, exc: Exception) -> JSONResponse: if is_5xx_server_error(status_code): _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"HTTP error handler caught an {exception_cls.__name__} exception and responds with {status_code} status code", error=exc, error_context={"request": request, "status_code": status_code}, diff --git a/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_base.py b/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_base.py index 17a7b8a09afd..da882c263499 100644 --- a/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_base.py +++ b/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_base.py @@ -31,7 +31,7 @@ from networkx.classes.reportviews import InDegreeView from pydantic import PositiveInt from servicelib.common_headers import UNDEFINED_DEFAULT_SIMCORE_USER_AGENT_VALUE -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_catch, log_context from servicelib.rabbitmq import RabbitMQClient, RabbitMQRPCClient from servicelib.redis import RedisClientSDK @@ -701,7 +701,7 @@ async def apply( ) except PipelineNotFoundError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"pipeline {project_id} is missing from `comp_pipelines` DB table, something is corrupted. Aborting scheduling", error=exc, error_context={ @@ -719,7 +719,7 @@ async def apply( ) except InvalidPipelineError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"pipeline {project_id} appears to be misconfigured. Aborting scheduling", error=exc, error_context={ @@ -740,7 +740,7 @@ async def apply( ClustersKeeperNotAvailableError, ) as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpectedly lost connection to the computational backend. Tasks are set back to WAITING_FOR_CLUSTER state until we eventually reconnect", error=exc, error_context={ @@ -848,7 +848,7 @@ async def _schedule_tasks_to_start( ClustersKeeperNotAvailableError, ) as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Computational backend is not connected. Tasks are set back " "to WAITING_FOR_CLUSTER state until scheduler comes back!", error=exc, @@ -885,7 +885,7 @@ async def _schedule_tasks_to_start( except ComputationalBackendOnDemandNotReadyError as exc: _logger.info( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "The on demand computational backend is not ready yet. Tasks are set to WAITING_FOR_CLUSTER state until the cluster is ready!", error=exc, error_context={ @@ -917,7 +917,7 @@ async def _schedule_tasks_to_start( comp_tasks[f"{task}"].state = RunningState.WAITING_FOR_CLUSTER except TaskSchedulingError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "A task could not be scheduled, it is set to FAILED and the rest of the pipeline will be ABORTED", error=exc, error_context={ @@ -944,7 +944,7 @@ async def _schedule_tasks_to_start( comp_tasks[f"{exc.node_id}"].state = RunningState.FAILED except Exception as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpected error happened when scheduling tasks, all tasks to start are set to FAILED and the rest of the pipeline will be ABORTED", error=exc, error_context={ diff --git a/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_dask.py b/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_dask.py index ea6366ca21db..04bdb0e799cf 100644 --- a/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_dask.py +++ b/services/director-v2/src/simcore_service_director_v2/modules/comp_scheduler/_scheduler_dask.py @@ -22,7 +22,7 @@ from models_library.users import UserID from pydantic import PositiveInt from servicelib.common_headers import UNDEFINED_DEFAULT_SIMCORE_USER_AGENT_VALUE -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_catch, log_context from servicelib.redis._client import RedisClientSDK from servicelib.redis._semaphore_decorator import ( @@ -399,7 +399,7 @@ async def _handle_successful_run( return RunningState.SUCCESS, SimcorePlatformStatus.OK, [], True except PortsValidationError as err: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpected error while parsing output data, comp_tasks/comp_pipeline is not in sync with what was started", error=err, error_context=log_error_context, @@ -417,7 +417,7 @@ async def _handle_computational_retrieval_error( ) -> tuple[RunningState, SimcorePlatformStatus, list[ErrorDict], bool]: assert task.job_id # nosec _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Retrieval of task {task.job_id} result timed-out", error=result, error_context=log_error_context, @@ -474,7 +474,7 @@ async def _handle_computational_backend_not_connected_error( ) -> tuple[RunningState, SimcorePlatformStatus, list[ErrorDict], bool]: assert task.job_id # nosec _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Computational backend disconnected when retrieving task {task.job_id} result", error=result, error_context=log_error_context, @@ -497,7 +497,7 @@ async def _handle_task_error( # the task itself failed, check why if isinstance(result, TaskCancelledError): _logger.info( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Task {task.job_id} was cancelled", error=result, error_context=log_error_context, @@ -506,7 +506,7 @@ async def _handle_task_error( return RunningState.ABORTED, SimcorePlatformStatus.OK, [], True _logger.info( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Task {task.job_id} completed with errors", error=result, error_context=log_error_context, diff --git a/services/director-v2/src/simcore_service_director_v2/modules/dask_client.py b/services/director-v2/src/simcore_service_director_v2/modules/dask_client.py index add720d6372c..571d4acdaa08 100644 --- a/services/director-v2/src/simcore_service_director_v2/modules/dask_client.py +++ b/services/director-v2/src/simcore_service_director_v2/modules/dask_client.py @@ -56,7 +56,7 @@ from models_library.users import UserID from pydantic import ValidationError from pydantic.networks import AnyUrl -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_context from servicelib.utils import limited_gather from settings_library.s3 import S3Settings @@ -468,7 +468,7 @@ async def _get_task_state(job_id: str) -> RunningState: if isinstance(exception, TaskCancelledError): _logger.info( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Task {job_id} was aborted by user", error=exception, error_context=log_error_context, @@ -477,7 +477,7 @@ async def _get_task_state(job_id: str) -> RunningState: return RunningState.ABORTED assert exception # nosec _logger.info( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Task {job_id} completed with an error", error=exception, error_context=log_error_context, @@ -486,7 +486,7 @@ async def _get_task_state(job_id: str) -> RunningState: return RunningState.FAILED except TimeoutError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Task {job_id} exception could not be retrieved due to timeout", error=exc, error_context=log_error_context, @@ -497,7 +497,7 @@ async def _get_task_state(job_id: str) -> RunningState: except KeyError as exc: # the task does not exist _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Task {job_id} not found. State is UNKNOWN.", error=exc, error_context=log_error_context, diff --git a/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_observer.py b/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_observer.py index fa02698fb973..3ac029d4e426 100644 --- a/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_observer.py +++ b/services/director-v2/src/simcore_service_director_v2/modules/dynamic_sidecar/scheduler/_core/_observer.py @@ -6,7 +6,7 @@ from common_library.error_codes import create_error_code from fastapi import FastAPI -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from .....core.dynamic_services_settings.scheduler import ( DynamicServicesSchedulerSettings, @@ -150,7 +150,7 @@ async def observing_single_service( error_code = create_error_code(exc) logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exc, error_context={ diff --git a/services/dynamic-scheduler/src/simcore_service_dynamic_scheduler/services/director_v2/_public_client.py b/services/dynamic-scheduler/src/simcore_service_dynamic_scheduler/services/director_v2/_public_client.py index d833d3169bf6..e45b0ae1725f 100644 --- a/services/dynamic-scheduler/src/simcore_service_dynamic_scheduler/services/director_v2/_public_client.py +++ b/services/dynamic-scheduler/src/simcore_service_dynamic_scheduler/services/director_v2/_public_client.py @@ -80,7 +80,7 @@ async def stop_dynamic_service( node_id: NodeID, simcore_user_agent: str, save_state: bool, - timeout: datetime.timedelta # noqa: ASYNC109 + timeout: datetime.timedelta, # noqa: ASYNC109 ) -> None: try: await self.thin_client.delete_dynamic_service( @@ -95,7 +95,8 @@ async def stop_dynamic_service( == status.HTTP_409_CONFLICT ): raise ServiceWaitingForManualInterventionError( - node_id=node_id + node_id=node_id, + unexpected_status_error=f"{e}", ) from None if ( e.response.status_code # type: ignore[attr-defined] # pylint:disable=no-member @@ -110,7 +111,7 @@ async def retrieve_inputs( *, node_id: NodeID, port_keys: list[ServicePortKey], - timeout: datetime.timedelta # noqa: ASYNC109 + timeout: datetime.timedelta, # noqa: ASYNC109 ) -> RetrieveDataOutEnveloped: response = await self.thin_client.dynamic_service_retrieve( node_id=node_id, port_keys=port_keys, timeout=timeout diff --git a/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/core/utils.py b/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/core/utils.py index 8dba8270e11d..1634f0b1b2c0 100644 --- a/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/core/utils.py +++ b/services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/core/utils.py @@ -8,7 +8,7 @@ import psutil from common_library.error_codes import create_error_code -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ..modules.mounted_fs import MountedVolumes @@ -110,7 +110,7 @@ async def async_command( error_code = create_error_code(err) user_error_msg = f"Unexpected error [{error_code}]" _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_context={"command": command, "proc.returncode": proc.returncode}, diff --git a/services/invitations/src/simcore_service_invitations/core/exceptions_handlers.py b/services/invitations/src/simcore_service_invitations/core/exceptions_handlers.py index c3c89f67d38e..c4209b542292 100644 --- a/services/invitations/src/simcore_service_invitations/core/exceptions_handlers.py +++ b/services/invitations/src/simcore_service_invitations/core/exceptions_handlers.py @@ -2,7 +2,7 @@ from fastapi import FastAPI, Request, status from fastapi.responses import JSONResponse -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ..services.invitations import InvalidInvitationCodeError @@ -16,7 +16,7 @@ def handle_invalid_invitation_code_error(request: Request, exception: Exception) user_msg = INVALID_INVITATION_URL_MSG _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_msg, error=exception, error_context={ diff --git a/services/payments/src/simcore_service_payments/api/rest/_acknowledgements.py b/services/payments/src/simcore_service_payments/api/rest/_acknowledgements.py index 9a46d2469b6c..73b28c165918 100644 --- a/services/payments/src/simcore_service_payments/api/rest/_acknowledgements.py +++ b/services/payments/src/simcore_service_payments/api/rest/_acknowledgements.py @@ -6,7 +6,7 @@ PaymentMethodNotFoundError, PaymentNotFoundError, ) -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_context from ..._constants import ACKED, PGDB @@ -80,7 +80,7 @@ async def acknowledge_payment( if ack.saved: if ack.saved.payment_method_id is None or not ack.saved.success: _logger.error( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Got ack that {payment_id=} was completed but failed to save the payment-method used for the payment as requested.", error=RuntimeError("Failed to save payment-method after payment"), error_context={ diff --git a/services/payments/src/simcore_service_payments/api/rpc/_payments.py b/services/payments/src/simcore_service_payments/api/rpc/_payments.py index fe6e4db28dcf..66420c509887 100644 --- a/services/payments/src/simcore_service_payments/api/rpc/_payments.py +++ b/services/payments/src/simcore_service_payments/api/rpc/_payments.py @@ -16,7 +16,8 @@ from models_library.users import UserID from models_library.wallets import WalletID from pydantic import EmailStr, HttpUrl -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.rabbitmq import RPCRouter from ...db.payments_transactions_repo import PaymentsTransactionsRepo @@ -80,7 +81,6 @@ async def cancel_payment( user_id: UserID, wallet_id: WalletID, ) -> None: - with log_context( _logger, logging.INFO, diff --git a/services/payments/src/simcore_service_payments/api/rpc/_payments_methods.py b/services/payments/src/simcore_service_payments/api/rpc/_payments_methods.py index 360dcf962c07..8d7f208c1c61 100644 --- a/services/payments/src/simcore_service_payments/api/rpc/_payments_methods.py +++ b/services/payments/src/simcore_service_payments/api/rpc/_payments_methods.py @@ -18,7 +18,8 @@ from models_library.users import UserID from models_library.wallets import WalletID from pydantic import EmailStr -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.rabbitmq import RPCRouter from ...db.payments_methods_repo import PaymentsMethodsRepo diff --git a/services/payments/src/simcore_service_payments/services/notifier_email.py b/services/payments/src/simcore_service_payments/services/notifier_email.py index 422ab9efb350..2d9b222e785e 100644 --- a/services/payments/src/simcore_service_payments/services/notifier_email.py +++ b/services/payments/src/simcore_service_payments/services/notifier_email.py @@ -15,7 +15,7 @@ from models_library.products import ProductName from models_library.users import UserID from pydantic import EmailStr -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from settings_library.email import EmailProtocol, SMTPSettings from tenacity import ( retry, @@ -239,7 +239,7 @@ async def _create_user_email( except Exception as exc: # pylint: disable=broad-exception-caught _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Cannot attach invoice to payment. Email sent w/o attached pdf invoice", error=exc, error_context={ diff --git a/services/resource-usage-tracker/src/simcore_service_resource_usage_tracker/exceptions/handlers/_http_error.py b/services/resource-usage-tracker/src/simcore_service_resource_usage_tracker/exceptions/handlers/_http_error.py index 05ba5d7a3dcb..f09fc5e69842 100644 --- a/services/resource-usage-tracker/src/simcore_service_resource_usage_tracker/exceptions/handlers/_http_error.py +++ b/services/resource-usage-tracker/src/simcore_service_resource_usage_tracker/exceptions/handlers/_http_error.py @@ -3,7 +3,7 @@ from fastapi import HTTPException, status from fastapi.encoders import jsonable_encoder -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.status_codes_utils import is_5xx_server_error from starlette.requests import Request from starlette.responses import JSONResponse @@ -18,7 +18,7 @@ async def http_error_handler(request: Request, exc: Exception) -> JSONResponse: if is_5xx_server_error(exc.status_code): _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpected error happened in the Resource Usage Tracker. Please contact support.", error=exc, error_context={ diff --git a/services/web/server/src/simcore_service_webserver/catalog/_controller_rest_exceptions.py b/services/web/server/src/simcore_service_webserver/catalog/_controller_rest_exceptions.py index 3f685f644a00..839042f2a01c 100644 --- a/services/web/server/src/simcore_service_webserver/catalog/_controller_rest_exceptions.py +++ b/services/web/server/src/simcore_service_webserver/catalog/_controller_rest_exceptions.py @@ -7,7 +7,7 @@ from common_library.user_messages import user_message from models_library.rest_error import ErrorGet from servicelib.aiohttp import status -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.rabbitmq._errors import RemoteMethodNotRegisteredError from servicelib.rabbitmq.rpc_interfaces.catalog.errors import ( CatalogForbiddenError, @@ -64,7 +64,7 @@ async def _handler_catalog_client_errors( # Log for further investigation oec = create_error_code(exception) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_msg, error=exception, error_code=oec, diff --git a/services/web/server/src/simcore_service_webserver/director_v2/_controller/_rest_exceptions.py b/services/web/server/src/simcore_service_webserver/director_v2/_controller/_rest_exceptions.py index e1d822f8bb15..6376f622fe9f 100644 --- a/services/web/server/src/simcore_service_webserver/director_v2/_controller/_rest_exceptions.py +++ b/services/web/server/src/simcore_service_webserver/director_v2/_controller/_rest_exceptions.py @@ -6,7 +6,7 @@ from models_library.rest_error import ErrorGet from servicelib import status_codes_utils from servicelib.aiohttp import status -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ...constants import MSG_TRY_AGAIN_OR_SUPPORT from ...exception_handling import ( @@ -54,7 +54,7 @@ async def _handler_director_service_error_as_503_or_4xx( # Log for further investigation oec = create_error_code(exception) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_msg, error=exception, error_code=oec, diff --git a/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py b/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py index 426ea55d3299..b7fe746ccfa2 100644 --- a/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py +++ b/services/web/server/src/simcore_service_webserver/director_v2/_director_v2_service.py @@ -16,7 +16,7 @@ from pydantic.types import PositiveInt from servicelib.aiohttp import status from servicelib.exception_utils import suppress_exceptions -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_decorator from simcore_postgres_database.utils_groups_extra_properties import ( GroupExtraProperties, @@ -80,7 +80,7 @@ async def create_or_update_pipeline( except DirectorV2ServiceError as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"Could not create pipeline from project {project_id}", error=exc, error_context={**body, "backend_url": backend_url}, diff --git a/services/web/server/src/simcore_service_webserver/email/_handlers.py b/services/web/server/src/simcore_service_webserver/email/_handlers.py index 968fae7c2a1f..9e96a388205a 100644 --- a/services/web/server/src/simcore_service_webserver/email/_handlers.py +++ b/services/web/server/src/simcore_service_webserver/email/_handlers.py @@ -5,7 +5,7 @@ from models_library.emails import LowerCaseEmailStr from pydantic import BaseModel, Field from servicelib.aiohttp.requests_validation import parse_request_body_as -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from .._meta import API_VTAG from ..login.decorators import login_required @@ -93,7 +93,7 @@ async def test_email(request: web.Request): except Exception as err: # pylint: disable=broad-except _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg="Email test failed", error=err, error_context={ diff --git a/services/web/server/src/simcore_service_webserver/exception_handling/_factory.py b/services/web/server/src/simcore_service_webserver/exception_handling/_factory.py index 3fbf86bc541f..7f8f42251cc1 100644 --- a/services/web/server/src/simcore_service_webserver/exception_handling/_factory.py +++ b/services/web/server/src/simcore_service_webserver/exception_handling/_factory.py @@ -7,7 +7,7 @@ from models_library.rest_error import ErrorGet from servicelib.aiohttp.rest_responses import safe_status_message from servicelib.aiohttp.web_exceptions_extension import get_all_aiohttp_http_exceptions -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.status_codes_utils import ( get_code_display_name, is_5xx_server_error, @@ -106,7 +106,7 @@ async def _exception_handler( } _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_msg, error=exception, error_code=oec, diff --git a/services/web/server/src/simcore_service_webserver/garbage_collector/_core_orphans.py b/services/web/server/src/simcore_service_webserver/garbage_collector/_core_orphans.py index d94ade770498..e1f176c89dfe 100644 --- a/services/web/server/src/simcore_service_webserver/garbage_collector/_core_orphans.py +++ b/services/web/server/src/simcore_service_webserver/garbage_collector/_core_orphans.py @@ -9,7 +9,7 @@ ) from models_library.projects_nodes_io import NodeID from servicelib.common_headers import UNDEFINED_DEFAULT_SIMCORE_USER_AGENT_VALUE -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_catch, log_context from servicelib.utils import limited_as_completed, limited_gather @@ -113,7 +113,7 @@ async def remove_orphaned_services( potentially_running_service_ids.append(project_nodes) except BaseException as e: # pylint:disable=broad-exception-caught _logger.warning( - create_troubleshootting_log_kwargs( + create_troubleshooting_log_kwargs( ( "Skipping orpahn services removal, call to " "`list_node_ids_in_project` raised" diff --git a/services/web/server/src/simcore_service_webserver/garbage_collector/_tasks_users.py b/services/web/server/src/simcore_service_webserver/garbage_collector/_tasks_users.py index f5043cbef16a..efda89ee747f 100644 --- a/services/web/server/src/simcore_service_webserver/garbage_collector/_tasks_users.py +++ b/services/web/server/src/simcore_service_webserver/garbage_collector/_tasks_users.py @@ -10,7 +10,8 @@ from aiohttp import web from models_library.users import UserID from servicelib.background_task_utils import exclusive_periodic -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from ..login import login_service from ..redis import get_redis_lock_manager_client_sdk @@ -44,7 +45,6 @@ async def notify_user_logout_all_sessions( async def _update_expired_users(app: web.Application): - if updated := await users_service.update_expired_users(app): # expired users might be cached in the auth. If so, any request # with this user-id will get thru producing unexpected side-effects @@ -68,7 +68,6 @@ async def _update_expired_users(app: web.Application): def create_background_task_for_trial_accounts(wait_s: float) -> CleanupContextFunc: - async def _cleanup_ctx_fun(app: web.Application) -> AsyncIterator[None]: interval = timedelta(seconds=wait_s) diff --git a/services/web/server/src/simcore_service_webserver/groups/_classifiers_service.py b/services/web/server/src/simcore_service_webserver/groups/_classifiers_service.py index eb2ba75aea7e..0e8d4ba3bbcc 100644 --- a/services/web/server/src/simcore_service_webserver/groups/_classifiers_service.py +++ b/services/web/server/src/simcore_service_webserver/groups/_classifiers_service.py @@ -23,7 +23,7 @@ ValidationError, field_validator, ) -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from simcore_postgres_database.models.classifiers import group_classifiers from ..db.plugin import get_database_engine_legacy @@ -99,7 +99,7 @@ async def get_classifiers_from_bundle(self, gid: int) -> dict[str, Any]: ) except ValidationError as err: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"DB corrupt data in 'groups_classifiers' table. Invalid classifier for gid={gid}. Returning empty bundle.", error=err, error_context={ diff --git a/services/web/server/src/simcore_service_webserver/login/_controller/rest/auth.py b/services/web/server/src/simcore_service_webserver/login/_controller/rest/auth.py index 972a3861343e..de6ca2dc1068 100644 --- a/services/web/server/src/simcore_service_webserver/login/_controller/rest/auth.py +++ b/services/web/server/src/simcore_service_webserver/login/_controller/rest/auth.py @@ -7,7 +7,8 @@ from pydantic import TypeAdapter from servicelib.aiohttp import status from servicelib.aiohttp.requests_validation import parse_request_body_as -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.request_keys import RQT_USERID_KEY from simcore_postgres_database.models.users import UserRole diff --git a/services/web/server/src/simcore_service_webserver/login/_controller/rest/change.py b/services/web/server/src/simcore_service_webserver/login/_controller/rest/change.py index 50a412f3c771..b87934e389eb 100644 --- a/services/web/server/src/simcore_service_webserver/login/_controller/rest/change.py +++ b/services/web/server/src/simcore_service_webserver/login/_controller/rest/change.py @@ -3,7 +3,7 @@ from aiohttp import web from aiohttp.web import RouteTableDef from servicelib.aiohttp.requests_validation import parse_request_body_as -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.request_keys import RQT_USERID_KEY from simcore_postgres_database.utils_users import UsersRepo @@ -122,7 +122,7 @@ def _get_error_context( user = await _auth_service.get_user_or_none(request.app, email=request_body.email) if not user: _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"{_error_msg_prefix} for non-existent email. {_error_msg_suffix}", error=Exception("No user found with this email"), error_context=_get_error_context(), @@ -145,7 +145,7 @@ def _get_error_context( # NOTE: we abuse here (untiby reusing `validate_user_status` and catching http errors that we # do not want to forward but rather log due to the special rules in this entrypoint _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"{_error_msg_prefix} for invalid user. {err.text}. {_error_msg_suffix}", error=err, error_context={**_get_error_context(user), "error.text": err.text}, @@ -163,7 +163,7 @@ def _get_error_context( request.app, user_id=user["id"], product_name=product.name ): _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( f"{_error_msg_prefix} for a user with NO access to this product. {_error_msg_suffix}", error=Exception("User cannot access this product"), error_context=_get_error_context(user), @@ -206,7 +206,7 @@ def _get_error_context( ) except Exception as err: # pylint: disable=broad-except _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unable to send email", error=err, error_context=_get_error_context(user), diff --git a/services/web/server/src/simcore_service_webserver/login/_controller/rest/confirmation.py b/services/web/server/src/simcore_service_webserver/login/_controller/rest/confirmation.py index 1f05e965d686..e62a2ae4c13d 100644 --- a/services/web/server/src/simcore_service_webserver/login/_controller/rest/confirmation.py +++ b/services/web/server/src/simcore_service_webserver/login/_controller/rest/confirmation.py @@ -13,7 +13,7 @@ parse_request_body_as, parse_request_path_parameters_as, ) -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON from yarl import URL @@ -181,7 +181,7 @@ async def validate_confirmation_and_redirect(request: web.Request): ) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, diff --git a/services/web/server/src/simcore_service_webserver/login/_controller/rest/registration.py b/services/web/server/src/simcore_service_webserver/login/_controller/rest/registration.py index 796a47241565..a4a636d87de8 100644 --- a/services/web/server/src/simcore_service_webserver/login/_controller/rest/registration.py +++ b/services/web/server/src/simcore_service_webserver/login/_controller/rest/registration.py @@ -6,7 +6,7 @@ from common_library.error_codes import create_error_code from servicelib.aiohttp import status from servicelib.aiohttp.requests_validation import parse_request_body_as -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON from simcore_postgres_database.models.users import UserStatus @@ -255,7 +255,7 @@ async def register(request: web.Request): user_error_msg = MSG_CANT_SEND_MAIL _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, @@ -382,7 +382,7 @@ async def register_phone(request: web.Request): user_error_msg = "Currently we cannot register phone numbers" _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, diff --git a/services/web/server/src/simcore_service_webserver/login/_invitations_service.py b/services/web/server/src/simcore_service_webserver/login/_invitations_service.py index 3a8c5ceb13a2..3cd8bac78174 100644 --- a/services/web/server/src/simcore_service_webserver/login/_invitations_service.py +++ b/services/web/server/src/simcore_service_webserver/login/_invitations_service.py @@ -23,7 +23,7 @@ ValidationError, field_validator, ) -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON from simcore_postgres_database.models.confirmations import ConfirmationAction from simcore_postgres_database.models.users import UserStatus @@ -226,7 +226,7 @@ def _invitations_request_context(invitation_code: str) -> Iterator[URL]: user_error_msg = f"Invalid invitation. {MSG_INVITATIONS_CONTACT_SUFFIX}" _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, @@ -243,7 +243,7 @@ def _invitations_request_context(invitation_code: str) -> Iterator[URL]: user_error_msg = "Unable to process your invitation since the invitations service is currently unavailable" _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, diff --git a/services/web/server/src/simcore_service_webserver/login/_security_service.py b/services/web/server/src/simcore_service_webserver/login/_security_service.py index 82738d1ace5c..14b263088599 100644 --- a/services/web/server/src/simcore_service_webserver/login/_security_service.py +++ b/services/web/server/src/simcore_service_webserver/login/_security_service.py @@ -3,7 +3,8 @@ import logging from aiohttp import web -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from ..security import security_web from ..web_utils import flash_response diff --git a/services/web/server/src/simcore_service_webserver/login_accounts/_controller_rest.py b/services/web/server/src/simcore_service_webserver/login_accounts/_controller_rest.py index bdc46745ab5b..04ff7151b9cb 100644 --- a/services/web/server/src/simcore_service_webserver/login_accounts/_controller_rest.py +++ b/services/web/server/src/simcore_service_webserver/login_accounts/_controller_rest.py @@ -13,7 +13,8 @@ handle_validation_as_http_error, parse_request_body_as, ) -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.utils import fire_and_forget_task from .._meta import API_VTAG diff --git a/services/web/server/src/simcore_service_webserver/projects/_controller/nodes_rest.py b/services/web/server/src/simcore_service_webserver/projects/_controller/nodes_rest.py index a6e36c0091a9..9835b97f3549 100644 --- a/services/web/server/src/simcore_service_webserver/projects/_controller/nodes_rest.py +++ b/services/web/server/src/simcore_service_webserver/projects/_controller/nodes_rest.py @@ -47,7 +47,7 @@ UNDEFINED_DEFAULT_SIMCORE_USER_AGENT_VALUE, X_SIMCORE_USER_AGENT, ) -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.long_running_tasks.models import TaskProgress from servicelib.long_running_tasks.task import TaskRegistry from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON @@ -334,7 +334,7 @@ async def _stop_dynamic_service_task( f"Could not stop dynamic service {dynamic_service_stop.project_id}.{dynamic_service_stop.node_id}" ) _logger.debug( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exc, error_code=error_code, diff --git a/services/web/server/src/simcore_service_webserver/projects/_project_document_service.py b/services/web/server/src/simcore_service_webserver/projects/_project_document_service.py index dacc6833dc57..f00d99bf8cbc 100644 --- a/services/web/server/src/simcore_service_webserver/projects/_project_document_service.py +++ b/services/web/server/src/simcore_service_webserver/projects/_project_document_service.py @@ -15,7 +15,7 @@ from models_library.api_schemas_webserver.socketio import SocketIORoomStr from models_library.projects import ProjectID, ProjectTemplateType from models_library.projects import ProjectType as ProjectTypeAPI -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_context from servicelib.redis import ( PROJECT_DB_UPDATE_REDIS_LOCK_KEY, @@ -168,7 +168,7 @@ async def remove_project_documents_as_admin(app: web.Application) -> None: f"Project {project_uuid} has {len(room_sessions)} connected users but is not in Redis Resources table" ) _logger.error( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg=f"Project {project_uuid} has {len(room_sessions)} connected users in the socket io room (This is not expected, as project resource is not in the Redis Resources table), keeping document just in case", error=unexpected_state_error, error_context={ @@ -187,7 +187,7 @@ async def remove_project_documents_as_admin(app: web.Application) -> None: except (KeyError, AttributeError, ValueError) as exc: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg=f"Failed to check room participants for project {project_uuid}", error=exc, error_context={ diff --git a/services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy.py b/services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy.py index 32bd7c00a539..11bf8dbe9f11 100644 --- a/services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy.py +++ b/services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy.py @@ -41,7 +41,8 @@ from pydantic import TypeAdapter from pydantic.types import PositiveInt from servicelib.aiohttp.application_keys import APP_AIOPG_ENGINE_KEY -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from simcore_postgres_database.aiopg_errors import UniqueViolation from simcore_postgres_database.models.groups import user_to_groups from simcore_postgres_database.models.project_to_groups import project_to_groups diff --git a/services/web/server/src/simcore_service_webserver/projects/_projects_service.py b/services/web/server/src/simcore_service_webserver/projects/_projects_service.py index 12bbc4b2e30e..01b442ff8159 100644 --- a/services/web/server/src/simcore_service_webserver/projects/_projects_service.py +++ b/services/web/server/src/simcore_service_webserver/projects/_projects_service.py @@ -84,7 +84,8 @@ X_FORWARDED_PROTO, X_SIMCORE_USER_AGENT, ) -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.rabbitmq import RemoteMethodNotRegisteredError, RPCServerError from servicelib.rabbitmq.rpc_interfaces.catalog import services as catalog_rpc from servicelib.rabbitmq.rpc_interfaces.clusters_keeper.ec2_instances import ( diff --git a/services/web/server/src/simcore_service_webserver/resource_manager/user_sessions.py b/services/web/server/src/simcore_service_webserver/resource_manager/user_sessions.py index da0010f20218..41370df9edcd 100644 --- a/services/web/server/src/simcore_service_webserver/resource_manager/user_sessions.py +++ b/services/web/server/src/simcore_service_webserver/resource_manager/user_sessions.py @@ -7,7 +7,8 @@ from aiohttp import web from models_library.users import UserID -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from .models import ResourcesDict, UserSession from .registry import ( diff --git a/services/web/server/src/simcore_service_webserver/security/_authz_policy.py b/services/web/server/src/simcore_service_webserver/security/_authz_policy.py index c54eeb4d196c..08a594e257a1 100644 --- a/services/web/server/src/simcore_service_webserver/security/_authz_policy.py +++ b/services/web/server/src/simcore_service_webserver/security/_authz_policy.py @@ -14,7 +14,7 @@ from models_library.products import ProductName from models_library.users import UserID from servicelib.aiohttp.db_asyncpg_engine import get_async_engine -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from simcore_postgres_database.aiopg_errors import DatabaseError as AiopgDatabaseError from sqlalchemy.exc import DatabaseError as SQLAlchemyDatabaseError @@ -50,7 +50,7 @@ def _handle_exceptions_as_503(): yield except (AiopgDatabaseError, SQLAlchemyDatabaseError) as err: _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Auth unavailable due to database error", error=err, tip="Check database connection", diff --git a/services/web/server/src/simcore_service_webserver/socketio/_handlers.py b/services/web/server/src/simcore_service_webserver/socketio/_handlers.py index d3706fb2ee02..5e11a422a476 100644 --- a/services/web/server/src/simcore_service_webserver/socketio/_handlers.py +++ b/services/web/server/src/simcore_service_webserver/socketio/_handlers.py @@ -4,7 +4,6 @@ SEE http://python-socketio.readthedocs.io/en/latest/ """ -import contextlib import logging from typing import Any @@ -16,8 +15,9 @@ from models_library.users import UserID from pydantic import TypeAdapter from servicelib.aiohttp.observer import emit -from servicelib.logging_errors import create_troubleshootting_log_kwargs -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_errors import create_troubleshooting_log_kwargs +from servicelib.logging_utils import log_context from servicelib.request_keys import RQT_USERID_KEY from ..groups.api import list_user_groups_ids_with_read_access @@ -165,63 +165,58 @@ async def connect( @register_socketio_handler async def disconnect(socket_id: SocketID, app: web.Application) -> None: """socketio reserved handler for when the socket.io connection is disconnected.""" - async with contextlib.AsyncExitStack() as stack: - # retrieve the socket session - try: - socketio_session = await stack.enter_async_context( - get_socket_server(app).session(socket_id) - ) - - except KeyError as err: - _logger.warning( - **create_troubleshootting_log_kwargs( - f"Socket session {socket_id} not found during disconnect, already cleaned up", - error=err, - error_context={"socket_id": socket_id}, - ) - ) - return - - # session is wel formed, we can access its data - try: - user_id = socketio_session["user_id"] - client_session_id = socketio_session["client_session_id"] - product_name = socketio_session["product_name"] - - except KeyError as err: - _logger.exception( - **create_troubleshootting_log_kwargs( - f"Socket session {socket_id} does not have user_id or client_session_id during disconnect", - error=err, - error_context={ - "socket_id": socket_id, - "socketio_session": socketio_session, - }, - tip="Check if session is corrupted", + try: + async with get_socket_server(app).session(socket_id) as socketio_session: + # if session is well formed, we can access its data + try: + user_id = socketio_session["user_id"] + client_session_id = socketio_session["client_session_id"] + product_name = socketio_session["product_name"] + + except KeyError as err: + _logger.exception( + **create_troubleshooting_log_kwargs( + f"Socket session {socket_id} does not have user_id or client_session_id during disconnect", + error=err, + error_context={ + "socket_id": socket_id, + "socketio_session": socketio_session, + }, + tip="Check if session is corrupted", + ) ) + return + + except KeyError as err: + _logger.warning( + **create_troubleshooting_log_kwargs( + f"Socket session {socket_id} not found during disconnect, already cleaned up", + error=err, + error_context={"socket_id": socket_id}, ) - return - - # Disconnecting - with log_context( - _logger, - logging.INFO, - "disconnection of %s with %s", - f"{user_id=}", - f"{client_session_id=}", - ): - with managed_resource(user_id, client_session_id, app) as user_session: - await user_session.remove_socket_id() - - # signal same user other clients if available - await emit( - app, - "SIGNAL_USER_DISCONNECTED", - user_id, - client_session_id, - app, - product_name, - ) + ) + return + + # Notify disconnection to all replicas/plugins + with log_context( + _logger, + logging.INFO, + "disconnection of %s with %s", + f"{user_id=}", + f"{client_session_id=}", + ): + with managed_resource(user_id, client_session_id, app) as user_session: + await user_session.remove_socket_id() + + # signal same user other clients if available + await emit( + app, + "SIGNAL_USER_DISCONNECTED", + user_id, + client_session_id, + app, + product_name, + ) @register_socketio_handler diff --git a/services/web/server/src/simcore_service_webserver/socketio/_observer.py b/services/web/server/src/simcore_service_webserver/socketio/_observer.py index 5d6360033dee..16e991abc6b3 100644 --- a/services/web/server/src/simcore_service_webserver/socketio/_observer.py +++ b/services/web/server/src/simcore_service_webserver/socketio/_observer.py @@ -9,7 +9,7 @@ from aiohttp import web from servicelib.aiohttp.application_keys import APP_FIRE_AND_FORGET_TASKS_KEY from servicelib.aiohttp.observer import register_observer, setup_observer_registry -from servicelib.logging_utils import get_log_record_extra +from servicelib.logging_base import get_log_record_extra from servicelib.utils import fire_and_forget_task, logged_gather from socketio import AsyncServer # type: ignore[import-untyped] diff --git a/services/web/server/src/simcore_service_webserver/storage/api.py b/services/web/server/src/simcore_service_webserver/storage/api.py index 839c26bc89c0..300f88441490 100644 --- a/services/web/server/src/simcore_service_webserver/storage/api.py +++ b/services/web/server/src/simcore_service_webserver/storage/api.py @@ -22,7 +22,8 @@ from models_library.users import UserID from pydantic import ByteSize, HttpUrl, TypeAdapter from servicelib.aiohttp.client_session import get_client_session -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.rabbitmq.rpc_interfaces.async_jobs.async_jobs import ( AsyncJobComposedResult, submit_and_wait, diff --git a/services/web/server/src/simcore_service_webserver/studies_dispatcher/_controller/rest/redirects_exceptions.py b/services/web/server/src/simcore_service_webserver/studies_dispatcher/_controller/rest/redirects_exceptions.py index bdd7ee662a35..e5110c8730d5 100644 --- a/services/web/server/src/simcore_service_webserver/studies_dispatcher/_controller/rest/redirects_exceptions.py +++ b/services/web/server/src/simcore_service_webserver/studies_dispatcher/_controller/rest/redirects_exceptions.py @@ -7,7 +7,7 @@ from models_library.function_services_catalog._utils import ServiceNotFound from servicelib.aiohttp import status from servicelib.aiohttp.typing_extension import Handler -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ....exception_handling import create_error_context_from_request from ....utils import compose_support_error_msg @@ -54,7 +54,7 @@ def _create_error_redirect_with_logging( user_error_msg = compose_support_error_msg(msg=message, error_code=error_code) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, diff --git a/services/web/server/src/simcore_service_webserver/studies_dispatcher/_studies_access.py b/services/web/server/src/simcore_service_webserver/studies_dispatcher/_studies_access.py index 16137769f16a..3c25e491cfa6 100644 --- a/services/web/server/src/simcore_service_webserver/studies_dispatcher/_studies_access.py +++ b/services/web/server/src/simcore_service_webserver/studies_dispatcher/_studies_access.py @@ -24,7 +24,7 @@ from models_library.projects import ProjectID from servicelib.aiohttp import status from servicelib.aiohttp.typing_extension import Handler -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from ..constants import INDEX_RESOURCE_NAME from ..director_v2 import director_v2_service @@ -268,7 +268,7 @@ async def wrapper(request: web.Request) -> web.StreamResponse: msg=MSG_UNEXPECTED_DISPATCH_ERROR, error_code=error_code ) _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=err, error_code=error_code, @@ -341,7 +341,7 @@ async def get_redirection_to_study_page(request: web.Request) -> web.Response: user_error_msg = MSG_TOO_MANY_GUESTS _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exc, error_code=error_code, @@ -373,7 +373,7 @@ async def get_redirection_to_study_page(request: web.Request) -> web.Response: user_error_msg = MSG_UNEXPECTED_DISPATCH_ERROR _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( user_error_msg, error=exc, error_code=error_code, diff --git a/services/web/server/src/simcore_service_webserver/trash/_service.py b/services/web/server/src/simcore_service_webserver/trash/_service.py index 968cd458dd10..d436a1eedb85 100644 --- a/services/web/server/src/simcore_service_webserver/trash/_service.py +++ b/services/web/server/src/simcore_service_webserver/trash/_service.py @@ -7,7 +7,7 @@ from aiohttp import web from models_library.products import ProductName from models_library.users import UserID -from servicelib.logging_errors import create_troubleshootting_log_kwargs +from servicelib.logging_errors import create_troubleshooting_log_kwargs from servicelib.logging_utils import log_context from ..folders import folders_trash_service @@ -50,7 +50,7 @@ async def _empty_explicitly_trashed_projects( except Exception as exc: # pylint: disable=broad-exception-caught _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Error deleting a trashed project while emptying trash.", error=exc, error_context={ @@ -87,7 +87,7 @@ async def _empty_explicitly_trashed_folders_and_content( except Exception as exc: # pylint: disable=broad-exception-caught _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Error deleting a trashed folders (and content) while emptying trash.", error=exc, error_context={ @@ -124,7 +124,7 @@ async def _empty_explicitely_trashed_workspaces_and_content( except Exception as exc: # pylint: disable=broad-exception-caught _logger.warning( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Error deleting a trashed workspace (and content) while emptying trash.", error=exc, error_context={ @@ -187,7 +187,7 @@ async def safe_delete_expired_trash_as_admin(app: web.Application) -> None: except Exception as exc: # pylint: disable=broad-exception-caught _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpected error while batch deleting expired workspaces as admin:", error=exc, error_context=ctx, @@ -206,7 +206,7 @@ async def safe_delete_expired_trash_as_admin(app: web.Application) -> None: except Exception as exc: # pylint: disable=broad-exception-caught ctx_with_product = {**ctx, "product_name": product_name} _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpected error while batch deleting expired trashed folders as admin:", error=exc, error_context=ctx_with_product, @@ -226,7 +226,7 @@ async def safe_delete_expired_trash_as_admin(app: web.Application) -> None: except Exception as exc: # pylint: disable=broad-exception-caught _logger.exception( - **create_troubleshootting_log_kwargs( + **create_troubleshooting_log_kwargs( "Unexpected error while batch deleting expired projects as admin:", error=exc, error_context=ctx, diff --git a/services/web/server/src/simcore_service_webserver/wallets/_payments_handlers.py b/services/web/server/src/simcore_service_webserver/wallets/_payments_handlers.py index 577ba772c666..69d95703bdf0 100644 --- a/services/web/server/src/simcore_service_webserver/wallets/_payments_handlers.py +++ b/services/web/server/src/simcore_service_webserver/wallets/_payments_handlers.py @@ -21,7 +21,8 @@ parse_request_path_parameters_as, parse_request_query_parameters_as, ) -from servicelib.logging_utils import get_log_record_extra, log_context +from servicelib.logging_base import get_log_record_extra +from servicelib.logging_utils import log_context from servicelib.utils import fire_and_forget_task from .._meta import API_VTAG as VTAG