我记录了我的应用错误。但是如果日志记录过程因某些原因失败(数据库错误,硬盘中没有空间等)。我怎么知道的?如何记录失败的日志。
示例:
try{
this_will_throw_exception();
}catch(Exception e){
result = Log.error(e.getMessage());
if( result == false)
{
// what should I do ?
}
}
答案 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/