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
Expose logger properties on Logger #3424
Conversation
Codecov Report
@@ Coverage Diff @@
## release/4.6.4 #3424 +/- ##
==============================================
- Coverage 80% 80% -<1%
==============================================
Files 358 358
Lines 28373 28517 +144
Branches 3785 3814 +29
==============================================
+ Hits 22750 22838 +88
- Misses 4537 4583 +46
- Partials 1086 1096 +10 |
src/NLog/Logger.cs
Outdated
/// <summary> | ||
/// Properties added with <see cref="WithProperty"/> or <see cref="SetProperty"/> | ||
/// </summary> | ||
public IDictionary<string, object> Properties => _contextProperties ?? new Dictionary<string, object>(); |
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.
You are opening a door to race-condition-hell by returning an unprotected dictionary.
I recommend that you return IReadOnlyDictionary
that only works on the platforms where it is known.
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.
And that race condition isn't there with WithProperty/SetProperty
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 know WithProperty/SetProperty
are nice and sweet (because I made them so). But the evil user that starts calling the IDictionary-inteface to insert/remove elements will break everything.
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, I don't see what it should break. Could you please give an example ?
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.
Very confused that you don't know what happens if one enumerates a collection while another modifies the collection. Made some pseudo-code in new comment.
var logger = LogManager.GetLogger("Hello").WithProperty("Test", 0);
var thread = new Thread(() => {
for (int i = 1; i < 1000000; ++i)
{
logger.Properties.Remove("Test");
logger.Properties.Add("Test", i);
}
});
thread.Start();
for (int i = 0; i < 1000000; ++i)
logger.Info("Hello World"); // Collection was modified |
We could change it to a concurrent dictionary? (Could, not saying we should) |
That would be a bad trade, regarding logging-performance. Since the current reason for adding Properties-properties is to make it easier to see the current values. And the logger will be punished on every logevent with concurrentdictionary. Ofcourse if the IDictionary-logic just created for GDC was extracted then we would have a thread-safe idictionary that could be used here. |
@@ -128,16 +138,15 @@ public void SetProperty(string propertyKey, object propertyValue) | |||
if (string.IsNullOrEmpty(propertyKey)) | |||
throw new ArgumentException(nameof(propertyKey)); | |||
|
|||
_contextProperties = CopyOnWrite(propertyKey, propertyValue); | |||
_contextProperties = CreateContextPropertiesDictionary(_contextProperties); | |||
_contextProperties[propertyKey] = propertyValue; |
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.
This is not good. As you are modifying the active dictionary.
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 really, CreateContextPropertiesDictionary made a new reference. But anyway, I see this PR is already superseded 👼
superseded by #3430 |
fixes #3422 + refactor