C# 如何知道log4net是否记录了错误

C# 如何知道log4net是否记录了错误,c#,log4net,C#,Log4net,我在控制台应用程序中使用log4net,我使用log.Error(“消息到日志”)在if/else结构中多次执行。 我的应用程序必须返回一个代码,该代码指定在应用程序运行期间是否发生错误(0→ 好的,1→ 至少发生1个错误)。 是否有办法询问log4net是否记录了错误,例如: bool b = LogManager.AtLeastOneErrorHasBeenLogged; 我不这么认为……但是使用decorator模式并修饰ILog接口来收集信息是很容易的。问题在于,log4net实例化记

我在控制台应用程序中使用log4net,我使用
log.Error(“消息到日志”)在if/else结构中多次执行。
我的应用程序必须返回一个代码,该代码指定在应用程序运行期间是否发生错误(0→ 好的,1→ 至少发生1个错误)。
是否有办法询问log4net是否记录了错误,例如:

bool b = LogManager.AtLeastOneErrorHasBeenLogged;

我不这么认为……但是使用decorator模式并修饰
ILog
接口来收集信息是很容易的。问题在于,log4net实例化记录器的标准方法是让每个类通过
LogManager.GetLogger(Type t)
实例化自己的特定于类的记录器实例

但是,您不应该在
Main()
方法中捕获异常,记录它并在条件代码设置为0或1(视情况而定)时退出吗

static int Main( string[] argv )
{
  int cc ;
  try
  {
     ExecApplicationCore( argv ) ;
     cc = 0 ;
  }
  catch( Exception e )
  {
     ILog log = LogManager.GetLogger(this.GetType()) ;
     log.Fatal(e) ;
     cc = 1 ;
  }
  return cc ;
}
这就是例外。如果你真的不能处理它,你就不应该抓住它:让它冒泡到顶部

编辑注释:示例
ILog
装饰器和工厂:

using log4net;
using log4net.Core;
using log4net.Repository;

public class CountingLogger : ILog , ILogger
{
  public IDictionary<Level , int> Counts { get; private set; }
  private ILog Log4Net { get; set; }

  public CountingLogger( ILog logger )
  {
    this.Log4Net = logger ;
    this.Counts  = this.Log4Net.Logger.Repository.LevelMap.AllLevels.Cast<Level>().ToDictionary( x => x , x => 0 ) ;
    return;
  }
  private void Count( Level level )
  {
    int count;
    bool success = this.Counts.TryGetValue( level , out count );
    this.Counts[level] = ++count;
    return;
  }


  public bool IsDebugEnabled { get { return Log4Net.IsDebugEnabled ; } }
  public bool IsErrorEnabled { get { return Log4Net.IsErrorEnabled ; } }
  public bool IsFatalEnabled { get { return Log4Net.IsFatalEnabled ; } }
  public bool IsInfoEnabled  { get { return Log4Net.IsInfoEnabled  ; } }
  public bool IsWarnEnabled  { get { return Log4Net.IsWarnEnabled  ; } }

  public ILogger Logger { get { return this ; } }

  public void Debug( object message , Exception exception ) { Count( Level.Debug ) ; Log4Net.Debug( message , exception ) ; }
  public void Info(  object message , Exception exception ) { Count( Level.Info  ) ; Log4Net.Info(  message , exception ) ; }
  public void Warn(  object message , Exception exception ) { Count( Level.Warn  ) ; Log4Net.Warn(  message , exception ) ; }
  public void Error( object message , Exception exception ) { Count( Level.Error ) ; Log4Net.Error( message , exception ) ; }
  public void Fatal( object message , Exception exception ) { Count( Level.Fatal ) ; Log4Net.Fatal( message , exception ) ; }

  public void Debug( object message ) { Count( Level.Debug ) ; Log4Net.Debug( message ) ; }
  public void Info(  object message ) { Count( Level.Info  ) ; Log4Net.Info(  message ) ; }
  public void Warn(  object message ) { Count( Level.Warn  ) ; Log4Net.Warn(  message ) ; }
  public void Error( object message ) { Count( Level.Error ) ; Log4Net.Error( message ) ; }
  public void Fatal( object message ) { Count( Level.Fatal ) ; Log4Net.Fatal( message ) ; }

  public void DebugFormat( IFormatProvider provider , string format , params object[] args ) { Count( Level.Debug ) ; Log4Net.DebugFormat( provider , format , args ) ; }
  public void InfoFormat(  IFormatProvider provider , string format , params object[] args ) { Count( Level.Info  ) ; Log4Net.InfoFormat(  provider , format , args ) ; }
  public void WarnFormat(  IFormatProvider provider , string format , params object[] args ) { Count( Level.Warn  ) ; Log4Net.WarnFormat(  provider , format , args ) ; }
  public void ErrorFormat( IFormatProvider provider , string format , params object[] args ) { Count( Level.Error ) ; Log4Net.ErrorFormat( provider , format , args ) ; }
  public void FatalFormat( IFormatProvider provider , string format , params object[] args ) { Count( Level.Fatal ) ; Log4Net.FatalFormat( provider , format , args ) ; }

  public void DebugFormat( string format , object arg0 , object arg1 , object arg2 ) { Count( Level.Debug ) ; Log4Net.DebugFormat( format , arg0 , arg1 , arg2 ) ; }
  public void InfoFormat(  string format , object arg0 , object arg1 , object arg2 ) { Count( Level.Info  ) ; Log4Net.InfoFormat(  format , arg0 , arg1 , arg2 ) ; }
  public void WarnFormat(  string format , object arg0 , object arg1 , object arg2 ) { Count( Level.Warn  ) ; Log4Net.WarnFormat(  format , arg0 , arg1 , arg2 ) ; }
  public void ErrorFormat( string format , object arg0 , object arg1 , object arg2 ) { Count( Level.Error ) ; Log4Net.ErrorFormat( format , arg0 , arg1 , arg2 ) ; }
  public void FatalFormat( string format , object arg0 , object arg1 , object arg2 ) { Count( Level.Fatal ) ; Log4Net.FatalFormat( format , arg0 , arg1 , arg2 ) ; }

  public void DebugFormat( string format , object arg0 , object arg1 ) { Count( Level.Debug ) ; Log4Net.DebugFormat( format , arg0 , arg1 ) ; }
  public void InfoFormat(  string format , object arg0 , object arg1 ) { Count( Level.Info  ) ; Log4Net.InfoFormat(  format , arg0 , arg1 ) ; }
  public void WarnFormat(  string format , object arg0 , object arg1 ) { Count( Level.Warn  ) ; Log4Net.WarnFormat(  format , arg0 , arg1 ) ; }
  public void ErrorFormat( string format , object arg0 , object arg1 ) { Count( Level.Error ) ; Log4Net.ErrorFormat( format , arg0 , arg1 ) ; }
  public void FatalFormat( string format , object arg0 , object arg1 ) { Count( Level.Fatal ) ; Log4Net.FatalFormat( format , arg0 , arg1 ) ; }

  public void DebugFormat( string format , object arg0 ) { Count( Level.Debug ) ; Log4Net.DebugFormat( format , arg0 ) ; }
  public void InfoFormat(  string format , object arg0 ) { Count( Level.Info  ) ; Log4Net.InfoFormat(  format , arg0 ) ; }
  public void WarnFormat(  string format , object arg0 ) { Count( Level.Warn  ) ; Log4Net.WarnFormat(  format , arg0 ) ; }
  public void ErrorFormat( string format , object arg0 ) { Count( Level.Error ) ; Log4Net.ErrorFormat( format , arg0 ) ; }
  public void FatalFormat( string format , object arg0 ) { Count( Level.Fatal ) ; Log4Net.FatalFormat( format , arg0 ) ; }

  public void DebugFormat( string format , params object[] args ) { Count( Level.Debug ) ; Log4Net.DebugFormat( format , args ) ; }
  public void InfoFormat(  string format , params object[] args ) { Count( Level.Info  ) ; Log4Net.InfoFormat(  format , args ) ; }
  public void WarnFormat(  string format , params object[] args ) { Count( Level.Warn  ) ; Log4Net.WarnFormat(  format , args ) ; }
  public void ErrorFormat( string format , params object[] args ) { Count( Level.Error ) ; Log4Net.ErrorFormat( format , args ) ; }
  public void FatalFormat( string format , params object[] args ) { Count( Level.Fatal ) ; Log4Net.FatalFormat( format , args ) ; }

  #region ILogger implementation

  bool ILogger.IsEnabledFor( Level level )
  {
    return this.Log4Net.Logger.IsEnabledFor( level ) ;
  }

