Skip to content

Implement adr-9 logging; implemented via tracing. #6748

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

Merged
merged 1 commit into from
May 21, 2025

Conversation

mhammond
Copy link
Member

@mhammond mhammond commented May 6, 2025

No changes required for mobile consumers, it's all abstracted in rust_log_forwarder

Summary of changes:

  • Existing error-support crate re-exports log, info, warn, trace etc. All existing components are changed so that instead of using log:: directly we use the re-exports from error-support.

  • error-support also grows a testing feature to expose a couple of helpers for tests.

  • new crate tracing-support which also re-exports log, info, warn, trace etc and also has a testing feature which re-exports the same test functions.

  • error-support also grows new features to control whether it re-exports the log calls from the log and env_logger crates, or from tracing-support.

The intent here is that in app-services we will use the feature which uses tracing (because we also have rust_log_forwarder setup to support that), but initially on desktop we will enable the feature to continue using log while we work on setting up an appropriate tracing subscriber there.

There's also a feature to control how error reporting is done - by default it is done like has always been done on mobile, but is setup so that on Desktop it will use the tracing facility. This means we can eventually end up using a single tracing subscriber for both error reports and logs (and also any other event types we invent in the future).

@mhammond mhammond force-pushed the log-to-tracing branch 7 times, most recently from 2cc1a10 to 232db75 Compare May 6, 2025 21:25
@mhammond mhammond changed the title Move autofill to tracing crate, add new support/tracing module for te… Implement adr-9 logging; implemented via tracing. May 7, 2025
@mhammond mhammond force-pushed the log-to-tracing branch 12 times, most recently from 44d3fcf to 4cf0c93 Compare May 12, 2025 14:56
@mhammond mhammond requested a review from bendk May 13, 2025 14:36
@mhammond mhammond marked this pull request as ready for review May 13, 2025 14:36
@mhammond
Copy link
Member Author

Hey @bendk, sorry about this 😬 Let's talk about it later today.

Copy link
Contributor

@bendk bendk left a comment

Choose a reason for hiding this comment

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

Overall, I love these changes.

There were a couple pieces of leftover debug code that should be removed. Other than that, the only "blocker" for me is the question of how we filter for app-services events. Is a list of target strings the best way? The answer may be yes, but I just wanted to discuss it some.

println!("XXXXX - hello println");
eprintln!("XXXXX - hello eprintln");
error!("oh no places");
//panic!("at the disco!!!");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is hilarious, but probably should be deleted.

// println!(
// "TRACING EVENT {target} - {prefix} - {}",
// SINKS_BY_TARGET.read().len()
// );
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: another piece of leftover code.


// The "targets" (in practice, crate names) which are hooked up to the `tracing` crate for logging.
// We should improve this, or better still, just kill this crate entirely - but it is a natural consequence
// of using `tracing` that each target must be explicitly listened for *somewhere*.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you expand on this one a bit. Killing this crate sounds great, but how would that work in practice?

Also, what do you mean by "each target must be explicitly listened for somewhere."? When I first read that, I added "..or else something would break" in my head. Now that I re-read it, it seems like we would lose the logs. I think you framed this on our call as "there's no way to globally listen for all events", which seems clearer to me.

pub use foreign_logger::{AppServicesLogger, Level, Record};
// ideally we'd use tracing::Level as an external type, but that would cause a breaking change
// for mobile, so we clone it.
// (it's a shame uniffi can't re-export types!)
Copy link
Contributor

Choose a reason for hiding this comment

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

Cloning seems okay to me, but I don't understand what's stopping us from using this as an external type. Can you link to an issue?

Copy link
Member Author

Choose a reason for hiding this comment

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

It can work as an "external type", but in that scenario it means that the existing rust-log-support in the mobile platforms needs to change - eg, we'd need a PR for Swift and Android which subtly changes the dependencies so that the new crate tracing_support is referenced. IOW, this is just a work-around to avoid the breaking-change dance.

The second comment was a reflection on this - it's kinda a shame we can't have uniffi pretend Level was directly exported by rust-log-forwarder, but I've no idea how that would work - maybe I should remove that comment?

wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh, I see what you mean now.

The "re-export types" feature seems doable to me. Maybe it already works on some languages. For example python imports the type name, that might be enough. We probably should be adding the name to __all__ as well though.

// Set up a tracing subscriber for crates which use tracing and forward to the foreign log forwarder.
for target in TRACING_TARGETS {
tracing_support::register_event_sink_arc(target, (*level).into(), sink.clone())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should work fine, but I want to try to figure out how to wire this all up differently -- mostly just to think about the possibilities here and understand the requirements better.

Could we have a tracing field that distinguished app-services events from other events and have this code subscribe to all those events at once? For example, the error_support macros could set a boolean field named app_services and the tracing_support code could decide if an event should be forwarded to the event sink by looking for the presence of that field rather than filtering on the target.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the problem here is that we'd also need to filter on the target? ie, we'd need some way of getting all targets and then filtering after the target matches, which I'm not sure if possible, and if it was, would leave us in the same place we are in the log crate wrt performance impact of intercepting and formatting logs we don't ultimately care about.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking that we could replace this code in tracing_support and then we get access to all the events, regardless of target.

However, looking through that code again makes me see some bigger-picture issues. By using target as the basis of the filter, you could easily extend that to having different levels per-target and having that filtering happen before anything gets pushed across the FFI. That makes me now want to change anything. I feel like there might be some changes down the road, especially as we try to make this work for both error reporting and logging, but the current code seems like the best place to start.

Copy link
Contributor

@bendk bendk left a comment

Choose a reason for hiding this comment

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

Thanks for talking through that filtering question with me. I think this one is ready to merge once those printlns are removed from places_api.rs

pub use foreign_logger::{AppServicesLogger, Level, Record};
// ideally we'd use tracing::Level as an external type, but that would cause a breaking change
// for mobile, so we clone it.
// (it's a shame uniffi can't re-export types!)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh, I see what you mean now.

The "re-export types" feature seems doable to me. Maybe it already works on some languages. For example python imports the type name, that might be enough. We probably should be adding the name to __all__ as well though.

// Set up a tracing subscriber for crates which use tracing and forward to the foreign log forwarder.
for target in TRACING_TARGETS {
tracing_support::register_event_sink_arc(target, (*level).into(), sink.clone())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking that we could replace this code in tracing_support and then we get access to all the events, regardless of target.

However, looking through that code again makes me see some bigger-picture issues. By using target as the basis of the filter, you could easily extend that to having different levels per-target and having that filtering happen before anything gets pushed across the FFI. That makes me now want to change anything. I feel like there might be some changes down the road, especially as we try to make this work for both error reporting and logging, but the current code seems like the best place to start.

@mhammond
Copy link
Member Author

I was thinking that we could replace this code in tracing_support and then we get access to all the events, regardless of target.

huh, yeah, maybe that could work! I do agree we shouldn't over-rotate now because I doubt many of these limitations are going to be a problem in practice. Eg, even today, all logs from sql-support don't indicate what component they originated in, but in practice this isn't a problem we've noticed because there's enough context to guess that. So let's just see what actually hurts us once this is in place.

@mhammond mhammond requested a review from bendk May 15, 2025 18:09
@bendk
Copy link
Contributor

bendk commented May 15, 2025

Weird, I thought I already approved. In any case, it's looking great to me.

@mhammond
Copy link
Member Author

/taskcluster ci full

…r logging.

Summary of changes:

* Existing `error-support` crate re-exports `log`, `info`, `warn`, `trace` etc. All existing components are changed so that instead of using `log::` directly we use the re-exports from `error-support`.
* `error-support` also grows a `testing` feature to expose a couple of helpers for tests.
* new crate `tracing-support` which also re-exports `log`, `info`, `warn`, `trace` etc and also has a `testing` feature which re-exports the same test functions.
* `error-support` also grows new features to control whether it re-exports the log calls from the `log` and `env_logger` crates, or from `tracing-support`.

The intent here is that in app-services we will use the feature which uses `tracing` (because we also have `rust_log_forwarder` setup to support that, but initially on desktop we will enable the feature to continue using `log` while we work on setting up an appropriate tracing subscriber there.

There's also a feature to control how error reporting is done - by default it is done like has always been done on mobile, but is setup so that on Desktop it will use the tracing facility. This means we can eventually end up using a single tracing subscriber for both error reports and logs (and also any other event types we invent in the future).
@mhammond mhammond added this pull request to the merge queue May 21, 2025
Merged via the queue into mozilla:main with commit 75a87f0 May 21, 2025
16 checks passed
@mhammond mhammond deleted the log-to-tracing branch May 21, 2025 02:18
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.

2 participants