Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在项目中实现良好的调试/日志功能_C++_C_Debugging_Logging - Fatal编程技术网

C++ 如何在项目中实现良好的调试/日志功能

C++ 如何在项目中实现良好的调试/日志功能,c++,c,debugging,logging,C++,C,Debugging,Logging,我正在做一个小项目,总共约3-4人。我希望有一种可靠的方法来调试应用程序,例如通过日志。在如何构建it等方面是否有好的资源?我从项目经理那里听说了很多,一个好的日志功能对每个项目都是至关重要的,但我不确定如何做到这一点。取决于你所说的“日志记录”是什么意思。一种形式是简单地提供一种将某个对象的内容打印到输出流的方法。对于ClassName类型的对象,这需要为类编写插入运算符: std::ostream &operator<< (std::ostream &stream

我正在做一个小项目,总共约3-4人。我希望有一种可靠的方法来调试应用程序,例如通过日志。在如何构建it等方面是否有好的资源?我从项目经理那里听说了很多,一个好的日志功能对每个项目都是至关重要的,但我不确定如何做到这一点。

取决于你所说的“日志记录”是什么意思。一种形式是简单地提供一种将某个对象的内容打印到输出流的方法。对于ClassName类型的对象,这需要为类编写插入运算符:

std::ostream &operator<< (std::ostream &stream, const ClassName & obj) {
   // Implementation elided
}

std::ostream&operator我发现多布博士的这篇文章对这个主题非常有用

还有Dobb博士的:

如果您只需要一个简单的线程安全日志类,它总是输出到
stderr
,那么您可以使用我编写的这个类:

#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
\ifndef\u记录器\u水电站_
#定义\u记录器\u水电站_
#包括
#包括
*考虑添加Boost线程ID,因为我们想知道谁的写入和
*我不想每次打电话都重复*/
*考虑添加策略类以允许用户将日志重定向到特定
*通过命令行发送文件
*/
枚举日志级别
{logERROR、logWARNING、logINFO、logDEBUG、logDEBUG1、logDEBUG2、logDEBUG3、logDEBUG4};
类罗吉特
{
公众:
logIt(loglevel\u e\u loglevel=logERROR){

缓冲区如果你问的是<强>日志框架你在C++中工作,检查Apache的。它需要一些时间来理解架构,但是一旦你完成了,你就知道它是一个很好的平衡灵活性、易用性和(如所说)性能。
log4cxx
具有非常灵活的配置,通过该配置,您可以控制子组件的调试级别,而无需重新编译输出(文件/旋转文件/控制台等)(例如,您希望关注特定的类/组件,因此您可以将其设置为
DEBUG
级别,而其余的设置为
INFO
),日志条目的格式等


如果您询问有关如何进行日志记录的一般指导原则,我还没有看到这样的指导原则(不是我实际寻找的)。我认为这主要是经验-您决定每个日志记录级别需要什么信息,如信息、调试等,并根据您和您的客户的需要对其进行优化(别忘了你的客户也可能是日志的客户,这取决于你的项目)。

我认为良好的日志记录很重要(如果不是必要的话),无论项目大小。诚然,这对于长时间运行的服务器进程可能更重要,但它通常会导致客户端应用程序中的错误解决方案,尤其是当用户反馈可能无意中误导或遗漏重要细节时。请参阅@Neil-抱歉,如果可能的话,我会否决你的评论。这很重要呃,多产且受欢迎在我的情况下,我从不使用日志记录,但更喜欢在检测到问题时让断言破坏程序。这迫使开发人员在出现错误时立即修复。我不确定日志记录是否可以帮助您修复问题。我认为它只能用于检测触发错误的原因,这有助于重新生成错误我试图使用你的代码,但是
#define log(level)\if(level>loglevel);\else logIt(level)
给了我很多错误。它说
语法错误:if
语法错误:else
。有什么想法吗?Visual Studio 2012Express@CharlesW.这真的很奇怪。我是在Linux上用g++编译的。您是否将
#define
语句保留为三行?您必须确保在反斜杠\字符。这很奇怪。我通过避免多次包含
logger.hpp
解决了这个问题。我在这里问了一个单独的问题,顺便问一下
if(level>loglevel);\
中的分号应该被空块{}替换吗?顺便问一下
if(level>loglevel);\`应该被空块{}替换吗如果不是,则为logleveldebug;否则为logIt(logInfo)运算符的有趣用法。还可以为ClassName提供toString()方法。
// 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;
}