0

我在我的项目中使用 Google glog 日志系统。具体来说,我在代码的不同位置使用了以下类型的语句:

#include <glog/logging.h>
CHECK_EQ(foo,bar) << "Generic error message";
LOG(ERROR) << "Generic error message";
LOG(FATAL) << "Generic error message";

这个日志系统对于帮助我暂存和验证我的代码很重要。但是,有时我会将代码的生产运行外包给更大的服务器。这个大型生产服务器没有日志系统。(我尝试在此生产服务器上构建日志系统,但遇到了问题。)

那么,假设我不能在生产服务器上使用日志系统,我该如何配置东西以使日志命令在服务器上处于非活动状态?


在询问SO之前尝试自己解决这个问题,我尝试了以下...

在名为“globals.h”的现有头文件中,我定义了:

#ifdef NOGLOG
    #define MYLOG(i,m) std::cerr << #i << ": " << m
#else
    #include <glog/logging.h>
    #define MYLOG(i,m) LOG(i) << m
#endif

然后,我可以LOG(ERROR) << "ab" << x << "cd"MYLOG(ERROR,"ab" << x << "cd"). 然后,当我使用类似的命令构建时make all CUSTOM="-DNOGLOG",我的 gcc 编译语句是使用名为 的变量设置的$(CUSTOM),glog 语句将不会被编译,而是std::cerr会编译简单的语句。

我在使用这种方法时遇到了两个问题:(1)我不知道如何让 Eclipse IDE 插入$(CUSTOM)到 Eclipse 生成的 makefile 中的 gcc 编译语句中;(2) 将#include <glog/logging.h>语句放在#else正文中会导致很多错误消息,如下所示。

In file included from /usr/include/errno.h:36,
                 from /usr/local/include/glog/logging.h:39,
                 from ../globals.h:23,
                 from ../COMPASS.h:11,
                 from ../COMPASS.cpp:13:
/usr/include/bits/errno.h: In function 'int* __errno_location()':
/usr/include/bits/errno.h:43: error: expected primary-expression before ',' token

注意:目前,我只是注释掉了CHECK_EQ调用,我的想法是一旦我弄清楚如何解决LOG调用的这个问题,我应该能够轻松地将解决方案扩展到CHECK_EQ调用。

4

2 回答 2

1

对于您的编译问题,

message << x << y无效。

你可以使用类似的东西:

// mystream.h

// class MyStreamImpl; // forward declaration for pimpl idiom if necessary

class MyStream
{
public:
    MyStream(int level);
    ~MyStream();

    MyStream& operator << (const char*);
    MyStream& operator << (int);
    // some other needed base type.
private:
    int level;
    // std::unique_ptr<MyStreamImpl> m_impl; // for pimpl idiom if necessary
};

MyStream MYLOG(int level) { return MyStream(level); }


// mylog.cpp


#ifdef NOGLOG
#include <iostream>

// implementation of all methods without glog

MyStream& MyStream::operator << (const char* message)
{
    std::cerr << message;
    return *this;
}

// other forwards to std::cerr

#else // NOGLOG

#include <glog/logging.h>

// implementation of all methods with glog

MyStream& MyStream::operator << (const char* message)
{
    Log(level) << message;
    return *this;
}

// other forwards to LOG()

#endif
于 2013-09-20T15:57:01.580 回答
0

我接受了 Jarod42 的答案,但我想在这里添加我自己的答案,我最终可能会使用它。我认为 Jarod42 可能更优雅更好,但我这里的 hack 解决方案很容易实现。


我发现,与其尝试在编译步骤中向 CXXFLAGS 添加一个变量,然后我可以定义它来表示是否使用 glog 系统,不如简单地在 Eclipse 中基于现有配置创建另一个构建release配置。在这个新配置中,调用它release_noglog,然后我可以转到 Properties > C/C++ Build > Settings > GCC C++ Compiler > Preprocessor,并添加NOGLOG为“已定义符号”。这样,build in不会release添加到compile 语句中,而是 build in willNOGLOGrelease_noglog

然后,我可以简单地使用以下宏定义:

#ifdef NOGLOG
    #define MYLOG(i,m) std::cerr << #i << ": " << m
    #define MYCHECK_EQ(i,j,m) CHECK_EQ(i,j) << m
#else
    #define MYLOG(i,m) LOG(i) << m
    #define MYCHECK_EQ(i,j,m) std::cerr << #i << " != " << #j << ": " << m
#endif

而且,我不会#include <glog/logging.h>依赖是否定义,因为NOGLOG未解决的包含不会阻止编译。(至少,不是在有问题的特定系统上。)

于 2013-09-20T22:33:11.433 回答