-
Notifications
You must be signed in to change notification settings - Fork 235
Change logging to use Serilog #666
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
Conversation
Can you add the Serilog reference to the TPN? |
Looks like the logging tests are failing! |
I should add a TPN for each of the Serilog bits I assume, since they are separate. Also, is there a reason the Third Party Notice file has quotes in the name? It's named |
@@ -177,13 +177,13 @@ task TestServer -If { !$script:IsUnix } { | |||
exec { & $script:dotnetExe xunit -configuration $Configuration -framework net452 -verbose -nobuild } | |||
} | |||
|
|||
task TestProtocol -If { !$script:IsUnix} { | |||
task TestProtocol -If { !$script:IsUnix } { |
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.
We should add the config line to trim trailing whitespace if/when we add a .editorconfig
file. :-)
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.
Agreed! I think the .editorconfig
is a good idea.
Do you mean here I should remove the space I added before the brace?
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.
Sorry, bad example. There were some trailing spaces after a chained exception filter that got removed. That's where the editorconfig file would have helped me where I use VS and it doesn't normally trim trailing whitespace.
So @rkeithhill made a good point about renaming |
Less code churn is usually better unless there's a good reason for it. :-) |
@@ -101,7 +101,7 @@ public string SettingsPath | |||
/// Creates an instance of the AnalysisService class. | |||
/// </summary> | |||
/// <param name="settingsPath">Path to a PSScriptAnalyzer settings file.</param> | |||
/// <param name="logger">An ILogger implementation used for writing log messages.</param> | |||
/// <param name="logger">A logger used for writing log messages.</param> |
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.
Might as well revert all these comment changes. That removes ~25 more files from the PR. :-)
BTW what does the log file look like with this change? |
Logging looks like this at the moment:
|
I wonder if we should consider adding a |
Actually I was thinking the same thing! |
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.
Other than the extra newline to space out the individual log messages a bit, this PR LGTM!
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 - just a few questions before a approve.
/// <param name="logLevel">The minimum log level for this file</param> | ||
/// <param name="useMultiprocess">Set whether the log file should be readable by other processes</param> | ||
/// <returns>the ILogger builder for reuse.</returns> | ||
public Builder AddLogFile(string filePath, LogLevel? logLevel = null, bool useMultiprocess = false) |
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.
useMultiprocess isn't used at all. Is this on purpose?
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.
Also, what happens when the log level is null? What logs will we see?
} | ||
|
||
/// <summary> | ||
/// Take the log configuration use it to create An ILogger implementation. |
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.
nit: grammar? "Take the log configuration and use it..."?
/// </summary> | ||
/// <param name="logLevel">The minimum log level for console logging.</param> | ||
/// <returns>the ILogger builder for reuse.</returns> | ||
public Builder AddConsoleLogging(LogLevel? logLevel = null) |
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.
Will this show up in the Integrated Terminal or in the VSCode logging view?
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'm not sure. Possibly the latter if VSCode redirects stdout to its logging view.
I put it in so you can start EditorServices by itself and see logs printed to the console you start it in. I haven't actually tested that that works though.
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.
LGTM Yay async logging 🎉 🎉
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.
Really excited for this change, great work @rjmholt!
Just a couple very minor suggestions.
@@ -54,7 +54,7 @@ public IEditorOperations EditorOperations | |||
/// <param name="messageHandlers">An object that manages all of the message handlers</param> | |||
/// <param name="messageSender">The message sender</param> | |||
/// <param name="serverCompletedTask">A TaskCompletionSource<bool> that will be completed to stop the running process</param> | |||
/// <param name="logger">The logger</param> | |||
/// <param name="logger">the logger</param> |
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.
Any particular reason for changing the case here? Not a big deal, just curious if this was intentional.
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.
Not intentional — the result of changing all the logging doc lines and back again.
|
||
return new PsesLogger(configuration.CreateLogger()); | ||
} | ||
|
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.
Style nitpick: Extra new line can be removed.
{ | ||
return s_nullLogger ?? (s_nullLogger = CreateLogger().Build()); | ||
} | ||
} |
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.
Style nitpick: Add new line to separate members NullLogger
and s_nullLogger
[CallerLineNumber] int callerLineNumber = 0) | ||
{ | ||
_logger.Error("[{Error:l}] {CallerSourceFile:l}: In method '{CallerName:l}', line {CallerLineNumber}:\n {ErrorMessage:l}\n {Exception:l}\n", | ||
LogLevel.Error.ToString().ToUpper(), callerSourceFile, callerName, callerLineNumber, errorMessage, exception); |
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 the result of LogLevel.Error.ToString().ToUpper()
be a constant somewhere instead? I'm assuming that ToString().ToUpper()
will be called on each invocation regardless of log level.
msgLines[i] = msgLines[i].Insert(0, " "); | ||
} | ||
|
||
return String.Join("\n", msgLines)+"\n"; |
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.
Is it feasible to use StringBuilder
here to reduce some string allocations? Something like
var sb = new System.Text.StringBuilder(logMessage);
return sb.Replace("\n", "\n ").ToString();
Edit: I should clarify that I'm referring to the method, not this line in particular
} | ||
|
||
#region IDisposable Support | ||
private bool disposedValue = false; // To detect redundant calls |
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.
Style nitpick: field name should be _disposedValue
and comment should be above.
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.
Agreed, although this is what the "dispose pattern" snippet expands to.
…ervices into logging-serilog
…, use cross-platform newlines
Ok, I think I've finally understood Serilog's template string stuff. Because we do some indirection, we basically don't end up using a lot of it and do our own string processing, which I don't think can really be helped. I've changed the newlines to use Our current log files look something like this:
|
Just to document: Serilog has two levels of string template: the output template and the actual event template. The output template would be useful to us, since it has pre-defined settings for
So instead we call But it's still very worth using Serilog, since it handles all the sinks and the asynchronous stuff very nicely. |
We might be able to do our own string processing and still let Serilog handle the when. You can pass it a custom I wouldn't suggest holding up the PR for any of that though, this is already way better than what we currently have :) |
Yeah, I actually implemented a custom format provider for our It took a surprising amount of code and playing around with the |
Anyway, unless there are any objections, I'll merge this at the end of the day (in about 8 hours). |
After having a few problems with logging and thread safety, I've replaced our hand-rolled logger with Serilog, and in such a way that only one file depends on it. Note that we also have to copy the Serilog DLLs into the module.
There are probably a couple of rough edges that still need patching up here, so please give it a try. Especially on .NET Framework platforms.