Skip to content

Improve Logging Documentation with Overview#140

Open
danielkent-net wants to merge 7 commits into
esphome:mainfrom
danielkent-net:improve-logging-docs
Open

Improve Logging Documentation with Overview#140
danielkent-net wants to merge 7 commits into
esphome:mainfrom
danielkent-net:improve-logging-docs

Conversation

@danielkent-net

Copy link
Copy Markdown

Summary

This PR adds a high-level overview of the logging framework, intended for developers or advanced users of ESPHome who need a better understanding of the underlying logging framework for development or advanced troubleshooting. I wrote this in response to some challenges I had figuring out how to get serial logs for troubleshooting. The existing logging documentation is moved into a "best practices" page, as that is the topic the existing page mainly covers.

I also added a brief mention in best practices regarding component state change logging (i.e., don't, as it's already covered client-side).

Specific Feedback Requested

  1. For USB to UART, I mention the RP2040 Debug Probe, which I have confirmed works well for getting serial logs on both RP2040 and ESP32 based ESPHome devices. I'm sure there's similar hardware/custom ESP32 firmware that works, but I have no experience with trying any of these out. If there is a specific firmware we can recommend, I think this would be helpful to add.

  2. I've never used MQTT before, and I'm unsure if there's anything to know about MQTT-based logs that don't already apply to network-based logging in general (i.e., it won't work if the network is up, sometimes early pre-network log messages get dropped, etc.)

@netlify

netlify Bot commented May 3, 2026

Copy link
Copy Markdown

Deploy Preview for esphome-dev-docs ready!

Name Link
🔨 Latest commit 22ecd88
🔍 Latest deploy log https://app.netlify.com/projects/esphome-dev-docs/deploys/6a0dd8aebc18c40008a888fc
😎 Deploy Preview https://deploy-preview-140--esphome-dev-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new high-level overview page for ESPHome's logging framework aimed at developers/advanced users, restructures the navigation to group logging docs under a new section, and augments the (renamed) best-practices page with guidance against logging component state changes.

Changes:

  • Add docs/architecture/logging/overview.md covering ESP_LOG macro usage, log levels, and how to obtain logs via serial / network API / MQTT.
  • Update docs/architecture/logging/best_practices.md (renamed location) with a new "Logging State Changes: Don't" section and minor wording tweaks.
  • Update mkdocs.yml navigation to introduce a Logging subsection with Overview and Best Practices pages.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 11 comments.

File Description
mkdocs.yml Adds the new Logging subsection grouping the overview and best-practices pages.
docs/architecture/logging/overview.md New overview document for ESPHome logging framework.
docs/architecture/logging/best_practices.md Adds state-change logging guidance and minor wording/formatting cleanup.
Comments suppressed due to low confidence (1)

docs/architecture/logging/best_practices.md:58

  • "irregardless" is non-standard; use "regardless".

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/architecture/logging/overview.md Outdated

`void ESP_LOGD(const char * TAG, const char * msg, void **margs)`

`TAG` is usually defined in a component's header and/or at the top of the source code file as a
Comment thread docs/architecture/logging/overview.md Outdated

The `ESP_LOG` macro is available to perform all of the necessary log functions in a space- and processing-efficient manner. The macro has the following signature (using the `DEBUG` log channel):

`void ESP_LOGD(const char * TAG, const char * msg, void **margs)`
Comment thread docs/architecture/logging/overview.md Outdated
this->update_interval_,
this->samples_,
this->get_mode_str());
}
Comment thread docs/architecture/logging/overview.md Outdated
Comment thread docs/architecture/logging/overview.md Outdated
can then connect to your computer using:

- A deducated USB to UART adapter, or
- An [RP2040 Debug Probe](https://www.raspberrypi.com/products/debug-probe/) or another RP2040 device such as a Raspberry Pi Pico loaded with [debug probe firmware](github.com/raspberrypi/debugprobe). This will work for any UART-capable ESPHome device, not just RP2040 devices.
Comment thread docs/architecture/logging/overview.md Outdated
- `VERBOSE` (`ESP_LOGV()`): Messages that don't normally need to be seen but may add value when troubleshooting or preparing/commissioning a new device/configuration.
- `VERY_VERBOSE` (`ESP_LOGVV()`): Detailed technical information, such as the content of data packets/messages being processed and/or processing state/status.

By default, `DEBUG` is the lowest severity level message type that are logged. To log less verbose messages, change the `logger` component's `level` to the desired log level, recompile, and reflash the firmware onto the device.
Comment thread docs/architecture/logging/overview.md Outdated
Comment on lines +64 to +93
## Obtaining Log Data

In general, you can use `esphome logs` to retrieve real-time logs from a running ESPHome device over serial or the network API:

```bash
esphome logs path/to/configuration.yaml
```

If both network and serial connections for a single device are available, or if multiple devices are connected over serial, `esphome` will give you a choice of connection. You can automatically select the correct device using the `--device` flag:

```bash
esphome logs --device 192.168.1.111 path/to/configuration.yaml
esphome logs --device ttyACM1 path/to/configuration.yaml
```

!!! important "Missing Logs over Network API"
Some problems may be difficult to troubleshoot when using the Network API, either due to the errors occurring well before the device network stack is initialized, or if the network stack itself is causing an issue. If this is the case, you may need to use hardware serial to obtain logs.


To retrieve logs over serial, you can either configure your hardware's USB CDC if it has such hardware, or configure your device to use specific UART pins, which you
can then connect to your computer using:

- A deducated USB to UART adapter, or
- An [RP2040 Debug Probe](https://www.raspberrypi.com/products/debug-probe/) or another RP2040 device such as a Raspberry Pi Pico loaded with [debug probe firmware](github.com/raspberrypi/debugprobe). This will work for any UART-capable ESPHome device, not just RP2040 devices.

If your logs look garbled, make sure that your PC UART interface baud rate is
the same baud rate as your ESPHome device UART (default is 115200), and that
both your interface and device have a shared ground connection.

### Over MQTT
Comment on lines +24 to +30
A full example of a `VERBOSE` log message:
```c++
// Constant TAG placed somewhere in your source or header file
static const char *const TAG = "component_name";
// ...
ESP_LOGV(TAG, "Received data: %d", recv_data);
```
Comment thread docs/architecture/logging/overview.md Outdated
- `ERROR` (`ESP_LOGE()`): Indicates problems that prevent the ESPHome device from working correctly.
- `WARN` (`ESP_LOGW()`): Warnings are recoverable issues like invalid sensor readings.
- `INFO` (`ESP_LOGI()`): Informational messages that may be useful to a non-technically savvy user
- `DEBUG` (`ESP_LOGD()`): Messages that are important for normal device information.
Comment thread docs/architecture/logging/overview.md Outdated
@bdraco

bdraco commented May 16, 2026

Copy link
Copy Markdown
Member

@bluetoothbot review

@bluetoothbot

Copy link
Copy Markdown

PR Review — Improve Logging Documentation with Overview

The restructure into logging/overview.md + logging/best_practices.md is a sound improvement and the nav change is correct. The new overview, however, has a couple of factual errors that need fixing before merge: the documented ESP_LOG* macro signature is wrong (they are variadic macros, not a function taking void **margs), and the explanation of how to change logger: level: is framed backwards relative to the most common user goal (seeing more verbose output during troubleshooting). The page also contains a truncated sentence, a stray } in a code example, a missing URL scheme, and several smaller copy-edit issues (typos, terminology drift between "channels" and "levels", heading-hierarchy inconsistency for MQTT vs. the other transports). On the best-practices side, the new "don't log state changes" rule is useful but would benefit from spelling out which entity types it covers and why (perf), plus fixing "irregardless". For the author's specific questions: (a) on the RP2040 Debug Probe — that recommendation is fine and broadly applicable; you could also mention generic CP2102/CH340/FTDI USB-UART adapters as the commodity option, and ESP-PROG for ESP32; (b) on MQTT — the current treatment is thin but accurate as far as it goes; worth adding a line that MQTT log delivery requires the network and broker to be up, so it has the same early-boot blind spot as the API and is not a substitute for serial when diagnosing pre-network failures.


🔴 Blocking

1. Inaccurate `ESP_LOG*` macro signature (`docs/architecture/logging/overview.md`, L20)

The signature void ESP_LOGD(const char * TAG, const char * msg, void **margs) is factually wrong and will mislead developers writing components. ESP_LOG* are variadic preprocessor macros that wrap a printf-style formatter — they are not C functions, and the trailing argument is not void **margs. Show the actual variadic shape so readers don't try to call them with a void ** array.

Suggested replacement:

ESP_LOGD(TAG, format, ...);

or, with brief callouts:

  • TAGstatic const char *const identifier shown in the log line
  • format — printf-style format string
  • ... — values substituted into format
`void ESP_LOGD(const char * TAG, const char * msg, void **margs)`
2. Truncated sentence describing `TAG` (`docs/architecture/logging/overview.md`, L22)

The sentence ends mid-thought: "TAG is usually defined in a component's header and/or at the top of the source code file as a ". The expected continuation is presumably something like "...as a static const char *const, e.g." — please finish it so the section reads coherently. The example block immediately below (lines 25-30) shows the right pattern; just make the prose match.

`TAG` is usually defined in a component's header and/or at the top of the source code file as a 

🟡 Important

1. Backwards framing of log-level configuration (`docs/architecture/logging/overview.md`, L62)

Two problems on this line:

  1. Subject/verb agreement: "message type that are logged" → "message type that is logged".
  2. The framing is backwards for the most common case. The default level DEBUG already includes ERROR/WARN/INFO/DEBUG; users editing logger: level: are almost always trying to see more verbose output (VERBOSE/VERY_VERBOSE) when troubleshooting, not less. As written ("To log less verbose messages, change the logger component's level...") it implies the opposite of the typical workflow.

Suggested rewrite:

By default, DEBUG is the most verbose level emitted; VERBOSE and VERY_VERBOSE messages are suppressed. To see additional detail, lower the threshold (level: VERBOSE or level: VERY_VERBOSE). To reduce output to only warnings/errors, raise it (level: WARN, level: ERROR). After changing the level, recompile and reflash.

By default, `DEBUG` is the lowest severity level message type that are logged. To log less verbose messages, change the `logger` component's `level` to the desired log level, recompile, and reflash the firmware onto the device.
2. Multi-line example has stray `}` and inconsistent indentation (`docs/architecture/logging/overview.md`, L33-45)

The snippet opens with no function header but closes with a } on line 44. Readers copying this verbatim will paste an unmatched brace. Either wrap the example in a representative function body (void MyComponent::update() { ... }) so the } is justified, or drop the } so the snippet is a clean standalone statement. The leading two-space indent on the ESP_LOGV call is also inconsistent with the simple example above (lines 26-29) and should be flush-left if presented standalone.

  ESP_LOGV(TAG,
           "Device properties updated:\n"
           ...
            this->get_mode_str());
}
3. Debug probe firmware URL missing scheme (`docs/architecture/logging/overview.md`, L87)

