I've created a simple WF4 console app and set up log4net identically to my other apps. However, when I fire up the console and use the ILog
object inside WF4 (I actually pass it into the workflow), no information is presented using my ColoredConsoleAppender
. What am I doing wrong?
Asked
Active
Viewed 2,011 times
2

Maurice
- 27,582
- 5
- 49
- 62

Dmitri Nesteruk
- 23,067
- 22
- 97
- 166
-
Do you have a .Net 4 app that works with log4net? Based on some questions here, you would think that there might be problems with .Net 4 in general... – Stefan Egli Jun 04 '10 at 08:24
-
2Yes, I have multiple .Net 4 apps (e.g., windows services) that use log4net just fine. – Dmitri Nesteruk Jun 04 '10 at 09:31
2 Answers
3
Workflow trace output is written to trace listeners and as far as I am aware log4net doesn't log the output written to a trace listener by default. I am no expert on log4net so there might be an easier way but creating a TraceListener that just passes all data on to log4net is not hard, the following code worked just fine in a quick test.
public class Log4netTraceListener : TraceListener
{
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
{
base.TraceData(eventCache, source, eventType, id, data);
}
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
{
var logger = LogManager.GetLogger(source);
switch (eventType)
{
case TraceEventType.Critical:
logger.Fatal(data);
break;
case TraceEventType.Error:
logger.Error(data);
break;
case TraceEventType.Information:
logger.Info(data);
break;
case TraceEventType.Verbose:
logger.Debug(data);
break;
case TraceEventType.Warning:
logger.Warn(data);
break;
default:
base.TraceData(eventCache, source, eventType, id, data);
break;
}
}
public override void Write(string message)
{
_log.Info(message);
}
public override void WriteLine(string message)
{
_log.Info(message);
}
Next you need to make sure the activity trace information is send to this TraceListener using the following code in you app.config.
<system.diagnostics>
<sources>
<source name="System.Activities"
switchValue="Verbose">
<listeners>
<add name="Test"
type="WorkflowConsoleApplication17.Log4netTraceListener, WorkflowConsoleApplication17"/>
</listeners>
</source>
</sources>
</system.diagnostics>

Maurice
- 27,582
- 5
- 49
- 62
-
Thanks for that! But the problem I face is that I'm using an `ILog` right in the workflow and the output doesn't appear in my console. – Dmitri Nesteruk Jun 06 '10 at 16:09
-
If you load your logger inside of a workflow you need to specify the assembly to use. Something like: log4net.LogManager.GetLogger(System.Reflection.Assembly.GetEntryAssembly(), "System.Activities"). If you only specify a name it will try to load the configuration of a dynamic assembly and won't find anything. – Maurice Jun 07 '10 at 06:43
3
Create an Extension for your workflow that your activities can get from the context.
var wf = new WorkflowApplication(myActivity);
var log = new MyLogForNetExtensionLol();
wf.Extensions.Add(log);
then, within the activity:
var log = context.GetExtension<ILog>();
log.Write("Worked!");