如果“记录过程”失败,我该怎么办?

时间:2012-09-03 12:27:28

标签: design-patterns logging

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

示例:

try{

    this_will_throw_exception();

}catch(Exception e){

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

3 个答案:

答案 0 :(得分: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.
    }
  }
}

答案 1 :(得分:1)

我想到的事情:

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

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

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

答案 2 :(得分: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/