解决log4cxx退出时的异常

(金庆的专栏)

如果使用log4cxx的FileWatchdog线程来监视日志配置文件进行动态配置,就可能碰到程序退出时产生的异常。
程序退出时清理工作耗时很长时,该异常很容易出现。
原因是main()之后FileWatchdog线程试图checkAndConfigure()检查配置文件。
该错误已提交,见:LOGCXX-416 ( https://issues.apache.org/jira/browse/LOGCXX-416?jql=project%20%3D%20LOGCXX )
其中有错误复现代码。

只需在main()结束时结束Watchdog线程,就可以避开错误。
log4cxx中的FileWatchdog是个new出来的变量,没有结束,没有删除。
可以自定义一个Watchdog, 仅作为main()的局部变量,main()退出时自动结束。

    Log4cxxConfigurator::XmlWatchdog wdog("log4j.xml", 5000);
代替原来的
    log4cxx::xml::DOMConfigurator::configAndWatch("log4j.xml", 5000);
    
例如:
int main()
{
    setlocale(LC_ALL, "");
    Log4cxxConfigurator::XmlWatchdog wdog("log4j.xml", 5000);
    ...
}    

Log4cxxConfigurator代码如下:

// log4cxxconfigurator.h
#pragma once

#include <string>
#include <boost/scoped_ptr.hpp>

namespace log4cxx { namespace helpers {
class FileWatchdow;
}}

namespace Log4cxxConfigurator {

typedef boost::scoped_ptr<log4cxx::helpers::FileWatchdog> FileWatchdogPtr;

class PropertyWatchdow
{
public:
    PropertyWatchdog(const std::string & sPropertyFileName, long lDelayMs);
    ~PropertyWatchdog();
private:
    FileWatchdogPtr m_pImpl;
};

class XmlWatchdog
{
public:
    XmlWatchdog(const std::string & sXmlFileName, long lDelayMs);
    ~XmlWatchdog();
private:
    FileWatchdogPtr m_pImpl;
};

}  // namespace Log4cxxConfigurator

// log4cxxconfigurator.cpp
#include "log4cxxconfigurator.h"

#include <log4cxx/helpers/filewatchdow.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/xml/domconfigurator.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::xml;

namespace {

class XmlWatchdogImp : public FileWatchdog
{
public:
    XmlWatchdogImp(const File & filename) : FileWatchdog(filename) {};

    virtural void doOnChange()
    {
        DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
    }
};

class PropertyWatchdogImp : public FileWatchdog
{
public:
    explicit PropertyWatchdogImp(const File & filename) : FileWatchdog(filename) {};

    virtual void doOnChange()
    {
        PropertyConfigurator().doConfigure(file, LogManager::getLoggerRepository())
    }
};

}  // namespace

namespace Log4cxxConfigurator {

PropertyWatchdog::PropertyWatchdog(const std::string & sPropertyFileName, long lDelayMs)
: m_pImpl(new PropertyWatchdogImp(File(sPropertyFileName)))  // scoped_ptr
{
    m_pImpl->setDelay(lDelayMs);
    m_pImpl->start();
}

PropertyWatchdog::~PropertyWatchdog()
{
    m_pImpl.reset()
    LogManager::shutdown();
}

XmlWatchdow::XmlWatchdow(const std::string & sXmlFileName, long lDelayMs)
: m_pImpl(new XmlWatchdogImp(File(sXmlFileName)))  // scoped_ptr
{
    m_pImpl->setDelay(lDelayMs);
    m_pImpl->start();
}

XmlWatchdog::~XmlWatchdog()
{
    m_pImpl.reset();
    LogManager::shutdown();
}

}  // namespace Log4cxxConfigurator

另外,AsyncAppender线程在退出时也可能抛 ThreadException,
所以在Watchdog的析构中调用了shutdown().
详见:Log4Cxx 0.10.0 在 Linux 下退出程序时导致程序中断
( http://blog.waterlin.org/articles/log4cxx-10-exit-error-under-linux.html )

解决log4cxx退出时的异常的更多相关文章

  1. 解决hibernate删除时的异常

    由于关联关系是一对多和多对一的关系,于是在代码中需要删除多的一方的对象时出现了 deleted object would be re-saved by cascade (remove deleted ...

  2. 解决hibernate删除时的异常 deleted object would be re-saved by cascade (remove deleted object from associa

    今天在做项目时,需要删除一个对象,由于关联关系是一对多和多对一的关系,于是在代码中需要删除多的一方的对象时出现了 deleted object would be re-saved by cascade ...

  3. 用Supervisor实现进程守护,在异常退出时自动重启

    程序启动后,有些是以daemon的形式运行,但在意外退出后,如果不能及时重新启动,会有比较严重的影响. 比如Zimg在图片处理中由于某些图片处理失败,会导致zimg进程挂掉,影响正常的服务提供,并且只 ...

  4. C# Webservice 解决在运行配置文件中指定的扩展时出现异常。 ---> System.Web.HttpException: 超过了最大请求长度问

    摘自: http://blog.csdn.net/gulijiang2008/article/details/4482993 请在服务器端配置 方法一: 在通过WebService处理大数据量数据时出 ...

  5. 使用XmlInclude解决WebService调用时无法识别子类的异常

    一.定义抽象类及子类,WebMethod实际返回子类参数 //使用XmlInclude解决WebService调用时无法识别子类的异常 [System.Xml.Serialization.XmlInc ...

  6. java spring 等启动项目时的异常 或 程序异常的解决思路

    今天搭建ssm项目的时候,因为pagehelper的一个jar包没有导入idea的web项目下的lib目录中,异常报错找不到pagehelper,这个问题在出异常的时候疯狂crash,让人心情十分不舒 ...

  7. .net安装部署“Error 1001 在初始化安装时发生异常” 的解决方法

    状况描述:打包安装后,如果删除安装目录中的某个文件,这时从桌面快捷方式启动软件系统会自动运行修复程序,此时因为路径问题会报出“错误 1001 在初始化安装时发生异常xxx”的异常.(前提是你的安装部署 ...

  8. 解决linux-mysql 登录时,报异常:Access denied for user 'root'@'localhost'

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/hhj724/article/details/73277506 解决linux-mysql 登录时,报 ...

  9. .net应用程序安装部署时异常 Error 1001. 在初始化安装时发生异常 System.BadImageFormatException:未能加载文件或程序集 的解决办法【成功解决】

    采用.net 4.0框架开发的一个桌面应用程序在某学校的一体机(Windows7的32位操作系统)上做安装部署时抛出异常,安装程序回滚,多次尝试仍不成功. Error 1001. 在初始化安装时发生异 ...

随机推荐

  1. 在循环列表的富文本里摘出每个item的img标签内容(适合vue渲染)

    昨天在做公司项目的社区动态内容.后台接口返回的数据是数组套对象,对象里有富文本,然后需要摘出富文本里的img标签在列表里分开渲染(即图片九宫格样式).最终效果如图: 这个是后盾接口返回的json数据 ...

  2. 利用Python进行数据分析——Numpy基础:数组和矢量计算

    利用Python进行数据分析--Numpy基础:数组和矢量计算 ndarry,一个具有矢量运算和复杂广播能力快速节省空间的多维数组 对整组数据进行快速运算的标准数学函数,无需for-loop 用于读写 ...

  3. seaborn使用(样式管理)

    seaborn使用(样式管理) Seaborn是一个在Python中制作具有吸引力和丰富信息的统计图形的库.它建立在matplotlib之上,并与PyData堆栈紧密集成,包括支持scipy和pand ...

  4. MySQL CURTIME() 函数

    定义和用法 CURTIME() 返回当前的时间. 语法 CURTIME() 实例 下面是 SELECT 语句: SELECT NOW(),CURDATE(),CURTIME() 结果如下所示: NOW ...

  5. Ubuntu 16.04: How to resolve libqt5x11extras5 (>= 5.1.0) but it is not going to be installed

    Issue: When you install Virtualbox 5.1 on Ubuntu 16.04, you may encounter following error: root@XIAY ...

  6. 防止SpringMVC拦截器拦截js等静态资源文件

    SpringMVC提供<mvc:resources>来设置静态资源,但是增加该设置如果采用通配符的方式增加拦截器的话仍然会被拦截器拦截,可采用如下方案进行解决: 方案一.拦截器中增加针对静 ...

  7. Redis之(二)数据类型及存储结构

    Redis支持五中数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及zset(sortedset:有序集合). Redis定义了丰富的原语命令,可以直接与Redis ...

  8. Quartz学习笔记1:Quartz概述

    Quartz是开源任务调度框架中的翘楚,它提供了强大的 任务调度机制.Quartz允许开发人员灵活的定义触发器的调度时间表,并可对触发器和任务进行关联映射.此外,Quartz提供了调度运行环境的持久化 ...

  9. shiro自定义Realm

    1.1 自定义Realm 上边的程序使用的是shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. ...

  10. PHP 验证码 浅析

    拓展 背景图 imagecreatetruecolor imagecolorallocate imagepng imagedestoryimage 简易数字验证码 imagecolorallocate ...