libqi  1.14
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
log.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Aldebaran Robotics. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the COPYING file.
5  */
6 
12 #pragma once
13 #ifndef _LIBQI_QI_LOG_HPP_
14 #define _LIBQI_QI_LOG_HPP_
15 
16 # include <map>
17 # include <string>
18 # include <iostream>
19 # include <sstream>
20 # include <cstdarg>
21 # include <cstdio>
22 
23 #include <boost/function/function_fwd.hpp>
24 
25 #include <qi/config.hpp>
26 #include <qi/os.hpp>
27 
28 #if defined(NO_QI_DEBUG) || defined(NDEBUG)
29 # define qiLogDebug(...) if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
30 #elif defined(NO_QI_LOG_DETAILED_CONTEXT) || defined(NDEBUG)
31 # define qiLogDebug(...) qi::log::LogStream(qi::log::debug, "", __FUNCTION__, 0, __VA_ARGS__).self()
32 #else
33 # define qiLogDebug(...) qi::log::LogStream(qi::log::debug, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
34 #endif
35 
36 #ifdef NO_QI_VERBOSE
37 # define qiLogVerbose(...) if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
38 #elif defined(NO_QI_LOG_DETAILED_CONTEXT) || defined(NDEBUG)
39 # define qiLogVerbose(...) qi::log::LogStream(qi::log::verbose, "", __FUNCTION__, 0, __VA_ARGS__).self()
40 #else
41 # define qiLogVerbose(...) qi::log::LogStream(qi::log::verbose, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
42 #endif
43 
44 #ifdef NO_QI_INFO
45 # define qiLogInfo(...) if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
46 #elif defined(NO_QI_LOG_DETAILED_CONTEXT) || defined(NDEBUG)
47 # define qiLogInfo(...) qi::log::LogStream(qi::log::info, "", __FUNCTION__, 0, __VA_ARGS__).self()
48 #else
49 # define qiLogInfo(...) qi::log::LogStream(qi::log::info, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
50 #endif
51 
52 #ifdef NO_QI_WARNING
53 # define qiLogWarning(...) if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
54 #elif defined(NO_QI_LOG_DETAILED_CONTEXT) || defined(NDEBUG)
55 # define qiLogWarning(...) qi::log::LogStream(qi::log::warning, "", __FUNCTION__, 0, __VA_ARGS__).self()
56 #else
57 # define qiLogWarning(...) qi::log::LogStream(qi::log::warning, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
58 #endif
59 
60 #ifdef NO_QI_ERROR
61 # define qiLogError(...) if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
62 #elif defined(NO_QI_LOG_DETAILED_CONTEXT) || defined(NDEBUG)
63 # define qiLogError(...) qi::log::LogStream(qi::log::error, "", __FUNCTION__, 0, __VA_ARGS__).self()
64 #else
65 # define qiLogError(...) qi::log::LogStream(qi::log::error, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
66 #endif
67 
68 #ifdef NO_QI_FATAL
69 # define qiLogFatal(...) if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
70 #elif defined(NO_QI_LOG_DETAILED_CONTEXT) || defined(NDEBUG)
71 # define qiLogFatal(...) qi::log::LogStream(qi::log::fatal, "", __FUNCTION__, 0, __VA_ARGS__).self()
72 #else
73 # define qiLogFatal(...) qi::log::LogStream(qi::log::fatal, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
74 #endif
75 
76 
77 // enum level {
78 // silent = 0,
79 // fatal,
80 // error,
81 // warning,
82 // info,
83 // verbose,
84 // debug
85 // };
86 
87 
88 namespace qi {
89  namespace log {
90 
91  namespace detail {
92 
93  class NullStream {
94  public:
95  NullStream(const char *, ...)
96  {
97  }
98 
99  NullStream &self()
100  {
101  return *this;
102  }
103 
104  template <typename T>
105  NullStream& operator<<(const T &QI_UNUSED(val))
106  {
107  return self();
108  }
109 
110  NullStream& operator<<(std::ostream& (*QI_UNUSED(f))(std::ostream&))
111  {
112  return self();
113  }
114 
115  };
116 
117  };
118 
119  enum LogLevel {
120  silent = 0,
127  };
128 
129  typedef boost::function7<void,
130  const qi::log::LogLevel,
131  const qi::os::timeval,
132  const char*,
133  const char*,
134  const char*,
135  const char*,
137 
138  QI_API void init(qi::log::LogLevel verb = qi::log::info,
139  int ctx = 0,
140  bool synchronous = true);
141 
142  QI_API void destroy();
143 
144  QI_API void log(const qi::log::LogLevel verb,
145  const char *category,
146  const char *msg,
147  const char *file = "",
148  const char *fct = "",
149  const int line = 0);
150 
151  QI_API const char* logLevelToString(const qi::log::LogLevel verb);
152 
153  QI_API qi::log::LogLevel stringToLogLevel(const char* verb);
154 
155  QI_API void setVerbosity(const qi::log::LogLevel lv);
156 
157  QI_API qi::log::LogLevel verbosity();
158 
159 
160  QI_API void setContext(int ctx);
161 
162  QI_API int context();
163 
164  QI_API void setSynchronousLog(bool sync);
165 
166  QI_API void addLogHandler(const std::string& name,
168 
169  QI_API void removeLogHandler(const std::string& name);
170 
171  QI_API void flush();
172 
173  class LogStream: public std::stringstream
174  {
175  public:
176  LogStream(const LogLevel level,
177  const char *file,
178  const char *function,
179  const int line,
180  const char *category)
181  : _logLevel(level)
182  , _category(category)
183  , _file(file)
184  , _function(function)
185  , _line(line)
186  {
187  }
188 
189  LogStream(const LogLevel level,
190  const char *file,
191  const char *function,
192  const int line,
193  const char *category,
194  const char *fmt, ...)
195  : _logLevel(level)
196  , _category(category)
197  , _file(file)
198  , _function(function)
199  , _line(line)
200  {
201  char buffer[2048];
202  va_list vl;
203  va_start(vl, fmt);
204  #ifdef _MSC_VER
205  vsnprintf_s(buffer, 2048, 2047, fmt, vl);
206  #else
207  vsnprintf(buffer, 2048, fmt, vl);
208  #endif
209  buffer[2047] = 0;
210  va_end(vl);
211  *this << buffer;
212  }
213 
215  {
216  qi::log::log(_logLevel, _category, this->str().c_str(), _file, _function, _line);
217  }
218 
219  LogStream& self() {
220  return *this;
221  }
222 
223  private:
224  LogLevel _logLevel;
225  const char *_category;
226  const char *_file;
227  const char *_function;
228  int _line;
229 
230  //avoid copy
231  LogStream(const LogStream &rhs);
232  LogStream &operator=(const LogStream &rhs);
233  };
234  }
235 }
236 
237 #endif // _LIBQI_QI_LOG_HPP_