  void ILogger.Log( LoggingEvent logEvent )
  {
    Count( logEvent.Level ) ;
    this.Log4Net.Logger.Log( logEvent ) ;
    return ;
  }

  void ILogger.Log( Type callerStackBoundaryDeclaringType , Level level , object message , Exception exception )
  {
    Count( level ) ;
    this.Log4Net.Logger.Log( callerStackBoundaryDeclaringType , level , message , exception ) ;
    return ;
  }

  string            ILogger.Name       { get { return this.Log4Net.Logger.Name       ; } }
  ILoggerRepository ILogger.Repository { get { return this.Log4Net.Logger.Repository ; } }

  #endregion

}

static class LoggerFactory
{

  public static ILog GetLogger( string name )
  {
    ILog log             = LogManager.GetLogger( name );
    ILog decoratedLogger = new CountingLogger( log );
    return decoratedLogger;
  }
  public static ILog GetLogger( Type type )
  {
    ILog log             = LogManager.GetLogger( type );
    ILog decoratedLogger = new CountingLogger( log );
    return decoratedLogger;
  }

  public static ILog GetLogger( string repository , string name )
  {
    ILog log             = LogManager.GetLogger( repository , name );
    ILog decoratedLogger = new CountingLogger( log );
    return decoratedLogger;
  }
  public static ILog GetLogger( string repository , Type type )
  {
    ILog log             = LogManager.GetLogger( repository , type );
    ILog decoratedLogger = new CountingLogger( log );
    return decoratedLogger;
  }

