Static wrapper class for log4net Logging - thread safety
up vote
1
down vote
favorite
I'm using log4net
in my application and have a static Log
class which creates an instance of ILog
with a default log type, e.g CMS
. The ILog
instance is then used by the class to call the log4net
logging methods passing in a LogItem
type as the log message to enforce a strict logging format.
The user of the class can also change the logger targeted by the logger at runtime by setting a public static property LogType
for example: Log.LogType = Enums.LogType.Database
.
Here is the class:
/// <summary>
/// Log wrapper around ILog - enforces consistent log format.
/// </summary>
public static class Log
{
private static ILog Logger = LogManager.GetLogger(LogType.CMS.ToString());
/// <summary>
/// Sets the Logger to be used.
/// </summary>
public static LogType LogType
{
set
{
Logger = LogManager.GetLogger(value.ToString());
}
}
/// <summary>
/// Logs information to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Info(string source, string description, Exception exc = null)
{
Logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs a warning to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Warn(string source, string description, Exception exc = null)
{
Logger.Warn(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs an error to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Error(string source, string description, Exception exc)
{
Logger.Error(new LogItem() { Source = source, Description = description }, exc);
}
}
I'm concerned on whether the LogType
prop would be thread safe, what would happen if this is changed by another class before the logger does its job?
I've read that log4net
itself is thread safe and will block when calling the appenders - would having a single static class that everything logs through eventually cause a bottleneck?
c# thread-safety logging static log4net
add a comment |
up vote
1
down vote
favorite
I'm using log4net
in my application and have a static Log
class which creates an instance of ILog
with a default log type, e.g CMS
. The ILog
instance is then used by the class to call the log4net
logging methods passing in a LogItem
type as the log message to enforce a strict logging format.
The user of the class can also change the logger targeted by the logger at runtime by setting a public static property LogType
for example: Log.LogType = Enums.LogType.Database
.
Here is the class:
/// <summary>
/// Log wrapper around ILog - enforces consistent log format.
/// </summary>
public static class Log
{
private static ILog Logger = LogManager.GetLogger(LogType.CMS.ToString());
/// <summary>
/// Sets the Logger to be used.
/// </summary>
public static LogType LogType
{
set
{
Logger = LogManager.GetLogger(value.ToString());
}
}
/// <summary>
/// Logs information to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Info(string source, string description, Exception exc = null)
{
Logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs a warning to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Warn(string source, string description, Exception exc = null)
{
Logger.Warn(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs an error to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Error(string source, string description, Exception exc)
{
Logger.Error(new LogItem() { Source = source, Description = description }, exc);
}
}
I'm concerned on whether the LogType
prop would be thread safe, what would happen if this is changed by another class before the logger does its job?
I've read that log4net
itself is thread safe and will block when calling the appenders - would having a single static class that everything logs through eventually cause a bottleneck?
c# thread-safety logging static log4net
enforces consistent log format - not really, it just provides three APIs but it doesn't enforce actually anything because anyone could useLogManager.GetLogger(...);
anywhere in your application and do what they desire.
– t3chb0t
Sep 28 at 9:06
1
This is also not thread-safe because if two threads use theLogType
property at the same time one of them will overwrite the otherone and you'll be logging information from a different thread in the wrong log. You'd better take a look a dependency injection and pass loggers this way.
– t3chb0t
Sep 28 at 9:09
@t3chb0t - Wouldn't the other projects in the solution need a reference tolog4net
to do that? The log class is in it's own project, other projects would not be able to directly callLogManager
without going to the effort of installinglog4net
, unless I'm missing something. RegardingLogType
this was my concern, how would this work with DI? Can you inject property values on the fly? Or is there a way to make it thread safe with alock
maybe? Thanks
– DGibbs
Sep 28 at 9:19
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm using log4net
in my application and have a static Log
class which creates an instance of ILog
with a default log type, e.g CMS
. The ILog
instance is then used by the class to call the log4net
logging methods passing in a LogItem
type as the log message to enforce a strict logging format.
The user of the class can also change the logger targeted by the logger at runtime by setting a public static property LogType
for example: Log.LogType = Enums.LogType.Database
.
Here is the class:
/// <summary>
/// Log wrapper around ILog - enforces consistent log format.
/// </summary>
public static class Log
{
private static ILog Logger = LogManager.GetLogger(LogType.CMS.ToString());
/// <summary>
/// Sets the Logger to be used.
/// </summary>
public static LogType LogType
{
set
{
Logger = LogManager.GetLogger(value.ToString());
}
}
/// <summary>
/// Logs information to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Info(string source, string description, Exception exc = null)
{
Logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs a warning to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Warn(string source, string description, Exception exc = null)
{
Logger.Warn(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs an error to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Error(string source, string description, Exception exc)
{
Logger.Error(new LogItem() { Source = source, Description = description }, exc);
}
}
I'm concerned on whether the LogType
prop would be thread safe, what would happen if this is changed by another class before the logger does its job?
I've read that log4net
itself is thread safe and will block when calling the appenders - would having a single static class that everything logs through eventually cause a bottleneck?
c# thread-safety logging static log4net
I'm using log4net
in my application and have a static Log
class which creates an instance of ILog
with a default log type, e.g CMS
. The ILog
instance is then used by the class to call the log4net
logging methods passing in a LogItem
type as the log message to enforce a strict logging format.
The user of the class can also change the logger targeted by the logger at runtime by setting a public static property LogType
for example: Log.LogType = Enums.LogType.Database
.
Here is the class:
/// <summary>
/// Log wrapper around ILog - enforces consistent log format.
/// </summary>
public static class Log
{
private static ILog Logger = LogManager.GetLogger(LogType.CMS.ToString());
/// <summary>
/// Sets the Logger to be used.
/// </summary>
public static LogType LogType
{
set
{
Logger = LogManager.GetLogger(value.ToString());
}
}
/// <summary>
/// Logs information to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Info(string source, string description, Exception exc = null)
{
Logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs a warning to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Warn(string source, string description, Exception exc = null)
{
Logger.Warn(new LogItem() { Source = source, Description = description }, exc);
}
/// <summary>
/// Logs an error to the system.
/// </summary>
/// <param name="source">Source of the info.</param>
/// <param name="description">Info description.</param>
/// <param name="exc">Associated Exception object.</param>
public static void Error(string source, string description, Exception exc)
{
Logger.Error(new LogItem() { Source = source, Description = description }, exc);
}
}
I'm concerned on whether the LogType
prop would be thread safe, what would happen if this is changed by another class before the logger does its job?
I've read that log4net
itself is thread safe and will block when calling the appenders - would having a single static class that everything logs through eventually cause a bottleneck?
c# thread-safety logging static log4net
c# thread-safety logging static log4net
asked Sep 28 at 8:34
DGibbs
1285
1285
enforces consistent log format - not really, it just provides three APIs but it doesn't enforce actually anything because anyone could useLogManager.GetLogger(...);
anywhere in your application and do what they desire.
– t3chb0t
Sep 28 at 9:06
1
This is also not thread-safe because if two threads use theLogType
property at the same time one of them will overwrite the otherone and you'll be logging information from a different thread in the wrong log. You'd better take a look a dependency injection and pass loggers this way.
– t3chb0t
Sep 28 at 9:09
@t3chb0t - Wouldn't the other projects in the solution need a reference tolog4net
to do that? The log class is in it's own project, other projects would not be able to directly callLogManager
without going to the effort of installinglog4net
, unless I'm missing something. RegardingLogType
this was my concern, how would this work with DI? Can you inject property values on the fly? Or is there a way to make it thread safe with alock
maybe? Thanks
– DGibbs
Sep 28 at 9:19
add a comment |
enforces consistent log format - not really, it just provides three APIs but it doesn't enforce actually anything because anyone could useLogManager.GetLogger(...);
anywhere in your application and do what they desire.
– t3chb0t
Sep 28 at 9:06
1
This is also not thread-safe because if two threads use theLogType
property at the same time one of them will overwrite the otherone and you'll be logging information from a different thread in the wrong log. You'd better take a look a dependency injection and pass loggers this way.
– t3chb0t
Sep 28 at 9:09
@t3chb0t - Wouldn't the other projects in the solution need a reference tolog4net
to do that? The log class is in it's own project, other projects would not be able to directly callLogManager
without going to the effort of installinglog4net
, unless I'm missing something. RegardingLogType
this was my concern, how would this work with DI? Can you inject property values on the fly? Or is there a way to make it thread safe with alock
maybe? Thanks
– DGibbs
Sep 28 at 9:19
enforces consistent log format - not really, it just provides three APIs but it doesn't enforce actually anything because anyone could use
LogManager.GetLogger(...);
anywhere in your application and do what they desire.– t3chb0t
Sep 28 at 9:06
enforces consistent log format - not really, it just provides three APIs but it doesn't enforce actually anything because anyone could use
LogManager.GetLogger(...);
anywhere in your application and do what they desire.– t3chb0t
Sep 28 at 9:06
1
1
This is also not thread-safe because if two threads use the
LogType
property at the same time one of them will overwrite the otherone and you'll be logging information from a different thread in the wrong log. You'd better take a look a dependency injection and pass loggers this way.– t3chb0t
Sep 28 at 9:09
This is also not thread-safe because if two threads use the
LogType
property at the same time one of them will overwrite the otherone and you'll be logging information from a different thread in the wrong log. You'd better take a look a dependency injection and pass loggers this way.– t3chb0t
Sep 28 at 9:09
@t3chb0t - Wouldn't the other projects in the solution need a reference to
log4net
to do that? The log class is in it's own project, other projects would not be able to directly call LogManager
without going to the effort of installing log4net
, unless I'm missing something. Regarding LogType
this was my concern, how would this work with DI? Can you inject property values on the fly? Or is there a way to make it thread safe with a lock
maybe? Thanks– DGibbs
Sep 28 at 9:19
@t3chb0t - Wouldn't the other projects in the solution need a reference to
log4net
to do that? The log class is in it's own project, other projects would not be able to directly call LogManager
without going to the effort of installing log4net
, unless I'm missing something. Regarding LogType
this was my concern, how would this work with DI? Can you inject property values on the fly? Or is there a way to make it thread safe with a lock
maybe? Thanks– DGibbs
Sep 28 at 9:19
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
This is not thread safe, just because the LogType
static property. The basic problem of such design is that any log operation while setting the log type requires two calls and changes in global state. Imagine how an hypothetical client code would look like:
Log.LogType = LogType.Database;
//What happens between these two lines?
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
The first line sets the global log type, and the second uses it, quite simple. But what happens if another thread runs similar code in between? LogType
can be changed in the meanwhile (look at my comment in the code), changing the effective destination to the unsuspecting code. Thus, it's not thread safe. As you mention, since Log4Net in itself is thread safe, logs methods have no problems with this, but the destination can be somewhat surprising.
You mention a lock to overcome this in comments. Again an hypothetical usage could be like this:
lock (typeof(Log))
{
Log.LogType = LogType.Database;
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
}
This solves the issue but at a high cost, the "fix" must be implemented in each and every call, instead of doing it centrally from within the Log
class. Since the operation spans 2 methods, you can't lock within a method. Additionally this increases contention and reduces performance, as all logging is now syncronized and each thread must wait for the others to finish logging. While Log4Net could potentially do the same internally, it may also implement other optimizations, that such approach will nulify.
The root problem comes from the global state, the logger is a just stored in a static variable and can be overwriten by anyone, including between calls. A possible solution would be to pass the log type as a parameter and create a local logger for each call and get rid of the LogType
property altogether:
public static void Info(string source, string description, Exception exc = null, LogType logType = LogType.CMS)
{
ILog logger = LogManager.GetLogger(logType.ToString());
logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
This results in NO global state, which eliminates chances of races conditions, and also simplify client code, as now every log request is a single call to the appropriate method.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f204516%2fstatic-wrapper-class-for-log4net-logging-thread-safety%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
This is not thread safe, just because the LogType
static property. The basic problem of such design is that any log operation while setting the log type requires two calls and changes in global state. Imagine how an hypothetical client code would look like:
Log.LogType = LogType.Database;
//What happens between these two lines?
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
The first line sets the global log type, and the second uses it, quite simple. But what happens if another thread runs similar code in between? LogType
can be changed in the meanwhile (look at my comment in the code), changing the effective destination to the unsuspecting code. Thus, it's not thread safe. As you mention, since Log4Net in itself is thread safe, logs methods have no problems with this, but the destination can be somewhat surprising.
You mention a lock to overcome this in comments. Again an hypothetical usage could be like this:
lock (typeof(Log))
{
Log.LogType = LogType.Database;
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
}
This solves the issue but at a high cost, the "fix" must be implemented in each and every call, instead of doing it centrally from within the Log
class. Since the operation spans 2 methods, you can't lock within a method. Additionally this increases contention and reduces performance, as all logging is now syncronized and each thread must wait for the others to finish logging. While Log4Net could potentially do the same internally, it may also implement other optimizations, that such approach will nulify.
The root problem comes from the global state, the logger is a just stored in a static variable and can be overwriten by anyone, including between calls. A possible solution would be to pass the log type as a parameter and create a local logger for each call and get rid of the LogType
property altogether:
public static void Info(string source, string description, Exception exc = null, LogType logType = LogType.CMS)
{
ILog logger = LogManager.GetLogger(logType.ToString());
logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
This results in NO global state, which eliminates chances of races conditions, and also simplify client code, as now every log request is a single call to the appropriate method.
add a comment |
up vote
1
down vote
This is not thread safe, just because the LogType
static property. The basic problem of such design is that any log operation while setting the log type requires two calls and changes in global state. Imagine how an hypothetical client code would look like:
Log.LogType = LogType.Database;
//What happens between these two lines?
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
The first line sets the global log type, and the second uses it, quite simple. But what happens if another thread runs similar code in between? LogType
can be changed in the meanwhile (look at my comment in the code), changing the effective destination to the unsuspecting code. Thus, it's not thread safe. As you mention, since Log4Net in itself is thread safe, logs methods have no problems with this, but the destination can be somewhat surprising.
You mention a lock to overcome this in comments. Again an hypothetical usage could be like this:
lock (typeof(Log))
{
Log.LogType = LogType.Database;
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
}
This solves the issue but at a high cost, the "fix" must be implemented in each and every call, instead of doing it centrally from within the Log
class. Since the operation spans 2 methods, you can't lock within a method. Additionally this increases contention and reduces performance, as all logging is now syncronized and each thread must wait for the others to finish logging. While Log4Net could potentially do the same internally, it may also implement other optimizations, that such approach will nulify.
The root problem comes from the global state, the logger is a just stored in a static variable and can be overwriten by anyone, including between calls. A possible solution would be to pass the log type as a parameter and create a local logger for each call and get rid of the LogType
property altogether:
public static void Info(string source, string description, Exception exc = null, LogType logType = LogType.CMS)
{
ILog logger = LogManager.GetLogger(logType.ToString());
logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
This results in NO global state, which eliminates chances of races conditions, and also simplify client code, as now every log request is a single call to the appropriate method.
add a comment |
up vote
1
down vote
up vote
1
down vote
This is not thread safe, just because the LogType
static property. The basic problem of such design is that any log operation while setting the log type requires two calls and changes in global state. Imagine how an hypothetical client code would look like:
Log.LogType = LogType.Database;
//What happens between these two lines?
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
The first line sets the global log type, and the second uses it, quite simple. But what happens if another thread runs similar code in between? LogType
can be changed in the meanwhile (look at my comment in the code), changing the effective destination to the unsuspecting code. Thus, it's not thread safe. As you mention, since Log4Net in itself is thread safe, logs methods have no problems with this, but the destination can be somewhat surprising.
You mention a lock to overcome this in comments. Again an hypothetical usage could be like this:
lock (typeof(Log))
{
Log.LogType = LogType.Database;
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
}
This solves the issue but at a high cost, the "fix" must be implemented in each and every call, instead of doing it centrally from within the Log
class. Since the operation spans 2 methods, you can't lock within a method. Additionally this increases contention and reduces performance, as all logging is now syncronized and each thread must wait for the others to finish logging. While Log4Net could potentially do the same internally, it may also implement other optimizations, that such approach will nulify.
The root problem comes from the global state, the logger is a just stored in a static variable and can be overwriten by anyone, including between calls. A possible solution would be to pass the log type as a parameter and create a local logger for each call and get rid of the LogType
property altogether:
public static void Info(string source, string description, Exception exc = null, LogType logType = LogType.CMS)
{
ILog logger = LogManager.GetLogger(logType.ToString());
logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
This results in NO global state, which eliminates chances of races conditions, and also simplify client code, as now every log request is a single call to the appropriate method.
This is not thread safe, just because the LogType
static property. The basic problem of such design is that any log operation while setting the log type requires two calls and changes in global state. Imagine how an hypothetical client code would look like:
Log.LogType = LogType.Database;
//What happens between these two lines?
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
The first line sets the global log type, and the second uses it, quite simple. But what happens if another thread runs similar code in between? LogType
can be changed in the meanwhile (look at my comment in the code), changing the effective destination to the unsuspecting code. Thus, it's not thread safe. As you mention, since Log4Net in itself is thread safe, logs methods have no problems with this, but the destination can be somewhat surprising.
You mention a lock to overcome this in comments. Again an hypothetical usage could be like this:
lock (typeof(Log))
{
Log.LogType = LogType.Database;
Log.Info("CodeReview", "Testing error logging", new Exception("Kaboom"));
}
This solves the issue but at a high cost, the "fix" must be implemented in each and every call, instead of doing it centrally from within the Log
class. Since the operation spans 2 methods, you can't lock within a method. Additionally this increases contention and reduces performance, as all logging is now syncronized and each thread must wait for the others to finish logging. While Log4Net could potentially do the same internally, it may also implement other optimizations, that such approach will nulify.
The root problem comes from the global state, the logger is a just stored in a static variable and can be overwriten by anyone, including between calls. A possible solution would be to pass the log type as a parameter and create a local logger for each call and get rid of the LogType
property altogether:
public static void Info(string source, string description, Exception exc = null, LogType logType = LogType.CMS)
{
ILog logger = LogManager.GetLogger(logType.ToString());
logger.Info(new LogItem() { Source = source, Description = description }, exc);
}
This results in NO global state, which eliminates chances of races conditions, and also simplify client code, as now every log request is a single call to the appropriate method.
answered Oct 13 at 15:29
Alejandro
30829
30829
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f204516%2fstatic-wrapper-class-for-log4net-logging-thread-safety%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
enforces consistent log format - not really, it just provides three APIs but it doesn't enforce actually anything because anyone could use
LogManager.GetLogger(...);
anywhere in your application and do what they desire.– t3chb0t
Sep 28 at 9:06
1
This is also not thread-safe because if two threads use the
LogType
property at the same time one of them will overwrite the otherone and you'll be logging information from a different thread in the wrong log. You'd better take a look a dependency injection and pass loggers this way.– t3chb0t
Sep 28 at 9:09
@t3chb0t - Wouldn't the other projects in the solution need a reference to
log4net
to do that? The log class is in it's own project, other projects would not be able to directly callLogManager
without going to the effort of installinglog4net
, unless I'm missing something. RegardingLogType
this was my concern, how would this work with DI? Can you inject property values on the fly? Or is there a way to make it thread safe with alock
maybe? Thanks– DGibbs
Sep 28 at 9:19