Tomographer  v5.2
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 namespace tomo_internal {
1301 
1307 inline std::size_t matched_length(const std::string & s, const std::string & pattern)
1308 {
1309  std::size_t k = 0;
1310  while (s[k] == pattern[k]) {
1311  ++k;
1312  }
1313  return k;
1314 }
1315 
1316 } // namespace tomo_internal
1317 
1318 template<typename BaseLogger> class OriginFilteredLogger;
1322 template<typename BaseLogger>
1323 struct LoggerTraits<OriginFilteredLogger<BaseLogger> > : public LoggerTraits<BaseLogger>
1324 {
1326  enum {
1327  HasOwnGetLevel = 1,
1328  HasFilterByOrigin = 1
1329  };
1330 };
1331 
1352 template<typename BaseLogger>
1353 class TOMOGRAPHER_EXPORT OriginFilteredLogger
1354  : public Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >
1355 {
1357  BaseLogger & baselogger;
1358 
1360  std::map<std::string,int> levels_set;
1361 public:
1362 
1368  OriginFilteredLogger(BaseLogger & baselogger_)
1369  : Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >(),
1370  baselogger(baselogger_),
1371  levels_set()
1372  {
1373  }
1374 
1384  inline void setDomainLevel(const std::string& origin_pattern, int level)
1385  {
1386  levels_set[origin_pattern] = level;
1387  }
1388 
1394  inline void removeDomainSetting(const std::string& s)
1395  {
1396  auto it = levels_set.find(s);
1397  if (it == levels_set.end()) {
1398  this->warning("OriginFilteredLogger<BaseLogger>::removeDomainSetting", "domain not set: `%s'", s.c_str());
1399  return;
1400  }
1401  levels_set.erase(it);
1402  }
1403 
1412  inline int level() const
1413  {
1414  return LOWEST_SEVERITY_LEVEL;
1415  }
1416 
1421  inline void emitLog(int level, const char * origin, std::string msg)
1422  {
1423  baselogger.emitLog(level, origin, std::move(msg));
1424  }
1425 
1433  inline bool filterByOrigin(int level, const char * origin) const
1434  {
1435  typedef std::map<std::string, int>::const_iterator ConstIterator;
1436 
1437  std::string s(origin);
1438 
1439  int loglevel = -1;
1440  std::size_t last_matched_length = 0;
1441  for (ConstIterator it = levels_set.begin(); it != levels_set.end(); ++it) {
1442  const std::size_t mlen = tomo_internal::matched_length((*it).first, s);
1443  if (mlen > last_matched_length) {
1444  loglevel = (*it).second;
1445  last_matched_length = mlen;
1446  }
1447  }
1448  if (loglevel == -1) {
1449  // default logger level
1450  loglevel = baselogger.level();
1451  }
1452  return isAtLeastOfSeverity(level, loglevel);
1453  }
1454 
1455 };
1456 
1457 
1458 
1459 
1460 
1461 // --------------------------------------------------
1462 
1463 
1464 
1465 
1466 
1475 
1478  : origin_prefix(s), origin_prefix_add(""), glue(gl) { }
1480  constexpr LocalLoggerOriginSpec(const Tools::conststr& s, const Tools::conststr& s2, const Tools::conststr& gl)
1481  : origin_prefix(s), origin_prefix_add(s2), glue(gl) { }
1482 };
1483 
1484 namespace tomo_internal {
1486 struct extractTomoOrigin_helper {
1487  static inline constexpr LocalLoggerOriginSpec step2(const Tools::conststr fn, std::size_t last_doublecolons,
1488  std::size_t after_prelast_doublecolons)
1489  {
1490  return ( fn.substr_e(after_prelast_doublecolons, last_doublecolons) == fn.substr(last_doublecolons+2)
1491  // fn is a constructor, so keep class name and use "::" as glue
1492  ? LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "::")
1493  // looks like a method name. Strip off the class name. Also use an internal
1494  // glue to indicate a logical level.
1495  : LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "()", "/")
1496  );
1497  }
1498  static inline constexpr std::size_t afterprelast_doublecolons(std::size_t prelast_doublecolons_found)
1499  {
1500  return (prelast_doublecolons_found == std::string::npos) ? 0 : prelast_doublecolons_found+2;
1501  }
1502  static inline constexpr LocalLoggerOriginSpec step1(const Tools::conststr fn, std::size_t last_doublecolons)
1503  {
1504  return last_doublecolons == std::string::npos || last_doublecolons == 0
1505  ? LocalLoggerOriginSpec(fn, "()", "/") // looks like simple function name with no parent scope
1506  : step2(fn, last_doublecolons, afterprelast_doublecolons(fn.rfind("::", last_doublecolons-1)));
1507  }
1508 
1509  static inline constexpr LocalLoggerOriginSpec extract_from_func_name(const Tools::conststr fn)
1510  {
1511  return step1(fn, fn.rfind("::"));
1512  }
1513 };
1514 
1516 constexpr const LocalLoggerOriginSpec extractTomoOrigin(const Tools::conststr fn)
1517 {
1518  return extractTomoOrigin_helper::extract_from_func_name(Tomographer::Tools::extractFuncName(fn));
1519 }
1520 
1521 } // namespace tomo_internal
1522 
1523 
1528 #define TOMO_ORIGIN Tomographer::Logger::tomo_internal::extractTomoOrigin(TOMO_FUNCTION)
1529 
1530 
1531 
1532 
1533 template<typename BaseLoggerType_> class LocalLogger;
1534 
1535 
1536 namespace tomo_internal {
1538 template<typename BaseLoggerType>
1539 struct is_local_logger {
1540  enum { value = 0 };
1541 };
1542 template<typename BaseLoggerType>
1543 struct is_local_logger<LocalLogger<BaseLoggerType> > {
1544  enum { value = 1 };
1545 };
1547 template<typename BaseLoggerType>
1548 struct local_logger_parent {
1549  typedef BaseLoggerType ParentType;
1550 };
1551 template<typename BaseLoggerType>
1552 struct local_logger_parent<LocalLogger<BaseLoggerType> > {
1553  typedef typename local_logger_parent<BaseLoggerType>::ParentType ParentType;
1554 };
1555 } // namespace tomo_internal
1556 
1558 template<typename BaseLoggerType_>
1559 struct LoggerTraits<LocalLogger<BaseLoggerType_> > : public LoggerTraits<BaseLoggerType_>
1560 {
1561  enum {
1563  HasOwnGetLevel = 1
1564  };
1565 };
1566 
1567 
1626 template<typename BaseLoggerType_>
1627 class TOMOGRAPHER_EXPORT LocalLogger
1628  : public LoggerBase<LocalLogger<BaseLoggerType_> >
1629 {
1630 public:
1632  typedef BaseLoggerType_ BaseLoggerType;
1633 
1634 private:
1636 
1638  const std::string _origin_prefix;
1640  const std::string _glue;
1641 
1642  BaseLoggerType & _baselogger;
1643 
1644 public:
1655  LocalLogger(std::string origin_fn_name, BaseLoggerType & logger_)
1656  : Base_(), _origin_prefix(std::move(origin_fn_name)), _glue("::"), _baselogger(logger_)
1657  {
1658  this->longdebug("[begin]");
1659  }
1666  LocalLogger(std::string origin_prefix, std::string glue, BaseLoggerType & logger_)
1667  : Base_(), _origin_prefix(std::move(origin_prefix)), _glue(std::move(glue)), _baselogger(logger_)
1668  {
1669  this->longdebug("[begin]");
1670  }
1676  LocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & logger_)
1677  : Base_(), _origin_prefix(spec.origin_prefix.to_string()+spec.origin_prefix_add.to_string()),
1678  _glue(spec.glue.to_string()), _baselogger(logger_)
1679  {
1680  this->longdebug("[begin]");
1681  }
1682 
1687  : Base_(), _origin_prefix(std::move(movecopy._origin_prefix)), _glue(std::move(movecopy._glue)),
1688  _baselogger(movecopy._baselogger)
1689  {
1690  this->longdebug("[logger moved]");
1691  }
1693  LocalLogger(const LocalLogger & other)
1694  : Base_(), _origin_prefix(other._origin_prefix), _glue(other._glue),
1695  _baselogger(other._baselogger)
1696  {
1697  this->longdebug("[logger copied]");
1698  }
1699 
1700  ~LocalLogger()
1701  {
1702  this->longdebug("[done]");
1703  }
1704 
1713  inline std::string originPrefix() const { return _origin_prefix; }
1714 
1717  inline std::string glue() const { return _glue; }
1718 
1724  inline BaseLoggerType & baseLogger() { return _baselogger; }
1725 
1726 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
1727 
1732  typedef _PARENT_LOGGER_TYPE ParentLoggerType;
1733 
1741  ParentLoggerType & parentLogger() { }
1742 #else
1743 
1744  typedef typename tomo_internal::local_logger_parent<BaseLoggerType>::ParentType ParentLoggerType;
1745 
1747  inline ParentLoggerType & parentLogger()
1748  {
1749  return baseLogger();
1750  }
1752  inline ParentLoggerType & parentLogger() {
1753  return baseLogger().parentLogger();
1754  }
1755 #endif
1756 
1767  {
1768  return LocalLogger<LocalLogger<BaseLoggerType> >(std::move(new_prefix), *this);
1769  }
1777  std::string new_glue)
1778  {
1779  return LocalLogger<LocalLogger<BaseLoggerType> >(std::move(new_prefix), std::move(new_glue), *this);
1780  }
1787  {
1788  return LocalLogger<LocalLogger<BaseLoggerType> >(spec, *this);
1789  }
1790 
1795  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<LONGDEBUG>())
1796  PRINTF2_ARGS_SAFE inline void longdebug(const char * fmt, ...)
1797  { va_list ap; va_start(ap, fmt); log<LONGDEBUG>(fmt, ap); va_end(ap); }
1802  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<DEBUG>())
1803  PRINTF2_ARGS_SAFE inline void debug(const char * fmt, ...)
1804  { va_list ap; va_start(ap, fmt); log<DEBUG>(fmt, ap); va_end(ap); }
1809  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<INFO>())
1810  PRINTF2_ARGS_SAFE inline void info(const char * fmt, ...)
1811  { va_list ap; va_start(ap, fmt); log<INFO>(fmt, ap); va_end(ap); }
1816  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<WARNING>())
1817  PRINTF2_ARGS_SAFE inline void warning(const char * fmt, ...)
1818  { va_list ap; va_start(ap, fmt); log<WARNING>(fmt, ap); va_end(ap); }
1823  TOMOGRAPHER_ENABLED_IF(Base_::template staticallyEnabledFor<ERROR>())
1824  PRINTF2_ARGS_SAFE inline void error(const char * fmt, ...)
1825  { va_list ap; va_start(ap, fmt); log<ERROR>(fmt, ap); va_end(ap); }
1826 
1831  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<LONGDEBUG>()),
1832  typename... Args>
1833  inline void longdebug(Args &&... a) { log<Tomographer::Logger::LONGDEBUG>(std::forward<Args>(a)...); }
1838  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<DEBUG>()),
1839  typename... Args>
1840  inline void debug(Args &&... a) { log<Tomographer::Logger::DEBUG>(std::forward<Args>(a)...); }
1845  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<INFO>()),
1846  typename... Args>
1847  inline void info(Args &&... a) { log<Tomographer::Logger::INFO>(std::forward<Args>(a)...); }
1852  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<WARNING>()),
1853  typename... Args>
1854  inline void warning(Args &&... a) { log<Tomographer::Logger::WARNING>(std::forward<Args>(a)...); }
1859  template<TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<ERROR>()),
1860  typename... Args>
1861  inline void error(Args &&... a) { log<Tomographer::Logger::ERROR>(std::forward<Args>(a)...); }
1862 
1867  template<int Level,
1868  TOMOGRAPHER_ENABLED_IF_TMPL(Base_::template staticallyEnabledFor<Level>()),
1869  typename... Args>
1870  inline void log(Args && ... args)
1871  {
1872  Base_::template log<Level>("", std::forward<Args>(args)...);
1873  }
1874 
1875 
1877  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<LONGDEBUG>()),
1878  typename... Args>
1879  inline void longdebug(Args &&... ) { }
1881  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<DEBUG>()),
1882  typename... Args>
1883  inline void debug(Args &&... ) { }
1885  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<INFO>()),
1886  typename... Args>
1887  inline void info(Args &&... ) { }
1889  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<WARNING>()),
1890  typename... Args>
1891  inline void warning(Args &&... ) { }
1893  template<TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<ERROR>()),
1894  typename... Args>
1895  inline void error(Args &&... ) { }
1897  template<int Level, TOMOGRAPHER_ENABLED_IF_TMPL(!Base_::template staticallyEnabledFor<Level>()),
1898  typename... Args>
1899  inline void log(Args &&... ) { }
1900 
1901 
1902  // relay calls to base logger
1903 
1912  inline std::string getSubOrigin(const char * origin) const
1913  {
1914  return ( origin == NULL || origin[0] == 0
1915  ? _origin_prefix
1916  : _origin_prefix + _glue + origin );
1917  }
1918 
1920  inline void emitLog(int level, const char * origin, std::string msg)
1921  {
1922  // this might also be called if we have a sublogger. In that case, if we have a
1923  // sublogger, then use their prefix.
1924  _baselogger.emitLog(level, getSubOrigin(origin).c_str(), std::move(msg));
1925  }
1926 
1928  inline int level() const
1929  {
1930  return _baselogger.level();
1931  }
1932 
1935  inline bool filterByOrigin(int level, const char * origin)
1936  {
1937  return _baselogger.filterByOrigin(level, getSubOrigin(origin).c_str());
1938  }
1939 };
1940 
1941 
1942 
1959 template<typename BaseLoggerType>
1961  BaseLoggerType & baselogger)
1962 {
1963  return LocalLogger<BaseLoggerType>(std::move(origin_fn_name), baselogger);
1964 }
1965 
1972 template<typename BaseLoggerType>
1974  BaseLoggerType & baselogger)
1975 {
1976  return LocalLogger<BaseLoggerType>(std::move(origin_prefix), std::move(glue), baselogger);
1977 }
1978 
1985 template<typename BaseLoggerType>
1987  BaseLoggerType & baselogger)
1988 {
1989  return LocalLogger<BaseLoggerType>(spec, baselogger);
1990 }
1991 
1992 
1993 
1994 
1995 
1996 } // namespace Logger
1997 } // namespace Tomographer
1998 
1999 
2000 
2001 #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:1854
LocalLogger(std::string origin_fn_name, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1655
std::string originPrefix() const
The fixed origin specified at the constructor.
Definition: loggers.h:1713
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:1533
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:1920
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:1480
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:1384
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
const Tools::conststr glue
the glue to use in the local logger
Definition: loggers.h:1474
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.
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:1928
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:1883
bool filterByOrigin(int level, const char *origin) const
Message filtering by origin implementation.
Definition: loggers.h:1433
OriginFilteredLogger(BaseLogger &baselogger_)
Constructor based on a base logger reference.
Definition: loggers.h:1368
ParentLoggerType & parentLogger()
The parent logger responsible for actually emitting the messages in some useful way.
Definition: loggers.h:1741
STL class.
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(std::string new_prefix)
Create a sub-logger.
Definition: loggers.h:1766
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:1394
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:1912
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:1776
BaseLoggerType & baseLogger()
The base logger type specified to the constructor.
Definition: loggers.h:1724
std::string glue() const
The "glue" string to use to concatenate origins from sub-loggers.
Definition: loggers.h:1717
void info(Args &&...)
Statically optimized call if we know at compile time that the message will be discarded.
Definition: loggers.h:1887
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:1666
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:1477
BaseLoggerType_ BaseLoggerType
The base logger type (see class documentation)
Definition: loggers.h:1632
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:1421
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:1468
LocalLogger< BaseLoggerType > makeLocalLogger(std::string origin_fn_name, BaseLoggerType &baselogger)
Create a local logger.
Definition: loggers.h:1960
const Tools::conststr origin_prefix
Origin prefix for the local logger.
Definition: loggers.h:1470
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:1899
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:1693
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:1879
T find(T... args)
void debug(Args &&... a)
Generate a log message with level Logger::DEBUG.
Definition: loggers.h:1840
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:1870
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:1732
LocalLogger(const LocalLoggerOriginSpec &spec, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1676
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:1472
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:1412
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:1895
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:1891
T fprintf(T... args)
STL class.
LocalLogger(LocalLogger &&movecopy)
Definition: loggers.h:1686
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const LocalLoggerOriginSpec &spec)
Create a sub-logger.
Definition: loggers.h:1786
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:1861
void info(Args &&... a)
Generate a log message with level Logger::INFO.
Definition: loggers.h:1847
void longdebug(Args &&... a)
Generate a log message with level Logger::LONGDEBUG.
Definition: loggers.h:1833
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:1318