重写日志库的感悟

    技术2022-05-11  54

    如服务器软件中所述,对于一个需要长期运行的服务器程序,日志功能必不可少。服务器端通用日志库的需求包括:

    - 灵活的日志策略

    - 因为用于实时程序,需要后台线程写日志

    - 对于有界面程序,需要在用户界面显示日志;对于daemon程序,需要通过socket将日志发送给监控程序。

     

    原有的日志库存在以下问题:

    - 写文件、控制格式、文件大小等都是自己编码的。日志策略不够灵活,历史久远无人维护;

    - 启动线程采用的是beginthread,既与Windows平台绑定,又不是面向对象的;

    - 在用户界面日志或socket发送日志功能,和后台写日志文件混在一起。

     

    小鸡射手在重写日志库的工作中得到一些感悟:

    1.       尽量不要自己写程序。小鸡射手采用了开源软件log4cpp实现日志灵活性问题,采用ACETask Framework实现后台线程功能。其中log4cpp代码很简明:

    void  Log4cppListener::Error( const   char *   const  message) {    assert(message != 0);    get_log4cpp_log().error(message);} static  inline log4cpp::Category &  get_log4cpp_log() {    if (g_log == 0)    {        g_log = & initial_log4cpp();    }    return *g_log;} static  log4cpp::Category &  initial_log4cpp() {    try    {         log4cpp::PropertyConfigurator::configure(DEFAULT_CONF_FILE);        return log4cpp::Category::getRoot();    }     catch(log4cpp::ConfigureFailure& f)    {        std::cout << "配置文件错误:" << f.what() << std::endl;        return defualt_log();    }    catch(...)     {        return defualt_log();    }} static  log4cpp::Category &  defualt_log() {    log4cpp::Layout* layout = new log4cpp::BasicLayout();        log4cpp::RollingFileAppender* appender = new log4cpp::RollingFileAppender("FileAppender", DEFAULT_LOG_FILE, DEFAULT_LOG_SIZE, DEFAULT_MAX_FILES);    appender->setLayout(layout);    log4cpp::Category& log = log4cpp::Category::getInstance("log4cpp");    log.setAdditivity(false);    log.setAppender(appender);    log.setPriority(log4cpp::Priority::INFO);    return log;}

     

    2.       设计符合Open-Close原则,即Open for Extension, Close for Modification。小鸡射手设计了ILogListener接口,各类日志功能实现该接口并通过Observer模式组装,具体日志实现和日志框架相分离;

    class  ILogListener  {public:    virtual ~ILogListener() {}    virtual void  Error(const char* const message)=0;    virtual void      Warning(const char* const message)=0;    virtual void      Trace(const char* const message)=0;    virtual void      Always(const char* const message)=0;} ;

     

    3.       针对接口编程,这是《设计模式》倡导的最佳实践。公司这方面做得不错,所以即使日志库发生了翻天覆地的变化,客户端程序只需增加AddListener/RemoveListener


    最新回复(0)