-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
Promote extension log API to stable #43276
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.
Looks good to me!
Check Travis though. Seems like all good there. |
@roblourens I'm fine with the new API but Joh has the final say as he is the API police ;-) |
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.
New interfaces look good to me. We should add comments on the Logger
interface properties too before shipping this
8351e06
to
1fd0f50
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.
With this addition, we will have two somewhat competing APIs, the output channel and the logger.
IMHO, we should make it clear which one an extension author is supposed to use.
export interface Logger { | ||
readonly onDidChangeLogLevel: Event<LogLevel>; | ||
readonly currentLevel: LogLevel; | ||
readonly logDirectory: Thenable<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.
Typically, we make read API synchronous. Why is logDirectory
a Thenable
?
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 directory is only created when this is called or when the logger is used. Otherwise there will be a ton of empty folders sitting around.
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.
@roblourens IMHO that is super weird. I've never seen a lazy getter field that creates a directory when accessed. Is there no other way to solve the problem of the empty folders ? Why does each extension need to get its own folder ? Can't we use the extension id as the filename and thus avoid collisions ?
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.
If an extension owns it own log file(s), where would it write to? The main logging directory? Then it would have to know about the window id or rotate files itself.
It could be a get() method too.
*/ | ||
export interface Logger { | ||
readonly onDidChangeLogLevel: Event<LogLevel>; | ||
readonly currentLevel: LogLevel; |
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 the log level be exposed as API ?
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.
One use case might be when for when an extension is managing its own logging and writing to a file on its own.
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.
Has anyone asked for this? There are very many things we could add to the API, but IMHO it is a good practice to be as limited as possible and add something only if really needed...
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.
If we expose the log directory, we have to expose this, it makes no sense to only provide one.
@roblourens There is still my question:
|
I see these as different things, output channel for transient info that users would want to monitor, and logging for bug reports and info for developers. I'm actually not sure why we show all the log files in the output pane - do we expect users to want to look at these? Even as a developer I don't see generally useful info there unless I'm looking at a specific component or issue. But if my view is wrong then maybe there's room to merge them instead. |
Yes, we use We already use Output channel to show extension logs, example: Typescript log. May be there are more extensions doing the same. So, I see the point that it might confuse the authors when to use Output channel and when to use log api. To me, log api looks more as a utility than an API to the extensions. Also, we can enhance Output to stream the log files from extensions into output channel. |
TypeScript has a verbose logging mode which writes tons of info to a file, but doesn't use the output channel. Spamming the output channel in that case would just slow things down. I assume that the output channel API transfers all data to the renderer process whether or not the output channel is visible. So that's a big difference between the two. |
I do not think there will be any slow down or data transfer. If we provide an api to create a file based output channel and if extension has a log file and wanted to show in output channel, then it can create an output channel using the new API passing the log file URI. Streaming of data happens in the renderer which will be similar to our internal log channels inside product. I did several improvements to output channels in last milestone and one of those is that no streaming happens when a file based channel is not visible. |
I, personally, as a user, never ever want to see output channels, unless we're talking about the output of executing my program or the output from testing my program. I find it hard to imagine there are people that want to monitor output channels. Take, for example, the following output channels: My point is that nobody wants to monitor output channels as part of their regular flow, similar to how nobody wants to monitor log files as part of their regular flow. So, IMHO, output channels are log files. They simply miss some tracing level, some special methods to avoid writing If I understand you correctly, we have the requirement that extensions maybe want to log from a separate process than the extension host. In such a case, I believe they would use a logging library available in their runtime's programming language. e.g. OmniSharp would use a logger written in C#, TypeScript could also use spdlog, etc. I understand how it is useful in such a case for them to write their log files close to the other VS Code log files, and us giving them a folder path and log level API makes good sense. It's just that these should be synchronous, not asynchronous, and should be pure. Getting a property should, IMHO, have no side effects, such as creating a folder on disk... |
@roblourens Glad you are asking..
In this PR we are still on phase 2 (propose something that doesn't conflict with the guidelines) and maybe on something like phase 0 - in what shape do we want/need this api. I agree with @alexandrudima that there is too much overlap with output channels (be minimal) and if we untangle the proposal into two pieces we might end up with a better solution. One part of this proposal is being part of the vs code logging infrastructure and using (improved) output channels seems like a promising idea/exploration. The other part is exposing log config data, like level and file location. If those aren't extension-specific we should look into adding something to |
Outcome of discussing this
We are aiming to deliver the first two items during this milestone and consider the last as stretch. |
This PR is now n/a |
What's the protocol for this? Discussion here and merge it if I get 👍s?
Earlier discussion at 98c58df
Fixes #43275