> For the complete documentation index, see [llms.txt](https://docs.hello-robot.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello-robot.com/stretch4_docs/working-with-stretch/common_tasks/logging-data.md).

# Logging Data

The Stretch software stack uses a combination of standard python loggers and ros2 logging infrastructure. A global logging configuration is saved in `stretch4_body.core.robot_params.RobotParams`. Any object derived from `Device` will inherit this configuration, and the logs can be reviewed using the stretch\_body\_server interface. Monitoring the output of stretch4\_body is useful for debugging robot motion and identifying underlying hardware faults. Standard ROS 2 tooling can be used for debugging higher-level ROS 2 node behaviors.

## High-Level Design Summary

* **Configuration via DictConfig:** The logger's configuration is managed centrally within `stretch4_body.core.robot_params.RobotParams`. At initialization, `RobotParams` loads the system defaults (defined in `nominal_system_params`), which dictate logger formats, handlers, and save paths.
* **Handlers:**
  * **Console Handler:** Configured via `HelloLoggerScreen`, providing color-coded, human-readable logging to the terminal/IDE.
  * **Rotating File Handler:** Writing to `stretch_body_server.log` by default (formatted using `HelloLoggerFile`). It implements automatic rotation when logs exceed 10MB, retaining up to 10 historical backups to prevent logs from overtaking disk space.
* **Log Locations:** Logs are saved inside the stretch\_user directory inside the `stretch_user/log` directory. Stretch\_body\_server logs from an active session are recorded in `stretch_user/log/stretch_body_logger/stretch_body_server.log`. Archived logs from previous sessions are saved to `stretch_user/log/stretch_body_logger/stretch_body_server_archived/`.
* **Component Loggers:** Subsystem and module components are subclasses of `stretch4_body.core.device.Device`. The base `Device` class orchestrates the `logging.config.dictConfig(...)` initialization and exposes `self.logger = logging.getLogger(self.name)` automatically to all subclasses.
* **Throttling Filter:** To prevent spamming (such as missed loop warnings occurring extremely rapidly), standard device loggers initialize with a custom `LoggerThrottleFilter` instance. You can throttle any log message by passing `extra={'throttle_s': <seconds>}` during the log call. The filter tracks log frequency using a combination of the calling file name and the exact line number to accurately throttle specific messages without affecting others.

## Understanding Stretch Behavior using Logs

Inspecting the main log (`stretch_body_server.log`) helps unravel mysterious behavior or failures on the robot:

1. **Startup Procedures:** Device initialization attempts logs parameters that could not be loaded or hardware subsystems that could not be reached. Error messages indicating "Parameters for device \[xxx] not found" typically mean YAML configurations are out of sync or corrupted.
2. **Loop Iterations and Control Rates:** Tools like `LoopStats` will log `WARNING` level messages directly to the logger if they cannot maintain their target refresh rate (e.g., due to CPU spikes).
3. **Deprecation/Configuration Drift:** Core utilities log errors and force-quit if they detect deprecated settings (such as outdated collision/contact force thresholds or outdated URDF kinematic tree joint names).
4. **Behavior Analysis:** Since every sub-component (e.g., `pimu`, `arm`, `lift`) is uniquely named, it is straightforward to `grep` the log file for specific subsystems to see exactly when they fault, hit limits, or drop communication.

## How to Add New Logs

Because `stretch4_body` handles the `logging.config` execution for you globally, adding new logs is seamless.

### Inside a `Device` subclass

If your class derives from `stretch4_body.core.device.Device`, you already have a pre-configured logger:

```python
class MyNewSensor(Device):
    def __init__(self):
        super().__init__('my_sensor')
        self.logger.info("Initializing MyNewSensor")

    def poll_data(self):
        try:
            # Polling hardware...
            self.logger.debug("Successfully polled hardware.")
        except Exception as e:
            # Logs the error at most once every 5.0 seconds
            self.logger.error(f"Failed pulling data: {e}", extra={'throttle_s': 5.0})
```

### In a standalone script or module

If you're writing a utility script or an isolated class, you can setup logging to integrate into stretch4\_body with the following example:

```python
import logging
from stretch4_body.core.robot_params import RobotParams

def setup_logging():
    try:
        _, robot_params = RobotParams.get_params()
        logging_params = robot_params['logging'].copy()
        # Update filename to be specific to this tool
        if 'file_handler' in logging_params['handlers']:
            logging_params['handlers']['file_handler']['filename'] = hello_utils.get_stretch_directory('log/stretch_body_logger/') + 'stretch4_urdf.log'
        logging.config.dictConfig(logging_params)
    except:
        # Fallback to basic configuration if robot_params cannot be loaded
        logging.basicConfig(
            level=logging.INFO,
            format="[%(asctime)s] [%(name)s] [%(levelname)s]: %(message)s",
            datefmt="%m/%d/%Y %H:%M:%S"
        )
```

### Modifying Log Verbosity Dynamically

During testing or debugging, you can elevate the verbosity for the console handler to include deeper `DEBUG` traces:

```python
from stretch4_body.core.robot_params import RobotParams
RobotParams.set_logging_level('DEBUG', handler='console_handler')
```

## Interacting with Server Logs

You can easily launch the server and view its logs directly using the `stretch_body_server` command line tool:

* **`stretch_body_server --print`**: Use this command to live-tail the server's active log. It will gracefully track internal file rotation boundaries and print using native color coding to distinguish `INFO` (white), `WARNING` (yellow), and `ERROR` (red). If no active server is detected locally, it will intelligently extract and print the final 10 lines of the most recent `.tar.gz` archived log instead to provide immediate context on what just happened.
* **`stretch_body_server --launch`**: This command spins up the Stretch Body Server directly in the terminal. It maintains the same logging and log aggregation behavior as the background process, but will additionally surface standard `print` statements.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hello-robot.com/stretch4_docs/working-with-stretch/common_tasks/logging-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
