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
Improve EventLogTarget installation logic - handle MaximumKilobytes for apps without elevated privileges #3017
Improve EventLogTarget installation logic - handle MaximumKilobytes for apps without elevated privileges #3017
Conversation
Remove MaximumKilobytes setting from GetEventLog(), because when app is run without elevated privileges, the method spams exceptions. Move MaximumKilobytes setting to installation (and initialization) phase, when the application is typically run with elevated privileges. Add logic to not override a bigger value of MaximumKilobytes, because the Event log can be used by multiple Sources, each having its own space requirements.
Codecov Report
@@ Coverage Diff @@
## dev #3017 +/- ##
======================================
- Coverage 80% 80% -<1%
======================================
Files 338 341 +3
Lines 26615 27014 +399
Branches 3521 3586 +65
======================================
+ Hits 21261 21574 +313
- Misses 4356 4419 +63
- Partials 998 1021 +23 |
Hi again, @304NotModified, what are the expected actions to address the "codecov/patch" check? |
To improve testability wrap EventLog with EventLogStaticWrapper and EventLogInstanceWrapper - implementations of IEventLogStaticWrapper and IEventLogInstanceWrapper. Fix spelling, typos, clarify some comments. Refactor several unit tests into a 'Theory' with InlineData, in particular "TruncatedMessagesShould..." and "SplittedMessagesShould..." tests. Add unit tests to check MaxKilobytes initialized from configuration, EventLogTarget.MaxKilobytes setter for positive, negative, corner cases. Add unit tests to check the behaviour during installation using EventLogStaticMock and EventLogInstanceStub.
Hi, @304NotModified. Could you please check if the codecov/patch actually ran on 84319d6? |
src/NLog/Targets/EventLogTarget.cs
Outdated
/// Gets or sets the provider of Windows event log static methods to be utilized by <see cref="EventLogTarget"/>. | ||
/// </summary> | ||
/// <remarks>Introduced to improve the testability of the class.</remarks> | ||
protected internal IEventLogStaticWrapper EventLogStaticMethods { get; set; } = EventLogStaticWrapper.Instance; |
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.
Think it would be nicer if you implemented an internal constructor that took an internal IEventLogWrapper-interface as input parameter. The default constructor would then call the new internal constructor with a private-class-implementation of the IEventLogWrapper-interface. Ofcourse the unit-tests will not be able to test initialization from NLog.config, but I think that is okay. protected internal
means that it becomes part of the public interface.
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 get your point on injecting the implementation in the constructor instead of the property. But you mentioned an IEventLogWrapper
, do you suggest merging the IEventLogStaticWrapper
and IEventLogInstanceWrapper
?
Also, you think these new interfaces and implementations should not fall under protected internal
?
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.
do you suggest merging the IEventLogStaticWrapper and IEventLogInstanceWrapper?
Yes I would prefer just a single interface. And this interface and the constructor getting it as parameter are both marked as internal
-only (Not protected).
Move magic numbers to constants. Inject the event log wrapper through internal constructor. Unite the IEventLogStaticWrapper and IEventLogInstanceWrapper into a single IEventLogWrapper.
Hi, @snakefoot. I've addressed your comments in 5017749, but the build failed. Can you, or maybe @304NotModified, assist? |
Was thinking that all public constructors should call the unified internal constructor: private readonly IEventLogWrapper _eventLogWrapper;
/// <summary>
/// Initializes a new instance of the <see cref="EventLogTarget"/> class.
/// </summary>
public EventLogTarget()
: this(null, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="EventLogTarget"/> class.
/// </summary>
/// <param name="name">Name of the target.</param>
public EventLogTarget(string name)
: this(null, null)
{
Name = name;
}
/// <summary>
/// Initializes a new instance of the <see cref="EventLogTarget"/> class.
/// </summary>
public EventLogTarget(IAppDomain appDomain)
: this(null, appDomain)
{
}
internal EventLogTarget(IEventLogWrapper eventLogWrapper, IAppDomain appDomain)
{
_eventLogWrapper = eventLogWrapper ?? new EventLogWrapper()
appDomain = appDomain ?? LogFactory.CurrentAppDomain;
Source = appDomain.FriendlyName;
Log = "Application";
MachineName = ".";
MaxMessageLength = EventLogMaxMessageLength;
OptimizeBufferReuse = GetType() == typeof(EventLogTarget); // Class not sealed, reduce breaking changes
} |
@Coriolanuss I know it is weird with the constructor We have to keep it until NLog ver. 5.0 where it can be removed. You are welcome to add the obsolete attribute. Ex: [Obsolete("This constructor will be removed in NLog 5. Marked obsolete on NLog 4.6")]
public EventLogTarget(IAppDomain appDomain)
: this(null, appDomain)
{
} |
Hi @snakefoot, I have brought back the constructor. Any other suggestions? |
No I think it looks great. Especially with the improved tests.
But I don't have the final verdict :)
|
It's nice to hear. |
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! please move the new interfaces/classes (the interface to the "internal" folder and namespace) to new files (don't forget to copy the license header) and then I will merge this one.
PS: builds failed, not sure what's wrong but restarted all of them
You approval says a lot anyway 👍 |
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.
please move the new interfaces/classes (the interface to the "internal" folder and namespace) to new files (don't forget to copy the license header)
Maybe that isn't that easy with the multi projects now, so fine for now :) |
Merged, thanks for the contribution and unit tests! |
Remove MaximumKilobytes setting from GetEventLog(), because when app is run without elevated privileges, the method spams exceptions.
Move MaximumKilobytes setting to installation (and initialization) phase, when the application is typically run with elevated privileges.
Add logic to not override a bigger value of MaximumKilobytes, because the Event log can be used by multiple Sources, each having its own space requirements.