[debug probe firmware](github.com/raspberrypi/debugprobe) lacks the https:// scheme. MkDocs will treat this as a relative path and produce a broken link in the rendered docs. Replace with https://github.com/raspberrypi/debugprobe.

[debug probe firmware](github.com/raspberrypi/debugprobe)
4. Incomplete INFO and weak DEBUG descriptions (`docs/architecture/logging/overview.md`, L57-58)

Two adjacent issues in the level list:

  • Line 57 (INFO): the description ends mid-sentence with a trailing space and no terminal punctuation: "Informational messages that may be useful to a non-technically savvy user ". Complete the thought and add a period.
  • Line 58 (DEBUG): "Messages that are important for normal device information." is awkward and doesn't differentiate DEBUG from INFO. Since DEBUG is the default level, its description should make clear what a typical user sees — e.g. "Diagnostic detail useful when developing or troubleshooting a component; the default level."
 - `INFO` (`ESP_LOGI()`): Informational messages that may be useful to a non-technically savvy user 
 - `DEBUG` (`ESP_LOGD()`): Messages that are important for normal device information.

🟢 Suggestions

1. Typo: "deducated" (`docs/architecture/logging/overview.md`, L86)

"A deducated USB to UART adapter" → "A dedicated USB to UART adapter".

- A deducated USB to UART adapter, or
2. "Channels" vs "levels" — terminology drift (`docs/architecture/logging/overview.md`, L47-53)

The section heading is ## Log Levels, the configuration key is level:, and the rest of the document uses "log level". The body, however, calls them "log channels" (lines 48 and 53) and the ESP_LOG macro intro on line 18 says "using the DEBUG log channel". This is unusual terminology in the ESP-IDF / ESPHome ecosystem and inconsistent within the same page. Recommend standardising on "log level" everywhere. Also, ESP_LOGCONFIG is best described as another level (it has its own filter behavior tied to dump_config()), not a separate kind of "channel".

