Interface for logger:
public interface ILogger
{
void Log(Exception ex, string contextualMessage = "");
void Log(string message);
}
Interface for web job logger:
public interface IJobLogger : ILogger
{
void SetWriter(TextWriter logWriter);
}
Web job logger:
public class WebJobLogger : IJobLogger
{
private TextWriter writer;
public WebJobLogger()
{
writer = TextWriter.Null;
}
public void SetWriter(TextWriter logWriter)
{
writer = logWriter;
}
public void Log(Exception ex, string contextualMessage = "")
{
writer.WriteLine("Logger: Exception thrown with message {0}, exception : {1}", contextualMessage, ex);
}
public void Log(string message)
{
writer.WriteLine("Logger: {0}", message);
}
}
Usage:
public async Task TestJob(
[QueueTrigger(QueueName.StorageExcelImport)] StartImportCommand blobInfo,
[Blob(Global.BlobContainerName + BlobReferenceName, FileAccess.Read)] Stream input,
TextWriter logWriter)
{
await logWriter.WriteLineAsync("Start");
try
{
//Implemetation
}
catch (Exception ex)
{
//Set writer
log.SetWriter(logWriter);
//Log exception
log.Log(ex);
}
await logWriter.WriteLineAsync(string.Format("File: '{0}' successfuly processed from blob to the database. ({1})", blobInfo.OriginalFileName, DateTime.UtcNow));
}
Dependency injection:
container.Register<ILogger, WebJobLogger>();
The problem with this is that I always have to call log.SetWriter(logWriter); before call log.Log(ex);. If I forget that, then will not work. The whole point of this is to mock logger in unit test. What do you think?
TextWriter, you may want to look into TraceSource and TextWriterTraceListener. \$\endgroup\$