开源日志系统 - log4cplus (六)

log4cplus在很多方面做的都很出色,但是使用过程有些地方感觉不爽。在继续吹捧之前我先把不爽之处

稍微提一提,然后继续介绍关于线程和套接字的知识。

### 一些可以改进之处 ###

1. 用户自定义LogLevel的实现机制不够开放

在第五篇中曾经介绍过如何实现用户自行定义LogLevel,为了实现比较理想的效果,甚至还需要改log4cplus

的源代码。:(

2. 生成Logger对象的机制可以改进

我在使用时候,经常需要在不同的文件、函数中操作同一个logger,虽然log4cplus实现了树状存储以及根据

名称生成Logger,却没有充分利用这样的特点确保同一个名称对应的logger对象的唯一性,比如以下代码:

    ... ...

   

    Logger logger1 = Logger::getInstance("test");

    Logger logger2 = Logger::getInstance("test");

    Logger * plogger1 = &logger1;

    Logger * plogger2 = &logger2;

    std::cout << "plogger1: " << plogger1 << std::endl << "plogger2: " << plogger2 << std::endl;

   

    ... ...

   

   

运行结果:

plogger1: 0xbfffe5a0

plogger2: 0xbfffe580

从结果可以看出,明明是同一个Logger,但每次调用都会产生一个Logger副本,虽然结果是正确的(因为将存

储和操作分开了),但是资源有些浪费,我看了一下log4cplus的代码,其实可以按照如下方式实现(示意性

的):

#include <iostream>

#include <string>

#include <map>

/* forward declaration */

class Logger;

class LoggerContainer

{

public:

    ~LoggerContainer();

    Logger * getinstance(const std::string & strLogger);

private:

    typedef std::map<:string,> LoggerMap;

    LoggerMap loggerPtrs;

};

class Logger

{

public:

     Logger() {std::cout << "ctor of Logger " << std::endl; }

    ~Logger() {std::cout << "dtor of Logger " << std::endl; }

    static Logger * getInstance( const std::string & strLogger)

    {

        static LoggerContainer defaultLoggerContainer;

        return defaultLoggerContainer.getinstance(strLogger);

    }

};

LoggerContainer::~LoggerContainer()

{

    /* release all ptr in LoggerMap */

    LoggerMap::iterator itr = loggerPtrs.begin();

    for( ; itr != loggerPtrs.end(); ++itr )

 {

     delete (*itr).second;

 }

}

Logger * LoggerContainer::getinstance(const std::string & strLogger)

{

   LoggerMap::iterator itr = loggerPtrs.find(strLogger);

   if(itr != loggerPtrs.end())

   {

       /* logger exist, just return it */

       return (*itr).second;

   }

   else

   {

       /* return a new logger */

       Logger * plogger = new Logger();

       loggerPtrs.insert(std::make_pair(strLogger, plogger));

       return plogger;

   }

}

int main()

{

    Logger * plogger1 = Logger::getInstance("test");

    Logger * plogger2 = Logger::getInstance("test");

    std::cout << "plogger1: " << plogger1 << std::endl << "plogger2: " << plogger2 << std::endl;

    return 0;

}

运行结果:

ctor of Logger

plogger1: 0x804fc30

plogger2: 0x804fc30

dtor of Logger

这里的LoggerContainer相当于log4cplus中的Hierarchy类,结果可以看出,通过同一个名称可以获取相同的

Logger实例。

还有一些小毛病比如RollingFileAppender和DailyRollingFileAppender的参数输入顺序可以调整成统一方式

等等,就不细说了。

本部分提到了使用log4cplus时候感觉不爽的地方,最后一部分将介绍一下log4cplus中线程和套接字实现情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值