문제

I wonder, what is the best trace technique for you. Currently, I am defining trace level for each source witch macro just before including trace header, which is using defined macro.

For example: trace.h:

#if DEBUG == 0
#define debug(...) 
#define trace(...)

#elif DEBUG==1
#define debug(...) 
#define trace(...) printf(__VA_ARGS__)

#elif DEBUG==2
#define debug(...) printf(__VA_ARGS__)
#define trace(...) printf(__VA_ARGS__)

#else
#error Bad DEBUG value
#endif

For all sources.c (trace_value varies)

#define DEBUG trace_value
#include "trace.h"

void func(){
  debug("func()");
  trace("func() ok");
  reurn;
}

However, project grows and I want to use precompiled header. It would be great to include trace header in my precompiled header. So I am wondering, what are your trace techniques? Thank you.

EDIT: I forgot to write important thing, I am interested in logging technique for latency critical application.

도움이 되었습니까?

해결책

Logging is a complex issue and what it does/how you use it depends greatly on the needs of your application.

In small applications, I tend to use either injected std::ostream references, or custom code for logging specifically. I also stay away from the C formatted printing APIs (and define my own operator<< for things I need to trace).

In large applications, if you have complex tracing needs (rotate log files between executions, logs per category and configurable from outside the application, automatic log formatting, high-throughput/performance logging, and so on) use an external library (like log4cpp).

I also tend to use/define macros, only after all my code can be written without them.

Example implementation with injected logging stream:

#include<iosfwd>

class http_server {
public:
    http_server(std::string server, std::uint16_t listening_port,
        std::ostream& log = cnull); // cnull is as defined at 
                                    // http://stackoverflow.com/a/6240980/186997
private:
    std::ostream& log_;
};

Main (console) code:

int main(...) {
    http_server("localhost", 8080, std::clog);
}

Unit test code:

std::ostringstream server_log;
http_server("localhost", 8080, server_log);
// assert on the contents of server_log

Basically, I consider that if I need tracing, it is a part of the API interface and not an afterthought, something I would disable through macros, or something to hardcode.

If I need formatted logging, I would consider specializing a std::ostream, or (most probably) wrapping it into a specialized formatting class and injecting that around.

Macros for tracing code are usually reserved for performance-critical code (where you cannot afford to call stuff if it doesn't do anything).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top