ESPHome has seven log channels: one for configuration, and six for runtime messages of varying verbosity and severity.
3. Heading hierarchy inconsistent across transports (`docs/architecture/logging/overview.md`, L64-93)

Under ## Obtaining Log Data you have prose for esphome logs (network API + serial) running flat, then a sudden ### Over MQTT subheading. To a reader scanning the TOC, this looks like MQTT is the only transport with its own subsection. Either:

  1. Add sibling ### Over the Network API and ### Over Serial / UART subsections so all three transports are at the same heading level, or
  2. Drop ### Over MQTT and demote that paragraph to inline prose alongside the others.

Option 1 will also make the page deep-linkable (e.g. linking to #over-serial from troubleshooting docs).

### Over MQTT
4. "irregardless" → "regardless" (`docs/architecture/logging/best_practices.md`, L58)

"irregardless" is non-standard / a double negative. Use "regardless" in technical documentation.

messages into log output irregardless of sensor log level
5. Clarify scope and rationale of the "don't log state changes" rule (`docs/architecture/logging/best_practices.md`, L52-60)

Two small improvements would make this guidance land harder:

  1. Scope. The rule says "Component code should not include any log calls for state changes" but the supporting text only mentions "Sensor state changes". Does this apply equally to binary_sensor, switch, light, cover, text_sensor, etc.? aioesphomeapi does emit state messages for all of those, so the rule probably applies broadly — but say so explicitly, or scope the rule to "sensor-style entities whose state is published through the API".
  2. Rationale tie-in. The surrounding page is about performance overhead. Naming the cost here (duplicate work on every publish, wasted flash for log strings on a hot path, and noise in the client log) ties the rule to the page's theme and helps developers reason about edge cases (e.g. transient internal state during a multi-step transition, which is not what aioesphomeapi surfaces and may legitimately warrant a VERBOSE log).
### Logging State Changes: Don't

Component code should **not** include any log calls for state changes.
6. Missing blank line after `## Log Levels` heading (`docs/architecture/logging/overview.md`, L47-48)

## Log Levels is immediately followed by a paragraph on the next line with no blank line between. Most CommonMark parsers (and MkDocs Material) tolerate this, but the rest of the file consistently uses a blank line after headings — add one here for consistency and to avoid surprising any stricter renderer.

## Log Levels
ESPHome has seven log channels: one for configuration, and six for runtime messages of varying verbosity and severity.

Checklist

  • No hardcoded secrets
  • Documentation is technically accurate — critical #1, warning #3
  • Sentences and code examples are complete — critical #2, warning #4
  • Links render correctly — warning #5
  • Terminology is consistent within the document — suggestion #3
  • Heading hierarchy is consistent — suggestion #4
  • Spelling and grammar — warning #6, suggestion #1, suggestion #5
  • mkdocs.yml nav matches new file layout

Summary

The restructure into logging/overview.md + logging/best_practices.md is a sound improvement and the nav change is correct. The new overview, however, has a couple of factual errors that need fixing before merge: the documented ESP_LOG* macro signature is wrong (they are variadic macros, not a function taking void **margs), and the explanation of how to change logger: level: is framed backwards relative to the most common user goal (seeing more verbose output during troubleshooting). The page also contains a truncated sentence, a stray } in a code example, a missing URL scheme, and several smaller copy-edit issues (typos, terminology drift between "channels" and "levels", heading-hierarchy inconsistency for MQTT vs. the other transports). On the best-practices side, the new "don't log state changes" rule is useful but would benefit from spelling out which entity types it covers and why (perf), plus fixing "irregardless". For the author's specific questions: (a) on the RP2040 Debug Probe — that recommendation is fine and broadly applicable; you could also mention generic CP2102/CH340/FTDI USB-UART adapters as the commodity option, and ESP-PROG for ESP32; (b) on MQTT — the current treatment is thin but accurate as far as it goes; worth adding a line that MQTT log delivery requires the network and broker to be up, so it has the same early-boot blind spot as the API and is not a substitute for serial when diagnosing pre-network failures.


Automated review by Kōan0a9a4c1
b49fc62
95ec5fc
489b2ab
9f74a7a
534a46b