  public static ILog GetLogger( Assembly repositoryAssembly , string name )
  {
    ILog log             = LogManager.GetLogger( repositoryAssembly , name );
    ILog decoratedLogger = new CountingLogger( log );
    return decoratedLogger;
  }
  public static ILog GetLogger( Assembly repositoryAssembly , Type type )
  {
    ILog log             = LogManager.GetLogger( repositoryAssembly , type );
    ILog decoratedLogger = new CountingLogger( log );
    return decoratedLogger;
  }

}
使用log4net;
使用log4net.Core;
使用log4net.Repository;
公共类计数记录器:ILog,ILOGER
{
公共IDictionary计数{get;private set;}
私有ILOGlog4net{get;set;}
公共计数记录器(ILog记录器)
{
this.Log4Net=记录器;
this.Counts=this.Log4Net.Logger.Repository.LevelMap.AllLevels.Cast().ToDictionary(x=>x,x=>0);
返回;
}
私人作废计数(级别)
{
整数计数;
bool success=this.Counts.TryGetValue(级别,超出计数);
此.Counts[级别]=++计数;
返回;
}
public bool IsDebugEnabled{get{return Log4Net.IsDebugEnabled;}}
public bool-IsErrorEnabled{get{return Log4Net.IsErrorEnabled;}}
public bool IsFatalEnabled{get{return Log4Net.IsFatalEnabled;}}
公共bool IsInfo启用{get{return Log4Net.IsInfo启用;}
public bool iswarnabled{get{return Log4Net.iswarnabled;}
公共ILogger记录器{get{返回此;}}
public void Debug(对象消息,异常){Count(Level.Debug);Log4Net.Debug(消息,异常);}
public void Info(对象消息,异常){Count(Level.Info);Log4Net.Info(消息,异常);}
public void Warn(对象消息,异常){Count(Level.Warn);Log4Net.Warn(消息,异常);}
公共无效错误(对象消息,异常){Count(Level.Error);Log4Net.Error(消息,异常);}
public void Fatal(对象消息,异常){Count(Level.Fatal);Log4Net.Fatal(消息,异常);}
public void Debug(对象消息){Count(Level.Debug);Log4Net.Debug(message);}
public void Info(对象消息){Count(Level.Info);Log4Net.Info(message);}
public void Warn(对象消息){Count(Level.Warn);Log4Net.Warn(消息);}
公共无效错误(对象消息){Count(Level.Error);Log4Net.Error(消息);}
public void Fatal(对象消息){Count(Level.Fatal);Log4Net.Fatal(消息);}
public void DebugFormat(IFormatProvider提供程序,字符串格式,params对象[]args){Count(Level.Debug);Log4Net.DebugFormat(提供程序,格式,args);}
public void InfoFormat(IFormatProvider提供程序,字符串格式,参数对象[]args){Count(Level.Info);Log4Net.InfoFormat(提供程序,格式,args);}
public void WarnFormat(IFormatProvider提供程序,字符串格式,参数对象[]args){Count(Level.Warn);Log4Net.WarnFormat(提供程序,格式,args);}
public void ErrorFormat(IFormatProvider提供程序,字符串格式,参数对象[]args){Count(Level.Error);Log4Net.ErrorFormat(提供程序,格式,args);}
public void FatalFormat(IFormatProvider提供程序,字符串格式,参数对象[]args){Count(Level.Fatal);Log4Net.FatalFormat(提供程序,格式,args);}
public void DebugFormat(字符串格式,对象arg0,对象arg1,对象arg2){Count(Level.Debug);Log4Net.DebugFormat(格式,arg0,arg1,arg2);}
public void InfoFormat(字符串格式,对象arg0,对象arg1,对象arg2){Count(Level.Info);Log4Net.InfoFormat(格式,arg0,arg1,arg2);}
public void WarnFormat(字符串格式,对象arg0,对象arg1,对象arg2){Count(Level.Warn);Log4Net.WarnFormat(格式,arg0,arg1,arg2);}
public void ErrorFormat(字符串格式,对象arg0,对象arg1,对象arg2){Count(Level.Error);Log4Net.ErrorFormat(格式,arg0,arg1,arg2);}
public void FatalFormat(字符串格式,对象arg0,对象arg1,对象arg2){Count(Level.Fatal);Log4Net.FatalFormat(格式,arg0,arg1,arg2);}
public void DebugFormat(字符串格式,对象arg0,对象arg1){Count(Level.Debug);Log4Net.DebugFormat(格式,arg0,arg1);}
public void InfoFormat(字符串格式,对象arg0,对象arg1){Count(Level.Info);Log4Net.InfoFormat(格式,arg0,arg1);}
public void WarnFormat(字符串格式,对象arg0,对象arg1){Count(Level.Warn);Log4Net.WarnFormat(格式,arg0,arg1);}
public void ErrorFormat(字符串格式,对象arg0,对象arg1){Count(Level.Error);Log4Net.ErrorFormat(格式,arg0,arg1);}
public void FatalFormat(字符串格式,对象arg0,对象arg1){Count(Level.Fatal);Log4Net.FatalFormat(格式,arg0,arg1);}
public void DebugFormat(字符串格式,对象arg0){Count(Level.Debug);Log4Net.DebugFormat(格式,arg0);}
public void InfoFormat(字符串格式,对象arg0){Count(Level.Info);Log4Net.InfoFormat(格式,arg0);}
public void WarnFormat(字符串格式,对象arg0){Count(Level.Warn);Log4Net.WarnFormat(格式,arg0);}
公共无效错误
static int Main( string[] argv )
{
  static int errorOccurred = 0;
  try
  {
    log.Info("Begin");
    if (SomeImportantPreconditionExists())
    {
      DoSomeStuff();
      if (DoingSomeStuffWorkedRight())
      {
        Hooray();
      }
      else
      {
        log.Error("DoSomeStuff seems to have failed");
        ErrorOccurred();
      }
    }
    else
    {
      log.Error("SomeImportantPrecondition does not exist");
      ErrorOccurred();
    }
  }
  catch( Exception e )
  {
     log.Error("Exception of some sort", e);
     ErrorOccurred();
  }
  return ErrorStatus();
}

private static void InitializeErrorOccurred()
{
  errorOccurred = 0;
}

private static void ErrorOccurred()
{
  errorOccurred = 1;
}

private static int ErrorStatus()
{
  return errorOccurred;
}
public namespace MyApp
{
    public class ErrorFlagAppender : AppenderSkeleton
    {
        public bool ErrorOccurred { get; set; }

        protected override void Append(LoggingEvent loggingEvent)
        {
            ErrorOccurred = true;
        }
    }
} 
<appender name="ErrorFlagAppender" type="MyApp.ErrorFlagAppender,MyApp" >
    <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="ERROR"/>
        <levelMax value="ERROR"/>
    </filter>
</appender>

<root>
  <appender-ref ref="[your existingappender]" />
  <appender-ref ref="ErrorFlagAppender" />
</root>
public static class LogManagerExtensions
{
    public static bool AtLeastOneErrorHasBeenLogged(this LogManager logManager)
    {
        var flagAppenders = logManager.GetRepository()
                                      .GetAppenders()
                                      .OfType<ErrorFlagAppender>();

        return flagAppenders.Any(f => f. ErrorOccurred);
    }
}