My application contains a lot of logging statements, something like this:
var logger = new Logger(/*..get flag from settings if the logger should be active..*/);
// ....
logger.LogActivity(..serialize an object..);
//...
logger.LogActivity(..get another object's expensive overriden ToString method..);
//...
logger.LogActivity(..log something new..);
Logger class:
public class Logger
{
private readonly bool _isActive;
public Logger(bool isActive)
{
_isActive = isActive;
}
public void LogActivity(string activity)
{
if (_isActive)
{
// Save activity to Database.
}
}
}
When I disable logger in settings (so the _isActive field in Logger class is false), then nothing is saved to database.
But all the expressions in the Logger.LogActivity methods are still evaluated (for instance ..serialize object.. in previous example) and this slows down my application.
I could use log statements like this:
var logger = new Logger(/*..get flag from settings if the logger should be active..*/);
// ....
if (loggerIsActive) logger.LogActivity(..serialize an object..);
//...
if (loggerIsActive) logger.LogActivity(..get another object's expensive overriden ToString method..);
//...
if (loggerIsActive) logger.LogActivity(..log something new..);
But for me it would be best to change only my LogActivity
method somehow.
Is it possible to modify the Logger class so that when logging gets disabled (or log level changes), the expressions in LogActivity(...)
calls aren't evaluated?
Is there any pattern to do this in C#?
You could add an overload that takes a Func<string>
that would generate the string to be logged.
public void LogActivity(Func<string> activity)
{
if (_isActive)
{
string log = activity();
// save 'log' to database
}
}
Then use it like this:
logger.LogActivity(() => expensiveObject.ToString());