> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmelody.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Debug Logging

> Enable real-time device debug logging, receive log frames over WebSocket, and view stored logs in the CMS.

The **Debug Logging** feature lets you turn on verbose log output from a connected Melody device, capture those logs on the server, and inspect them in the CMS — without needing a serial cable or physical access to the device.

***

## How It Works

```
CMS toggle / API call
        │
        ▼
POST /api/cms/devices/{id}/debug-logging   (Manager)
        │  resolves active subscription, proxies to broadcast
        ▼
POST /device/debug/logging   (Broadcast → Device over WebSocket)
        │  DeviceRemoteControl SET DebugInformation { debug_logging_enabled }
        ▼
        Device confirms (same proto message echoed back)

        ── when logging is on ──►

Device emits FrameType_DEBUG_LOG frames (type 21)
        │  DebugLogMessage { message: string }
        ▼
Broadcast forwards to Manager
        │  POST /api/internal/device/debug-log
        ▼
Stored in DB per device (newest-first, max 1000 entries)
```

***

## Enabling / Disabling Logging

Use the SDK endpoint (requires an active device connection):

```http theme={null}
POST /device/debug/logging
Authorization: Bearer <YOUR_DEVICE_TOKEN>
Content-Type: application/json

{
  "enabled": true
}
```

**Response** (`200 OK`) — current `DebugInformation` from the device:

```json theme={null}
{
  "free_heap_size": 180000,
  "external_flash_size": 4194304,
  "debug_logging_enabled": true
}
```

**`404`** — device is not currently connected to the server.

<Warning>
  This setting is **not persisted** on the device. After a reconnect the device reverts to its firmware default (logging off). You must re-enable after each reconnect if needed.
</Warning>

***

## Receiving Log Frames (Device → Server)

While logging is enabled, the device sends unsolicited WebSocket frames:

| Field            | Value              |
| ---------------- | ------------------ |
| Frame type       | `DEBUG_LOG = 21`   |
| Protobuf message | `DebugLogMessage`  |
| Field            | `message` (string) |

The server intercepts these frames automatically — no client-side handling is required. Each message is stored in the database with a timestamp.

***

## Viewing Logs in the CMS

1. Open **CMS → Devices** and click any device.
2. Switch to the **Debug Logs** tab.
3. Use the **Enable debug logging** toggle to activate/deactivate logging on the connected device.
4. Logs appear in the table (newest first), auto-refreshing every **10 seconds** while the tab is open.
5. Use **Clear all logs** to delete all stored log entries for this device.

<Info>
  The CMS stores up to **1000 log entries** per device. Older entries are automatically trimmed when the limit is reached.
</Info>

***

## CMS REST API

If you need programmatic access to stored logs:

| Method   | Endpoint                           | Description                                                                          |
| -------- | ---------------------------------- | ------------------------------------------------------------------------------------ |
| `GET`    | `/api/cms/devices/{id}/debug-logs` | List logs. Supports `limit` and `offset` query params (default limit: 50, max: 500). |
| `DELETE` | `/api/cms/devices/{id}/debug-logs` | Delete all stored logs for the device.                                               |

**GET response shape:**

```json theme={null}
{
  "logs": [
    {
      "id": 42,
      "device_id": 7,
      "log_message": "motor init ok",
      "created_at": "2026-04-08T10:00:00Z"
    }
  ],
  "total_count": 1,
  "limit": 50,
  "offset": 0
}
```

***

## Constraints & Notes

* Logging toggle only works when the device is **currently connected** (has an active subscription on the broadcast server).
* The state is **not saved** — toggling off and on is fire-and-forget per connection.
* Log entries are stored **server-side only**; the device does not buffer them locally.
* Retention is **1000 entries per device**, trimmed automatically on insert.
