如何在项目中实现良好的调试/日志功能 [英] How to implement a good debug/logging feature in a project

查看:139
本文介绍了如何在项目中实现良好的调试/日志功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个很小的项目,总共约3-4人。我想有一个稳定的方法来调试应用程序,例如日志。有没有什么好的资源,如何构建它等等?我从项目经理那里听到很多记录功能对每个项目至关重要,但我不知道该怎么做。

解决方案

我发现Dobb博士的文章,登录C ++ ,对此主题非常有用。



还有Dr. Dobb的:高度可配置的日志记录框架C ++



如果你想要的是一个死的简单线程安全的日志记录类,它总是输出到 stderr 那么你可以使用我写的这个类:

  #ifndef _LOGGER_HPP_ 
#define _LOGGER_HPP_

#include< iostream>
#include< sstream>

/ *考虑添加boost线程ID,因为我们想知道他的写作和
*不想为每一个调用重复它* /

/ *考虑添加策略类,以允许用户通过命令行将日志记录重定向到特定的
*文件
* /

enum loglevel_e
{logERROR,logWARNING, logINFO,logDEBUG,logDEBUG1,logDEBUG2,logDEBUG3,logDEBUG4};

class logIt
{
public:
logIt(loglevel_e _loglevel = logERROR){
_buffer<< _loglevel<< :
< std :: string(
_loglevel> logDEBUG
?(_loglevel - logDEBUG)* 4
:1
,'');
}

模板< typename T>
logIt&运算符<(T const& value)
{
_buffer<<值;
return * this;
}

〜logIt()
{
_buffer<< std :: endl;
//这是根据POSIX标准的原子
// http://www.gnu.org/s/libc/manual/html_node/Streams-and-Threads.html
std :: cerr<< _buffer.str();
}

private:
std :: ostringstream _buffer;
};

extern loglevel_e loglevel;

#define log(level)\
if(level> loglevel); \
else logIt(level)

#endif

使用它像这样:

  //为测试套件的其余部分定义和关闭
loglevel_e loglevel = logERROR ;

void logTest(void){
loglevel_e loglevel_save = loglevel;

loglevel = logDEBUG4;

log(logINFO)<< foo< bar< 巴兹

int count = 3;
log(logDEBUG)<< A loop with<计数<< 迭代 (int i = 0; i!= count; ++ i)
{
log(logDEBUG1)<< 计数器i =<一世;
log(logDEBUG2)<< 计数器i =<一世;
}

loglevel = loglevel_save;
}


I am making a smallish project, total of about 3-4 people. I want to have a solid way of debugging the application, by logs for example. Are there any good resources on how to structure it and such? I've heard a lot from project managers that a good logging feature is critical to each project, but I'm not sure how to do it.

解决方案

I found this Dr. Dobb's article, Logging In C++, very useful regarding this subject.

Also on Dr. Dobb's: A Highly Configurable Logging Framework In C++

If all you want is a dead simple thread safe logging class which always outputs to stderr then you could use this class I wrote:

#ifndef _LOGGER_HPP_
#define _LOGGER_HPP_

#include <iostream>
#include <sstream>

/* consider adding boost thread id since we'll want to know whose writting and
 * won't want to repeat it for every single call */

/* consider adding policy class to allow users to redirect logging to specific
 * files via the command line
 */

enum loglevel_e
    {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};

class logIt
{
public:
    logIt(loglevel_e _loglevel = logERROR) {
        _buffer << _loglevel << " :" 
            << std::string(
                _loglevel > logDEBUG 
                ? (_loglevel - logDEBUG) * 4 
                : 1
                , ' ');
    }

    template <typename T>
    logIt & operator<<(T const & value)
    {
        _buffer << value;
        return *this;
    }

    ~logIt()
    {
        _buffer << std::endl;
        // This is atomic according to the POSIX standard
        // http://www.gnu.org/s/libc/manual/html_node/Streams-and-Threads.html
        std::cerr << _buffer.str();
    }

private:
    std::ostringstream _buffer;
};

extern loglevel_e loglevel;

#define log(level) \
if (level > loglevel) ; \
else logIt(level)

#endif

Use it like this:

// define and turn off for the rest of the test suite
loglevel_e loglevel = logERROR;

void logTest(void) {
    loglevel_e loglevel_save = loglevel;

    loglevel = logDEBUG4;

    log(logINFO) << "foo " << "bar " << "baz";

    int count = 3;
    log(logDEBUG) << "A loop with "    << count << " iterations";
    for (int i = 0; i != count; ++i)
    {
        log(logDEBUG1) << "the counter i = " << i;
        log(logDEBUG2) << "the counter i = " << i;
    }

    loglevel = loglevel_save;
}

这篇关于如何在项目中实现良好的调试/日志功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