-
Notifications
You must be signed in to change notification settings - Fork 13
refactor: refactor to spdlog-rs instead of tracing
#538
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
Conversation
|
Initially it looks good, but what I'm wondering is whether we should just replace the |
|
Yeah we should replace tracing with spdlog, current codes is just convenient for debugging. I'll delete the tracing codes after spdlog parts are good to go. |
SpriteOvO
left a comment
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 a brief look and most of it seems to be fine. I'll probably merge SpriteOvO/spdlog-rs#93 in the next couple days. In the meantime, you can try removing the use of tracing from oma entirely.
src/main.rs
Outdated
| let rotating_sink = if let Ok(log_file) = &log_file { | ||
| Some( | ||
| AsyncPoolSink::builder() | ||
| .sink(Arc::new( | ||
| RotatingFileSink::builder() | ||
| .base_path(&log_file) | ||
| .formatter(formatter.clone()) | ||
| .rotation_policy(RotationPolicy::Hourly) | ||
| .build() | ||
| .unwrap(), | ||
| )) | ||
| .overflow_policy(spdlog::sink::OverflowPolicy::DropIncoming) | ||
| .build() | ||
| .unwrap(), | ||
| ) | ||
| } else { | ||
| None | ||
| }; |
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.
The RotatingFileSink should not rotate hourly as oma did not do so. Could try RotationPolicy::FileSize(u64::MAX) and set max_files(config.save_log_count()).
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.
Fixed, file size is set to 10MB.
src/main.rs
Outdated
| .join("oma") | ||
| }; | ||
|
|
||
| let log_file = create_log_file(&log_dir); |
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.
Creating variants for filenames has been done internally by spdlog-rs, so oma no longer needs to create names manually.
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.
Fixed
|
FYI, SpriteOvO/spdlog-rs#93 is merged. |
|
I'll work on this PR tomorrow. |
|
|
3ef6995 to
95052c9
Compare
oma-console/src/print.rs
Outdated
| /// StdStreamSink::builder().formatter(Box::new(OmaLayer::default())).build().unwrap() | ||
| /// )).build().unwrap(); |
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.
It is preferred that unwrap() not be used inside an example, and some of the error handling components be hidden if they make the example too difficult to follow.
Quote from https://doc.rust-lang.org/rustdoc/write-documentation/what-to-include.html?highlight=unwrap#examples
oma-console/src/print.rs
Outdated
| dest.write_str(&console::strip_ansi_codes(record.payload()))?; | ||
| } | ||
|
|
||
| dest.write_char('\n')?; |
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.
Also, we should write out the key-values of the record here.
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.
Where we place the KV data? Just append it to the end of the log? 🤔
And it looks messy if we output the KV data in stdout.
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.
Lines 210 to 269 in 24424a1
| let mut visitor = OmaRecorder(BTreeMap::new()); | |
| event.record(&mut visitor); | |
| for (k, v) in visitor.0 { | |
| if k == "message" { | |
| if self.with_ansi { | |
| self.writer.writeln(&prefix, &v).ok(); | |
| } else { | |
| self.writer | |
| .writeln(&prefix, &console::strip_ansi_codes(&v)) | |
| .ok(); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /// OmaRecorder | |
| /// `OmaRecorder` is used for recording oma-style logs. | |
| /// | |
| /// # Example: | |
| /// ```ignore | |
| /// let mut visitor = OmaRecorder(BTreeMap::new()); | |
| /// event.record(&mut visitor); | |
| /// for (k, v) in visitor.0 { | |
| /// if k == "message" { | |
| /// self.writer.writeln(&prefix, &v).ok(); | |
| /// } | |
| /// } | |
| /// ``` | |
| struct OmaRecorder<'a>(BTreeMap<&'a str, String>); | |
| impl tracing::field::Visit for OmaRecorder<'_> { | |
| fn record_f64(&mut self, field: &Field, value: f64) { | |
| self.0.insert(field.name(), value.to_string()); | |
| } | |
| fn record_i64(&mut self, field: &Field, value: i64) { | |
| self.0.insert(field.name(), value.to_string()); | |
| } | |
| fn record_u64(&mut self, field: &Field, value: u64) { | |
| self.0.insert(field.name(), value.to_string()); | |
| } | |
| fn record_bool(&mut self, field: &Field, value: bool) { | |
| self.0.insert(field.name(), value.to_string()); | |
| } | |
| fn record_str(&mut self, field: &Field, value: &str) { | |
| self.0.insert(field.name(), value.to_string()); | |
| } | |
| fn record_error(&mut self, field: &Field, value: &(dyn std::error::Error + 'static)) { | |
| self.0.insert(field.name(), format!("{value:#?}")); | |
| } | |
| fn record_debug(&mut self, field: &Field, value: &dyn std::fmt::Debug) { | |
| self.0.insert(field.name(), format!("{value:#?}")); | |
| } | |
| } |
Since before this PR, oma is already used OmaRecorder to write KV to the end of a log record, I think keeping the behavior should be fine.
Some dep crates may completely use KV to recording variables instead of formatting into the payload.
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.
Oops, seems I understand it incorrectly, oma only cares value with "message" as the key.
My bad, let's just keep the old behavior. You can use KeyValues::get method to get value with "message" as the key.
EDIT: NVM, tracing uses "message" KV to store payload, the current code works the same as before already, so looks good to me.
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'll leave the original implementation here, which is not to print KV
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.
The with_kv field is added to formatter but unused if we need to print KV later.
src/main.rs
Outdated
| // FIXME: `spdlog::error` is conflict with `mod error` | ||
| use spdlog::{ | ||
| Level, LevelFilter, Logger, debug, default_logger, error as error2, info, set_default_logger, |
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.
Yes, this is definitely a mistake in spdlog-rs, I haven't figure out the right way to fix it. For now, we can import the error! macro from spdlog::prelude::error.
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.
use spdlog:prelude:error has the same issue
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.
Hmm, so it's not a conflict between spdlog::error mod and spdlog::error! macro? So, if not, then it's probably should not consider as a mistake from spdlog-rs.
Okay, let's just keep the alias here. I'll suggest another name error as err.
src/main.rs
Outdated
| .to_string_lossy() | ||
| .to_string(); |
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.
Hmm, since spdlog-rs accepts a path type instead of a string type, I think we should place the conversion to the end of the function.
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.
Fixed
| let level_filter = LevelFilter::MoreSevereEqual(Level::Info); | ||
|
|
||
| if !debug && !dry_run { | ||
| let no_i18n_embd: EnvFilter = "i18n_embed=off,info".parse().unwrap(); |
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.
Looks like we have not setup the log crate proxy in this PR. The logs from log crate will only be available after we set it up via spdlog::init_log_crate_proxy().
And we really should migrate env filters, but spdlog-rs currently does not support filter logs from log crate, we will probably support this feature in the next minor release.
For now, is it acceptable for not migrate this at the moment? @eatradish
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.
Looks like we have not setup the log crate proxy in this PR. The logs from
logcrate will only be available after we set it up viaspdlog::init_log_crate_proxy().And we really should migrate env filters, but spdlog-rs currently does not support filter logs from
logcrate, we will probably support this feature in the next minor release.For now, is it acceptable for not migrate this at the moment? @eatradish
Yes, but subsequent releases may include this feature as a breaking
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.
init_log_crate_proxy() added.
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.
Env filter for log crate is added in spdlog-rs v0.5.2 (docs), so filter directive i18n_embed=off can now be migrated! :D
@NotEvenANeko Please also adding this in the PR.
|
FYI, we have just released spdlog-rs v0.5.0. You could target the dependency spdlog-rs in this PR to the crates.io registry now. |
95052c9 to
c0266fb
Compare
|
Updated to v0.5.0 |
125bbbf to
ecaf9a1
Compare
|
Doc tests should be fixed now |
ecaf9a1 to
55e6fc9
Compare
|
Ok I think clippy check is passed now... |
SpriteOvO
left a comment
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.
Basically LGTM, @eatradish is there anything you are still concerned about?
LGTM, I'll test the functionality tomorrow |
| .writeln(&prefix, &console::strip_ansi_codes(&v)) | ||
| .ok(); | ||
| time | ||
| } |
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.
Looks like the 80col limit feature was implemented in oma_console::Writer, the original Writer directly writes to the IO handle stdout or stderr, probably we should implement one that writes to a string buf for spdlog-rs.
@NotEvenANeko Could you make time to have a look at it and try to fix?
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.
Should be fixed now.
|
I'm so sorry for AFK for 3 weeks, I'm busy at study recently so I don't have much time for this, really sorry for this :( I'm continue this PR now. After reviewing the code I think that if we can migrate We can migrate all the Will it be a good idea? 🤔 |
I think putting the behavior "writing to console" into a formatter is not an ideal design. Why don't we just replace the field |
|
Not the |
I think it's acceptable. |
232f031 to
1ca1cb5
Compare
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 left some reviews, though I didn't test it locally, maybe @eatradish wanna check the output's appearance.
oma-console/src/print.rs
Outdated
| Level::Debug => console::style("DEBUG").dim().to_string(), | ||
| Level::Info => console::style("INFO").blue().bold().to_string(), | ||
| Level::Warn => console::style("WARNING").yellow().bold().to_string(), | ||
| Level::Error => console::style("ERROR").red().bold().to_string(), | ||
| Level::Trace => console::style("TRACE").dim().to_string(), | ||
| Level::Critical => console::style("CRITICAL").red().bright().bold().to_string(), |
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.
@eatradish Just saying, if you care about performance, here is a good optimization point, by caching these string into a immutable array. However, since the previous also used to_string, so I think this can be done in future PRs, not in this one.
Same thing for the to_string uses below.
| let level_filter = LevelFilter::MoreSevereEqual(Level::Info); | ||
|
|
||
| if !debug && !dry_run { | ||
| let no_i18n_embd: EnvFilter = "i18n_embed=off,info".parse().unwrap(); |
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.
Env filter for log crate is added in spdlog-rs v0.5.2 (docs), so filter directive i18n_embed=off can now be migrated! :D
@NotEvenANeko Please also adding this in the PR.
| (level_filter, formatter) | ||
| } else { | ||
| let filter = EnvFilter::try_from_default_env() | ||
| .unwrap_or_else(|_| "hyper=off,rustls=off,debug".parse().unwrap()); |
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.
Same thing for hyper=off,rustls=off directives.
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.
Added. First we look for RUST_LOG environment variable as what tracing_subscriber does, if RUST_LOG is empty we use the hyper=off,rustls=off,debug directive for debug or dry run.
For any case besides debug and dry run we use i18n_embed=off,info
| // 10 MB | ||
| .rotation_policy(RotationPolicy::FileSize(10 * 1024 * 1024)) |
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.
Before this PR, oma does not limit the single log file size, is 10MB for a single log file makes sense to you? @eatradish
If not, we could simply change to u64::MAX here :)
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.
Before this PR,
omadoes not limit the single log file size, is 10MB for a single log file makes sense to you? @eatradishIf not, we could simply change to
u64::MAXhere :)
Agree 10MiB
| .build() | ||
| .unwrap(), | ||
| )) | ||
| .overflow_policy(spdlog::sink::OverflowPolicy::DropIncoming) |
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.
tracing also uses the same policy, quoting from their docs:
The queue has a fixed capacity, and if it becomes full, any logs written to it will be dropped until capacity is once again available.
So from the perspective of migration, this is fine. 👍
| logger_builder | ||
| .level_filter(level_filter) | ||
| .sink(Arc::new(stream_sink)) | ||
| .sink(Arc::new(rotating_sink)); |
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.
Since we have wrapped RotatingFileSink with AsyncPoolSink, writing logs to file will not block the current thread, we can set the flush level filter for the logger to All, for flushing the buffer in time.
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.
Added
src/subcommand/search.rs
Outdated
| "{}", | ||
| color_formatter().color_str(body.trim(), Action::Secondary) | ||
| ) | ||
| // Keep original behavior (? |
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 think this is fine as long as we can display the same results as before.
oma-console/src/print.rs
Outdated
| /// `OmaLayer` is used for outputting oma-style logs to `tracing` | ||
|
|
||
| // '1970-01-01T00:00:00Z' costs 24 chars, and a space costs 1. | ||
| const TIME_RFC3339_LEN: u16 = 24 + 1; |
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.
So it should be 20 + 1?
Or we could play some fancy feature here.
| const TIME_RFC3339_LEN: u16 = 24 + 1; | |
| const TIME_RFC3339_LEN: usize = "1970-01-01T00:00:00Z ".len(); |
It is a const variable, so it computes at compile-time.
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.
Oh I forgot to count the milliseconds part...
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.
LGTM. If @eatradish has no further concerns, I feel this PR can be merged.
EDIT: Oh, looks like CI clippy failed, just one more tiny fix and a rebase needed.
Signed-off-by: Neko <[email protected]>
b478406 to
ba8e4fb
Compare
|
Thanks! |
|
@eatradish Thanks for your reviews and @NotEvenANeko's hard work on this. If you experience any issues while using |




Refactor
tracingtospdlog-rsfor logging.This closes #486 .
cc @SpriteOvO