0

我记录我的应用程序错误。但如果由于某些原因(数据库错误、硬盘中没有空间……等),日志记录过程失败。我怎么知道?如何记录失败的日志。

例子 :

try{

    this_will_throw_exception();

}catch(Exception e){

    result = Log.error(e.getMessage());
    if( result == false)
        {
         // what should I do ?
        }
}
4

3 回答 3

2

您应该保持您的应用程序代码简单,即不要担心日志记录失败并将日志记录失败委托给记录器本身。

因此,您的应用程序代码应如下所示:

try{
  this_will_throw_exception();
} catch(Exception e){
  Log.error(e.getMessage());
}

现在我们看看如何处理记录器中的故障。

首先,有很多日志框架提供 appender 故障转移。例如,我们在 log4j 中有一个 FailoverAppender,如果主要失败,它会记录到辅助 appender。http://logging.apache.org/log4j/2.x/manual/appenders.html

如果您出于某种原因选择构建自己的日志记录层,您可能会发现装饰器模式对自己构建故障转移记录器很有用。

public interface Logger {
  boolean error(String message);
}

public DataBaseLogger implements Logger {
  ...
}

public FileLogger implements Logger {
  ...
}

public FailoverLogger implements Logger {
  private Logger primary;
  private Logger secondary;

  public boolean error(String message) {
    boolean succeed = primary.error(message);
    if (! succeed) {
      secondary.error("Primary logger failed");
      secondary.error(message);
      // Try to restart the primary logger, however it might be difficult.
    }
  }
}
于 2012-09-03T21:32:32.887 回答
1
try{

    this_will_throw_exception();

}catch(Exception e){

    result = Log.error(e.getMessage());
    if( result == false)
        LoggingFallback.Invoke(e);

    //important, don't hide exceptions
    throw;
}

public class LoggingFallback
{
    public static void Invoke(Exception exception)
    {
       // send an email or whatever

       // if that fails: throw  (include original exception as inner)
       throw new LoggingFailedException("Failed to log exception", exception);
    }
}

动机:

如果日志记录很重要,请确保它始终成功,如果不能,则让应用程序失败。否则你最终会得到一个没有存储日志的应用程序。

如果您无法正确处理异常,也不要在不重新抛出的情况下捕获异常:http: //blog.gauffin.org/2010/11/do-not-catch-that-exception/

于 2012-09-03T13:57:15.727 回答
1

我想到的事情:

  • 重新创建日志/更改配置(文件、存储等)。

  • 将日志发送到远程位置。

  • 向用户显示一个对话框(如果适用),以便通过电子邮件或类似方式报告此错误。

于 2012-09-03T12:35:35.320 回答