-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Using my_python_executable | head
caused a cascading error due to ignoring SIGPIPE error condition
#3400
Comments
This error condition occurred inside both xterm terminal (whose Python |
After taking out the $ # 2>&1 is used to fold the logging's default stderr into the stdout.
$ python logme.py 2>&1 | head
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
spam_application.auxiliary.Auxiliary: this should be main, before
sublogger: did I get the sublogger's name? |
This probably isn't a good solution, but for reference I put together a modified RichHandler based on this note in the python docs. It implements the /dev/null switching that you're looking for. I think handling the BrokenPipeError would be best placed here around the import os
from logging import LogRecord
import rich.logging
from rich.traceback import Traceback
from rich._null_file import NullFile
class RichHandler(rich.logging.RichHandler):
def emit(self, record: LogRecord) -> None:
"""Invoked by logging."""
message = self.format(record)
traceback = None
if (
self.rich_tracebacks
and record.exc_info
and record.exc_info != (None, None, None)
):
exc_type, exc_value, exc_traceback = record.exc_info
assert exc_type is not None
assert exc_value is not None
traceback = Traceback.from_exception(
exc_type,
exc_value,
exc_traceback,
width=self.tracebacks_width,
code_width=self.tracebacks_code_width,
extra_lines=self.tracebacks_extra_lines,
theme=self.tracebacks_theme,
word_wrap=self.tracebacks_word_wrap,
show_locals=self.tracebacks_show_locals,
locals_max_length=self.locals_max_length,
locals_max_string=self.locals_max_string,
suppress=self.tracebacks_suppress,
max_frames=self.tracebacks_max_frames,
)
message = record.getMessage()
if self.formatter:
record.message = record.getMessage()
formatter = self.formatter
if hasattr(formatter, "usesTime") and formatter.usesTime():
record.asctime = formatter.formatTime(record, formatter.datefmt)
message = formatter.formatMessage(record)
message_renderable = self.render_message(record, message)
log_renderable = self.render(
record=record, traceback=traceback, message_renderable=message_renderable
)
if isinstance(self.console.file, NullFile):
# Handles pythonw, where stdout/stderr are null, and we return NullFile
# instance from Console.file. In this case, we still want to make a log record
# even though we won't be writing anything to a file.
self.handleError(record)
else:
try:
self.console.print(log_renderable)
except BrokenPipeError:
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, self.console.file.fileno())
self.console.print(log_renderable)
except Exception:
self.handleError(record) |
Related discussion at PR #3233 |
Fixed in main |
I hope we solved your problem. If you like using Rich, you might also enjoy Textual |
When UNIX piping its output into a
head
executable, it outputs the next 10 line, then starts returning back a traceback for each log output.Otherwise, ideally, one would expect the
head
to close the PIPE and the application switch over to/dev/null
for all lines after the first 10 lines as shown below:Ideally, such SIGPIPE or close condition due to PIPE should be silently switching over to
/dev/null
on the remainder of its execution time after a file-connection-closed condition.Actually sends a traceback dump for every
logger
line until its completion.The first Traceback is unique from the rest and has RichHandler-related error.
then subsequential traceback shows application-specific errors with little or no RichHandler-related errors:
The minimal code example that demonstrates the issue is
my_test_code.py
file, its UNIX file mode set as an executable and is given below:Platform
Click to expand
Platform
╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface. │
│ │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ color_system = 'truecolor' │
│ encoding = 'utf-8' │
│ file = <_io.TextIOWrapper name='' mode='w' encoding='utf-8'> │
│ height = 26 │
│ is_alt_screen = False │
│ is_dumb_terminal = False │
│ is_interactive = True │
│ is_jupyter = False │
│ is_terminal = True │
│ legacy_windows = False │
│ no_color = False │
│ options = ConsoleOptions( │
│ size=ConsoleDimensions(width=128, height=26), │
│ legacy_windows=False, │
│ min_width=1, │
│ max_width=128, │
│ is_terminal=True, │
│ encoding='utf-8', │
│ max_height=26, │
│ justify=None, │
│ overflow=None, │
│ no_wrap=False, │
│ highlight=None, │
│ markup=None, │
│ height=None │
│ ) │
│ quiet = False │
│ record = False │
│ safe_box = True │
│ size = ConsoleDimensions(width=128, height=26) │
│ soft_wrap = False │
│ stderr = False │
│ style = None │
│ tab_size = 8 │
│ width = 128 │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭─── <class 'rich._windows.WindowsConsoleFeatures'> ────╮
│ Windows features available. │
│ │
│ ╭───────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │
│ ╰───────────────────────────────────────────────────╯ │
│ │
│ truecolor = False │
│ vt = False │
╰───────────────────────────────────────────────────────╯
╭────── Environment Variables ───────╮
│ { │
│ 'TERM': 'xterm-256color', │
│ 'COLORTERM': 'truecolor', │
│ 'CLICOLOR': None, │
│ 'NO_COLOR': None, │
│ 'TERM_PROGRAM': None, │
│ 'COLUMNS': None, │
│ 'LINES': None, │
│ 'JUPYTER_COLUMNS': None, │
│ 'JUPYTER_LINES': None, │
│ 'JPY_PARENT_PID': None, │
│ 'VSCODE_VERBOSE_LOGGING': None │
│ } │
╰────────────────────────────────────╯
platform="Linux"
rich==13.7.1
The text was updated successfully, but these errors were encountered: