首页 > 其他分享 >解决log4cxx退出时的异常

解决log4cxx退出时的异常

时间:2023-06-15 23:06:10浏览次数:33  
标签:XmlWatchdog Log4cxxConfigurator namespace pImpl 退出 include 异常 log4cxx


解决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 下退出程序时导致程序中断




标签:XmlWatchdog,Log4cxxConfigurator,namespace,pImpl,退出,include,异常,log4cxx
From: https://blog.51cto.com/u_16162321/6495481

相关文章

  • 自建log4cxx.sln
    log4cxx的下载包是0.10版本的,代码较旧,有些错误,应该从主干下载最新的代码. 0.10的下载包中有projects目录,内有VC6的工程文件;还有site目录,内有vc构建的帮助文档vstudio.html.VC构建步骤如下:unzipapr-1.2.11-win32-src.ziprenameapr-1.2.11aprunzipapr-util-1.2.10-win32-src.z......
  • 02项目数据库隐藏密码,封装logger,环境变量的设置,封装全局异常,Response,开启media访问,前
    1项目数据库之隐藏密码#我们直接把mysql的用户名和密码写死在了代码中----》后期可能会存在风险----》代码如果泄露----》mysql的用户密码泄露----》可以远程登录----》脱裤(拖库)----》所有数据会被黑客获取到----》卖钱#华住---》在代码中把数据库用户名和密码写死了----》......
  • 【Docker/K8s】启动容器镜像,使其空转不退出
    场景描述有些时候,我们仅仅想启动一个Docker容器,而不需要它执行预置的命令。比如一个场景是我想检查集群的网络状况,那我需要启动一个容器,然后进入到容器里执行命令来调试。大部分的镜像都带有默认的启动cmd,导致直接dockerrun启动的话,很快就会因为预置命令执行失败导致退出。解决......
  • k8s pod 状态异常状态分析和处理方法
    pod状态一般分为以下几种:1、terminating2、pending3、containercreating或waiting4、CrashloopBackoff5、imagePullBackoff6、imageinspectError7、unknown8、Error1、一般处于imageinspectError通常指的是镜像文件损坏了,可以尝试删除损坏的镜像重新拉取。2、Error状......
  • C#Non-static method requires a target异常
    非静态方法需要一个目标,一般这种情况是调用的某个方法时传参为null,这种情况编译时不会报错,运行时会出错解决方法就是检查代码中涉及的实体是否为空,就比如我这里,getchildren的list就是空在使用finall时就报错了 ......
  • 异常
    异常Exception运行时出现的不期而至的状况,区分errortry、catch:  try{    System.out.println(a/b); }catch(Throwablet){    System.out.println("程序异常"); }finally{    System.out.println("finally"); }finally:善后工作,无......
  • springboot-feign接口压缩异常
    WARNorg.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver-Resolved[org.springframework.http.converter.HttpMessageNotReadableException:JSONparseerror:Illegalcharacter((CTRL-CHAR,code31)):onlyregularwhitespace(\r,\......
  • MaxCompute中如何处理异常字符
    背景在处理数据时,当业务数据同步至MaxCompute后,会产生一些含异常字符的脏数据,比如字段中包含了一个不可见字符,在DataWorks中显示不出来,但在BI界面又会显示成其他字符,影响整体观感。这种情况,通常我们的解法是,将异常的字符洗掉,下面来介绍几种常见的处理异常字符的方法。问题描述定位......
  • IDEA 退出 springboot 应用没有关闭
    使用idea发现的问题。当运行spring-boot:run启动项目后,在控制台关闭项目。再次启动项目,报错端口被占用  Addressalreadyinuse:bind。后发现虽然使用idea控制台关闭项目,但是实际上该项目依旧在运行中,只能通过kill进程id来解决。但是这种方式极不方便,总不能每次都......
  • 解决docker中gitlab的ssh拉取代码需要密码异常的问题
    安装gitlab命令dockerrun--name='gitlab'-d--publish222:22--publish1443:443--publish18080:80--restartalways--privileged=true--volume/home/docker_mount/gitlab/config:/etc/gitlab--volume/home/docker_mount/gitlab/logs:/var/log/gitlab--v......