解决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. electron应用以管理员权限启动

    最近在用electron开发PC桌面应用,其中有个需求就是整个应用以管理员权限启动.很头痛,各种google,baidu. 最后终于解决了,可以分为三个步骤,做个总结分享. 一.如果没有manifes ...

  2. 创建OpenGL Context(WGL)

    创建OpenGL Context(WGL) 创建OpenGL Context是初始化OpenGL的一部分.只有在此之后才能使用OpenGL. 关于platform的注意事项 创建OpenGL cont ...

  3. 有一个排序二叉树,数据类型是int型,如何找出中间大的元素。

    void tree2Dll(TNode* root, TNode*& tail) { if (!root) { return; } if (root->left) { tree2Dll( ...

  4. iOS开源加密相册Agony的实现(二)

    简介 虽然目前市面上有一些不错的加密相册App,但不是内置广告,就是对上传的张数有所限制.本文介绍了一个加密相册的制作过程,该加密相册将包括多密码(输入不同的密码即可访问不同的空间,可掩人耳目).Wi ...

  5. Swift3中如何为Array写一个限定Type的扩展

    我们知道Swift可以扩展已存在的类或结构,这些类或结构可以存在于标准库(或称为核心库)中.如果结构是一个集合类型(比如Array)就更有趣了.我们想尝试写一个限定Type数组的扩展,So我们就拿Ar ...

  6. RAP在线接口管理统计部署

    文档: https://github.com/thx/RAP/wiki/home_cn centos上部署 参考:https://github.com/thx/RAP/wiki/deploy_on_c ...

  7. pycallgraph 追踪Python函数内部调用

    安装 安装pycallgraph 安装依赖 使用 待测脚本 追踪脚本 追踪结果 高级篇 隐藏私密函数 控制最大追踪深度 总结 GitHub上好代码真的是太多了,名副其实的一个宝藏.但是最近自己也反思了 ...

  8. Hazelcast源码剖析之Eviction

    v:* { } o:* { } w:* { } .shape { }p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-botto ...

  9. EBS开发性能优化之查找需要优化的程序

    1.登陆数据库LINUX环境 使用 top 命令查看进程状况 [oratest@ebsdb~]$top top - 15:58:59 up 8 days, 22:04,  1 user,  load ...

  10. Ubuntu下配置Telnet服务器

    1. 首先介绍linux中的守护进程 在Linux系统中有一个特殊的守护进程inetd(InterNET services Daemon),它用于Internet标准服务,通常在系统启动时启动.通过命 ...