# Custom Logging We forward all agent and worker logs (i.e. from {mod}`logging`, `stdout`, and `stderr`) to the launcher process. ## Defaults By default, the logs from the rank 0 agent and rank 0 worker are handled by loggers on the launcher process (and so they should be printed to `stdout`/`stderr`). You may control these logs like: ```python logging.basicConfig(level=logging.INFO) logging.getLogger("torchrunx").setLevel(logging.DEBUG) logging.getLogger("torchrunx.node1").setLevel(logging.INFO) logging.getLogger("torchrunx.node1.1").setLevel(logging.INFO) # worker 1 (local rank) on node 1 ``` Also, logs from all agents and workers are written to a directory (by the current timestamp) in `$TORCHRUNX_LOG_DIR` (default: `./torchrunx_logs`). These can be controlled using `$TORCHRUNX_LOG_LEVEL` (default: `INFO`). ## Customization You can fully customize how logs are processed using {func}`torchrunx.Launcher.set_logging_handlers`. You should provide it a factory function that constructs and returns a list of {obj}`logging.Handler` objects. Each {obj}`logging.Handler` controls where logs should be written. You can also add a filter to restrict the handler to the logs of a specific agent or worker. Here's an example: ```python from torchrunx.utils.log_handling import RedirectHandler, get_handler_filter def custom_handlers() -> list[logging.Handler]: # Handler: redirect logs from (host 0, agent) to logger on launcher process redirect_handler = RedirectHandler() redirect_handler.addFilter(get_handler_filter( hostname=hostnames[0], local_rank=None, log_level=logging.DEBUG )) # Handler: output logs from (host 0, worker 0) to "output.txt" file_handler = logging.FileHandler("output.txt") file_handler.addFilter(get_handler_filter( hostname=hostnames[0], local_rank=0, log_level=logging.DEBUG )) return [ redirect_handler, file_handler, ] ``` ```python torchrunx.Launcher(...).set_logging_handlers(custom_handlers).run(...) ``` Finally, you can control library-specific logging (within the worker processes) by modifying the distributed function: ```python def distributed_function(): logging.getLogger("transformers").setLevel(logging.DEBUG) logger = logging.getLogger("my_app") logger.info("Hello world!") ... torchrunx.Launcher(...).run(distributed_function) ```