Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/lmstudio/_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,5 +147,7 @@ def critical(
self._log(logging.CRITICAL, msg, exc_info, stack_info, stacklevel, event_dict)


def get_logger(name: str, /, *args: Any, **kwds: Any) -> StructuredLogger:
def new_logger(name: str, /, *args: Any, **kwds: Any) -> StructuredLogger:
# Loggers contain runtime state, so they are NOT shared based on their names
# Function name reflects this to avoid false expectations from stdlib logging
return StructuredLogger(logging.getLogger(name, *args, **kwds))
7 changes: 3 additions & 4 deletions src/lmstudio/_ws_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from .schemas import DictObject
from .json_api import LMStudioWebsocket, LMStudioWebsocketError

from ._logging import get_logger, LogEventContext
from ._logging import new_logger, LogEventContext


# Allow the core client websocket management to be shared across all SDK interaction APIs
Expand Down Expand Up @@ -281,7 +281,7 @@ def call_in_background(self, func: Callable[[], Any]) -> None:
class AsyncWebsocketThread(BackgroundThread):
def __init__(self, log_context: LogEventContext | None = None) -> None:
super().__init__(task_target=self._log_thread_execution)
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context, thread_id=self.name)

async def _log_thread_execution(self) -> None:
Expand Down Expand Up @@ -322,8 +322,7 @@ def __init__(
self._ws_disconnected = asyncio.Event()
self._rx_task: asyncio.Task[None] | None = None
self._enqueue_message = enqueue_message
self._logger = get_logger(type(self).__name__)
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context)

async def connect(self) -> bool:
Expand Down
4 changes: 2 additions & 2 deletions src/lmstudio/async_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
ModelCompatibilityType,
)

from ._logging import get_logger, LogEventContext
from ._logging import new_logger, LogEventContext

# Only the async API itself is published from
# this module. Anything needed for type hints
Expand Down Expand Up @@ -192,7 +192,7 @@ def __init__(
"""Initialize asynchronous remote procedure call."""
self._rx_queue = rx_queue
self._rpc = RemoteCallHandler(call_id, log_context, notice_prefix)
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context, call_id=call_id)

def get_rpc_message(
Expand Down
12 changes: 6 additions & 6 deletions src/lmstudio/json_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
RepositoryRpcSearchModelsParameter,
SerializedLMSExtendedError,
)
from ._logging import get_logger, LogEventContext, StructuredLogger
from ._logging import new_logger, LogEventContext, StructuredLogger

# The sync and async modules publish the main SDK client API.
# From here, we publish everything that might be needed
Expand Down Expand Up @@ -661,7 +661,7 @@ def __init__(
# Channel processing state tracking
self._is_finished = False
self._result: T | None = None
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(endpoint=self._API_ENDPOINT)

@property
Expand Down Expand Up @@ -1602,7 +1602,7 @@ def __init__(
self._is_finished = False
self._channel_id = channel_id
self._endpoint = endpoint
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context, channel_id=channel_id)

@property
Expand Down Expand Up @@ -1681,7 +1681,7 @@ def __init__(
) -> None:
"""Initialize websocket remote procedure call."""
self._call_id = call_id
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context, call_id=call_id)
self._notice_prefix = notice_prefix

Expand Down Expand Up @@ -1776,7 +1776,7 @@ def __init__(
"""Initialize I/O independent websocket details."""
self._ws_url = ws_url
self._auth_details = auth_details
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context, ws_url=ws_url)
self._mux = MultiplexingManager(logger)
# Subclasses handle actually creating a websocket instance
Expand Down Expand Up @@ -2042,7 +2042,7 @@ def __init__(self, model_identifier: str, session: TSession) -> None:
"""Initialize the LM Studio model reference."""
self.identifier = model_identifier
self._session = session
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(model_identifier=model_identifier)

def __repr__(self) -> str:
Expand Down
4 changes: 2 additions & 2 deletions src/lmstudio/sync_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
ModelCompatibilityType,
)

from ._logging import get_logger, LogEventContext
from ._logging import new_logger, LogEventContext

# Only the sync API itself is published from
# this module. Anything needed for type hints
Expand Down Expand Up @@ -218,7 +218,7 @@ def __init__(
"""Initialize synchronous remote procedure call."""
self._rx_queue = rx_queue
self._rpc = RemoteCallHandler(call_id, log_context, notice_prefix)
self._logger = logger = get_logger(type(self).__name__)
self._logger = logger = new_logger(type(self).__name__)
logger.update_context(log_context, call_id=call_id)

def get_rpc_message(
Expand Down
4 changes: 2 additions & 2 deletions tests/test_traceback_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from lmstudio import LMStudioError
from lmstudio.sdk_api import sdk_callback_invocation
from lmstudio._logging import get_logger
from lmstudio._logging import new_logger

from .support import check_sdk_error, check_unfiltered_error
from .support.lmstudio import (
Expand Down Expand Up @@ -65,7 +65,7 @@ async def test_async_api_truncation_internal_error(public_api: TestCoro) -> None


def test_callback_invocation(caplog: LogCap) -> None:
logger = get_logger(__name__)
logger = new_logger(__name__)
exc_to_raise = Exception("This will be raised")
with sdk_callback_invocation("Callback test", logger):
raise exc_to_raise
Expand Down