mirror of
https://github.com/espressif/esptool.git
synced 2025-10-16 23:06:31 +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 --- Cmd READ_REG (0x0a) | data_len 4 | wait_response 1 | timeout 3.000 | data 00100040 ---
|
||||||
TRACE +0.000 Write 14 bytes: c0000a0400000000001400f43fc0
|
TRACE +0.000 Write 14 bytes: c0000a04000000000000100040c0
|
||||||
TRACE +0.005 Read 1 bytes: c0
|
TRACE +0.046 Read 1 bytes: c0
|
||||||
TRACE +0.000 Read 11 bytes: 010a0200620100000000c0
|
TRACE +0.000 Read 11 bytes: 010a0200090000000000c0
|
||||||
TRACE +0.000 Received full packet: 010a0200620100000000
|
TRACE +0.000 Received full packet: 010a0200090000000000
|
||||||
|
|
||||||
The +X.XXX value is the time delta (in seconds) since the last trace line.
|
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:
|
TRACE +0.000 Write 46 bytes:
|
||||||
c000082400000000 0007071220555555 | ...$........ UUU
|
c000082400000000 0007071220555555 | ...$........ UUU
|
||||||
5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
|
5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
|
||||||
5555555555555555 5555555555c0 | UUUUUUUUUUUUU.
|
5555555555555555 5555555555c0 | UUUUUUUUUUUUU.
|
||||||
TRACE +0.011 Read 1 bytes: c0
|
TRACE +0.012 Read 1 bytes: c0
|
||||||
TRACE +0.000 Read 63 bytes:
|
TRACE +0.000 Read 63 bytes:
|
||||||
0108040007122055 00000000c0c00108 | ...... U........
|
0108040007071220 00000000c0c00108 | ....... ........
|
||||||
0400071220550000 0000c0c001080400 | .... U..........
|
0400070712200000 0000c0c001080400 | ..... ..........
|
||||||
0712205500000000 c0c0010804000712 | .. U............
|
0707122000000000 c0c0010804000707 | ... ............
|
||||||
205500000000c0c0 01080400071220 | U............
|
122000000000c0c0 01080400070712 | . .............
|
||||||
TRACE +0.000 Received full packet: 010804000712205500000000
|
TRACE +0.000 Received full packet: 010804000707122000000000
|
||||||
TRACE +0.000 Received full packet: 010804000712205500000000
|
TRACE +0.000 Received full packet: 010804000707122000000000
|
||||||
|
|
||||||
.. important::
|
.. 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.
|
* ``--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>`_
|
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}"
|
percent = f"{100 * (cur_iter / float(total_iters)):.1f}"
|
||||||
self.print(f"Finished: {percent}%")
|
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
|
# Replace the default logger with the custom logger
|
||||||
log.set_logger(CustomLogger())
|
log.set_logger(CustomLogger())
|
||||||
|
|
||||||
@@ -344,9 +348,10 @@ To ensure compatibility with esptool, the custom logger should re-implement (or
|
|||||||
- ``error``: Logs error messages.
|
- ``error``: Logs error messages.
|
||||||
- ``stage``: Starts or ends a collapsible output stage.
|
- ``stage``: Starts or ends a collapsible output stage.
|
||||||
- ``progress_bar``: Displays a progress bar.
|
- ``progress_bar``: Displays a progress bar.
|
||||||
|
- ``set_verbosity``: Sets the verbosity level for logging.
|
||||||
|
|
||||||
.. autoclass:: esptool.logger.EsptoolLogger
|
.. 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
|
: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.
|
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,
|
is_flag=True,
|
||||||
help="Enable trace-level output of esptool.py interactions.",
|
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(
|
@click.option(
|
||||||
"--override-vddsdio",
|
"--override-vddsdio",
|
||||||
type=click.Choice(ESP32ROM.OVERRIDE_VDDSDIO_CHOICES),
|
type=click.Choice(ESP32ROM.OVERRIDE_VDDSDIO_CHOICES),
|
||||||
@@ -383,6 +395,18 @@ def cli(
|
|||||||
):
|
):
|
||||||
ctx.ensure_object(dict)
|
ctx.ensure_object(dict)
|
||||||
ctx.obj.update(kwargs)
|
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["invoked_subcommand"] = ctx.invoked_subcommand
|
||||||
ctx.obj["esp"] = getattr(ctx, "esp", None)
|
ctx.obj["esp"] = getattr(ctx, "esp", None)
|
||||||
log.print(f"esptool.py v{__version__}")
|
log.print(f"esptool.py v{__version__}")
|
||||||
|
@@ -57,6 +57,13 @@ class TemplateLogger(ABC):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def set_verbosity(self, verbosity: str):
|
||||||
|
"""
|
||||||
|
Set the verbosity level.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class EsptoolLogger(TemplateLogger):
|
class EsptoolLogger(TemplateLogger):
|
||||||
ansi_red: str = ""
|
ansi_red: str = ""
|
||||||
@@ -72,6 +79,8 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
_kept_lines: list[str] = []
|
_kept_lines: list[str] = []
|
||||||
|
|
||||||
_smart_features: bool = False
|
_smart_features: bool = False
|
||||||
|
_verbosity: str | None = None
|
||||||
|
_print_anyway: bool = False
|
||||||
|
|
||||||
def __new__(cls):
|
def __new__(cls):
|
||||||
"""
|
"""
|
||||||
@@ -79,7 +88,7 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
"""
|
"""
|
||||||
if not hasattr(cls, "instance"):
|
if not hasattr(cls, "instance"):
|
||||||
cls.instance = super(EsptoolLogger, cls).__new__(cls)
|
cls.instance = super(EsptoolLogger, cls).__new__(cls)
|
||||||
cls.instance._set_smart_features()
|
cls.instance.set_verbosity("auto")
|
||||||
return cls.instance
|
return cls.instance
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -138,6 +147,8 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
"""
|
"""
|
||||||
Log a plain message. Count newlines if in a collapsing stage.
|
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:
|
if self._stage_active:
|
||||||
# Count the number of newlines in the message
|
# Count the number of newlines in the message
|
||||||
message = "".join(map(str, args))
|
message = "".join(map(str, args))
|
||||||
@@ -145,12 +156,12 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
if kwargs.get("end", "\n") == "\n":
|
if kwargs.get("end", "\n") == "\n":
|
||||||
self._newline_count += 1
|
self._newline_count += 1
|
||||||
print(*args, **kwargs)
|
print(*args, **kwargs)
|
||||||
|
self._print_anyway = False
|
||||||
|
|
||||||
def note(self, message: str):
|
def note(self, message: str):
|
||||||
"""
|
"""
|
||||||
Log a Note: message in blue and white.
|
Log a Note: message in blue and white.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
formatted_message = f"{self.ansi_blue}Note:{self.ansi_normal} {message}"
|
formatted_message = f"{self.ansi_blue}Note:{self.ansi_normal} {message}"
|
||||||
if self._stage_active:
|
if self._stage_active:
|
||||||
self._kept_lines.append(formatted_message)
|
self._kept_lines.append(formatted_message)
|
||||||
@@ -160,7 +171,6 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
"""
|
"""
|
||||||
Log a Warning: message in yellow and white.
|
Log a Warning: message in yellow and white.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
formatted_message = f"{self.ansi_yellow}Warning:{self.ansi_normal} {message}"
|
formatted_message = f"{self.ansi_yellow}Warning:{self.ansi_normal} {message}"
|
||||||
if self._stage_active:
|
if self._stage_active:
|
||||||
self._kept_lines.append(formatted_message)
|
self._kept_lines.append(formatted_message)
|
||||||
@@ -170,8 +180,8 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
"""
|
"""
|
||||||
Log an error message in red to stderr.
|
Log an error message in red to stderr.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
formatted_message = f"{self.ansi_red}{message}{self.ansi_normal}"
|
formatted_message = f"{self.ansi_red}{message}{self.ansi_normal}"
|
||||||
|
self._print_anyway = True
|
||||||
self.print(formatted_message, file=sys.stderr)
|
self.print(formatted_message, file=sys.stderr)
|
||||||
|
|
||||||
def stage(self, finish: bool = False):
|
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.
|
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 terminal doesn't support ANSI escape codes, no collapsing happens.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if finish:
|
if finish:
|
||||||
if not self._stage_active:
|
if not self._stage_active:
|
||||||
return
|
return
|
||||||
@@ -219,7 +228,6 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
Call in a loop to print a progress bar overwriting itself in place.
|
Call in a loop to print a progress bar overwriting itself in place.
|
||||||
If terminal doesn't support ANSI escape codes, no overwriting happens.
|
If terminal doesn't support ANSI escape codes, no overwriting happens.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
filled = int(bar_length * cur_iter // total_iters)
|
filled = int(bar_length * cur_iter // total_iters)
|
||||||
if filled == bar_length:
|
if filled == bar_length:
|
||||||
bar = "=" * bar_length
|
bar = "=" * bar_length
|
||||||
@@ -238,5 +246,28 @@ class EsptoolLogger(TemplateLogger):
|
|||||||
def set_logger(self, new_logger):
|
def set_logger(self, new_logger):
|
||||||
self.__class__ = new_logger.__class__
|
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()
|
log = EsptoolLogger()
|
||||||
|
@@ -42,6 +42,9 @@ class CustomLogger(TemplateLogger):
|
|||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def set_verbosity(self, verbosity: str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Custom logger that doesn't implement all methods
|
# Custom logger that doesn't implement all methods
|
||||||
class CustomLoggerIncomplete:
|
class CustomLoggerIncomplete:
|
||||||
|
Reference in New Issue
Block a user