41 #ifndef GRAPHLAB_LOG_LOG_HPP
42 #define GRAPHLAB_LOG_LOG_HPP
50 #include <graphlab/util/timer.hpp>
82 #define OUTPUTLEVEL LOG_EMPH
96 #if OUTPUTLEVEL == LOG_NONE
98 #define logger(lvl,fmt,...)
99 #define logbuf(lvl,fmt,...)
100 #define logstream(lvl) null_stream()
102 #define logger_once(lvl,fmt,...)
103 #define logstream_once(lvl) null_stream()
105 #define logger_ontick(sec,lvl,fmt,...)
106 #define logstream_ontick(sec, lvl) null_stream()
110 #define logger(lvl,fmt,...) \
111 (log_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, __func__ ,__LINE__,fmt,##__VA_ARGS__))
114 #define logbuf(lvl,buf,len) \
115 (log_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, \
116 __func__ ,__LINE__,buf,len))
118 #define logstream(lvl) \
119 (log_stream_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, __func__ ,__LINE__) )
121 #define logger_once(lvl,fmt,...) \
123 static bool __printed__ = false; \
124 if (!__printed__) { \
125 __printed__ = true; \
126 (log_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, __func__ ,__LINE__,fmt,##__VA_ARGS__)); \
130 #define logstream_once(lvl) \
132 static bool __printed__ = false; \
133 bool __prev_printed__ = __printed__; \
134 if (!__printed__) __printed__ = true; \
135 &(log_stream_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, __func__ ,__LINE__, !__prev_printed__) ); \
138 #define logger_ontick(sec,lvl,fmt,...) \
140 static float last_print = -sec - 1; \
141 float curtime = graphlab::timer::approx_time_seconds(); \
142 if (last_print + sec <= curtime) { \
143 last_print = curtime; \
144 (log_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, __func__ ,__LINE__,fmt,##__VA_ARGS__)); \
148 #define logstream_ontick(sec,lvl) \
150 static float last_print = -sec - 1; \
151 float curtime = graphlab::timer::approx_time_seconds(); \
152 bool print_now = false; \
153 if (last_print + sec <= curtime) { \
154 last_print = curtime; \
157 &(log_stream_dispatch<(lvl >= OUTPUTLEVEL)>::exec(lvl,__FILE__, __func__ ,__LINE__, print_now) ); \
163 namespace logger_impl {
164 struct streambuff_tls_entry {
165 std::stringstream streambuffer;
172 void __print_back_trace();
197 log_to_console = consolelog;
207 return log_to_console;
215 file_logger& start_stream(
int lineloglevel,
const char* file,
const char*
function,
int line,
bool do_start =
true);
217 template <
typename T>
220 logger_impl::streambuff_tls_entry* streambufentry =
reinterpret_cast<logger_impl::streambuff_tls_entry*
>(
221 pthread_getspecific(streambuffkey));
222 if (streambufentry != NULL) {
223 std::stringstream& streambuffer = streambufentry->streambuffer;
224 bool& streamactive = streambufentry->streamactive;
226 if (streamactive) streambuffer << a;
233 logger_impl::streambuff_tls_entry* streambufentry =
reinterpret_cast<logger_impl::streambuff_tls_entry*
>(
234 pthread_getspecific(streambuffkey));
235 if (streambufentry != NULL) {
236 std::stringstream& streambuffer = streambufentry->streambuffer;
237 bool& streamactive = streambufentry->streamactive;
241 if (a[strlen(a)-1] ==
'\n') {
249 file_logger& operator<<(std::ostream& (*f)(std::ostream&)){
251 logger_impl::streambuff_tls_entry* streambufentry =
reinterpret_cast<logger_impl::streambuff_tls_entry*
>(
252 pthread_getspecific(streambuffkey));
253 if (streambufentry != NULL) {
254 std::stringstream& streambuffer = streambufentry->streambuffer;
255 bool& streamactive = streambufentry->streamactive;
257 typedef std::ostream& (*endltype)(std::ostream&);
259 if (endltype(f) == endltype(std::endl)) {
260 streambuffer <<
"\n";
263 __print_back_trace();
280 log_level = new_log_level;
294 void _log(
int loglevel,
const char* file,
const char*
function,
295 int line,
const char* fmt, va_list arg );
298 void _logbuf(
int loglevel,
const char* file,
const char*
function,
299 int line,
const char* buf,
int len);
301 void _lograw(
int loglevel,
const char* buf,
int len);
303 void stream_flush() {
305 logger_impl::streambuff_tls_entry* streambufentry =
reinterpret_cast<logger_impl::streambuff_tls_entry*
>(
306 pthread_getspecific(streambuffkey));
307 if (streambufentry != NULL) {
308 std::stringstream& streambuffer = streambufentry->streambuffer;
310 streambuffer.flush();
311 _lograw(streamloglevel,
312 streambuffer.str().c_str(),
313 (int)(streambuffer.str().length()));
314 streambuffer.str(
"");
319 std::string log_file;
321 pthread_key_t streambuffkey;
337 template <
bool dostuff>
342 inline static void exec(
int loglevel,
const char* file,
const char*
function,
343 int line,
const char* fmt, ... ) {
346 global_logger().
_log(loglevel, file,
function, line, fmt, argp);
349 __print_back_trace();
361 inline static void exec(
int loglevel,
const char* file,
const char*
function,
362 int line,
const char* fmt, ... ) {}
368 inline null_stream operator<<(T t) {
return null_stream(); }
369 inline null_stream operator<<(
const char* a) {
return null_stream(); }
370 inline null_stream operator<<(std::ostream& (*f)(std::ostream&)) {
return null_stream(); }
374 template <
bool dostuff>
375 struct log_stream_dispatch {};
378 struct log_stream_dispatch<true> {
379 inline static file_logger& exec(
int lineloglevel,
const char* file,
const char*
function,
int line,
bool do_start =
true) {
380 return global_logger().start_stream(lineloglevel, file,
function, line, do_start);
385 struct log_stream_dispatch<false> {
386 inline static null_stream exec(
int lineloglevel,
const char* file,
const char*
function,
int line,
bool do_start =
true) {
387 return null_stream();
391 void textcolor(FILE* handle,
int attr,
int fg);
392 void reset_color(FILE* handle);
394 #include <graphlab/logger/assertions.hpp>