mirror of
https://github.com/espressif/esptool.git
synced 2025-10-14 19:28:40 +08:00
feat(verbosity): Allow setting silent or verbose output levels
This commit is contained in:
@@ -468,11 +468,11 @@ Here is a sample extract, showing a READ_REG command and response:
|
||||
|
||||
::
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=1400f43f
|
||||
TRACE +0.000 Write 14 bytes: c0000a0400000000001400f43fc0
|
||||
TRACE +0.005 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 11 bytes: 010a0200620100000000c0
|
||||
TRACE +0.000 Received full packet: 010a0200620100000000
|
||||
TRACE +0.000 --- Cmd READ_REG (0x0a) | data_len 4 | wait_response 1 | timeout 3.000 | data 00100040 ---
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000000100040c0
|
||||
TRACE +0.046 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 11 bytes: 010a0200090000000000c0
|
||||
TRACE +0.000 Received full packet: 010a0200090000000000
|
||||
|
||||
The +X.XXX value is the time delta (in seconds) since the last trace line.
|
||||
|
||||
@@ -485,18 +485,18 @@ Here is a second example showing part of the initial synchronization sequence (l
|
||||
|
||||
::
|
||||
|
||||
TRACE +0.000 Write 46 bytes:
|
||||
c000082400000000 0007071220555555 | ...$........ UUU
|
||||
5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
|
||||
5555555555555555 5555555555c0 | UUUUUUUUUUUUU.
|
||||
TRACE +0.011 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 63 bytes:
|
||||
0108040007122055 00000000c0c00108 | ...... U........
|
||||
0400071220550000 0000c0c001080400 | .... U..........
|
||||
0712205500000000 c0c0010804000712 | .. U............
|
||||
205500000000c0c0 01080400071220 | U............
|
||||
TRACE +0.000 Received full packet: 010804000712205500000000
|
||||
TRACE +0.000 Received full packet: 010804000712205500000000
|
||||
TRACE +0.000 Write 46 bytes:
|
||||
c000082400000000 0007071220555555 | ...$........ UUU
|
||||
5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
|
||||
5555555555555555 5555555555c0 | UUUUUUUUUUUUU.
|
||||
TRACE +0.012 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 63 bytes:
|
||||
0108040007071220 00000000c0c00108 | ....... ........
|
||||
0400070712200000 0000c0c001080400 | ..... ..........
|
||||
0707122000000000 c0c0010804000707 | ... ............
|
||||
122000000000c0c0 01080400070712 | . .............
|
||||
TRACE +0.000 Received full packet: 010804000707122000000000
|
||||
TRACE +0.000 Received full packet: 010804000707122000000000
|
||||
|
||||
.. important::
|
||||
|
||||
|
@@ -162,3 +162,30 @@ at least one FilterValue for each specified FilterType to be considered. Example
|
||||
* ``--port-filter serial=7c98d1065267ee11bcc4c8ab93cd958c`` matches ports where the serial number contains the specified text.
|
||||
|
||||
See also the `Espressif USB customer-allocated PID repository <https://github.com/espressif/usb-pids>`_
|
||||
|
||||
Output Verbosity
|
||||
----------------
|
||||
|
||||
Output verbosity can be controlled using the ``--verbose`` and ``--silent`` flags.
|
||||
|
||||
Verbose output: ``--verbose``, ``-v``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. _verbose:
|
||||
|
||||
The ``--verbose``, ``-v`` flag can be used to show all output without any overwriting or collapsing stages into a single line:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
esptool.py --verbose flash-id
|
||||
|
||||
See :ref:`the trace option <tracing-communications>` if you want to dump all serial interactions to the standard output for debugging purposes.
|
||||
|
||||
Silent output: ``--silent``, ``-s``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. _silent:
|
||||
|
||||
The ``--silent``, ``-s`` flag can be used to limit the output to errors only:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
esptool.py -s write-flash 0x0 image.bin
|
||||
|
@@ -328,6 +328,10 @@ Esptool allows redirecting output by implementing a custom logger class. This ca
|
||||
percent = f"{100 * (cur_iter / float(total_iters)):.1f}"
|
||||
self.print(f"Finished: {percent}%")
|
||||
|
||||
def set_verbosity(self, verbosity):
|
||||
# Set verbosity level not needed in this example
|
||||
pass
|
||||
|
||||
# Replace the default logger with the custom logger
|
||||
log.set_logger(CustomLogger())
|
||||
|
||||
@@ -344,9 +348,10 @@ To ensure compatibility with esptool, the custom logger should re-implement (or
|
||||
- ``error``: Logs error messages.
|
||||
- ``stage``: Starts or ends a collapsible output stage.
|
||||
- ``progress_bar``: Displays a progress bar.
|
||||
- ``set_verbosity``: Sets the verbosity level for logging.
|
||||
|
||||
.. autoclass:: esptool.logger.EsptoolLogger
|
||||
:members: print, note, warning, error, stage, progress_bar
|
||||
:members: print, note, warning, error, stage, progress_bar, set_verbosity
|
||||
:member-order: bysource
|
||||
|
||||
These methods are essential for maintaining proper integration and behavior with esptool. Additionally, all output printing should be made using ``log.print()`` (or the respective method, such as ``log.info()`` or ``log.warning()``) instead of the standard ``print()`` function to ensure the output is routed through the custom logger. This ensures consistency and allows the custom logger to handle all output appropriately. You can further customize this logger to fit your application's needs, such as integrating with GUI components or advanced logging frameworks.
|
||||
|
@@ -364,6 +364,18 @@ def check_flash_size(esp: ESPLoader, address: int, size: int) -> None:
|
||||
is_flag=True,
|
||||
help="Enable trace-level output of esptool.py interactions.",
|
||||
)
|
||||
@click.option(
|
||||
"--verbose",
|
||||
"-v",
|
||||
is_flag=True,
|
||||
help="Print all output, disable collapsing output stages.",
|
||||
)
|
||||
@click.option(
|
||||
"--silent",
|
||||
"-s",
|
||||
is_flag=True,
|
||||
help="Silence all output except for errors.",
|
||||
)
|
||||
@click.option(
|
||||
"--override-vddsdio",
|
||||
type=click.Choice(ESP32ROM.OVERRIDE_VDDSDIO_CHOICES),
|
||||
@@ -383,6 +395,18 @@ def cli(
|
||||
):
|
||||
ctx.ensure_object(dict)
|
||||
ctx.obj.update(kwargs)
|
||||
if ctx.obj["verbose"] and ctx.obj["silent"]:
|
||||
raise FatalError(
|
||||
"Cannot use both --verbose and --silent options at the same time."
|
||||
)
|
||||
if ctx.obj["trace"] and ctx.obj["silent"]:
|
||||
raise FatalError(
|
||||
"Cannot use both --trace and --silent options at the same time."
|
||||
)
|
||||
if ctx.obj["verbose"]:
|
||||
log.set_verbosity("verbose")
|
||||
elif ctx.obj["silent"]:
|
||||
log.set_verbosity("silent")
|
||||
ctx.obj["invoked_subcommand"] = ctx.invoked_subcommand
|
||||
ctx.obj["esp"] = getattr(ctx, "esp", None)
|
||||
log.print(f"esptool.py v{__version__}")
|
||||
|
@@ -57,6 +57,13 @@ class TemplateLogger(ABC):
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def set_verbosity(self, verbosity: str):
|
||||
"""
|
||||
Set the verbosity level.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class EsptoolLogger(TemplateLogger):
|
||||
ansi_red: str = ""
|
||||
@@ -72,6 +79,8 @@ class EsptoolLogger(TemplateLogger):
|
||||
_kept_lines: list[str] = []
|
||||
|
||||
_smart_features: bool = False
|
||||
_verbosity: str | None = None
|
||||
_print_anyway: bool = False
|
||||
|
||||
def __new__(cls):
|
||||
"""
|
||||
@@ -79,7 +88,7 @@ class EsptoolLogger(TemplateLogger):
|
||||
"""
|
||||
if not hasattr(cls, "instance"):
|
||||
cls.instance = super(EsptoolLogger, cls).__new__(cls)
|
||||
cls.instance._set_smart_features()
|
||||
cls.instance.set_verbosity("auto")
|
||||
return cls.instance
|
||||
|
||||
@classmethod
|
||||
@@ -138,6 +147,8 @@ class EsptoolLogger(TemplateLogger):
|
||||
"""
|
||||
Log a plain message. Count newlines if in a collapsing stage.
|
||||
"""
|
||||
if self._verbosity == "silent" and not self._print_anyway:
|
||||
return
|
||||
if self._stage_active:
|
||||
# Count the number of newlines in the message
|
||||
message = "".join(map(str, args))
|
||||
@@ -145,12 +156,12 @@ class EsptoolLogger(TemplateLogger):
|
||||
if kwargs.get("end", "\n") == "\n":
|
||||
self._newline_count += 1
|
||||
print(*args, **kwargs)
|
||||
self._print_anyway = False
|
||||
|
||||
def note(self, message: str):
|
||||
"""
|
||||
Log a Note: message in blue and white.
|
||||
"""
|
||||
|
||||
formatted_message = f"{self.ansi_blue}Note:{self.ansi_normal} {message}"
|
||||
if self._stage_active:
|
||||
self._kept_lines.append(formatted_message)
|
||||
@@ -160,7 +171,6 @@ class EsptoolLogger(TemplateLogger):
|
||||
"""
|
||||
Log a Warning: message in yellow and white.
|
||||
"""
|
||||
|
||||
formatted_message = f"{self.ansi_yellow}Warning:{self.ansi_normal} {message}"
|
||||
if self._stage_active:
|
||||
self._kept_lines.append(formatted_message)
|
||||
@@ -170,8 +180,8 @@ class EsptoolLogger(TemplateLogger):
|
||||
"""
|
||||
Log an error message in red to stderr.
|
||||
"""
|
||||
|
||||
formatted_message = f"{self.ansi_red}{message}{self.ansi_normal}"
|
||||
self._print_anyway = True
|
||||
self.print(formatted_message, file=sys.stderr)
|
||||
|
||||
def stage(self, finish: bool = False):
|
||||
@@ -182,7 +192,6 @@ class EsptoolLogger(TemplateLogger):
|
||||
Warnings and notes will be saved and printed at the end of the stage.
|
||||
If terminal doesn't support ANSI escape codes, no collapsing happens.
|
||||
"""
|
||||
|
||||
if finish:
|
||||
if not self._stage_active:
|
||||
return
|
||||
@@ -219,7 +228,6 @@ class EsptoolLogger(TemplateLogger):
|
||||
Call in a loop to print a progress bar overwriting itself in place.
|
||||
If terminal doesn't support ANSI escape codes, no overwriting happens.
|
||||
"""
|
||||
|
||||
filled = int(bar_length * cur_iter // total_iters)
|
||||
if filled == bar_length:
|
||||
bar = "=" * bar_length
|
||||
@@ -238,5 +246,28 @@ class EsptoolLogger(TemplateLogger):
|
||||
def set_logger(self, new_logger):
|
||||
self.__class__ = new_logger.__class__
|
||||
|
||||
def set_verbosity(self, verbosity: str):
|
||||
"""
|
||||
Set the verbosity level to one of the following:
|
||||
- "auto": Enable smart terminal features and colors if supported by the terminal
|
||||
- "verbose": Enable verbose output (no collapsing output)
|
||||
- "silent": Disable all output except errors
|
||||
- "compact": Enable smart terminal features and colors even if not supported
|
||||
"""
|
||||
if verbosity == self._verbosity:
|
||||
return
|
||||
|
||||
self._verbosity = verbosity
|
||||
if verbosity == "auto":
|
||||
self._set_smart_features()
|
||||
elif verbosity == "verbose":
|
||||
self._set_smart_features(override=False)
|
||||
elif verbosity == "silent":
|
||||
pass
|
||||
elif verbosity == "compact":
|
||||
self._set_smart_features(override=True)
|
||||
else:
|
||||
raise ValueError(f"Invalid verbosity level: {verbosity}")
|
||||
|
||||
|
||||
log = EsptoolLogger()
|
||||
|
@@ -42,6 +42,9 @@ class CustomLogger(TemplateLogger):
|
||||
):
|
||||
pass
|
||||
|
||||
def set_verbosity(self, verbosity: str):
|
||||
pass
|
||||
|
||||
|
||||
# Custom logger that doesn't implement all methods
|
||||
class CustomLoggerIncomplete:
|
||||
|
Reference in New Issue
Block a user