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\$