-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
[core] Use pipe to redirect stdout #49548
Conversation
Signed-off-by: dentiny <[email protected]>
e2f2050
to
2dad6b1
Compare
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
b3ef8de
to
3129f18
Compare
class PipeStreamWriteHandle(IO[AnyStr]): | ||
def __init__(self, write_fd: int, log_name: str): | ||
self.name = log_name | ||
self.write_fd = write_fd | ||
self.stream = os.fdopen(write_fd, "w") | ||
|
||
def name(self): | ||
return self.name | ||
|
||
def fileno(self): | ||
return self.write_fd | ||
|
||
def write(self, s: str) -> int: | ||
return self.stream.write(s) | ||
|
||
def flush(self): | ||
self.stream.flush() | ||
|
||
def close(self): | ||
self.stream.close() | ||
|
||
def isatty(self) -> bool: | ||
return False | ||
|
||
def readable(self) -> bool: | ||
return False | ||
|
||
def writable(self) -> bool: | ||
return True | ||
|
||
def seekable(self) -> bool: | ||
return False | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configure_log_file
only requires this object has fileno()
method not others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
write, flush, name, fileno is definitely needed --- I have met issues without any of them;
Others are suggested by gpt, didn't verify one by one.
My personal opinion is it doesn't hurt to implement these overloads;
- All these overload functions are straightforward and short enough
- Some attribute function help explain the class, i.e. readable and writable.
There're CI failure, I will take a look at daytime. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!!
Also, a minor general comment: probably we should also update the wiki page here
Ray supports log rotation of log files. Note that not all components support log rotation. (Raylet, Python, and Java worker logs do not rotate). |
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
|
||
atexit.register(cleanup) | ||
|
||
return pipe_write_stream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the PipeStreamWriteHandle
wrapper, can we directly return open(write_fd)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open
takes a path-like object, not a fd
Ref: https://docs.python.org/3/library/functions.html#open
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fdopen
is the interface we want to wrap fd into a file object
Ref: https://docs.python.org/3/library/os.html#os.fdopen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use fdopen
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How to you plan to provide name
and write
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. write()
I think is supported by the object returned by fdopen()
? The issue is name
then. I guess you can do
file_like_io_object = os.fdopen(write_fd)
file_like_io_object.name = "xxxx"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tried
Traceback (most recent call last):
File "logging_redirection_test.py", line 13, in <module>
_LOG_STDOUT_FNAME, _ROTATION_MAX_BYTE, _ROTATION_FILE_NUM)
File "/home/ubuntu/py-logging-redirection/pipe_logging.py", line 90, in open_pipe_with_rotation
pipe_write_stream.name = fname
AttributeError: attribute 'name' of '_io.TextIOWrapper' objects is not writable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code snippet:
pipe_write_stream = os.fdopen(write_fd, "w")
pipe_write_stream.name = fname
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we can do https://stackoverflow.com/questions/60622854/how-to-instantiate-an-io-textiowrapper-object-with-a-name-attribute so we don't need to implement our own IO
subclass with all these methods.
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
|
||
By default, logs rotate when they reach 512MB (maxBytes), and have a maximum of five backup files (backupCount). Indexes are appended to all backup files (e.g., `raylet.out.1`) | ||
To change the log rotation configuration, specify environment variables. For example, | ||
By default, ray doesn't rotate for internal components. To change the log rotation configuration, specify environment variables. For example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some files that we have rotation by default? What are they?
with cond: | ||
# An empty line is read over, which indicates write side has | ||
# closed. | ||
if line == _EOF_TOKEN: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need _EOF_TOKEN
? If you close the pipe, reader will know? readline()
should return empty string to indicate EOF.
read_thread = threading.Thread(target=read_log_content_from_pipe, daemon=True) | ||
dump_thread = threading.Thread(target=dump_log_content_to_buffer, daemon=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give these two threads name?
"log file, default is " | ||
f"{ray_constants.LOGGING_ROTATE_BYTES} bytes.", | ||
default=sys.maxsize, | ||
help="Specify the max bytes for rotating " "log file, default no rotation.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
help="Specify the max bytes for rotating " "log file, default no rotation.", | |
help="Specify the max bytes for rotating log file, default no rotation.", |
logger.info(cur_content) | ||
|
||
# Python `atexit` hook only invokes when no other non-daemon threads running. | ||
read_thread = threading.Thread(target=read_log_content_from_pipe, daemon=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually thinking more, I think it's better to implement these in C++ so that the same implementation can be used for all language frontends (e.g. python , java, c++). The current way only works for python workers. I think implementing in C++ should be too much harder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will create another PR implemented in C++, I will try to get it out before tomorrow.
A followup for oversized logging file. It supports rotated logging file via overriding stdout and stderr with logging module.
High-level abstract:
Update: This PR only does rotation for stdout files; as previous, stderr are less important compared with stdout, and much trickier to get right because more unit tests are listening to the stderr.
Closes #49563