mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-06-05 21:20:40 +02:00
Merge pull request #143 from tiqi-group/fix/logging
configures pydase's logger only (not root logger anymore)
This commit is contained in:
commit
1789a6ad7e
@ -1,14 +1,45 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
import logging.config
|
||||||
import sys
|
import sys
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
import socketio # type: ignore[import-untyped]
|
import socketio # type: ignore[import-untyped]
|
||||||
|
import uvicorn.config
|
||||||
import uvicorn.logging
|
import uvicorn.logging
|
||||||
from uvicorn.config import LOGGING_CONFIG
|
|
||||||
|
|
||||||
import pydase.config
|
import pydase.config
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
if pydase.config.OperationMode().environment == "development":
|
||||||
|
LOG_LEVEL = logging.DEBUG
|
||||||
|
else:
|
||||||
|
LOG_LEVEL = logging.INFO
|
||||||
|
|
||||||
|
LOGGING_CONFIG = {
|
||||||
|
"version": 1,
|
||||||
|
"disable_existing_loggers": False,
|
||||||
|
"formatters": {
|
||||||
|
"default": {
|
||||||
|
"()": "pydase.utils.logging.DefaultFormatter",
|
||||||
|
"fmt": "%(asctime)s.%(msecs)03d | %(levelprefix)s | "
|
||||||
|
"%(name)s:%(funcName)s:%(lineno)d - %(message)s",
|
||||||
|
"datefmt": "%Y-%m-%d %H:%M:%S",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"handlers": {
|
||||||
|
"default": {
|
||||||
|
"formatter": "default",
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"stream": "ext://sys.stderr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"loggers": {
|
||||||
|
"pydase": {"handlers": ["default"], "level": LOG_LEVEL, "propagate": False},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class DefaultFormatter(uvicorn.logging.ColourizedFormatter):
|
class DefaultFormatter(uvicorn.logging.ColourizedFormatter):
|
||||||
"""
|
"""
|
||||||
@ -64,86 +95,31 @@ class SocketIOHandler(logging.Handler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(level: str | int | None = None) -> None:
|
def setup_logging() -> None:
|
||||||
"""
|
"""
|
||||||
Configures the logging settings for the application.
|
Configures the logging settings for the application.
|
||||||
|
|
||||||
This function sets up logging with specific formatting and colorization of log
|
This function sets up logging with specific formatting and colorization of log
|
||||||
messages. The log level is determined based on the application's operation mode,
|
messages. The log level is determined based on the application's operation mode. By
|
||||||
with an option to override the level. By default, in a development environment, the
|
default, in a development environment, the log level is set to DEBUG, whereas in
|
||||||
log level is set to DEBUG, whereas in other environments, it is set to INFO.
|
other environments, it is set to INFO.
|
||||||
|
|
||||||
Args:
|
|
||||||
level (Optional[str | int]):
|
|
||||||
A specific log level to set for the application. If None, the log level is
|
|
||||||
determined based on the application's operation mode. Accepts standard log
|
|
||||||
level names ('DEBUG', 'INFO', etc.) and corresponding numerical values.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```python
|
|
||||||
>>> import logging
|
|
||||||
>>> setup_logging(logging.DEBUG)
|
|
||||||
>>> setup_logging("INFO")
|
|
||||||
```
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger.debug("Configuring pydase logging.")
|
||||||
|
|
||||||
if pydase.config.OperationMode().environment == "development":
|
logging.config.dictConfig(LOGGING_CONFIG)
|
||||||
log_level = logging.DEBUG
|
|
||||||
else:
|
|
||||||
log_level = logging.INFO
|
|
||||||
|
|
||||||
# If a level is specified, check whether it's a string or an integer.
|
|
||||||
if level is not None:
|
|
||||||
if isinstance(level, str):
|
|
||||||
# Convert known log level strings directly to their corresponding logging
|
|
||||||
# module constants.
|
|
||||||
level_name = level.upper() # Ensure level names are uppercase
|
|
||||||
if hasattr(logging, level_name):
|
|
||||||
log_level = getattr(logging, level_name)
|
|
||||||
else:
|
|
||||||
raise ValueError(
|
|
||||||
f"Invalid log level: {level}. Must be one of 'DEBUG', 'INFO', "
|
|
||||||
"'WARNING', 'ERROR', etc."
|
|
||||||
)
|
|
||||||
elif isinstance(level, int):
|
|
||||||
log_level = level # Directly use integer levels
|
|
||||||
else:
|
|
||||||
raise ValueError("Log level must be a string or an integer.")
|
|
||||||
|
|
||||||
# Set the logger's level.
|
|
||||||
logger.setLevel(log_level)
|
|
||||||
|
|
||||||
# create console handler and set level to debug
|
|
||||||
ch = logging.StreamHandler()
|
|
||||||
|
|
||||||
# add formatter to ch
|
|
||||||
ch.setFormatter(
|
|
||||||
DefaultFormatter(
|
|
||||||
fmt=(
|
|
||||||
"%(asctime)s.%(msecs)03d | %(levelprefix)s | "
|
|
||||||
"%(name)s:%(funcName)s:%(lineno)d - %(message)s"
|
|
||||||
),
|
|
||||||
datefmt="%Y-%m-%d %H:%M:%S",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add ch to logger
|
|
||||||
logger.addHandler(ch)
|
|
||||||
|
|
||||||
logger.debug("Configuring service logging.")
|
|
||||||
logging.getLogger("asyncio").setLevel(logging.INFO)
|
|
||||||
logging.getLogger("urllib3").setLevel(logging.INFO)
|
|
||||||
|
|
||||||
# configuring uvicorn logger
|
# configuring uvicorn logger
|
||||||
LOGGING_CONFIG["formatters"]["default"][
|
uvicorn.config.LOGGING_CONFIG["formatters"]["default"]["fmt"] = (
|
||||||
"fmt"
|
"%(asctime)s.%(msecs)03d | %(levelprefix)s %(message)s"
|
||||||
] = "%(asctime)s.%(msecs)03d | %(levelprefix)s %(message)s"
|
)
|
||||||
LOGGING_CONFIG["formatters"]["default"]["datefmt"] = "%Y-%m-%d %H:%M:%S"
|
uvicorn.config.LOGGING_CONFIG["formatters"]["default"]["datefmt"] = (
|
||||||
LOGGING_CONFIG["formatters"]["access"]["fmt"] = (
|
"%Y-%m-%d %H:%M:%S"
|
||||||
|
)
|
||||||
|
uvicorn.config.LOGGING_CONFIG["formatters"]["access"]["fmt"] = (
|
||||||
"%(asctime)s.%(msecs)03d | %(levelprefix)s %(client_addr)s "
|
"%(asctime)s.%(msecs)03d | %(levelprefix)s %(client_addr)s "
|
||||||
'- "%(request_line)s" %(status_code)s'
|
'- "%(request_line)s" %(status_code)s'
|
||||||
)
|
)
|
||||||
LOGGING_CONFIG["formatters"]["access"]["datefmt"] = "%Y-%m-%d %H:%M:%S"
|
uvicorn.config.LOGGING_CONFIG["formatters"]["access"]["datefmt"] = (
|
||||||
|
"%Y-%m-%d %H:%M:%S"
|
||||||
|
)
|
||||||
|
@ -8,7 +8,8 @@ from pydase.data_service.data_service_observer import DataServiceObserver
|
|||||||
from pydase.data_service.state_manager import StateManager
|
from pydase.data_service.state_manager import StateManager
|
||||||
from pytest import LogCaptureFixture
|
from pytest import LogCaptureFixture
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger("pydase")
|
||||||
|
logger.propagate = True
|
||||||
|
|
||||||
|
|
||||||
def test_number_slider(caplog: LogCaptureFixture) -> None:
|
def test_number_slider(caplog: LogCaptureFixture) -> None:
|
||||||
|
@ -7,7 +7,8 @@ from pydase.data_service.data_service_observer import DataServiceObserver
|
|||||||
from pydase.data_service.state_manager import StateManager
|
from pydase.data_service.state_manager import StateManager
|
||||||
from pytest import LogCaptureFixture
|
from pytest import LogCaptureFixture
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger("pydase")
|
||||||
|
logger.propagate = True
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
@ -5,7 +5,8 @@ import pytest
|
|||||||
from pydase.observer_pattern.observable import Observable
|
from pydase.observer_pattern.observable import Observable
|
||||||
from pydase.observer_pattern.observer import Observer
|
from pydase.observer_pattern.observer import Observer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger("pydase")
|
||||||
|
logger.propagate = True
|
||||||
|
|
||||||
|
|
||||||
class MyObserver(Observer):
|
class MyObserver(Observer):
|
||||||
|
@ -5,7 +5,8 @@ import pytest
|
|||||||
from pydase.observer_pattern.observable import Observable
|
from pydase.observer_pattern.observable import Observable
|
||||||
from pydase.observer_pattern.observer import Observer
|
from pydase.observer_pattern.observer import Observer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger("pydase")
|
||||||
|
logger.propagate = True
|
||||||
|
|
||||||
|
|
||||||
class MyObserver(Observer):
|
class MyObserver(Observer):
|
||||||
|
@ -5,7 +5,8 @@ import pytest
|
|||||||
from pydase.observer_pattern.observable import Observable
|
from pydase.observer_pattern.observable import Observable
|
||||||
from pydase.observer_pattern.observer import Observer
|
from pydase.observer_pattern.observer import Observer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger("pydase")
|
||||||
|
logger.propagate = True
|
||||||
|
|
||||||
|
|
||||||
class MyObserver(Observer):
|
class MyObserver(Observer):
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pydase.utils.logging import setup_logging
|
|
||||||
from pytest import LogCaptureFixture
|
from pytest import LogCaptureFixture
|
||||||
|
|
||||||
|
|
||||||
def test_log_error(caplog: LogCaptureFixture):
|
def test_log_error(caplog: LogCaptureFixture):
|
||||||
setup_logging("ERROR")
|
logger = logging.getLogger("pydase")
|
||||||
logger = logging.getLogger()
|
logger.setLevel(logging.ERROR)
|
||||||
|
|
||||||
logger.debug("This is a debug message")
|
logger.debug("This is a debug message")
|
||||||
logger.info("This is an info message")
|
logger.info("This is an info message")
|
||||||
logger.warning("This is a warning message")
|
logger.warning("This is a warning message")
|
||||||
@ -21,8 +21,9 @@ def test_log_error(caplog: LogCaptureFixture):
|
|||||||
|
|
||||||
|
|
||||||
def test_log_warning(caplog: LogCaptureFixture):
|
def test_log_warning(caplog: LogCaptureFixture):
|
||||||
setup_logging("WARNING")
|
logger = logging.getLogger("pydase")
|
||||||
logger = logging.getLogger()
|
logger.setLevel(logging.WARNING)
|
||||||
|
|
||||||
logger.debug("This is a debug message")
|
logger.debug("This is a debug message")
|
||||||
logger.info("This is an info message")
|
logger.info("This is an info message")
|
||||||
logger.warning("This is a warning message")
|
logger.warning("This is a warning message")
|
||||||
@ -37,10 +38,9 @@ def test_log_warning(caplog: LogCaptureFixture):
|
|||||||
|
|
||||||
|
|
||||||
def test_log_debug(caplog: LogCaptureFixture):
|
def test_log_debug(caplog: LogCaptureFixture):
|
||||||
setup_logging("DEBUG")
|
logger = logging.getLogger("pydase")
|
||||||
logger = (
|
logger.setLevel(logging.DEBUG)
|
||||||
logging.getLogger()
|
|
||||||
) # Get the root logger or replace with the appropriate logger.
|
|
||||||
logger.debug("This is a debug message")
|
logger.debug("This is a debug message")
|
||||||
logger.info("This is an info message")
|
logger.info("This is an info message")
|
||||||
logger.warning("This is a warning message")
|
logger.warning("This is a warning message")
|
||||||
@ -54,10 +54,9 @@ def test_log_debug(caplog: LogCaptureFixture):
|
|||||||
|
|
||||||
|
|
||||||
def test_log_info(caplog: LogCaptureFixture):
|
def test_log_info(caplog: LogCaptureFixture):
|
||||||
setup_logging("INFO")
|
logger = logging.getLogger("pydase")
|
||||||
logger = (
|
logger.setLevel(logging.INFO)
|
||||||
logging.getLogger()
|
|
||||||
) # Get the root logger or replace with the appropriate logger.
|
|
||||||
logger.debug("This is a debug message")
|
logger.debug("This is a debug message")
|
||||||
logger.info("This is an info message")
|
logger.info("This is an info message")
|
||||||
logger.warning("This is a warning message")
|
logger.warning("This is a warning message")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user