@jesserockz

Copy link
Copy Markdown
Member

@esphbot review

@esphbot

esphbot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

PR Review — Improve Logging Documentation with Overview

Solid restructure; the earlier critical errors are fixed, only copy-edit polish remains.

  • The macro signature is now correctly shown as variadic (..., ) and the truncated TAG sentence is complete — the two blocking issues from prior reviews are resolved.
  • One real rendering bug remains: "DEBUGlevel" is missing a space (overview.md).
  • Copy-edit items: "irregardless" → "regardless", "channels" vs "levels" terminology drift, and missing blank lines around the ## Log Levels heading.
  • Content suggestion: the "don't log state changes" rule should state which entity types it covers and tie the reasoning to the page's performance theme.
  • For the author's questions: the RP2040 Debug Probe recommendation is fine (could also mention commodity CP2102/CH340/FTDI adapters and ESP-PROG for ESP32); MQTT logging needs the network + broker up, so it shares the API's early-boot blind spot and is not a serial substitute.
  • No blocking issues — all remaining items are non-blocking polish.

🟡 Important

1. Missing space: "`DEBUG`level" (`docs/architecture/logging/overview.md`, L66)

The inline code span and the following word are run together, so this renders as "DEBUGlevel message types".

Add a space after the closing backtick:

By default, ERROR, WARN, INFO, and DEBUG level message types are logged...

By default, `ERROR`, `WARN`, `INFO`, and `DEBUG`level message types are logged, and `ESP_LOGCONFIG` messages are always logged.

🟢 Suggestions

1. "irregardless" is non-standard (`docs/architecture/logging/best_practices.md`, L58)

Replace "irregardless" with "regardless" — it's widely considered non-standard and reads as an error in documentation. (The Copilot reviewer flagged the same thing.)

messages into log output irregardless of sensor log level (this behavior can be
2. Scope the "don't log state changes" rule and tie it to performance (`docs/architecture/logging/best_practices.md`, L52-59)

The rule says "Component code should not include any log calls for state changes" but the supporting text only mentions "Sensor state changes". aioesphomeapi emits state messages for binary_sensor, switch, light, cover, text_sensor, etc. too — so either say the rule applies broadly to all API-published entities, or scope it explicitly to sensor-style entities.

Two improvements:

  • Scope: name the entity types (or generalize to "any state published through the API") so readers know it isn't sensor-only.
  • Rationale: this page is about performance overhead. Naming the cost (duplicate work on every publish, wasted flash for log strings on a hot path, redundant noise in the client log) ties the rule to the page theme and clarifies the edge case where a transient internal state during a multi-step transition — which the API does not surface — may still legitimately warrant a VERBOSE log.
Component code should **not** include any log calls for state changes.
3. Missing blank lines around `## Log Levels` heading (`docs/architecture/logging/overview.md`, L50-52)

The ## Log Levels heading is jammed directly against the preceding code fence and the following paragraph with no blank lines on either side. MkDocs Material tolerates this, but the rest of the file consistently surrounds headings with blank lines — add one before and after for consistency and to avoid surprising stricter CommonMark renderers.

```
## Log Levels
ESPHome has six runtime logging channels, from `ERROR` to `VERY_VERBOSE`.
4. Terminology drift: "channels" vs "levels" (`docs/architecture/logging/overview.md`, L52)

The heading is ## Log Levels and the logger: config key is level:, but the body text calls them "logging channels" ("six runtime logging channels", "the channels are"). Pick one term — "levels" is consistent with the heading, the config key, and standard ESPHome terminology — and use it throughout.

ESPHome has six runtime logging channels, from `ERROR` to `VERY_VERBOSE`.

Checklist

  • Documentation is technically accurate
  • Sentences and code examples are complete
  • Inline code renders correctly — warning #1
  • Terminology is consistent within the document — suggestion #2
  • Heading hierarchy and spacing is consistent — suggestion #3
  • Spelling and grammar — suggestion #1
  • mkdocs.yml nav matches new file layout

To rebase specific severity levels, mention me: @esphbot rebase critical (fixes 🔴 only), @esphbot rebase important (fixes 🔴 + 🟡), or just @esphbot rebase for all.


Automated review by Kōan0a9a4c1
b49fc62
95ec5fc
489b2ab
9f74a7a
534a46b
22ecd88

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants