This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Add an always-on log channel
AbandonedPublic

Authored by JDevlieghere on Oct 10 2022, 3:03 PM.

Details

Summary

Add an "always on" log channel. The channel is meant to be used sparsely and deliberately for logging high-value information. Unlike other log channels, it's not exposed to the user. Log messages are logged to a ring buffer with a fixed number of entries. The ring buffer is dumped to disk as part of the diagnostics, i.e. when the debugger crashes or when the user explicitly requests a dump.

Diff Detail

Event Timeline

JDevlieghere created this revision.Oct 10 2022, 3:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 10 2022, 3:03 PM

I'm not sure if this will do what you wanted it to do. Despite the title, this patch is not adding a new log *channel* -- it is adding a new log *category* to the "lldb" channel. Our logging infra, perhaps somewhat misleadingly, manages all of the log state on a per-channel basis. This means that it is not e.g. possible to redirect one log category to a different sink than a different category in the same channel. I haven't checked this, but I suspect that for this reason, any explicit "log enable" commands by the user will redirect this special channel into the new (user-provided) destination. If this is not what you intended to do then, you probably ought to add a new log channel, for real.

That said, without knowing what kind of information do you want to log here, I am wondering if the same kind of information could be gathered by reusing some existing data collection mechanism, like session transcripts, or the yet-to-be-implemented telemetry data.

I'm not sure if this will do what you wanted it to do. Despite the title, this patch is not adding a new log *channel* -- it is adding a new log *category* to the "lldb" channel. Our logging infra, perhaps somewhat misleadingly, manages all of the log state on a per-channel basis. This means that it is not e.g. possible to redirect one log category to a different sink than a different category in the same channel. I haven't checked this, but I suspect that for this reason, any explicit "log enable" commands by the user will redirect this special channel into the new (user-provided) destination. If this is not what you intended to do then, you probably ought to add a new log channel, for real.

You're absolutely right. I actually came to that same conclusion myself when I implemented an earlier iteration of this patch a long while ago but evidently didn't think of it before recreating the patch from memory.

That said, without knowing what kind of information do you want to log here, I am wondering if the same kind of information could be gathered by reusing some existing data collection mechanism, like session transcripts, or the yet-to-be-implemented telemetry data.

I see those two things as orthogonal. Always-on logging is something that has comes up quite frequently. @kastiglione can talk about our downstream log channel for Swift and @Michael137 was also interested in this to triage common issues with the expression evaluator.

Maybe use LLDBLog::Diagnostics instead of LLDBLog::AlwaysOn? and maybe "diagnostics" instead of "always-on"?

I am also questioning if the these even belong in the LLDB logging stuff? Seems like it would be just as easy to create a diagnostic message by calling Diagnostics::Report(...). Do we really want to modify the log channels here? Seems like always on diagnostics should just a dedicated API.

It might be nice to also have a "diagnostics" log channel that _can_ be enabled, and any diagnostic messages would then also be included in the log output but only if enabled by the user?

lldb/include/lldb/Utility/Diagnostics.h
65

Move out of header file as a file static only? Better name might be a good idea. "g_log_messages" sounds like a boolean setting. Maybe "g_max_log_messages" or "g_num_log_messages"?

It might be nice to also have a "diagnostics" log channel that _can_ be enabled, and any diagnostic messages would then also be included in the log output but only if enabled by the user?

And if the logging gets enabled, we can write out all of the diagnostics and are in the circular buffer if the "log enable lldb diagnostics" is enabled, then as each diagnostic is reported, the Diagnostics::Report(...) call could emit the log messages real time.

  • Address code review feedback

I am also questioning if the these even belong in the LLDB logging stuff? Seems like it would be just as easy to create a diagnostic message by calling Diagnostics::Report(...). Do we really want to modify the log channels here? Seems like always on diagnostics should just a dedicated API.

I expect the majority of places where we want to log to the diagnostic log channel to be places where we already log today. It being a its own log channel complicates that somewhat, because unlike categories you can't do GetLog(LLDB::Expression | Diagnostics::Expression). That's still pretty important to us, so I've added two more macros that allow you to specify multiple log channels to achieve a somewhat similar result:

LOG_MULTI_PRINTF(GetLog(LLDBLog::Expression), GetLog(Diagnostics::Foo), "%s", foo)

Similarly, I also plan to change LLDB_LOG_ERROR to always log to the diagnostic channel. I didn't include it in this patch as it requires moving the macro in the diagnostics header and generates a lot of churn.

kastiglione accepted this revision.Oct 21 2022, 10:54 AM

I expect the majority of places where we want to log to the diagnostic log channel to be places where we already log today.

This is my expectation too. Some logs are helpful for diagnosing problems, and having them already saved makes it easier for users to include info in their reports.

lldb/source/Utility/Diagnostics.cpp
23

To me, it's not ideal that there's an "lldb" channel, and this channel has an "lldb" category.

Do you have other categories in mind for later updates, that should be moved into this patch? For example, will there eventually be "warning" and "error" categories? If so, maybe start with those instead of "lldb".

This revision is now accepted and ready to land.Oct 21 2022, 10:54 AM
JDevlieghere added inline comments.Oct 21 2022, 11:17 AM
lldb/source/Utility/Diagnostics.cpp
23

Yes, for the errors I was going to add an error category. Maybe we can call this one general or something?

I am also questioning if the these even belong in the LLDB logging stuff? Seems like it would be just as easy to create a diagnostic message by calling Diagnostics::Report(...). Do we really want to modify the log channels here? Seems like always on diagnostics should just a dedicated API.

I expect the majority of places where we want to log to the diagnostic log channel to be places where we already log today.

Yeah, but that could be achieved by having the "dedicated diagnostic API" forward the message to a regular log when it deems it necessary (or always).

Speaking of dedicated APIs, we already have the Debugger::ReportWarning/Error functions. I would expect we want those to show up in the diagnostic log, as these are things that we've already deemed important enough to print to the user. Wouldn't it be better to use that as a starting point? Possibly extend it by adding some sort of an "info" priority, which does not get printed to the user (but makes its way to the log)?

Similarly, I also plan to change LLDB_LOG_ERROR to always log to the diagnostic channel. I didn't include it in this patch as it requires moving the macro in the diagnostics header and generates a lot of churn.

I'm not sure that's a good default. Some of those messages could be fairly innocuous, and the ratio of the innocuous ones will probably increase as we use llvm::Error more.

lldb/source/Utility/Diagnostics.cpp
23

I'm not entirely sure of what's the purpose of having multiple categories, if they're all supposed to be on all the time (the category name is not recorded anywhere, so the only thing they do is enable one to selectively enable/disable some log messages).

lldb/test/Shell/Diagnostics/TestLogChannel.test
2

Judging by the patch, I think the user will still be able to disable diagnostics if he is able to "guess" that there is a log channel called that way (log disable diagnostics). Is that intentional?

JDevlieghere abandoned this revision.Oct 24 2022, 9:05 AM

Seems like the consensus is that we prefer a dedicated API rather than using the existing logging infrastructure.