Tomographer  v5.4
Tomographer C++ Framework Documentation
loggers.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2016 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  * Copyright (c) 2017 Caltech, Institute for Quantum Information and Matter, Philippe Faist
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #ifndef TOMOGRAPHER_TOOLS_LOGGERS_H
29 #define TOMOGRAPHER_TOOLS_LOGGERS_H
30 
31 #include <cstdio>
32 #include <cstdarg>
33 
34 #include <string>
35 #include <sstream> // std::stringstream
36 #include <iostream>
37 #include <functional> // std::function
38 #include <type_traits> // std::true_type
39 #include <map>
40 
41 #include <boost/algorithm/string.hpp> // to_upper()
42 
44 #include <tomographer/tools/fmt.h>
46 
47 
57 #ifdef ERROR
58 #error "The macro ERROR is defined. You may be on a Windows system. Make sure that <tomographer/tools/logger.h> is included BEFORE any windows-related header."
59 #endif
60 
61 
62 namespace Tomographer
63 {
64 
68 namespace Logger
69 {
70 
77 {
83  ERROR = 0,
84 
93 
101 
113 
123 
124 
132 
140 };
141 
142 
143 
158 class TOMOGRAPHER_EXPORT LogLevel
159 {
160  int _level;
161 public:
163  LogLevel(int level_ = INFO) { setLevel(level_); }
165  LogLevel(const char * s) { setLevel(s); }
167  LogLevel(std::string s) { setLevel(std::move(s)); }
168 
170  inline int level() const { return _level; }
171 
173  inline operator int() const { return _level; }
174 
176  inline std::string levelName() const
177  {
178  switch (_level) {
179  case LONGDEBUG: return std::string("LONGDEBUG");
180  case DEBUG: return std::string("DEBUG");
181  case INFO: return std::string("INFO");
182  case WARNING: return std::string("WARNING");
183  case ERROR: return std::string("ERROR");
184  default: return std::string("<INVALID LEVEL>");
185  };
186  }
187 
189  inline void setLevel(int level)
190  {
191  if (level != LONGDEBUG &&
192  level != DEBUG &&
193  level != INFO &&
194  level != WARNING &&
195  level != ERROR) {
196  throw std::invalid_argument("Invalid level code: "+std::to_string(level));
197  }
198  _level = level;
199  }
200 
202  inline void setLevel(std::string s)
203  {
204  // NOT const string `s`! we need our copy for to_upper():
205  boost::to_upper(s);
206  if (s == "LONGDEBUG") {
207  _level = LONGDEBUG;
208  } else if (s == "DEBUG") {
209  _level = DEBUG;
210  } else if (s == "INFO") {
211  _level = INFO;
212  } else if (s == "WARNING") {
213  _level = WARNING;
214  } else if (s == "ERROR") {
215  _level = ERROR;
216  } else {
217  throw std::invalid_argument("Invalid log level: '"+s+"'");
218  }
219  }
220 };
221 
224 {
225  std::string s;
226  str >> s;
227  l.setLevel(std::move(s));
228  return str;
229 }
231 inline std::ostream & operator<<(std::ostream & str, const LogLevel &l)
232 {
233  return str << l.levelName();
234 }
235 
236 
237 
248 inline bool isAtLeastOfSeverity(int level, int baselevel)
249 {
250  return (level <= baselevel);
251 }
252 
260 template<int Level, int BaseLevel>
261 struct TOMOGRAPHER_EXPORT StaticIsAtLeastOfSeverity {
262  enum {
263  value = (Level <= BaseLevel)
264  };
265 };
266 
267 
288 struct TOMOGRAPHER_EXPORT DefaultLoggerTraits
289 {
290  enum {
296  IsThreadSafe = 0,
297 
310  StaticMinimumSeverityLevel = LOWEST_SEVERITY_LEVEL,
311 
323  HasOwnGetLevel = 0,
324 
337  HasFilterByOrigin = 0
338  };
339 };
340 
350 template<typename LoggerType>
351 struct TOMOGRAPHER_EXPORT LoggerTraits
352 {
353  // by default, contains nothing and will produce errors if used unspecialized.
354 };
355 
356 
357 
358 namespace tomo_internal {
362 template<bool hasOwnGetLevel>
363 class
364 TOMOGRAPHER_EXPORT // export might be needed because this is used as base class of LoggerBase
365 LoggerRuntimeLevel
366 {
367 public:
368  LoggerRuntimeLevel(int level)
369  : _level(level)
370  {
371  }
372 
373  inline int level() const
374  {
375  return _level;
376  }
377 
378 protected:
379  inline void setLogLevel(int level)
380  {
381  _level = level;
382  }
383 
384 private:
385  int _level;
386 };
387 //
388 // Specialization for those classes which provide their own level() method. Do nothing.
389 //
390 template<>
391 class TOMOGRAPHER_EXPORT LoggerRuntimeLevel<true>
392 {
393 public:
394  LoggerRuntimeLevel(int /*level*/)
395  {
396  }
397 
398  inline void setLogLevel(int) {
399  tomographer_assert(0 && "Call to LoggerRuntimeLevel::setLogLevel() for Logger which defines HasOwnGetLevel=1!");
400  }
401 };
402 
403 
404 template<typename Fn>
405 struct IsOstreamArgCallable
406 {
407  enum {
411  >::value
412  };
413 };
414 
415 } // namespace tomo_internal
416 
417 
443 template<typename Derived>
444 class TOMOGRAPHER_EXPORT LoggerBase
445 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
446  : public tomo_internal::LoggerRuntimeLevel<LoggerTraits<Derived>::HasOwnGetLevel>
447 #endif
448 {
449 public:
452  enum {
461  };
462 
472  LoggerBase(int level_ = INFO)
473  : tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>(level_)
474  {
475  }
476 
477 
490  static inline bool staticallyEnabledFor(int level)
491  {
492  return ( isAtLeastOfSeverity(level, StaticMinimumSeverityLevel) );
493  }
494 
498  template<int Level>
499  static inline constexpr bool staticallyEnabledFor()
500  {
501  return ( StaticIsAtLeastOfSeverity<
502  Level,
503  StaticMinimumSeverityLevel
504  >::value ) ;
505  }
506 
517  inline bool enabledFor(int level_) const
518  {
519  return staticallyEnabledFor(level_) &&
520  isAtLeastOfSeverity(level_, getLevel());
521  };
522 
523 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
524  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
525  // exposed in the case where the logger doesn't define its own method. This is important
526  // to avoid "ambiguous calls to `level()`".
527 
539  inline int level() const
540  {
541  }
542 #endif
543 
544 
545 
546 
554  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<ERROR>())
555  PRINTF3_ARGS_SAFE
556  inline void error(const char * origin, const char * fmt, ...)
557  {
558  va_list ap;
559  va_start(ap, fmt);
560  log<ERROR>(origin, fmt, ap);
561  va_end(ap);
562  }
563 
571  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<ERROR>())
572  inline void error(const char * origin, std::string msg)
573  {
574  log<ERROR>(origin, std::move(msg));
575  }
576 
583  template<typename Fn,
584  TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<ERROR>() &&
586  inline void error(const char * origin, Fn && f)
587  {
588  log<ERROR>(origin, std::forward<Fn>(f));
589  }
590 
592  template<TOMOGRAPHER_ENABLED_IF_TMPL(!staticallyEnabledFor<ERROR>()), typename... Args>
593  inline void error(Args && ... ) { }
594 
602  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<WARNING>())
603  PRINTF3_ARGS_SAFE
604  inline void warning(const char * origin, const char * fmt, ...)
605  {
606  va_list ap;
607  va_start(ap, fmt);
608  log<WARNING>(origin, fmt, ap);
609  va_end(ap);
610  }
611 
619  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<WARNING>())
620  inline void warning(const char * origin, std::string msg)
621  {
622  log<WARNING>(origin, std::move(msg));
623  }
624 
631  template<typename Fn,
632  TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<WARNING>() &&
634  inline void warning(const char * origin, Fn && f)
635  {
636  log<WARNING>(origin, std::forward<Fn>(f));
637  }
638 
640  template<TOMOGRAPHER_ENABLED_IF_TMPL(!staticallyEnabledFor<WARNING>()), typename... Args>
641  inline void warning(Args && ... ) { }
642 
650  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<INFO>())
651  PRINTF3_ARGS_SAFE
652  inline void info(const char * origin, const char * fmt, ...)
653  {
654  va_list ap;
655  va_start(ap, fmt);
656  log<INFO>(origin, fmt, ap);
657  va_end(ap);
658  }
659 
667  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<INFO>())
668  inline void info(const char * origin, std::string msg)
669  {
670  log<INFO>(origin, std::move(msg));
671  }
678  template<typename Fn,
679  TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<INFO>() &&
681  inline void info(const char * origin, Fn && f)
682  {
683  log<INFO>(origin, std::forward<Fn>(f));
684  }
685 
687  template<TOMOGRAPHER_ENABLED_IF_TMPL(!staticallyEnabledFor<INFO>()), typename... Args>
688  inline void info(Args && ... ) { }
689 
690 
708  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<DEBUG>())
709  PRINTF3_ARGS_SAFE
710  inline void debug(const char * origin, const char * fmt, ...)
711  {
712  va_list ap;
713  va_start(ap, fmt);
714  log<DEBUG>(origin, fmt, ap);
715  va_end(ap);
716  }
717 
734  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<DEBUG>())
735  inline void debug(const char * origin, std::string msg)
736  {
737  log<DEBUG>(origin, std::move(msg));
738  }
739 
768  template<typename Fn,
769  TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<DEBUG>() &&
771  inline void debug(const char * origin, Fn && f)
772  {
773  log<DEBUG>(origin, std::forward<Fn>(f));
774  }
775 
777  template<TOMOGRAPHER_ENABLED_IF_TMPL(!staticallyEnabledFor<DEBUG>()), typename... Args>
778  inline void debug(Args && ... ) { }
779 
787  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<LONGDEBUG>())
788  PRINTF3_ARGS_SAFE
789  inline void longdebug(const char * origin, const char * fmt, ...)
790  {
791  va_list ap;
792  va_start(ap, fmt);
793  log<LONGDEBUG>(origin, fmt, ap);
794  va_end(ap);
795  }
796 
804  TOMOGRAPHER_ENABLED_IF(staticallyEnabledFor<LONGDEBUG>())
805  inline void longdebug(const char * origin, std::string msg)
806  {
807  log<LONGDEBUG>(origin, std::move(msg));
808  }
815  template<typename Fn,
816  TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<LONGDEBUG>() &&
818  inline void longdebug(const char * origin, Fn && f)
819  {
820  log<LONGDEBUG>(origin, std::forward<Fn>(f));
821  }
822 
824  template<TOMOGRAPHER_ENABLED_IF_TMPL(!staticallyEnabledFor<LONGDEBUG>()), typename... Args>
825  inline void longdebug(Args && ... ) { }
826 
827 
837  PRINTF4_ARGS_SAFE
838  inline void log(int level, const char * origin, const char * fmt, ...)
839  {
840  va_list ap;
841  va_start(ap, fmt);
842  _do_log(level, origin, fmt, ap);
843  va_end(ap);
844  }
845 
855  inline void log(int level, const char * origin, std::string msg)
856  {
857  _do_log(level, origin, std::move(msg));
858  }
859 
870  inline void log(int level, const char * origin, Fn && f)
871  {
872  _do_log(level, origin, std::forward<Fn>(f));
873  }
874 
875 
884  template<int Level, TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<Level>())>
885  PRINTF3_ARGS_SAFE
886  inline void log(const char * origin, const char * fmt, ...)
887  {
888  va_list ap;
889  va_start(ap, fmt);
890  _do_log(Level, origin, fmt, ap);
891  va_end(ap);
892  }
893 
903  template<int Level, TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<Level>())>
904  inline void log(const char * origin, const char * fmt, va_list ap)
905  {
906  _do_log(Level, origin, fmt, ap);
907  }
908 
917  template<int Level, TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<Level>())>
918  inline void log(const char * origin, std::string msg)
919  {
920  _do_log(Level, origin, std::move(msg));
921  }
922 
931  template<int Level, typename Fn,
932  TOMOGRAPHER_ENABLED_IF_TMPL(staticallyEnabledFor<Level>() &&
934  inline void log(const char * origin, Fn f)
935  {
936  _do_log(Level, origin, f);
937  }
938 
940  template<int Level, TOMOGRAPHER_ENABLED_IF_TMPL(!staticallyEnabledFor<Level>()), typename ... Args>
941  inline void log(Args && ...) { }
942 
943 
944 
945 protected:
946 
947  // version in case we store our own level
948  TOMOGRAPHER_ENABLED_IF(!HasOwnGetLevel)
949  inline int getLevel() const
950  {
951  // use base class' implementation
952  return tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>::level();
953  }
954  // version in case we delegate to derived class' level()
955  TOMOGRAPHER_ENABLED_IF(HasOwnGetLevel)
956  inline int getLevel() const
957  {
958  return derived()->level();
959  }
960 
961 
962  inline Derived * derived()
963  {
964  return static_cast<Derived*>(this);
965  }
966  inline const Derived * derived() const
967  {
968  return static_cast<const Derived*>(this);
969  }
970 
971 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
972  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
973  // exposed in the case where the logger can actually set a new level.
974 
988  inline void setLogLevel(int level)
989  {
990  }
991 #endif
992 
993 private:
994 
995  TOMOGRAPHER_ENABLED_IF(!HasFilterByOrigin)
996  inline bool _test_filter_by_origin(int , const char * ) const { return true; }
997  TOMOGRAPHER_ENABLED_IF(HasFilterByOrigin)
998  inline bool _test_filter_by_origin(int level, const char * origin)
999  {
1000  return derived()->filterByOrigin(level, origin);
1001  }
1002 
1003  inline bool _test_should_emit(int level, const char * origin)
1004  {
1005  return enabledFor(level) && _test_filter_by_origin(level, origin) ;
1006  }
1007 
1008  inline void _do_log(int level, const char * origin, const char * fmt, va_list ap)
1009  {
1010  if (_test_should_emit(level, origin)) {
1011  std::string msg = Tools::vfmts(fmt, ap);
1012  derived()->emitLog(level, origin, std::move(msg));
1013  }
1014  }
1015  inline void _do_log(int level, const char * origin, std::string msg)
1016  {
1017  if (_test_should_emit(level, origin)) {
1018  derived()->emitLog(level, origin, std::move(msg));
1019  }
1020  }
1022  inline void _do_log(int level, const char * origin, Fn f)
1023  {
1024  if (_test_should_emit(level, origin)) {
1025  std::ostringstream sstr;
1026  f(sstr);
1027  derived()->emitLog(level, origin, sstr.str());
1028  }
1029  }
1030 
1031 };
1032 
1033 
1034 
1035 
1036 
1037 
1038 class FileLogger;
1043 template<>
1045 {
1047  enum {
1048  IsThreadSafe = 1
1049  };
1050 };
1051 
1062 class TOMOGRAPHER_EXPORT FileLogger : public LoggerBase<FileLogger>
1063 {
1064 public:
1065  FileLogger(FILE * fp_, int level = INFO, bool display_origin_ = true)
1066  : LoggerBase<FileLogger>(level), fp(fp_), display_origin(display_origin_)
1067  {
1068  }
1069 
1073  inline void setFp(FILE * fp_)
1074  {
1075  fp = fp_;
1076  }
1077 
1081  inline void setLevel(int level)
1082  {
1083  setLogLevel(level);
1084  }
1085 
1089  inline void setDisplayOrigin(bool display_origin_)
1090  {
1091  display_origin = display_origin_;
1092  }
1093 
1094  inline void emitLog(int level, const char * origin, std::string msg)
1095  {
1096  static const std::string level_prefixes[] = {
1097  std::string("\n\n*** ERROR -- "),
1098  std::string("\n*** Warning: ")
1099  };
1100 
1101  std::string finalmsg = (
1103  ? level_prefixes[level] : std::string() )
1104  + ((display_origin && origin && origin[0]) ? "["+std::string(origin)+"] " : std::string())
1105  + std::move(msg) // \a msg is moved here, don't use \a msg any more
1106  );
1107 
1108  // display the log message
1109  std::fprintf(fp, "%s\n", finalmsg.c_str());
1110 
1111  if (isAtLeastOfSeverity(level, WARNING)) {
1112  // force output also on stderr for warnings and errors if we are being redirected to a
1113  // file, or at least flush the buffer.
1114  std::fflush(fp);
1115  if (fp != stdout && fp != stderr) {
1116  std::fprintf(stderr, "%s\n", finalmsg.c_str());
1117  }
1118  }
1119  }
1120 
1121 private:
1122  std::FILE * fp;
1123  bool display_origin;
1124 };
1125 
1126 
1127 
1128 
1129 
1130 class VacuumLogger;
1135 template<>
1137 {
1139  enum {
1140  IsThreadSafe = 1,
1141  StaticMinimumSeverityLevel = -1
1142  };
1143 };
1144 
1149 class TOMOGRAPHER_EXPORT VacuumLogger : public LoggerBase<VacuumLogger>
1150 {
1151 public:
1152  inline void emitLog(int /*level*/, const char * /*origin*/, const std::string & /*msg*/)
1153  {
1154  }
1155 
1156 };
1157 
1163 static VacuumLogger vacuum_logger;
1164 
1165 
1166 
1167 
1168 class BufferLogger;
1173 template<>
1175 {
1177  enum {
1178  IsThreadSafe = 0
1179  };
1180 };
1181 
1187 class TOMOGRAPHER_EXPORT BufferLogger : public LoggerBase<BufferLogger>
1188 {
1189  std::ostringstream buffer;
1190 public:
1191  BufferLogger(int level)
1192  : LoggerBase<BufferLogger>(level)
1193  {
1194  }
1195 
1196  inline void emitLog(int /*level*/, const char * origin, std::string msg)
1197  {
1198  buffer << (origin&&origin[0] ? "["+std::string(origin)+"] " : std::string())
1199  << std::move(msg) << "\n";
1200  }
1201 
1206  inline void setLevel(int level)
1207  {
1208  setLogLevel(level);
1209  }
1210 
1216  inline void clear()
1217  {
1218  buffer.clear();
1219  buffer.str(std::string());
1220  }
1221 
1226  inline std::string getContents() const
1227  {
1228  return buffer.str();
1229  }
1230 };
1231 
1232 
1233 
1234 
1235 template<typename, int> class MinimumSeverityLogger;
1238 template<typename BaseLogger, int Level>
1239 struct LoggerTraits<MinimumSeverityLogger<BaseLogger,Level> > : public LoggerTraits<BaseLogger>
1240 {
1242  enum {
1243 
1245  StaticMinimumSeverityLevel = Level,
1246 
1248  HasOwnGetLevel = 1
1249 
1250  // Note: filter by origin flag is inherited from base logger.
1251  };
1252 };
1253 
1263 template<typename BaseLogger, int Level>
1264 class TOMOGRAPHER_EXPORT MinimumSeverityLogger : public LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >
1265 {
1267  BaseLogger & baselogger;
1268 public:
1274  MinimumSeverityLogger(BaseLogger & baselogger_)
1275  : LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >(), baselogger(baselogger_)
1276  {
1277  }
1278 
1280  inline void emitLog(int level, const char * origin, std::string msg)
1281  {
1282  baselogger.emitLog(level, origin, std::move(msg));
1283  }
1284 
1286  inline int level() const
1287  {
1288  return baselogger.level();
1289  }
1290 
1292  TOMOGRAPHER_ENABLED_IF(LoggerTraits<BaseLogger>::HasFilterByOrigin)
1293  inline bool filterByOrigin(int level, const char * origin)
1294  {
1295  return baselogger.filterByOrigin(level, origin);
1296  }
1297 };
1298 
1299 
1300 
1301 
1302 
1303 template<typename> class OriginPrefixedLogger;
1306 template<typename BaseLogger>
1307 struct LoggerTraits<OriginPrefixedLogger<BaseLogger> > : public LoggerTraits<BaseLogger>
1308 {
1310  enum {
1312  HasOwnGetLevel = 1
1313  };
1314 };
1315 
1327 template<typename BaseLogger>
1328 class TOMOGRAPHER_EXPORT OriginPrefixedLogger : public LoggerBase<OriginPrefixedLogger<BaseLogger> >
1329 {
1331  BaseLogger & baselogger;
1332 
1334  std::string prefix;
1335 
1336 public:
1342  OriginPrefixedLogger(BaseLogger & baselogger_, std::string prefix_)
1343  : LoggerBase<OriginPrefixedLogger<BaseLogger> >(),
1344  baselogger(baselogger_),
1345  prefix(prefix_)
1346  {
1347  }
1348 
1350  inline void setPrefix(std::string prefix_)
1351  {
1352  prefix = prefix_;
1353  }
1354 
1355 
1357  inline void emitLog(int level, const char * origin, std::string msg)
1358  {
1359  std::string neworigin = prefix + origin;
1360  baselogger.emitLog(level, neworigin.c_str(), std::move(msg));
1361  }
1362 
1364  inline int level() const
1365  {
1366  return baselogger.level();
1367  }
1368 
1370  TOMOGRAPHER_ENABLED_IF(LoggerTraits<BaseLogger>::HasFilterByOrigin)
1371  inline bool filterByOrigin(int level, const char * origin)
1372  {
1373  return baselogger.filterByOrigin(level, origin); // unmodified origin here for by-origin filtering
1374  }
1375 };
1376 
1377 
1378 
1379 
1380 namespace tomo_internal {
1381 
1387 inline std::size_t matched_length(const std::string & s, const std::string & pattern)
1388 {
1389  std::size_t k = 0;
1390  while (s[k] == pattern[k]) {
1391  ++k;
1392  }
1393  return k;
1394 }
1395 
1396 } // namespace tomo_internal
1397 
1398 template<typename BaseLogger> class OriginFilteredLogger;
1402 template<typename BaseLogger>
1403 struct LoggerTraits<OriginFilteredLogger<BaseLogger> > : public LoggerTraits<BaseLogger>
1404 {
1406  enum {
1407  HasOwnGetLevel = 1,
1408  HasFilterByOrigin = 1
1409  };
1410 };
1411 
1432 template<typename BaseLogger>
1433 class TOMOGRAPHER_EXPORT OriginFilteredLogger
1434  : public Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >
1435 {
1437  BaseLogger & baselogger;
1438 
1440  std::map<std::string,int> levels_set;
1441 public:
1442 
1448  OriginFilteredLogger(BaseLogger & baselogger_)
1449  : Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >(),
1450  baselogger(baselogger_),
1451  levels_set()
1452  {
1453  }
1454 
1464  inline void setDomainLevel(const std::string& origin_pattern, int level)
1465  {
1466  levels_set[origin_pattern] = level;
1467  }
1468 
1474  inline void removeDomainSetting(const std::string& s)
1475  {
1476  auto it = levels_set.find(s);
1477  if (it == levels_set.end()) {
1478  this->warning("OriginFilteredLogger<BaseLogger>::removeDomainSetting", "domain not set: `%s'", s.c_str());
1479  return;
1480  }
1481  levels_set.erase(it);
1482  }
1483 
1492  inline int level() const
1493  {
1494  return LOWEST_SEVERITY_LEVEL;
1495  }
1496 
1501  inline void emitLog(int level, const char * origin, std::string msg)
1502  {
1503  baselogger.emitLog(level, origin, std::move(msg));
1504  }
1505 
1513  inline bool filterByOrigin(int level, const char * origin) const
1514  {
1515  typedef std::map<std::string, int>::const_iterator ConstIterator;
1516 
1517  std::string s(origin);
1518 
1519  int loglevel = -1;
1520  std::size_t last_matched_length = 0;
1521  for (ConstIterator it = levels_set.begin(); it != levels_set.end(); ++it) {
1522  const std::size_t mlen = tomo_internal::matched_length((*it).first, s);
1523  if (mlen > last_matched_length) {
1524  loglevel = (*it).second;
1525  last_matched_length = mlen;
1526  }
1527  }
1528  if (loglevel == -1) {
1529  // default logger level
1530  loglevel = baselogger.level();
1531  }
1532  return isAtLeastOfSeverity(level, loglevel);
1533  }
1534 
1535 };
1536 
1537 
1538 
1539 
1540 
1541 // --------------------------------------------------
1542 
1543 
1544 
1545 
1546 
1555 
1558  : origin_prefix(s), origin_prefix_add(""), glue(gl) { }
1560  constexpr LocalLoggerOriginSpec(const Tools::conststr& s, const Tools::conststr& s2, const Tools::conststr& gl)
1561  : origin_prefix(s), origin_prefix_add(s2), glue(gl) { }
1562 };
1563 
1564 namespace tomo_internal {
1566 struct extractTomoOrigin_helper {
1567  static inline constexpr LocalLoggerOriginSpec step2(const Tools::conststr fn, std::size_t last_doublecolons,
1568  std::size_t after_prelast_doublecolons)
1569  {
1570  return ( fn.substr_e(after_prelast_doublecolons, last_doublecolons) == fn.substr(last_doublecolons+2)
1571  // fn is a constructor, so keep class name and use "::" as glue
1572  ? LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "::")
1573  // looks like a method name. Strip off the class name. Also use an internal
1574  // glue to indicate a logical level.
1575  : LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "()", "/")
1576  );
1577  }
1578  static inline constexpr std::size_t afterprelast_doublecolons(std::size_t prelast_doublecolons_found)
1579  {
1580  return (prelast_doublecolons_found == std::string::npos) ? 0 : prelast_doublecolons_found+2;
1581  }
1582  static inline constexpr LocalLoggerOriginSpec step1(const Tools::conststr fn, std::size_t last_doublecolons)
1583  {
1584  return last_doublecolons == std::string::npos || last_doublecolons == 0
1585  ? LocalLoggerOriginSpec(fn, "()", "/") // looks like simple function name with no parent scope
1586  : step2(fn, last_doublecolons, afterprelast_doublecolons(fn.rfind("::", last_doublecolons-1)));
1587  }
1588 
1589  static inline constexpr LocalLoggerOriginSpec extract_from_func_name(const Tools::conststr fn)
1590  {
1591  return step1(fn, fn.rfind("::"));
1592  }
1593 };
1594 
1596 constexpr const LocalLoggerOriginSpec extractTomoOrigin(const Tools::conststr fn)
1597 {
1598  return extractTomoOrigin_helper::extract_from_func_name(Tomographer::Tools::extractFuncName(fn));
1599 }
1600 
1601 } // namespace tomo_internal
1602 
1603 
1608 #define TOMO_ORIGIN Tomographer::Logger::tomo_internal::extractTomoOrigin(TOMO_FUNCTION)
1609 
1610 
1611 
1612 
1613 template<typename BaseLoggerType_> class LocalLogger;
1614 
1615 
1616 namespace tomo_internal {
1618 template<typename BaseLoggerType>
1619 struct is_local_logger {
1620  enum { value = 0 };
1621 };
1622 template<typename BaseLoggerType>
1623 struct is_local_logger<LocalLogger<BaseLoggerType> > {
1624  enum { value = 1 };
1625 };
1627 template<typename BaseLoggerType>
1628 struct local_logger_parent {
1629  typedef BaseLoggerType ParentType;
1630 };
1631 template<typename BaseLoggerType>
1632 struct local_logger_parent<LocalLogger<BaseLoggerType> > {
1633  typedef typename local_logger_parent<BaseLoggerType>::ParentType ParentType;
1634 };
1635 } // namespace tomo_internal
1636 
1638 template<typename BaseLoggerType_>
1639 struct LoggerTraits<LocalLogger<BaseLoggerType_> > : public LoggerTraits<BaseLoggerType_>
1640 {
1641  enum {
1643  HasOwnGetLevel = 1
1644  };
1645 };
1646 
1647 
1706 template<typename BaseLoggerType_>
1707 class TOMOGRAPHER_EXPORT LocalLogger
1708  : public LoggerBase<LocalLogger<BaseLoggerType_> >
1709 {
1710 public:
1712  typedef BaseLoggerType_ BaseLoggerType;
1713 
1714 private:
1716 
1718  const std::string _origin_prefix;
1720  const std::string _glue;
1721 
1722  BaseLoggerType & _baselogger;
1723 
1724 public:
1735  LocalLogger(std::string origin_fn_name, BaseLoggerType & logger_)
1736  : Base_(), _origin_prefix(std::move(origin_fn_name)), _glue("::"), _baselogger(logger_)
1737  {
1738  this->longdebug("[begin]");
1739  }
1746  LocalLogger(std::string origin_prefix, std::string glue, BaseLoggerType & logger_)
1747  : Base_(), _origin_prefix(std::move(origin_prefix)), _glue(std::move(glue)), _baselogger(logger_)
1748  {
1749  this->longdebug("[begin]");
1750  }
1756  LocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & logger_)
1757  : Base_(), _origin_prefix(spec.origin_prefix.to_string()+spec.origin_prefix_add.to_string()),
1758  _glue(spec.glue.to_string()), _baselogger(logger_)
1759  {
1760  this->longdebug("[begin]");
1761  }
1762 
1767  : Base_(), _origin_prefix(std::move(movecopy._origin_prefix)), _glue(std::move(movecopy._glue)),
1768  _baselogger(movecopy._baselogger)
1769  {
1770  this->longdebug("[logger moved]");
1771  }
1773  LocalLogger(const LocalLogger & other)
1774  : Base_(), _origin_prefix(other._origin_prefix), _glue(other._glue),
1775  _baselogger(other._baselogger)
1776  {
1777  this->longdebug("[logger copied]");
1778  }
1779 
1780  ~LocalLogger()
1781  {
1782  this->longdebug("[done]");
1783  }
1784 
1793  inline std::string originPrefix() const { return _origin_prefix; }
1794 
1797  inline std::string glue() const { return _glue; }
1798 
1804  inline BaseLoggerType & baseLogger() { return _baselogger; }
1805 
1806 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
1807 
1812  typedef _PARENT_LOGGER_TYPE ParentLoggerType;
1813 
1821  ParentLoggerType & parentLogger() { }
1822 #else
1823 
1824  typedef typename tomo_internal::local_logger_parent<BaseLoggerType>::ParentType ParentLoggerType;
1825 
1827  inline ParentLoggerType & parentLogger()
1828  {
1829  return baseLogger();
1830  }
1832  inline ParentLoggerType & parentLogger() {
1833  return baseLogger().parentLogger();
1834  }
1835 #endif
1836 
1847  {
1848  return LocalLogger<LocalLogger<BaseLoggerType> >(std::move(new_prefix), *this);
1849  }
1857  std::string new_glue)
1858  {
1859  return LocalLogger<LocalLogger<BaseLoggerType> >(std::move(new_prefix), std::move(new_glue), *this);
1860  }
1867  {
1868  return LocalLogger<LocalLogger<BaseLoggerType> >(spec, *this);
1869  }
1870 
1875  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<LONGDEBUG>())
1876  PRINTF2_ARGS_SAFE inline void longdebug(const char * fmt, ...)
1877  { va_list ap; va_start(ap, fmt); log<LONGDEBUG>(fmt, ap); va_end(ap); }
1882  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<DEBUG>())
1883  PRINTF2_ARGS_SAFE inline void debug(const char * fmt, ...)
1884  { va_list ap; va_start(ap, fmt); log<DEBUG>(fmt, ap); va_end(ap); }
1889  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<INFO>())
1890  PRINTF2_ARGS_SAFE inline void info(const char * fmt, ...)
1891  { va_list ap; va_start(ap, fmt); log<INFO>(fmt, ap); va_end(ap); }
1896  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<WARNING>())
1897  PRINTF2_ARGS_SAFE inline void warning(const char * fmt, ...)
1898  { va_list ap; va_start(ap, fmt); log<WARNING>(fmt, ap); va_end(ap); }
1903  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<ERROR>())
1904  PRINTF2_ARGS_SAFE inline void error(const char * fmt, ...)
1905  { va_list ap; va_start(ap, fmt); log<ERROR>(fmt, ap); va_end(ap); }
1906 
1911  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<LONGDEBUG>()),
1912  typename... Args>
1913  inline void longdebug(Args &&... a) { log<Tomographer::Logger::LONGDEBUG>(std::forward<Args>(a)...); }
1918  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<DEBUG>()),
1919  typename... Args>
1920  inline void debug(Args &&... a) { log<Tomographer::Logger::DEBUG>(std::forward<Args>(a)...); }
1925  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<INFO>()),
1926  typename... Args>
1927  inline void info(Args &&... a) { log<Tomographer::Logger::INFO>(std::forward<Args>(a)...); }
1932  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<WARNING>()),
1933  typename... Args>
1934  inline void warning(Args &&... a) { log<Tomographer::Logger::WARNING>(std::forward<Args>(a)...); }
1939  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<ERROR>()),
1940  typename... Args>
1941  inline void error(Args &&... a) { log<Tomographer::Logger::ERROR>(std::forward<Args>(a)...); }
1942 
1947  template<int Level,
1948  TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<Level>()),
1949  typename... Args>
1950  inline void log(Args && ... args)
1951  {
1952  Base_::template log<Level>("", std::forward<Args>(args)...);
1953  }
1954 
1955 
1957  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<LONGDEBUG>()),
1958  typename... Args>
1959  inline void longdebug(Args &&... ) { }
1961  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<DEBUG>()),
1962  typename... Args>
1963  inline void debug(Args &&... ) { }
1965  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<INFO>()),
1966  typename... Args>
1967  inline void info(Args &&... ) { }
1969  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<WARNING>()),
1970  typename... Args>
1971  inline void warning(Args &&... ) { }
1973  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<ERROR>()),
1974  typename... Args>
1975  inline void error(Args &&... ) { }
1977  template<int Level, TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<Level>()),
1978  typename... Args>
1979  inline void log(Args &&... ) { }
1980 
1981 
1982  // relay calls to base logger
1983 
1992  inline std::string getSubOrigin(const char * origin) const
1993  {
1994  return ( origin == NULL || origin[0] == 0
1995  ? _origin_prefix
1996  : _origin_prefix + _glue + origin );
1997  }
1998 
2000  inline void emitLog(int level, const char * origin, std::string msg)
2001  {
2002  // this might also be called if we have a sublogger. In that case, if we have a
2003  // sublogger, then use their prefix.
2004  _baselogger.emitLog(level, getSubOrigin(origin).c_str(), std::move(msg));
2005  }
2006 
2008  inline int level() const
2009  {
2010  return _baselogger.level();
2011  }
2012 
2015  inline bool filterByOrigin(int level, const char * origin)
2016  {
2017  return _baselogger.filterByOrigin(level, getSubOrigin(origin).c_str());
2018  }
2019 };
2020 
2021 
2022 
2039 template<typename BaseLoggerType>
2041  BaseLoggerType & baselogger)
2042 {
2043  return LocalLogger<BaseLoggerType>(std::move(origin_fn_name), baselogger);
2044 }
2045 
2052 template<typename BaseLoggerType>
2054  BaseLoggerType & baselogger)
2055 {
2056  return LocalLogger<BaseLoggerType>(std::move(origin_prefix), std::move(glue), baselogger);
2057 }
2058 
2065 template<typename BaseLoggerType>
2067  BaseLoggerType & baselogger)
2068 {
2069  return LocalLogger<BaseLoggerType>(spec, baselogger);
2070 }
2071 
2072 
2073 
2074 
2075 
2076 } // namespace Logger
2077 } // namespace Tomographer
2078 
2079 
2080 
2081 #endif
Utilities for formatting strings.
LogLevel(std::string s)
Construct a level using a string level name.
Definition: loggers.h:167
void error(Args &&...)
Special-case implementation for messages which are known to be discarded at compile time...
Definition: loggers.h:593
void warning(Args &&... a)
Generate a log message with level Logger::WARNING.
Definition: loggers.h:1934
void emitLog(int level, const char *origin, std::string msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:1357
LocalLogger(std::string origin_fn_name, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1735
std::string originPrefix() const
The fixed origin specified at the constructor.
Definition: loggers.h:1793
void info(const char *origin, const char *fmt,...)
emit an information/notice message
Definition: loggers.h:652
Simple logger class which logs everything into a given FILE pointer.
Definition: loggers.h:1062
static bool staticallyEnabledFor(int level)
Check whether the logger is statically disabled for some levels.
Definition: loggers.h:490
Local logger: avoid having to repeat origin at each emitted message.
Definition: loggers.h:1613
Lowest severity possible.
Definition: loggers.h:139
void emitLog(int level, const char *origin, std::string msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:2000
Log messages into an internal memory buffer.
Definition: loggers.h:1187
Base namespace for the Tomographer project.
Definition: densellh.h:45
constexpr LocalLoggerOriginSpec(const Tools::conststr &s, const Tools::conststr &s2, const Tools::conststr &gl)
complete constructor.
Definition: loggers.h:1560
void longdebug(const char *origin, const char *fmt,...)
emit a very verbose debugging message
Definition: loggers.h:789
void clear()
Clears the internal memory buffer.
Definition: loggers.h:1216
void setDomainLevel(const std::string &origin_pattern, int level)
Set a rule to log messages based on their origin.
Definition: loggers.h:1464
std::string vfmts(const char *fmt, va_list vl)
printf- formatting to a std::string, with va_list pointer
Definition: fmt.h:87
void warning(Args &&...)
Special-case implementation for messages which are known to be discarded at compile time...
Definition: loggers.h:641
void setLevel(std::string s)
Set the level to the given level name. See class doc.
Definition: loggers.h:202
void log(Args &&...)
Special-case implementation for messages which are known to be discarded at compile time...
Definition: loggers.h:941
void debug(const char *origin, Fn &&f)
emit an debug message
Definition: loggers.h:771
static constexpr bool staticallyEnabledFor()
Static version of staticallyEnabledFor()
Definition: loggers.h:499
void log(const char *origin, const char *fmt, va_list ap)
emit a log message at the given log level.
Definition: loggers.h:904
T to_string(T... args)
void log(int level, const char *origin, const char *fmt,...)
emit a log message at the given log level.
Definition: loggers.h:838
Highest severity possible.
Definition: loggers.h:131
Error logging level.
Definition: loggers.h:83
void setPrefix(std::string prefix_)
Change the prefix to a new value. Obviously not thread-safe.
Definition: loggers.h:1350
const Tools::conststr glue
the glue to use in the local logger
Definition: loggers.h:1554
Logger that discards all messages.
Definition: loggers.h:1149
void error(const char *origin, Fn &&f)
emit an error message
Definition: loggers.h:586
void info(Args &&...)
Special-case implementation for messages which are known to be discarded at compile time...
Definition: loggers.h:688
STL namespace.
Logger which prepends to each origin string a fixed prefix.
Definition: loggers.h:1303
void emitLog(int level, const char *origin, std::string msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:1280
Object which stores a log level and can initialize from a string.
Definition: loggers.h:158
T end(T... args)
Base logger class.
Definition: loggers.h:444
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:2008
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:1364
int level() const
Get the stored level code. See LogLevelCode.
Definition: loggers.h:170
void debug(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1963
bool filterByOrigin(int level, const char *origin) const
Message filtering by origin implementation.
Definition: loggers.h:1513
OriginFilteredLogger(BaseLogger &baselogger_)
Constructor based on a base logger reference.
Definition: loggers.h:1448
ParentLoggerType & parentLogger()
The parent logger responsible for actually emitting the messages in some useful way.
Definition: loggers.h:1821
STL class.
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(std::string new_prefix)
Create a sub-logger.
Definition: loggers.h:1846
void setLevel(int level)
Set the level to the given level code. See class doc and LogLevelCode.
Definition: loggers.h:189
void removeDomainSetting(const std::string &s)
Remove a rule set by setDomainLevel()
Definition: loggers.h:1474
void log(int level, const char *origin, std::string msg)
emit a log message at the given log level.
Definition: loggers.h:855
void setLogLevel(int level)
Store a new run-time log level.
Definition: loggers.h:988
void log(const char *origin, Fn f)
emit a log message at the given log level.
Definition: loggers.h:934
T fflush(T... args)
STL class.
std::string getSubOrigin(const char *origin) const
The full origin string to use for a sub-logger.
Definition: loggers.h:1992
std::string levelName() const
Get the stored level name.
Definition: loggers.h:176
void longdebug(const char *origin, Fn &&f)
emit a very verbose debugging message
Definition: loggers.h:818
Helper for statically determining if Level is at least as severe as BaseLevel.
Definition: loggers.h:261
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(std::string new_prefix, std::string new_glue)
Create a sub-logger.
Definition: loggers.h:1856
BaseLoggerType & baseLogger()
The base logger type specified to the constructor.
Definition: loggers.h:1804
OriginPrefixedLogger(BaseLogger &baselogger_, std::string prefix_)
Constructor from a base logger.
Definition: loggers.h:1342
std::string glue() const
The "glue" string to use to concatenate origins from sub-loggers.
Definition: loggers.h:1797
void info(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1967
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:1286
bool enabledFor(int level_) const
Check whether messages at the given log level are enabled.
Definition: loggers.h:517
void warning(const char *origin, Fn &&f)
emit a warning message
Definition: loggers.h:634
void info(const char *origin, Fn &&f)
emit an information/notice message
Definition: loggers.h:681
void log(int level, const char *origin, Fn &&f)
emit a log message at the given log level.
Definition: loggers.h:870
LocalLogger(std::string origin_prefix, std::string glue, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1746
Logger which statically discards any messages less important than a fixed severity.
Definition: loggers.h:1235
constexpr LocalLoggerOriginSpec(const Tools::conststr &s, const Tools::conststr &gl)
constructor. origin_prefix_add is left blank.
Definition: loggers.h:1557
BaseLoggerType_ BaseLoggerType
The base logger type (see class documentation)
Definition: loggers.h:1712
MinimumSeverityLogger(BaseLogger &baselogger_)
Constructor from a base logger.
Definition: loggers.h:1274
void emitLog(int level, const char *origin, std::string msg)
Emit a log message (relay to base logger).
Definition: loggers.h:1501
void log(const char *origin, const char *fmt,...)
emit a log message at the given log level.
Definition: loggers.h:886
T erase(T... args)
void setDisplayOrigin(bool display_origin_)
Definition: loggers.h:1089
Tool to specify arguments to LocalLogger.
Definition: loggers.h:1548
LocalLogger< BaseLoggerType > makeLocalLogger(std::string origin_fn_name, BaseLoggerType &baselogger)
Create a local logger.
Definition: loggers.h:2040
const Tools::conststr origin_prefix
Origin prefix for the local logger.
Definition: loggers.h:1550
T str(T... args)
void log(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1979
std::ostream & operator<<(std::ostream &str, const LogLevel &l)
C++ output stream operator for LogLevel.
Definition: loggers.h:231
A constexpr string type, suitable for basic compile-time string processing.
LocalLogger(const LocalLogger &other)
Make the local-logger copyable – there&#39;s nothing wrong with that.
Definition: loggers.h:1773
Default traits for Logger implementations.
Definition: loggers.h:288
T move(T... args)
void error(const char *origin, const char *fmt,...)
emit an error message
Definition: loggers.h:556
void longdebug(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1959
T find(T... args)
void debug(Args &&... a)
Generate a log message with level Logger::DEBUG.
Definition: loggers.h:1920
void log(const char *origin, std::string msg)
emit a log message at the given log level.
Definition: loggers.h:918
void setLevel(int level)
Changes the runtime log level to a new value.
Definition: loggers.h:1206
bool isAtLeastOfSeverity(int level, int baselevel)
Helper to compare severity levels.
Definition: loggers.h:248
void warning(const char *origin, const char *fmt,...)
emit a warning message
Definition: loggers.h:604
T begin(T... args)
Traits template struct to be specialized for specific Logger implementations.
Definition: loggers.h:351
VarValueDecoder< T >::RetType value(const Var &var)
Access the value of the given variable, as a C++ type.
Definition: ezmatio.h:878
T c_str(T... args)
void log(Args &&... args)
Generate a log message with level Level.
Definition: loggers.h:1950
Warning logging level.
Definition: loggers.h:92
_PARENT_LOGGER_TYPE ParentLoggerType
Type of the parent logger type, ultimately responsible for actually emitting the messages in some use...
Definition: loggers.h:1812
LocalLogger(const LocalLoggerOriginSpec &spec, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1756
std::istream & operator>>(std::istream &str, LogLevel &l)
C++ input stream operator for LogLevel.
Definition: loggers.h:223
LoggerBase(int level_=INFO)
Construct the base logger object.
Definition: loggers.h:472
LogLevelCode
Possible logging levels.
Definition: loggers.h:76
const Tools::conststr origin_prefix_add
optionally some string to append to origin_prefix
Definition: loggers.h:1552
Long Debug logging level.
Definition: loggers.h:122
std::string getContents() const
get the contents of the internal buffer
Definition: loggers.h:1226
constexpr conststr extractFuncName(const conststr &funcname)
Extract the function name from its signature.
Definition: cxxutil.h:664
LogLevel(const char *s)
Construct a level using a string level name.
Definition: loggers.h:165
int level() const
Unconditionally return LOWEST_SEVERITY_LEVEL for the underlying logging engine.
Definition: loggers.h:1492
LogLevel(int level_=INFO)
Construct a level using an integer level code. See LogLevelCode.
Definition: loggers.h:163
void debug(const char *origin, const char *fmt,...)
emit an debug message
Definition: loggers.h:710
int level() const
Get the log level set for this logger.
Definition: loggers.h:539
Basic definitions, which may have to be defined before any Eigen headers or further utilities are inc...
void error(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1975
A constexpr string type.
Definition: conststr.h:55
void warning(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1971
T fprintf(T... args)
STL class.
LocalLogger(LocalLogger &&movecopy)
Definition: loggers.h:1766
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const LocalLoggerOriginSpec &spec)
Create a sub-logger.
Definition: loggers.h:1866
Debug logging level.
Definition: loggers.h:112
Information logging level.
Definition: loggers.h:100
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:84
void error(Args &&... a)
Generate a log message with level Logger::ERROR.
Definition: loggers.h:1941
void info(Args &&... a)
Generate a log message with level Logger::INFO.
Definition: loggers.h:1927
void longdebug(Args &&... a)
Generate a log message with level Logger::LONGDEBUG.
Definition: loggers.h:1913
void longdebug(Args &&...)
Special-case implementation for messages which are known to be discarded at compile time...
Definition: loggers.h:825
void debug(Args &&...)
Special-case implementation for messages which are known to be discarded at compile time...
Definition: loggers.h:778
A logger which filters entries according to where they originated from.
Definition: loggers.h:1398