Skip to content
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

Unify logging implementations and remove simplelog #10686

Merged
merged 6 commits into from Aug 25, 2020

Conversation

gshuflin
Copy link
Contributor

@gshuflin gshuflin commented Aug 24, 2020

Problem

There are several inconsistencies and problems with pants logging at the moment. One is that (cf. #10646 ) the logging Rust crate currently uses two separate and slightly-different methods to output logs - a custom log string if pants is displaying stderr logs when the dynamic UI is active; and a custom wrapper around the simplelog::WriteLogger when writing logs to a file or displaying stderr logs when the dynamic UI is inactive.

Another issue is that Rust logging can sometimes be the source of deadlocks. Many pants log statements log the string representation of a Value type, which represents a Python object and calls into Python code to determine its string representation, which requires grabbing the Python GIL. WriteLogger uses a lock internally around its handle to a Write-implementing value, which can interfere with grabbing the GIL in the Display implementation of Value, causing deadlocks if we display log messages frequently enough.

Solution

This commit fixes both the inconsistency issue and the deadlocking issue by unifying the logging implementations in logger.rs and removing our MaybeWriteLogger wrapper around simplelog::WriteLogger entirely. Now, the custom log string built for the dynamic UI stderr logging case is the only log format string in use; and since we compute this string before grabbing the lock to a file (and remove the lock entirely for stderr), we avoid the deadlocks we were seeing.

@coveralls
Copy link

coveralls commented Aug 24, 2020

Coverage Status

Coverage remained the same at 0.0% when pulling 853783d on gshuflin:change_logger into 25e52af on pantsbuild:master.

[ci skip-build-wheels]
And just write the log string to stderr

[ci skip-build-wheels]
it's always stderr, and is ignored by the rust logging code anyway

Also fix a failing test

[ci skip-build-wheels]
@gshuflin gshuflin changed the title Unify logging implementations Unify logging implementations and remove simplelog Aug 25, 2020
@gshuflin gshuflin marked this pull request as ready for review August 25, 2020 00:38
Destination::Pantsd => {
let mut maybe_file = self.log_file.lock();
if let Some(ref mut file) = *maybe_file {
match writeln!(file, "{}", log_string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just use write_all? Won't the macro copy log_string and then write (which is redundant)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so. writeln! invokes write! which in turn invokes the format_args macro (https://doc.rust-lang.org/src/core/macros/mod.rs.html#414-416), which is a compiler builtin (https://doc.rust-lang.org/src/core/macros/mod.rs.html#789-792). Then Write::write_fmt is called with the Arguments structure created by the format_args( https://doc.rust-lang.org/src/core/macros/mod.rs.html#789-792). I don't think any of the types involved in this process are actually cloning log_string, and even if they were it's something I think the compiler is smart enough to optimize out.
write_all would also work for writing the string to the file, this way just makes it marginally easier to include the trailing newline.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems unnecessary though to invoke the macro and its attendant logic when you could just write_all. Regarding the newline, just adding a \n to the let log_string = format!("{} {} {}", time_str, level_marker, record.args()); would take care of that, correct?

Copy link
Contributor

Choose a reason for hiding this comment

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

(versus reasoning about what the macro may or may not do)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems unnecessary though to invoke the macro and its attendant logic when you could just write_all. Regarding the newline, just adding a \n to the let log_string = format!("{} {} {}", time_str, level_marker, record.args()); would take care of that, correct?

Yeah but that would add a newline in the dynamic UI case, which we don't want. It would be easy enough to just have two calls to write_all in the Destination::Pantsd block of the match, where the second one is just write_all(&['\n' as u8]). But this is exactly the sort of thing the writeln! macro is meant for, and in this case I think it makes the code clearer.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ack.

@gshuflin gshuflin merged commit 8ad2bfc into pantsbuild:master Aug 25, 2020
@gshuflin gshuflin deleted the change_logger branch August 25, 2020 05:35
Copy link
Contributor

@Eric-Arellano Eric-Arellano left a comment

Choose a reason for hiding this comment

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

Excellent! Thanks Greg. There are some stale comment in the Rust code that I'll fix.

Eric-Arellano added a commit that referenced this pull request Aug 28, 2020
Some of the comments are stale post #10686.

[ci skip-build-wheels]
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.

None yet

4 participants