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.
Details
Diff Detail
Event Timeline
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.
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.
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.
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". |
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? |
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? |
Seems like the consensus is that we prefer a dedicated API rather than using the existing logging infrastructure.
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"?