|
From: Geoghegan, W. A (Willie) <wil...@in...> - 2010-10-01 21:46:50
|
Part 2.
I also implemented a thread stack (NDC) for
Trace.CorrelationManager.LogicalOperationStack.
I also provided an implementation of GlobalProperties, ThreadProperties,
and ThreadStack (taken largely from NLog). They could be used in a
context where there is not a "real" logging platform behind the
Common.Logging abstraction. Say you have a logger for Silverlight that
logs to the debugger and might log to a WCF LogService. Context can
still be captured. The logging implementation, such as it is, can get
the context information and do something with it. Don't know how useful
it will prove to.
This could easily occur inside of LogManager so a user of Common.Logging
could write something like this:
LogManager.GlobalProperties["name"] = "hello"; //set the "name" global
property on currently abstracted logging platform.
Some notable items:
1. Log4net provides properties and stack info for both "thread"
and "logical thread". From what I can tell, the "thread" values
(formerly MDC and NDC) are way more commonly used then the "logical
thread" values. Castle did not implement an abstraction for the
"logical" flavor.
2. Log4net provides for multiple stacks per thread. Castle exposes
this.
3. NLog does not provide a "logical thread" context, even in NLog
2.0. Castle's implementation exposes "ThreadStacks" (presumably to
support log4net's multiple stacks) but the implementation always hands
back the one NLog stack (NDC/NestedDiagnosticContext) for the thread,
regardless of what stack was requested.
4. Log4net allows objects to be set in the "properties" collections
and strings to be pushed onto the stacks. NLog only allows strings as
"properties" and entries on the stack. Castle exposes a string for both
the "properties" and the stack.
5. Castle based their "properties" implementation on log4net's
"BaseProperties" (maybe not right name), which has only a get/set
property bag interface. As such, they did not implement Clear or
Remove. It seems to make more sense to have Clear and Remove.
If the most common usage of the thread stacks is to have one stack
(NDC), and since NLog has only one stack anyway, I wonder if it really
makes sense to expose the stacks/stack such that you have to write code
like this:
LogContext.ThreadStacks["NDC"].Push("whatever");
Maybe it is better to either only expose one stack or expose a stack AND
a dictionary of stacks. Normally one might just use the single (or
default) stack. If there is a particular application or workflow that
wants to use multiple stacks, they would be there.
LogContext.ThreadStack.Push("whatever"); //pushes onto NDC
LogContext.ThreadStacks["custom stack"].Push("whatever"); //pushes onto
custom stack.
If anyone at Common.Logging is interested in discussing this and whether
or it is relevant or not to Common.Logging's implementation (when?) of
logging contexts, please respond. Also, if anyone at Common.Logging
would like to see what I have done and how it might or might not fit
into Common.Logging, also please respond.
Thanks.
Willie Geoghegan.
|
|
From: Geoghegan, W. A (Willie) <wil...@in...> - 2010-10-01 21:47:40
|
Too long again. Part 1.
I have seen on the Common.Logging home page that Logging Context support
is planned for the next release. In the meantime, I have implemented a
logging context abstraction that is based, in part, on Castle's logging
context abstraction that they provide for log4net and NLog. At this
point I consider it somewhat experimental, but I think there are some ok
ideas here. I also did not modify any Common.Logging code. In a "real"
implementation, I would expect that context would be available from
LogManager (or maybe from ILog as was done in Castle). I think that
making it available from ILog could be misleading because it could be
read as "the logging context for THIS logger", which is not really true.
Anyway, with my code you can do something like to this to set the
context (LogContext is my static object that provides the entry point
into the logging context abstraction):
LogContext.GlobalProperties["number"] = 1234;
LogContext.ThreadProperties["id"] = System.Threading.Whatever.Id;
using (LogContext.ThreadStack.Push["outer level"])
{
DoSomeStuff();
using (LogContext.ThreadStack.Push["inner level")
{
DoSomeStuffFromInnerLevel();
}
}
Which logging context abstraction is in play is dictated by the current
LogManager.Adapter's implementation (or lack of same) of an interface,
IContextProvider. When one of the context operations (GlobalProperties,
ThreadProperties, ThreadStack) is access on LogContext, code like this
executes:
IContextProperties GlobalProperties
{
get
{
IAdapterContextProvider iacp = LogManager.Adapter as
IContextProvider;
if (iacp == null)
{
return NullContextProvider.GlobalProperties; //Does nothing, but
also does not fail.
}
else
{
return iacp.Context.GlobalProperties; //Global properties relevant
to the currently abstracted logger
}
}
}
To take advantage of LogContext, I have copied the NLog abstraction
provided by Common.Logging and added the IAdapterContextProvider
interface. Now, when I configure my NLog abstraction, LogContext finds
that LogManager.Adapter does support the interface, so the NLog context
values can be set. I have done something similar for log4net.
William A. Geoghegan
Software Scientist
Intergraph Corporation
Security, Government & Infrastructure (SG&I) Division
P.O. Box 6695, Huntsville, AL 35824-0695 USA
P 1.256.730.8371
wil...@in..., www.intergraph.com
|
|
From: Kenneth Xu <ke...@ho...> - 2010-10-11 13:40:47
|
William, I'm forwarding to Erich directly to see if he is still maintaining
the project.
On Fri, Oct 1, 2010 at 5:47 PM, Geoghegan, William A (Willie) <
wil...@in...> wrote:
> Too long again. Part 1.
>
> I have seen on the Common.Logging home page that Logging Context support is
> planned for the next release. In the meantime, I have implemented a logging
> context abstraction that is based, in part, on Castle’s logging context
> abstraction that they provide for log4net and NLog. At this point I
> consider it somewhat experimental, but I think there are some ok ideas
> here. I also did not modify any Common.Logging code. In a “real”
> implementation, I would expect that context would be available from
> LogManager (or maybe from ILog as was done in Castle). I think that making
> it available from ILog could be misleading because it could be read as “the
> logging context for THIS logger”, which is not really true.
>
> Anyway, with my code you can do something like to this to set the context
> (LogContext is my static object that provides the entry point into the
> logging context abstraction):
>
> LogContext.GlobalProperties[“number”] = 1234;
>
> LogContext.ThreadProperties[“id”] = System.Threading.Whatever.Id;
>
> using (LogContext.ThreadStack.Push[“outer level”])
>
> {
>
> DoSomeStuff();
>
>
>
> using (LogContext.ThreadStack.Push[“inner level”)
>
> {
>
> DoSomeStuffFromInnerLevel();
>
> }
>
> }
>
> Which logging context abstraction is in play is dictated by the current
> LogManager.Adapter’s implementation (or lack of same) of an interface,
> IContextProvider. When one of the context operations (GlobalProperties,
> ThreadProperties, ThreadStack) is access on LogContext, code like this
> executes:
>
> IContextProperties GlobalProperties
>
> {
>
> get
>
> {
>
> IAdapterContextProvider iacp = LogManager.Adapter as IContextProvider;
>
> if (iacp == null)
>
> {
>
> return NullContextProvider.GlobalProperties; //Does nothing, but also
> does not fail.
>
> }
>
> else
>
> {
>
> return iacp.Context.GlobalProperties; //Global properties relevant to
> the currently abstracted logger
>
> }
>
> }
>
> }
>
> To take advantage of LogContext, I have copied the NLog abstraction
> provided by Common.Logging and added the IAdapterContextProvider interface.
> Now, when I configure my NLog abstraction, LogContext finds that
> LogManager.Adapter does support the interface, so the NLog context values
> can be set. I have done something similar for log4net.
>
> *******William A. Geoghegan*
> Software Scientist
> Intergraph Corporation
> Security, Government & Infrastructure (SG&I) Division
> P.O. Box 6695, Huntsville, AL 35824-0695 USA
> *******P* 1.256.730.8371
> *****wil...@in...*, www.intergraph.com
>
>
>
> ------------------------------------------------------------------------------
> Start uncovering the many advantages of virtual appliances
> and start using them to simplify application deployment and
> accelerate your shift to cloud computing.
> http://p.sf.net/sfu/novell-sfdev2dev
> _______________________________________________
> Netcommon-developer mailing list
> Net...@li...
> https://lists.sourceforge.net/lists/listinfo/netcommon-developer
>
>
|
|
From: Erich E. <eei...@gm...> - 2010-10-11 13:45:09
|
Hi folks,
yes, I am. Unfortunately I am quite busy atm, I will come back to you as soon as possible, probably next week.
Thanks a lot Will for your effort, highly appreciated. Next week I hopefully have time to carefully read you posts and comment on them. Please be patient ;-)
cheers,
Erich
From: ken...@gm... [mailto:ken...@gm...] On Behalf Of Kenneth Xu
Sent: 11 October 2010 14:41
To: Geoghegan, William A (Willie); Erich Eichinger
Cc: net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
William, I'm forwarding to Erich directly to see if he is still maintaining the project.
On Fri, Oct 1, 2010 at 5:47 PM, Geoghegan, William A (Willie) <wil...@in...> wrote:
Too long again. Part 1.
I have seen on the Common.Logging home page that Logging Context support is planned for the next release. In the meantime, I have implemented a logging context abstraction that is based, in part, on Castle’s logging context abstraction that they provide for log4net and NLog. At this point I consider it somewhat experimental, but I think there are some ok ideas here. I also did not modify any Common.Logging code. In a “real” implementation, I would expect that context would be available from LogManager (or maybe from ILog as was done in Castle). I think that making it available from ILog could be misleading because it could be read as “the logging context for THIS logger”, which is not really true.
Anyway, with my code you can do something like to this to set the context (LogContext is my static object that provides the entry point into the logging context abstraction):
LogContext.GlobalProperties[“number”] = 1234;
LogContext.ThreadProperties[“id”] = System.Threading.Whatever.Id;
using (LogContext.ThreadStack.Push[“outer level”])
{
DoSomeStuff();
using (LogContext.ThreadStack.Push[“inner level”)
{
DoSomeStuffFromInnerLevel();
}
}
Which logging context abstraction is in play is dictated by the current LogManager.Adapter’s implementation (or lack of same) of an interface, IContextProvider. When one of the context operations (GlobalProperties, ThreadProperties, ThreadStack) is access on LogContext, code like this executes:
IContextProperties GlobalProperties
{
get
{
IAdapterContextProvider iacp = LogManager.Adapter as IContextProvider;
if (iacp == null)
{
return NullContextProvider.GlobalProperties; //Does nothing, but also does not fail.
}
else
{
return iacp.Context.GlobalProperties; //Global properties relevant to the currently abstracted logger
}
}
}
To take advantage of LogContext, I have copied the NLog abstraction provided by Common.Logging and added the IAdapterContextProvider interface. Now, when I configure my NLog abstraction, LogContext finds that LogManager.Adapter does support the interface, so the NLog context values can be set. I have done something similar for log4net.
William A. Geoghegan
Software Scientist
Intergraph Corporation
Security, Government & Infrastructure (SG&I) Division
P.O. Box 6695, Huntsville, AL 35824-0695 USA
P 1.256.730.8371
wil...@in..., www.intergraph.com
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Netcommon-developer mailing list
Net...@li...
https://lists.sourceforge.net/lists/listinfo/netcommon-developer
|
|
From: Geoghegan, W. A (Willie) <wil...@in...> - 2010-10-11 13:55:55
|
Erich,
Thanks. I understand about being busy. Feel free to contact me directly or via the netcommon list if you have any questions about what I have posted. I don’t know if there is any way that I can contribute, but I could certainly send you some work that I have done and you could decide for yourself if it looks useful or not.
Thanks again.
Willie.
From: Erich Eichinger [mailto:eei...@gm...]
Sent: Monday, October 11, 2010 8:45 AM
To: 'Kenneth Xu'; Geoghegan, William A (Willie)
Cc: net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
Hi folks,
yes, I am. Unfortunately I am quite busy atm, I will come back to you as soon as possible, probably next week.
Thanks a lot Will for your effort, highly appreciated. Next week I hopefully have time to carefully read you posts and comment on them. Please be patient ;-)
cheers,
Erich
From: ken...@gm... [mailto:ken...@gm...] On Behalf Of Kenneth Xu
Sent: 11 October 2010 14:41
To: Geoghegan, William A (Willie); Erich Eichinger
Cc: net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
William, I'm forwarding to Erich directly to see if he is still maintaining the project.
On Fri, Oct 1, 2010 at 5:47 PM, Geoghegan, William A (Willie) <wil...@in...> wrote:
Too long again. Part 1.
I have seen on the Common.Logging home page that Logging Context support is planned for the next release. In the meantime, I have implemented a logging context abstraction that is based, in part, on Castle’s logging context abstraction that they provide for log4net and NLog. At this point I consider it somewhat experimental, but I think there are some ok ideas here. I also did not modify any Common.Logging code. In a “real” implementation, I would expect that context would be available from LogManager (or maybe from ILog as was done in Castle). I think that making it available from ILog could be misleading because it could be read as “the logging context for THIS logger”, which is not really true.
Anyway, with my code you can do something like to this to set the context (LogContext is my static object that provides the entry point into the logging context abstraction):
LogContext.GlobalProperties[“number”] = 1234;
LogContext.ThreadProperties[“id”] = System.Threading.Whatever.Id;
using (LogContext.ThreadStack.Push[“outer level”])
{
DoSomeStuff();
using (LogContext.ThreadStack.Push[“inner level”)
{
DoSomeStuffFromInnerLevel();
}
}
Which logging context abstraction is in play is dictated by the current LogManager.Adapter’s implementation (or lack of same) of an interface, IContextProvider. When one of the context operations (GlobalProperties, ThreadProperties, ThreadStack) is access on LogContext, code like this executes:
IContextProperties GlobalProperties
{
get
{
IAdapterContextProvider iacp = LogManager.Adapter as IContextProvider;
if (iacp == null)
{
return NullContextProvider.GlobalProperties; //Does nothing, but also does not fail.
}
else
{
return iacp.Context.GlobalProperties; //Global properties relevant to the currently abstracted logger
}
}
}
To take advantage of LogContext, I have copied the NLog abstraction provided by Common.Logging and added the IAdapterContextProvider interface. Now, when I configure my NLog abstraction, LogContext finds that LogManager.Adapter does support the interface, so the NLog context values can be set. I have done something similar for log4net.
William A. Geoghegan
Software Scientist
Intergraph Corporation
Security, Government & Infrastructure (SG&I) Division
P.O. Box 6695, Huntsville, AL 35824-0695 USA
P 1.256.730.8371
wil...@in..., www.intergraph.com
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Netcommon-developer mailing list
Net...@li...
https://lists.sourceforge.net/lists/listinfo/netcommon-developer
|
|
From: Kenneth Xu <ke...@ho...> - 2010-10-11 23:54:56
|
I'm too interested in this, so it would be nice if we can keep the
conversation here instead of private. There aren't many subscriber on this
list anyway.
Thanks,
Kenneth
On Mon, Oct 11, 2010 at 9:49 AM, Geoghegan, William A (Willie) <
wil...@in...> wrote:
> Erich,
>
>
>
> Thanks. I understand about being busy. Feel free to contact me directly
> or via the netcommon list if you have any questions about what I have
> posted. I don’t know if there is any way that I can contribute, but I could
> certainly send you some work that I have done and you could decide for
> yourself if it looks useful or not.
>
>
>
> Thanks again.
>
>
>
> Willie.
>
>
>
> *From:* Erich Eichinger [mailto:eei...@gm...]
> *Sent:* Monday, October 11, 2010 8:45 AM
> *To:* 'Kenneth Xu'; Geoghegan, William A (Willie)
>
> *Cc:* net...@li...
> *Subject:* Re: [Netcommon-developer] Common.Logging and logging contexts
>
>
>
> Hi folks,
>
>
>
> yes, I am. Unfortunately I am quite busy atm, I will come back to you as
> soon as possible, probably next week.
>
>
>
> Thanks a lot Will for your effort, highly appreciated. Next week I
> hopefully have time to carefully read you posts and comment on them. Please
> be patient ;-)
>
>
>
> cheers,
>
> Erich
>
>
>
> *From:* ken...@gm... [mailto:ken...@gm...] *On Behalf Of *Kenneth
> Xu
> *Sent:* 11 October 2010 14:41
> *To:* Geoghegan, William A (Willie); Erich Eichinger
> *Cc:* net...@li...
> *Subject:* Re: [Netcommon-developer] Common.Logging and logging contexts
>
>
>
> William, I'm forwarding to Erich directly to see if he is still maintaining
> the project.
>
> On Fri, Oct 1, 2010 at 5:47 PM, Geoghegan, William A (Willie) <
> wil...@in...> wrote:
>
> Too long again. Part 1.
>
> I have seen on the Common.Logging home page that Logging Context support is
> planned for the next release. In the meantime, I have implemented a logging
> context abstraction that is based, in part, on Castle’s logging context
> abstraction that they provide for log4net and NLog. At this point I
> consider it somewhat experimental, but I think there are some ok ideas
> here. I also did not modify any Common.Logging code. In a “real”
> implementation, I would expect that context would be available from
> LogManager (or maybe from ILog as was done in Castle). I think that making
> it available from ILog could be misleading because it could be read as “the
> logging context for THIS logger”, which is not really true.
>
> Anyway, with my code you can do something like to this to set the context
> (LogContext is my static object that provides the entry point into the
> logging context abstraction):
>
> LogContext.GlobalProperties[“number”] = 1234;
>
> LogContext.ThreadProperties[“id”] = System.Threading.Whatever.Id;
>
> using (LogContext.ThreadStack.Push[“outer level”])
>
> {
>
> DoSomeStuff();
>
>
>
> using (LogContext.ThreadStack.Push[“inner level”)
>
> {
>
> DoSomeStuffFromInnerLevel();
>
> }
>
> }
>
> Which logging context abstraction is in play is dictated by the current
> LogManager.Adapter’s implementation (or lack of same) of an interface,
> IContextProvider. When one of the context operations (GlobalProperties,
> ThreadProperties, ThreadStack) is access on LogContext, code like this
> executes:
>
> IContextProperties GlobalProperties
>
> {
>
> get
>
> {
>
> IAdapterContextProvider iacp = LogManager.Adapter as IContextProvider;
>
> if (iacp == null)
>
> {
>
> return NullContextProvider.GlobalProperties; //Does nothing, but also
> does not fail.
>
> }
>
> else
>
> {
>
> return iacp.Context.GlobalProperties; //Global properties relevant to
> the currently abstracted logger
>
> }
>
> }
>
> }
>
> To take advantage of LogContext, I have copied the NLog abstraction
> provided by Common.Logging and added the IAdapterContextProvider interface.
> Now, when I configure my NLog abstraction, LogContext finds that
> LogManager.Adapter does support the interface, so the NLog context values
> can be set. I have done something similar for log4net.
>
> *William A. Geoghegan*
> Software Scientist
> Intergraph Corporation
> Security, Government & Infrastructure (SG&I) Division
> P.O. Box 6695, Huntsville, AL 35824-0695 USA
> *P* 1.256.730.8371
> *wil...@in...*, www.intergraph.com
>
>
>
> ------------------------------------------------------------------------------
> Start uncovering the many advantages of virtual appliances
> and start using them to simplify application deployment and
> accelerate your shift to cloud computing.
> http://p.sf.net/sfu/novell-sfdev2dev
> _______________________________________________
> Netcommon-developer mailing list
> Net...@li...
> https://lists.sourceforge.net/lists/listinfo/netcommon-developer
>
>
>
|
|
From: Geoghegan, W. A (Willie) <wil...@in...> - 2010-10-12 13:45:15
|
That’s ok with me. My only complaint about the list is that it keeps rejecting my mails because they are too long. Maybe I should try to be a bit less verbose ;-)
From: ken...@gm... [mailto:ken...@gm...] On Behalf Of Kenneth Xu
Sent: Monday, October 11, 2010 6:55 PM
To: Geoghegan, William A (Willie)
Cc: Erich Eichinger; net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
I'm too interested in this, so it would be nice if we can keep the conversation here instead of private. There aren't many subscriber on this list anyway.
Thanks,
Kenneth
On Mon, Oct 11, 2010 at 9:49 AM, Geoghegan, William A (Willie) <wil...@in...> wrote:
Erich,
Thanks. I understand about being busy. Feel free to contact me directly or via the netcommon list if you have any questions about what I have posted. I don’t know if there is any way that I can contribute, but I could certainly send you some work that I have done and you could decide for yourself if it looks useful or not.
Thanks again.
Willie.
From: Erich Eichinger [mailto:eei...@gm...]
Sent: Monday, October 11, 2010 8:45 AM
To: 'Kenneth Xu'; Geoghegan, William A (Willie)
Cc: net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
Hi folks,
yes, I am. Unfortunately I am quite busy atm, I will come back to you as soon as possible, probably next week.
Thanks a lot Will for your effort, highly appreciated. Next week I hopefully have time to carefully read you posts and comment on them. Please be patient ;-)
cheers,
Erich
From: ken...@gm... [mailto:ken...@gm...] On Behalf Of Kenneth Xu
Sent: 11 October 2010 14:41
To: Geoghegan, William A (Willie); Erich Eichinger
Cc: net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
William, I'm forwarding to Erich directly to see if he is still maintaining the project.
On Fri, Oct 1, 2010 at 5:47 PM, Geoghegan, William A (Willie) <wil...@in...> wrote:
Too long again. Part 1.
I have seen on the Common.Logging home page that Logging Context support is planned for the next release. In the meantime, I have implemented a logging context abstraction that is based, in part, on Castle’s logging context abstraction that they provide for log4net and NLog. At this point I consider it somewhat experimental, but I think there are some ok ideas here. I also did not modify any Common.Logging code. In a “real” implementation, I would expect that context would be available from LogManager (or maybe from ILog as was done in Castle). I think that making it available from ILog could be misleading because it could be read as “the logging context for THIS logger”, which is not really true.
Anyway, with my code you can do something like to this to set the context (LogContext is my static object that provides the entry point into the logging context abstraction):
LogContext.GlobalProperties[“number”] = 1234;
LogContext.ThreadProperties[“id”] = System.Threading.Whatever.Id;
using (LogContext.ThreadStack.Push[“outer level”])
{
DoSomeStuff();
using (LogContext.ThreadStack.Push[“inner level”)
{
DoSomeStuffFromInnerLevel();
}
}
Which logging context abstraction is in play is dictated by the current LogManager.Adapter’s implementation (or lack of same) of an interface, IContextProvider. When one of the context operations (GlobalProperties, ThreadProperties, ThreadStack) is access on LogContext, code like this executes:
IContextProperties GlobalProperties
{
get
{
IAdapterContextProvider iacp = LogManager.Adapter as IContextProvider;
if (iacp == null)
{
return NullContextProvider.GlobalProperties; //Does nothing, but also does not fail.
}
else
{
return iacp.Context.GlobalProperties; //Global properties relevant to the currently abstracted logger
}
}
}
To take advantage of LogContext, I have copied the NLog abstraction provided by Common.Logging and added the IAdapterContextProvider interface. Now, when I configure my NLog abstraction, LogContext finds that LogManager.Adapter does support the interface, so the NLog context values can be set. I have done something similar for log4net.
William A. Geoghegan
Software Scientist
Intergraph Corporation
Security, Government & Infrastructure (SG&I) Division
P.O. Box 6695, Huntsville, AL 35824-0695 USA
P 1.256.730.8371
wil...@in..., www.intergraph.com
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Netcommon-developer mailing list
Net...@li...
https://lists.sourceforge.net/lists/listinfo/netcommon-developer
|
|
From: Geoghegan, W. A (Willie) <wil...@in...> - 2010-10-11 13:51:57
|
Thanks, I appreciate it.
From: ken...@gm... [mailto:ken...@gm...] On Behalf Of Kenneth Xu
Sent: Monday, October 11, 2010 8:41 AM
To: Geoghegan, William A (Willie); Erich Eichinger
Cc: net...@li...
Subject: Re: [Netcommon-developer] Common.Logging and logging contexts
William, I'm forwarding to Erich directly to see if he is still maintaining the project.
On Fri, Oct 1, 2010 at 5:47 PM, Geoghegan, William A (Willie) <wil...@in...> wrote:
Too long again. Part 1.
I have seen on the Common.Logging home page that Logging Context support is planned for the next release. In the meantime, I have implemented a logging context abstraction that is based, in part, on Castle’s logging context abstraction that they provide for log4net and NLog. At this point I consider it somewhat experimental, but I think there are some ok ideas here. I also did not modify any Common.Logging code. In a “real” implementation, I would expect that context would be available from LogManager (or maybe from ILog as was done in Castle). I think that making it available from ILog could be misleading because it could be read as “the logging context for THIS logger”, which is not really true.
Anyway, with my code you can do something like to this to set the context (LogContext is my static object that provides the entry point into the logging context abstraction):
LogContext.GlobalProperties[“number”] = 1234;
LogContext.ThreadProperties[“id”] = System.Threading.Whatever.Id;
using (LogContext.ThreadStack.Push[“outer level”])
{
DoSomeStuff();
using (LogContext.ThreadStack.Push[“inner level”)
{
DoSomeStuffFromInnerLevel();
}
}
Which logging context abstraction is in play is dictated by the current LogManager.Adapter’s implementation (or lack of same) of an interface, IContextProvider. When one of the context operations (GlobalProperties, ThreadProperties, ThreadStack) is access on LogContext, code like this executes:
IContextProperties GlobalProperties
{
get
{
IAdapterContextProvider iacp = LogManager.Adapter as IContextProvider;
if (iacp == null)
{
return NullContextProvider.GlobalProperties; //Does nothing, but also does not fail.
}
else
{
return iacp.Context.GlobalProperties; //Global properties relevant to the currently abstracted logger
}
}
}
To take advantage of LogContext, I have copied the NLog abstraction provided by Common.Logging and added the IAdapterContextProvider interface. Now, when I configure my NLog abstraction, LogContext finds that LogManager.Adapter does support the interface, so the NLog context values can be set. I have done something similar for log4net.
William A. Geoghegan
Software Scientist
Intergraph Corporation
Security, Government & Infrastructure (SG&I) Division
P.O. Box 6695, Huntsville, AL 35824-0695 USA
P 1.256.730.8371
wil...@in..., www.intergraph.com
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Netcommon-developer mailing list
Net...@li...
https://lists.sourceforge.net/lists/listinfo/netcommon-developer
|
|
From: Geoghegan, W. A (Willie) <wil...@in...> - 2010-10-01 21:44:21
|
I have seen on the Common.Logging home page that Logging Context support
is planned for the next release. In the meantime, I have implemented a
logging context abstraction that is based, in part, on Castle's logging
context abstraction that they provide for log4net and NLog. At this
point I consider it somewhat experimental, but I think there are some ok
ideas here. I also did not modify any Common.Logging code. In a "real"
implementation, I would expect that context would be available from
LogManager (or maybe from ILog as was done in Castle). I think that
making it available from ILog could be misleading because it could be
read as "the logging context for THIS logger", which is not really true.
Anyway, with my code you can do something like to this to set the
context (LogContext is my static object that provides the entry point
into the logging context abstraction):
LogContext.GlobalProperties["number"] = 1234;
LogContext.ThreadProperties["id"] = System.Threading.Whatever.Id;
using (LogContext.ThreadStack.Push["outer level"])
{
DoSomeStuff();
using (LogContext.ThreadStack.Push["inner level")
{
DoSomeStuffFromInnerLevel();
}
}
Which logging context abstraction is in play is dictated by the current
LogManager.Adapter's implementation (or lack of same) of an interface,
IContextProvider. When one of the context operations (GlobalProperties,
ThreadProperties, ThreadStack) is access on LogContext, code like this
executes:
IContextProperties GlobalProperties
{
get
{
IAdapterContextProvider iacp = LogManager.Adapter as
IContextProvider;
if (iacp == null)
{
return NullContextProvider.GlobalProperties; //Does nothing, but
also does not fail.
}
else
{
return iacp.Context.GlobalProperties; //Global properties relevant
to the currently abstracted logger
}
}
}
To take advantage of LogContext, I have copied the NLog abstraction
provided by Common.Logging and added the IAdapterContextProvider
interface. Now, when I configure my NLog abstraction, LogContext finds
that LogManager.Adapter does support the interface, so the NLog context
values can be set. I have done something similar for log4net.
I also implemented a thread stack (NDC) for
Trace.CorrelationManager.LogicalOperationStack.
I also provided an implementation of GlobalProperties, ThreadProperties,
and ThreadStack (taken largely from NLog). They could be used in a
context where there is not a "real" logging platform behind the
Common.Logging abstraction. Say you have a logger for Silverlight that
logs to the debugger and might log to a WCF LogService. Context can
still be captured. The logging implementation, such as it is, can get
the context information and do something with it. Don't know how useful
it will prove to.
This could easily occur inside of LogManager so a user of Common.Logging
could write something like this:
LogManager.GlobalProperties["name"] = "hello"; //set the "name" global
property on currently abstracted logging platform.
Some notable items:
1. Log4net provides properties and stack info for both "thread"
and "logical thread". From what I can tell, the "thread" values
(formerly MDC and NDC) are way more commonly used then the "logical
thread" values. Castle did not implement an abstraction for the
"logical" flavor.
2. Log4net provides for multiple stacks per thread. Castle exposes
this.
3. NLog does not provide a "logical thread" context, even in NLog
2.0. Castle's implementation exposes "ThreadStacks" (presumably to
support log4net's multiple stacks) but the implementation always hands
back the one NLog stack (NDC/NestedDiagnosticContext) for the thread,
regardless of what stack was requested.
4. Log4net allows objects to be set in the "properties" collections
and strings to be pushed onto the stacks. NLog only allows strings as
"properties" and entries on the stack. Castle exposes a string for both
the "properties" and the stack.
5. Castle based their "properties" implementation on log4net's
"BaseProperties" (maybe not right name), which has only a get/set
property bag interface. As such, they did not implement Clear or
Remove. It seems to make more sense to have Clear and Remove.
If the most common usage of the thread stacks is to have one stack
(NDC), and since NLog has only one stack anyway, I wonder if it really
makes sense to expose the stacks/stack such that you have to write code
like this:
LogContext.ThreadStacks["NDC"].Push("whatever");
Maybe it is better to either only expose one stack or expose a stack AND
a dictionary of stacks. Normally one might just use the single (or
default) stack. If there is a particular application or workflow that
wants to use multiple stacks, they would be there.
LogContext.ThreadStack.Push("whatever"); //pushes onto NDC
LogContext.ThreadStacks["custom stack"].Push("whatever"); //pushes onto
custom stack.
If anyone at Common.Logging is interested in discussing this and whether
or it is relevant or not to Common.Logging's implementation (when?) of
logging contexts, please respond. Also, if anyone at Common.Logging
would like to see what I have done and how it might or might not fit
into Common.Logging, also please respond.
Thanks.
Willie Geoghegan.
|