Source code for ray._private.ray_logging.logging_config
import logging
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Set
from ray._private.ray_logging import default_impl
from ray._private.ray_logging.constants import LOGRECORD_STANDARD_ATTRS
from ray._private.ray_logging.filters import CoreContextFilter
from ray._private.ray_logging.formatters import JSONFormatter, TextFormatter
from ray.util.annotations import PublicAPI
class LoggingConfigurator(ABC):
    @abstractmethod
    def get_supported_encodings(self) -> Set[str]:
        raise NotImplementedError
    @abstractmethod
    def configure(self, logging_config: "LoggingConfig"):
        raise NotImplementedError
class DefaultLoggingConfigurator(LoggingConfigurator):
    def __init__(self):
        self._encoding_to_formatter = {
            "TEXT": TextFormatter(),
            "JSON": JSONFormatter(),
        }
    def get_supported_encodings(self) -> Set[str]:
        return self._encoding_to_formatter.keys()
    def configure(self, logging_config: "LoggingConfig"):
        formatter = self._encoding_to_formatter[logging_config.encoding]
        formatter.set_additional_log_standard_attrs(
            logging_config.additional_log_standard_attrs
        )
        core_context_filter = CoreContextFilter()
        handler = logging.StreamHandler()
        handler.setLevel(logging_config.log_level)
        handler.setFormatter(formatter)
        handler.addFilter(core_context_filter)
        root_logger = logging.getLogger()
        root_logger.setLevel(logging_config.log_level)
        root_logger.addHandler(handler)
        ray_logger = logging.getLogger("ray")
        ray_logger.setLevel(logging_config.log_level)
        # Remove all existing handlers added by `ray/__init__.py`.
        for h in ray_logger.handlers[:]:
            ray_logger.removeHandler(h)
        ray_logger.addHandler(handler)
        ray_logger.propagate = False
_logging_configurator: LoggingConfigurator = default_impl.get_logging_configurator()
# Class defines the logging configurations for a Ray job.
# To add a new logging configuration: (1) add a new field to this class; (2) Update the
# logic in the __post_init__ method in this class to add the validation logic;
# (3) Update the configure method in the DefaultLoggingConfigurator
# class to use the new field.
[docs]
@PublicAPI(stability="alpha")
@dataclass
class LoggingConfig:
    encoding: str = "TEXT"
    log_level: str = "INFO"
    # The list of valid attributes are defined as LOGRECORD_STANDARD_ATTRS in
    # constants.py.
    additional_log_standard_attrs: list = field(default_factory=list)
    def __post_init__(self):
        if self.encoding not in _logging_configurator.get_supported_encodings():
            raise ValueError(
                f"Invalid encoding type: {self.encoding}. "
                "Valid encoding types are: "
                f"{list(_logging_configurator.get_supported_encodings())}"
            )
        for attr in self.additional_log_standard_attrs:
            if attr not in LOGRECORD_STANDARD_ATTRS:
                raise ValueError(
                    f"Unknown python logging standard attribute: {attr}. "
                    "The valid attributes are: "
                    f"{LOGRECORD_STANDARD_ATTRS}"
                )
    def _configure_logging(self):
        """Set up the logging configuration for the current process."""
        _logging_configurator.configure(self)
    def _apply(self):
        """Set up the logging configuration."""
        self._configure_logging() 
LoggingConfig.__doc__ = """
    Logging configuration for a Ray job. These configurations are used to set up the
    root logger of the driver process and all Ray tasks and actor processes that belong
    to the job.
    Examples: 1. Configure the logging to use TEXT encoding.
        .. testcode::
            import ray
            import logging
            ray.init(
                logging_config=ray.LoggingConfig(encoding="TEXT", log_level="INFO", additional_log_standard_attrs=['name'])
            )
            @ray.remote
            def f():
                logger = logging.getLogger(__name__)
                logger.info("This is a Ray task")
            ray.get(f.remote())
            ray.shutdown()
        .. testoutput::
            :options: +MOCK
            2025-02-12 12:25:16,836 INFO test-log-config.py:11 -- This is a Ray task name=__main__ job_id=01000000 worker_id=51188d9448be4664bf2ea26ac410b67acaaa970c4f31c5ad3ae776a5 node_id=f683dfbffe2c69984859bc19c26b77eaf3866c458884c49d115fdcd4 task_id=c8ef45ccd0112571ffffffffffffffffffffffff01000000 task_name=f task_func_name=test-log-config.f timestamp_ns=1739391916836884000
    2. Configure the logging to use JSON encoding.
        .. testcode::
            import ray
            import logging
            ray.init(
                logging_config=ray.LoggingConfig(encoding="JSON", log_level="INFO", additional_log_standard_attrs=['name'])
            )
            @ray.remote
            def f():
                logger = logging.getLogger(__name__)
                logger.info("This is a Ray task")
            ray.get(f.remote())
            ray.shutdown()
        .. testoutput::
            :options: +MOCK
            {"asctime": "2025-02-12 12:25:48,766", "levelname": "INFO", "message": "This is a Ray task", "filename": "test-log-config.py", "lineno": 11, "name": "__main__", "job_id": "01000000", "worker_id": "6d307578014873fcdada0fa22ea6d49e0fb1f78960e69d61dfe41f5a", "node_id": "69e3a5e68bdc7eb8ac9abb3155326ee3cc9fc63ea1be04d11c0d93c7", "task_id": "c8ef45ccd0112571ffffffffffffffffffffffff01000000", "task_name": "f", "task_func_name": "test-log-config.f", "timestamp_ns": 1739391948766949000}
    Args:
        encoding: Encoding type for the logs. The valid values are
            {list(_logging_configurator.get_supported_encodings())}
        log_level: Log level for the logs. Defaults to 'INFO'. You can set
            it to 'DEBUG' to receive more detailed debug logs.
        additional_log_standard_attrs: List of additional standard python logger attributes to
            include in the log. Defaults to an empty list. The list of already
            included standard attributes are: "asctime", "levelname", "message",
            "filename", "lineno", "exc_text". The list of valid attributes are specified
            here: http://docs.python.org/library/logging.html#logrecord-attributes
    """  # noqa: E501