我正在研究C#日志记录,如果消息低于日志记录阈值,我不希望我的日志消息花费任何时间进行处理。我可以看到log4net最好的是在评估日志参数后进行阈值检查。
示例:
_logger.Debug( "My complicated log message " + thisFunctionTakesALongTime() + " will take a long time" )
即使阈值高于Debug,仍会评估thisFunctionTakesALongTime。
在log4net中,您应该使用_logger.isDebugEnabled,以便最终得到
if( _logger.isDebugEnabled )
_logger.Debug( "Much faster" )
我想知道是否有更好的.net日志记录解决方案,每次我都想记录时都不会进行检查。
在C ++中,我被允许做
LOG_DEBUG( "My complicated log message " + thisFunctionTakesALongTime() + " will take no time" )
因为我的LOG_DEBUG宏执行日志级别检查。这让我在整个应用程序中都有一行日志消息,我更喜欢这个消息。有人知道在C#中复制这种行为的方法吗?
答案 0 :(得分:9)
如果您可以使用.NET 3.5(C#3.0),则可以使用extension methods来包装if
语句。
所以你可以做相同的“宏”:
logger.Log_Debug("Much faster");
logger.Log_Debug(() => { "My complicated log message " + thisFunctionTakesALongTime() + " will take no time" });
将检查包装在此方法中:
public class Log4NetExtensionMethods {
// simple string wrapper
public void Log_Debug(this log4net.ILog logger, string logMessage) {
if(logger.isDebugEnabled) {
logger.Debug(logMessage);
}
}
// this takes a delegate so you can delay execution
// of a function call until you've determined it's necessary
public void Log_Debug(this log4net.ILog logger, Func<string> logMessageDelegate) {
if(logger.isDebugEnabled) {
logger.Debug(logMessageDelegate());
}
}
}
答案 1 :(得分:3)
17.4.2条件属性
Conditional属性启用条件方法的定义。 Conditional属性通过测试条件编译符号来指示条件。根据是否在调用点定义了此符号,可以包含或省略对条件方法的调用。如果定义了符号,则包括呼叫;否则,省略呼叫(包括对呼叫参数的评估)。
[ Conditional("DEBUG") ]
public static void LogLine(string msg,string detail)
{
Console.WriteLine("Log: {0} = {1}",msg,detail);
}
public static void Main(string[] args)
{
int Total = 0;
for(int Lp = 1; Lp < 10; Lp++)
{
LogLine("Total",Total.ToString());
Total = Total + Lp;
}
}
答案 2 :(得分:1)
这里的问题是必须在调用方法之前评估所有方法参数。根据您使用的语法,没有办法解决这个问题。由于C#没有真正的预处理器或宏,因此您无法执行“LOG_DEBUG”之类的操作。您可以做的最好的事情是按照建议使用if (logger.isDebugEnable)
。
我唯一能想到的就是使用lambda表达式来延迟评估。但是我会警告你,这几乎肯定会最终影响性能。
internal class Sample
{
private static void Main(string[] args)
{
DelayedEvaluationLogger.Debug(logger, () => "This is " + Expensive() + " to log.");
}
private static string Expensive()
{
// ...
}
}
internal static class DelayedEvaluationLogger
{
public static void Debug(ILog logger, Func<string> logString)
{
if (logger.isDebugEnabled)
{
logger.Debug(logString());
}
}
}
答案 3 :(得分:-1)
没有预处理器,你就是SOL。当然,在将代码提供给C#编译器之前,没有什么可以阻止您使用它。