-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Use 'tracing' library instead of 'log'. #1579
Conversation
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 haven't read through trace.rs
itself - I'll hold off on this until the rest of the code has undergone review - but I've left some comments on the rest of the changes. Some higher-level comments:
-
TheI see now that therocket
library feature should be calledtracing
or similar.log
feature is for enabling compatibility with thelog
crate. It does not appear that we can disable tracing at all. What kind of compile-time overhead are we adding? What kind of runtime overhead are we adding? -
Is the feature intended to be disabled? If so,it should be documented in
lib.rs
,be added as a tested feature inscripts/test.sh
, and explicitly
enabled in examples that make use of it. If not, why is it a feature at all?
At the moment, codegen seem to depend on this being enabled, so either this
should be fixed or it shouldn't be a feature. -
If codegen depends on this, why are the --core tests passing? -
What is the overhead this is adding? This is now in the critical path. If we
could really disable the feature, resulting in trace macro calls compiling
to nothing, we should be able to measure this accurately. -
examples/todo
should userocket/tracing
, notlog
. -
The
trace_env_logger
example needs some motivation. Is it just there to
check thatlog
integration "works"? In any case,hi
should take and
return an&str
, notString
. What's more, every macro excepttrace
is
used viarocket::
; should we just import them? -
Some config values on launch are colored white and others aren't.
-
In some places, tracing fields come before the message and sometimes after.
We should be consistent.trace!("msg", field = foo);
-
Sometimes span fields are used, sometimes they aren't. For example, when
logging config errors, why aren't all of those{}
fields? -
Why add a name to some spans and not others? What is the utility? Can we
just usemodule_name!()
or something to that effect? -
Lots of lines now exceed 100 characters, largely those that name the
trace/span. We should avoid this. -
The
config
changes are particularly difficult to read. -
Running arbitrary, non-trace related code
in_scope()
feels quite wrong to
me. There must be a better way. -
It seems like we really want a second macro, to avoid all of the
.in_scope(|| { })
:// the `, $expr` should be optional. error_span!("Some message", { info!("inside the span's scope"); });
@@ -40,7 +40,7 @@ | |||
//! This crate is expected to grow with time, bringing in outside crates to be | |||
//! officially supported by Rocket. | |||
|
|||
#[allow(unused_imports)] #[macro_use] extern crate log; | |||
#[allow(unused_imports)] #[macro_use] extern crate tracing; |
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 we be using whatever rocket
is using?
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.
What do you suggest changing here? I assume #[macro_use]
was used to avoid needing to add use
statements to each file, and I'm not aware of another way to do this (aside from making all of the different logging macros top-level exports from rocket
, and #[macro_use] extern crate rocket;
)
core/lib/src/rocket.rs
Outdated
warn!("secrets enabled without a stable `secret_key`"); | ||
info_!("disable `secrets` feature or configure a `secret_key`"); | ||
info_!("this becomes an {} in non-debug profiles", Paint::red("error")); | ||
warn_span!("unconfigured_secret_key", "secrets enabled without a stable `secret_key`").in_scope(|| { |
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 here with code in_scope.
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 don't think I agree on this particular usage. The more distance, if
statements, etc. between calling enter()
and the end of the scope, the harder it is to tell which messages are still "indented"; that's why I have (so far) used in_scope
here. There is also the alternative of info!(parent: span, ..)
, although it is more repetitive than the other options.
.instrument(span) | ||
.await | ||
|
||
}.in_current_span()); |
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 both of these?
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 instrument
call is what set ups the Request:
line in the log (and indents everything under it). (https://docs.rs/tracing/0.1.25/tracing/span/struct.Span.html#in-asynchronous-code explains why this is necessary)
The in_current_span
is there for the same reason as the other call to it.
pub(crate) async fn handle_error<'s, 'r: 's>( | ||
pub(crate) fn handle_error<'s, 'r: 's>( |
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 this change? It seems unnecessary? The code also got harder to read.
In general, these tail instrument
calls are hard to follow.
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.
This could alternatively remain an async fn
and use the #[instrument]
attribute, like:
#[tracing::instrument(
level = "warn",
skip(self, status, req),
fields(message = %format_args!("Responding with {} catcher.", Paint::red(&status)),
)]
pub(crate) async fn handle_error<'s, 'r: 's>(
// ...
} | ||
}); | ||
|
||
// NOTE: `hyper` uses `tokio::spawn()` as the default executor. | ||
#[derive(Clone)] | ||
struct InCurrentSpanExecutor; |
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 is this here? Isn't this what .instrument()
and .in_current_span()
are for?
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.
This is added so that hyper's calls to tokio::spawn
will "inherit" the active spans (e.g. the current connection, request, etc.), instead of being logged at the root level.
I added most of those comments to the top-level comment as additional TODOs, and will keep working through them along with the other inline comments.
I believe it was, yes. That, and/or as a demonstration to users how Rocket's and users's
The order is not flexible in that way:
Every span has a name. I mixed several of these up very early on, which now look like they have only a message, and never cleaned them all up.
Earlier versions of this PR did use the I do agree that some of the |
Answering some of the questions from above:
Yeah, that's correct; the example was supposed to demonstrate how to use Rocket with the
Running "arbitrary, non-trace related code" in
Yeah, this is correct. Format-string-based messages must always come last in the
See here for details on statically disabling specific Since the compile-time filtering is based on feature flags, which are always additive, a library dependency like Rocket should generally not enable them, since this prevents the user application from being able to configure them. However, we might want to document the existence of these feature flags in Rocket's docs so that users are aware of them, and they can be used for benchmarking. |
It would also definitely be possible to make the |
'tracing' is now used for all messages and for Rocket's default logger. Co-authored-by: Eliza Weisman <eliza@buoyant.io> Co-authored-by: Jeb Rosen <jeb@jebrosen.com>
…fig fields unpainted
9b822d8
to
f2a7e25
Compare
Hi, any news about when should we expect the move to LogTracer::init().expect("Unable to setup log tracer!");
let (non_blocking_writer, _guard) = tracing_appender::non_blocking(std::io::stdout());
let formatting_layer = fmt::layer().json().with_writer(non_blocking_writer);
let subscriber = Registry::default()
.with(EnvFilter::new(env!("LOG_LEVEL")))
.with(formatting_layer);
tracing::subscriber::set_global_default(subscriber).expect("Failed to set global subscriber");
rocket_builder().launch(); Which is not ideal because it interferes with rocket's logging configuration and then I end up getting ugly jsons with terminal color codes in raw form, which look like the following: {"timestamp":"2022-01-06T10:23:04.323575Z","level":"INFO","fields":{"message":"\u001b[1;49;39mOutcome:\u001b[0m \u001b[49;32mSuccess\u001b[0m","log.target":"_","log.module_path":"rocket::rocket","log.file":"/Users/me/.cargo/registry/src/gh.neting.cc-1ecc6299db9ec823/rocket-0.4.10/src/rocket.rs","log.line":303},"target":"_"} And notice that I don't have a request_id here as well for some reason... |
Hi there, I notice this PR has stalled. Is there anything a third party (like me) can do to help push it along? I'm eagerly looking forward to using Thanks! |
I'm closing this as Jeb has indicated that he won't be able to push it forward. This is something I will personally prioritize for Rocket 0.6. |
By the way: if anyone is interested in making this happen, I would love to actively mentor that person. |
I might be interested, let me check availability over the weekend and I'll get back to you with an answer. |
@oren0e Sounds good! Hop on the Matrix channel if/when you're ready. |
ah what is the Matrix channel? You have a discord server? |
It's in the README and the website. Here's a direct link: https://chat.mozilla.org/#/room/#rocket:mozilla.org |
any news @oren0e or @SergioBenitez or newer state of work? maybe i would like to take a look |
You're welcome to work on this, I will try to help with this as much as I can but I think I can't be the owner of this migration currently. I initially thought that I will have much more time to devote to this task where in reality I have something like only 10% of my initial estimation. I'm sorry that I inform of this only now. |
@@ -62,8 +63,8 @@ async fn run_blocking<F, R>(job: F) -> R | |||
|
|||
macro_rules! dberr { | |||
($msg:literal, $db_name:expr, $efmt:literal, $error:expr, $rocket:expr) => ({ | |||
rocket::error!(concat!("database ", $msg, " error for pool named `{}`"), $db_name); | |||
error_!($efmt, $error); | |||
error!(concat!("database ", $msg, " error for pool named `{}`"), $db_name); |
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.
please just one log per message / error + please keep logmessage clean from values (it is easier to indexing, search and anonymize in log systems, if all values are in defined files):
error!(concat!("database ", $msg, " error for pool named `{}`"), $db_name); | |
error!( | |
database.name = $msg, | |
database.pool = $db_name, | |
error = $error, | |
$efmt | |
); |
Supersedes #1410.
I likely missed a few spots and will need to make a few minor changes in follow-on commits, but this basically "ready to review".
TODOs:
examples/todo
should userocket::tracing
, notlog
trace_env_logger
example:hi
should take and return an&str
, notString
. And every macro excepttrace
is used viarocket::
; should we just import them?Id
s generated byRegistry
are a multi-level bit-packed generation index, and I threw something together that seemed to look nice on 64-bit systems.in_scope
callslogger.rs
that have not been rebased intotrace.rs
tracing
andtracing-subscriber
crates, like is done forfutures
,tokio
, andfigment
today.