Tomographer  v5.0
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::enable_if
39 #include <map>
40 
41 #include <boost/algorithm/string.hpp> // to_upper()
42 
43 #include <tomographer/tools/fmt.h>
45 
46 
55 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
56 
57 #define ENABLE_IF_Fn_CALLABLE_OSTREAM \
58  typename std::enable_if<std::is_convertible<Fn,std::function<void(std::ostream&)> >::value, void>::type
59 
60 #endif
61 
62 
63 #ifdef ERROR
64 #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."
65 #endif
66 
67 
68 namespace Tomographer
69 {
70 
74 namespace Logger
75 {
76 
83 {
89  ERROR = 0,
90 
99 
107 
119 
129 
130 
138 
146 };
147 
148 
149 
164 class TOMOGRAPHER_EXPORT LogLevel
165 {
166  int _level;
167 public:
169  LogLevel(int level_ = INFO) { setLevel(level_); }
171  LogLevel(const char * s) { setLevel(s); }
173  LogLevel(const std::string& s) { setLevel(s); }
174 
176  inline int level() const { return _level; }
177 
179  inline operator int() const { return _level; }
180 
182  inline std::string levelName() const
183  {
184  switch (_level) {
185  case LONGDEBUG: return std::string("LONGDEBUG");
186  case DEBUG: return std::string("DEBUG");
187  case INFO: return std::string("INFO");
188  case WARNING: return std::string("WARNING");
189  case ERROR: return std::string("ERROR");
190  default: return std::string("<INVALID LEVEL>");
191  };
192  }
193 
195  inline void setLevel(int level)
196  {
197  if (level != LONGDEBUG &&
198  level != DEBUG &&
199  level != INFO &&
200  level != WARNING &&
201  level != ERROR) {
202  throw std::invalid_argument("Invalid level code: "+std::to_string(level));
203  }
204  _level = level;
205  }
206 
208  inline void setLevel(std::string s)
209  {
210  // NOT const string `s`! we need our copy for to_upper():
211  boost::to_upper(s);
212  if (s == "LONGDEBUG") {
213  _level = LONGDEBUG;
214  } else if (s == "DEBUG") {
215  _level = DEBUG;
216  } else if (s == "INFO") {
217  _level = INFO;
218  } else if (s == "WARNING") {
219  _level = WARNING;
220  } else if (s == "ERROR") {
221  _level = ERROR;
222  } else {
223  throw std::invalid_argument("Invalid log level: '"+s+"'");
224  }
225  }
226 };
227 
230 {
231  std::string s;
232  str >> s;
233  l.setLevel(s);
234  return str;
235 }
237 inline std::ostream & operator<<(std::ostream & str, const LogLevel &l)
238 {
239  return str << l.levelName();
240 }
241 
242 
243 
254 inline bool isAtLeastOfSeverity(int level, int baselevel)
255 {
256  return (level <= baselevel);
257 }
258 
266 template<int Level, int BaseLevel>
267 struct TOMOGRAPHER_EXPORT StaticIsAtLeastOfSeverity {
268  enum {
269  value = (Level <= BaseLevel)
270  };
271 };
272 
273 
294 struct TOMOGRAPHER_EXPORT DefaultLoggerTraits
295 {
296  enum {
302  IsThreadSafe = 0,
303 
316  StaticMinimumSeverityLevel = LOWEST_SEVERITY_LEVEL,
317 
329  HasOwnGetLevel = 0,
330 
343  HasFilterByOrigin = 0
344  };
345 };
346 
356 template<typename LoggerType>
357 struct TOMOGRAPHER_EXPORT LoggerTraits
358 {
359  // by default, contains nothing and will produce errors if used unspecialized.
360 };
361 
362 
363 
364 namespace tomo_internal {
368 template<bool hasOwnGetLevel>
369 class
370 TOMOGRAPHER_EXPORT // export might be needed because this is used as base class of LoggerBase
371 LoggerRuntimeLevel
372 {
373 public:
374  LoggerRuntimeLevel(int level)
375  : _level(level)
376  {
377  }
378 
379  inline int level() const
380  {
381  return _level;
382  }
383 
384 protected:
385  inline void setLogLevel(int level)
386  {
387  _level = level;
388  }
389 
390 private:
391  int _level;
392 };
393 //
394 // Specialization for those classes which provide their own level() method. Do nothing.
395 //
396 template<>
397 class TOMOGRAPHER_EXPORT LoggerRuntimeLevel<true>
398 {
399 public:
400  LoggerRuntimeLevel(int /*level*/)
401  {
402  }
403 
404  inline void setLogLevel(int) {
405  tomographer_assert(0 && "Call to LoggerRuntimeLevel::setLogLevel() for Logger which defines HasOwnGetLevel=1!");
406  }
407 };
408 }
409 
410 
436 template<typename Derived>
437 class TOMOGRAPHER_EXPORT LoggerBase
438 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
439  : public tomo_internal::LoggerRuntimeLevel<LoggerTraits<Derived>::HasOwnGetLevel>
440 #endif
441 {
442 public:
445  enum {
454  };
455 
465  LoggerBase(int level_ = INFO)
466  : tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>(level_)
467  {
468  }
469 
477  PRINTF3_ARGS_SAFE
478  inline void error(const char * origin, const char * fmt, ...);
486  inline void error(const char * origin, const std::string & msg);
493  template<typename Fn>
494  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
495  error(const char * origin, Fn f);
496 
504  PRINTF3_ARGS_SAFE
505  inline void warning(const char * origin, const char * fmt, ...);
513  inline void warning(const char * origin, const std::string & msg);
520  template<typename Fn>
521  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
522  warning(const char * origin, Fn f);
523 
531  PRINTF3_ARGS_SAFE
532  inline void info(const char * origin, const char * fmt, ...);
540  inline void info(const char * origin, const std::string & msg);
547  template<typename Fn>
548  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
549  info(const char * origin, Fn f);
550 
568  PRINTF3_ARGS_SAFE
569  inline void debug(const char * origin, const char * fmt, ...);
570 
587  inline void debug(const char * origin, const std::string & msg);
616  template<typename Fn>
617  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
618  debug(const char * origin, Fn f);
619 
627  PRINTF3_ARGS_SAFE
628  inline void longdebug(const char * origin, const char * fmt, ...);
636  inline void longdebug(const char * origin, const std::string & msg);
643  template<typename Fn>
644  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
645  longdebug(const char * origin, Fn f);
646 
647 
657  PRINTF4_ARGS_SAFE
658  inline void log(int level, const char * origin, const char * fmt, ...);
668  inline void log(int level, const char * origin, const std::string & msg);
678  template<typename Fn>
679  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
680  log(int level, const char * origin, Fn f);
681 
682 
683 
692  template<int Level>
693  PRINTF3_ARGS_SAFE
694  inline void log(const char * origin, const char * fmt, ...);
704  template<int Level>
705  inline void log(const char * origin, const char * fmt, va_list ap);
714  template<int Level>
715  inline void log(const char * origin, const std::string & msg);
724  template<int Level, typename Fn>
725  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
726  log(const char * origin, Fn f);
727 
728 
741  static inline bool staticallyEnabledFor(int level)
742  {
743  return ( isAtLeastOfSeverity(level, StaticMinimumSeverityLevel) );
744  }
745 
749  template<int Level>
750  static inline bool staticallyEnabledFor()
751  {
752  return ( StaticIsAtLeastOfSeverity<
753  Level,
754  StaticMinimumSeverityLevel
755  >::value ) ;
756  }
757 
768  inline bool enabledFor(int level_) const
769  {
770  return derived()->staticallyEnabledFor(level_) &&
771  isAtLeastOfSeverity(level_, getLevel());
772  };
773 
774 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
775  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
776  // exposed in the case where the logger doesn't define its own method. This is important
777  // to avoid "ambiguous calls to `level()`".
778 
790  inline int level() const
791  {
792  }
793 #endif
794 
795 
796 protected:
797 
798  // version in case we store our own level
799  TOMOGRAPHER_ENABLED_IF(!HasOwnGetLevel)
800  inline int getLevel() const
801  {
802  // use base class' implementation
803  return tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>::level();
804  }
805  // version in case we delegate to derived class' level()
806  TOMOGRAPHER_ENABLED_IF(HasOwnGetLevel)
807  inline int getLevel() const
808  {
809  return derived()->level();
810  }
811 
812 
813  inline Derived * derived()
814  {
815  return static_cast<Derived*>(this);
816  }
817  inline const Derived * derived() const
818  {
819  return static_cast<const Derived*>(this);
820  }
821 
822 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
823  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
824  // exposed in the case where the logger can actually set a new level.
825 
839  inline void setLogLevel(int level)
840  {
841  }
842 #endif
843 
844 private:
845 };
846 
847 
848 namespace tomo_internal {
851  template<typename Derived, bool derivedHasFilterByOrigin>
852  struct LoggerBaseHelperFilterByOrigin {
853  static inline bool test_logger_filter(LoggerBase<Derived> * /*loggerbase*/, int /*level*/,
854  const char * /*origin*/)
855  {
856  // do nothing by default
857  return true;
858  }
859  };
860  //
861  // specialization for loggers with filtering by origin
862  //
863  template<typename Derived>
864  struct LoggerBaseHelperFilterByOrigin<Derived, true> {
865  static inline bool test_logger_filter(LoggerBase<Derived> * loggerbase, int level,
866  const char * origin)
867  {
868  return static_cast<const Derived*>(loggerbase)->filterByOrigin(level, origin);
869  }
870  };
876  template<typename Derived>
877  struct LoggerBaseHelperDynamic {
878  static inline void call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
879  const std::string & msg)
880  {
881  // try {
882  //printf("Calling emit_log(%d,\"%s\",\"%s\") on object %p\n", level, origin, msg.c_str(), loggerbase);
883  static_cast<Derived*>(loggerbase)->emitLog(level, origin, msg);
884  // } catch (const std::exception & e) {
885  // std::fprintf(stderr,
886  // "Warning in LoggerBaseHelperDynamic::call_emit_log(%d, \"%s\", \"%s\"):"
887  // " Exception caught: %s\n",
888  // level, origin, msg.c_str(), e.what());
889  // }
890  }
891  static inline bool test_should_emit(LoggerBase<Derived> * loggerbase, int level, const char * origin)
892  {
893  if ( ! static_cast<const Derived*>(loggerbase)->enabledFor(level) ) {
894  return false;
895  }
896  if ( ! LoggerBaseHelperFilterByOrigin<Derived, LoggerTraits<Derived>::HasFilterByOrigin>
897  ::test_logger_filter(loggerbase, level, origin) ) {
898  return false;
899  }
900  return true;
901  }
902 
903  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
904  const std::string & msg)
905  {
906  if ( ! test_should_emit(loggerbase, level, origin) ) {
907  return;
908  }
909 
910  call_emit_log(loggerbase, level, origin, msg);
911  }
912  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
913  const char * fmt, va_list ap)
914  {
915  if ( ! test_should_emit(loggerbase, level, origin) ) {
916  return;
917  }
918 
919  // try {
920  const std::string msg = Tools::vfmts(fmt, ap);
921  call_emit_log(loggerbase, level, origin, msg);
922  // } catch (const std::exception & e) {
923  // std::fprintf(stderr,
924  // "Warning in LoggerBase::test_and_call_emit_log(%d, \"%s\", \"%s\", ...):"
925  // " Exception caught: %s\n",
926  // level, origin, fmt, e.what());
927  // }
928  }
929  template<typename Fn>
930  static inline
931  ENABLE_IF_Fn_CALLABLE_OSTREAM
932  test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin, Fn f)
933  {
934  if ( ! test_should_emit(loggerbase, level, origin) ) {
935  return;
936  }
937 
938  // try {
939  std::ostringstream sstr;
940  f(sstr);
941  call_emit_log(loggerbase, level, origin, sstr.str());
942  // } catch (const std::exception & e) {
943  // std::fprintf(stderr, "Warning in LoggerBase::test_and_call_emit_log(%d, \"%s\", f(ostream)):"
944  // " Exception caught: %s\n",
945  // level, origin, e.what());
946  // }
947  }
948  };
949 
956  template<typename Derived, int Level, bool isStaticallyDiscarded = false>
957  struct LoggerBaseHelperStatic2 {
958  template<typename... Args>
959  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, const char * origin,
960  Args... args)
961  {
962  LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(loggerbase, Level, origin, args...);
963  }
964  };
965  // specialization for calls where the message should be statically discarded
966  template<typename Derived, int Level>
967  struct LoggerBaseHelperStatic2<Derived, Level, true> {
968  template<typename... Args>
969  static inline void test_and_call_emit_log(LoggerBase<Derived> *, const char *, Args...)
970  {
971  // discard logging message.
972  }
973  };
974 
978  template<typename Derived, int Level>
979  struct LoggerBaseHelperStatic {
980  template<typename... Args>
981  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, const char * origin,
982  Args... args)
983  {
984  // call the default or specialized version of our second helper, which will either
985  // relay the call the dynamic version or discard the message.
986  //std::fprintf(stderr,
987  // "LoggerBaseHelperStatic<Derived,Level=%d>::test_and_call_emit_log(...). StaticMinimumSeverityLevel=%d\n",
988  // (int)Level, (int)(LoggerTraits<Derived>::StaticMinimumSeverityLevel));
989  LoggerBaseHelperStatic2<
990  Derived, Level,
992  >::test_and_call_emit_log(
993  loggerbase, origin, args...
994  );
995  }
996  };
997 
998 
999 } // namespace tomo_internal
1000 
1001 
1002 template<typename Derived>
1003 inline void LoggerBase<Derived>::error(const char * origin, const char * fmt, ...)
1004 {
1005  va_list ap;
1006  va_start(ap, fmt);
1007  derived()->template log<ERROR>(origin, fmt, ap);
1008  va_end(ap);
1009 }
1010 
1011 template<typename Derived>
1012 inline void LoggerBase<Derived>::error(const char * origin, const std::string & msg)
1013 {
1014  derived()->template log<ERROR>(origin, msg);
1015 }
1016 
1017 template<typename Derived>
1018 template<typename Fn>
1019 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1020 LoggerBase<Derived>::error(const char * origin, Fn f)
1021 {
1022  derived()->template log<ERROR>(origin, f);
1023 }
1024 
1025 
1026 template<typename Derived>
1027 inline void LoggerBase<Derived>::warning(const char * origin, const char * fmt, ...)
1028 {
1029  va_list ap;
1030  va_start(ap, fmt);
1031  derived()->template log<WARNING>(origin, fmt, ap);
1032  va_end(ap);
1033 }
1034 
1035 template<typename Derived>
1036 inline void LoggerBase<Derived>::warning(const char * origin, const std::string & msg)
1037 {
1038  derived()->template log<WARNING>(origin, msg);
1039 }
1040 
1041 template<typename Derived>
1042 template<typename Fn>
1043 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1044 LoggerBase<Derived>::warning(const char * origin, Fn f)
1045 {
1046  derived()->template log<WARNING>(origin, f);
1047 }
1048 
1049 template<typename Derived>
1050 inline void LoggerBase<Derived>::info(const char * origin, const char * fmt, ...)
1051 {
1052  va_list ap;
1053  va_start(ap, fmt);
1054  derived()->template log<INFO>(origin, fmt, ap);
1055  va_end(ap);
1056 }
1057 
1058 template<typename Derived>
1059 inline void LoggerBase<Derived>::info(const char * origin, const std::string & msg)
1060 {
1061  derived()->template log<INFO>(origin, msg);
1062 }
1063 
1064 template<typename Derived>
1065 template<typename Fn>
1066 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1067 LoggerBase<Derived>::info(const char * origin, Fn f)
1068 {
1069  derived()->template log<INFO>(origin, f);
1070 }
1071 
1072 template<typename Derived>
1073 inline void LoggerBase<Derived>::debug(const char * origin, const char * fmt, ...)
1074 {
1075  va_list ap;
1076  va_start(ap, fmt);
1077  derived()->template log<DEBUG>(origin, fmt, ap);
1078  va_end(ap);
1079 }
1080 
1081 template<typename Derived>
1082 inline void LoggerBase<Derived>::debug(const char * origin, const std::string & msg)
1083 {
1084  derived()->template log<DEBUG>(origin, msg);
1085 }
1086 
1087 template<typename Derived>
1088 template<typename Fn>
1089 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1090 LoggerBase<Derived>::debug(const char * origin, Fn f)
1091 {
1092  derived()->template log<DEBUG>(origin, f);
1093 }
1094 
1095 template<typename Derived>
1096 inline void LoggerBase<Derived>::longdebug(const char * origin, const char * fmt, ...)
1097 {
1098  va_list ap;
1099  va_start(ap, fmt);
1100  derived()->template log<LONGDEBUG>(origin, fmt, ap);
1101  va_end(ap);
1102 }
1103 
1104 template<typename Derived>
1105 inline void LoggerBase<Derived>::longdebug(const char * origin, const std::string & msg)
1106 {
1107  derived()->template log<LONGDEBUG>(origin, msg);
1108 }
1109 
1110 template<typename Derived>
1111 template<typename Fn>
1112 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1113 LoggerBase<Derived>::longdebug(const char * origin, Fn f)
1114 {
1115  derived()->template log<LONGDEBUG>(origin, f);
1116 }
1117 
1118 
1119 template<typename Derived>
1120 inline void LoggerBase<Derived>::log(int level, const char * origin, const char * fmt, ...)
1121 {
1122  va_list ap;
1123  va_start(ap, fmt);
1124  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, fmt, ap);
1125  va_end(ap);
1126 }
1127 
1128 template<typename Derived>
1129 inline void LoggerBase<Derived>::log(int level, const char * origin, const std::string & msg)
1130 {
1131  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, msg);
1132 }
1133 
1134 template<typename Derived>
1135 template<typename Fn>
1136 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1137 LoggerBase<Derived>::log(int level, const char * origin, Fn f)
1138 {
1139  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, f);
1140 }
1141 
1142 
1143 template<typename Derived>
1144 template<int Level>
1145 inline void LoggerBase<Derived>::log(const char * origin, const char * fmt, ...)
1146 {
1147  va_list ap;
1148  va_start(ap, fmt);
1149  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, fmt, ap);
1150  va_end(ap);
1151 }
1152 
1153 template<typename Derived>
1154 template<int Level>
1155 inline void LoggerBase<Derived>::log(const char * origin, const char * fmt, va_list ap)
1156 {
1157  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, fmt, ap);
1158 }
1159 
1160 template<typename Derived>
1161 template<int Level>
1162 inline void LoggerBase<Derived>::log(const char * origin, const std::string & msg)
1163 {
1164  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, msg);
1165 }
1166 
1167 template<typename Derived>
1168 template<int Level, typename Fn>
1169 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1170 LoggerBase<Derived>::log(const char * origin, Fn f)
1171 {
1172  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, f);
1173 }
1174 
1175 
1176 
1177 
1178 class FileLogger;
1183 template<>
1184 struct LoggerTraits<FileLogger> : public DefaultLoggerTraits
1185 {
1187  enum {
1188  IsThreadSafe = 1
1189  };
1190 };
1191 
1202 class TOMOGRAPHER_EXPORT FileLogger : public LoggerBase<FileLogger>
1203 {
1204 public:
1205  FileLogger(FILE * fp_, int level = INFO, bool display_origin_ = true)
1206  : LoggerBase<FileLogger>(level), fp(fp_), display_origin(display_origin_)
1207  {
1208  }
1209 
1213  inline void setFp(FILE * fp_)
1214  {
1215  fp = fp_;
1216  }
1217 
1221  inline void setLevel(int level)
1222  {
1223  setLogLevel(level);
1224  }
1225 
1229  inline void setDisplayOrigin(bool display_origin_)
1230  {
1231  display_origin = display_origin_;
1232  }
1233 
1234  inline void emitLog(int level, const char * origin, const std::string & msg)
1235  {
1236  static const std::string level_prefixes[] = {
1237  std::string("\n\n*** ERROR -- "),
1238  std::string("\n*** Warning: ")
1239  };
1240 
1241  std::string finalmsg = (
1243  ? level_prefixes[level] : std::string() )
1244  + ((display_origin && origin && origin[0]) ? "["+std::string(origin)+"] " : std::string())
1245  + msg
1246  );
1247 
1248  // display the log message
1249  std::fprintf(fp, "%s\n", finalmsg.c_str());
1250 
1251  if (isAtLeastOfSeverity(level, WARNING)) {
1252  // force output also on stderr for warnings and errors if we are being redirected to a
1253  // file, or at least flush the buffer.
1254  std::fflush(fp);
1255  if (fp != stdout && fp != stderr) {
1256  std::fprintf(stderr, "%s\n", finalmsg.c_str());
1257  }
1258  }
1259  }
1260 
1261 private:
1262  std::FILE * fp;
1263  bool display_origin;
1264 };
1265 
1266 
1267 
1268 
1269 
1270 class VacuumLogger;
1275 template<>
1276 struct LoggerTraits<VacuumLogger> : public DefaultLoggerTraits
1277 {
1279  enum {
1280  IsThreadSafe = 1,
1281  StaticMinimumSeverityLevel = -1
1282  };
1283 };
1284 
1289 class TOMOGRAPHER_EXPORT VacuumLogger : public LoggerBase<VacuumLogger>
1290 {
1291 public:
1292  inline void emitLog(int /*level*/, const char * /*origin*/, const std::string & /*msg*/)
1293  {
1294  }
1295 
1296 };
1297 
1303 static VacuumLogger vacuum_logger;
1304 
1305 
1306 
1307 
1308 class BufferLogger;
1313 template<>
1314 struct LoggerTraits<BufferLogger> : public DefaultLoggerTraits
1315 {
1317  enum {
1318  IsThreadSafe = 0
1319  };
1320 };
1321 
1327 class TOMOGRAPHER_EXPORT BufferLogger : public LoggerBase<BufferLogger>
1328 {
1329  std::ostringstream buffer;
1330 public:
1331  BufferLogger(int level)
1332  : LoggerBase<BufferLogger>(level)
1333  {
1334  }
1335 
1336  inline void emitLog(int /*level*/, const char * origin, const std::string& msg)
1337  {
1338  buffer << (origin&&origin[0] ? "["+std::string(origin)+"] " : std::string())
1339  << msg.c_str() << "\n";
1340  }
1341 
1346  inline void setLevel(int level)
1347  {
1348  setLogLevel(level);
1349  }
1350 
1356  inline void clear()
1357  {
1358  buffer.clear();
1359  buffer.str(std::string());
1360  }
1361 
1366  inline std::string getContents() const
1367  {
1368  return buffer.str();
1369  }
1370 };
1371 
1372 
1373 
1374 
1375 template<typename, int> class MinimumSeverityLogger;
1378 template<typename BaseLogger, int Level>
1379 struct LoggerTraits<MinimumSeverityLogger<BaseLogger,Level> > : public LoggerTraits<BaseLogger>
1380 {
1382  enum {
1383 
1385  StaticMinimumSeverityLevel = Level,
1386 
1388  HasOwnGetLevel = 1
1389 
1390  // Note: filter by origin flag is inherited from base logger.
1391  };
1392 };
1393 
1403 template<typename BaseLogger, int Level>
1404 class TOMOGRAPHER_EXPORT MinimumSeverityLogger : public LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >
1405 {
1407  BaseLogger & baselogger;
1408 public:
1414  MinimumSeverityLogger(BaseLogger & baselogger_)
1415  : LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >(), baselogger(baselogger_)
1416  {
1417  }
1418 
1420  inline void emitLog(int level, const char * origin, const std::string& msg)
1421  {
1422  baselogger.emitLog(level, origin, msg);
1423  }
1424 
1426  inline int level() const
1427  {
1428  return baselogger.level();
1429  }
1430 
1432  template<bool dummy = true>
1434  filterByOrigin(int level, const char * origin)
1435  {
1436  return baselogger.filterByOrigin(level, origin);
1437  }
1438 };
1439 
1440 
1441 namespace tomo_internal {
1442 
1448 inline std::size_t matched_length(const std::string & s, const std::string & pattern)
1449 {
1450  std::size_t k = 0;
1451  while (s[k] == pattern[k]) {
1452  ++k;
1453  }
1454  return k;
1455 }
1456 
1457 } // namespace tomo_internal
1458 
1459 template<typename BaseLogger> class OriginFilteredLogger;
1463 template<typename BaseLogger>
1464 struct LoggerTraits<OriginFilteredLogger<BaseLogger> > : public LoggerTraits<BaseLogger>
1465 {
1467  enum {
1468  HasOwnGetLevel = 1,
1469  HasFilterByOrigin = 1
1470  };
1471 };
1472 
1493 template<typename BaseLogger>
1494 class TOMOGRAPHER_EXPORT OriginFilteredLogger
1495  : public Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >
1496 {
1498  BaseLogger & baselogger;
1499 
1501  std::map<std::string,int> levels_set;
1502 public:
1503 
1509  OriginFilteredLogger(BaseLogger & baselogger_)
1510  : Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >(),
1511  baselogger(baselogger_),
1512  levels_set()
1513  {
1514  }
1515 
1525  inline void setDomainLevel(const std::string& origin_pattern, int level)
1526  {
1527  levels_set[origin_pattern] = level;
1528  }
1529 
1535  inline void removeDomainSetting(const std::string& s)
1536  {
1537  auto it = levels_set.find(s);
1538  if (it == levels_set.end()) {
1539  this->warning("OriginFilteredLogger<BaseLogger>::removeDomainSetting", "domain not set: `%s'", s.c_str());
1540  return;
1541  }
1542  levels_set.erase(it);
1543  }
1544 
1553  inline int level() const
1554  {
1555  return LOWEST_SEVERITY_LEVEL;
1556  }
1557 
1562  inline void emitLog(int level, const char * origin, const std::string& msg)
1563  {
1564  baselogger.emitLog(level, origin, msg);
1565  }
1566 
1574  inline bool filterByOrigin(int level, const char * origin) const
1575  {
1576  typedef std::map<std::string, int>::const_iterator ConstIterator;
1577 
1578  std::string s(origin);
1579 
1580  int loglevel = -1;
1581  std::size_t last_matched_length = 0;
1582  for (ConstIterator it = levels_set.begin(); it != levels_set.end(); ++it) {
1583  const std::size_t mlen = tomo_internal::matched_length((*it).first, s);
1584  if (mlen > last_matched_length) {
1585  loglevel = (*it).second;
1586  last_matched_length = mlen;
1587  }
1588  }
1589  if (loglevel == -1) {
1590  // default logger level
1591  loglevel = baselogger.level();
1592  }
1593  return isAtLeastOfSeverity(level, loglevel);
1594  }
1595 
1596 };
1597 
1598 
1599 
1600 
1601 
1602 // --------------------------------------------------
1603 
1604 
1605 
1606 
1607 
1616 
1619  : origin_prefix(s), origin_prefix_add(""), glue(gl) { }
1621  constexpr LocalLoggerOriginSpec(const Tools::conststr& s, const Tools::conststr& s2, const Tools::conststr& gl)
1622  : origin_prefix(s), origin_prefix_add(s2), glue(gl) { }
1623 };
1624 
1625 namespace tomo_internal {
1627 struct extractTomoOrigin_helper {
1628  static inline constexpr LocalLoggerOriginSpec step2(const Tools::conststr fn, std::size_t last_doublecolons,
1629  std::size_t after_prelast_doublecolons)
1630  {
1631  return ( fn.substr_e(after_prelast_doublecolons, last_doublecolons) == fn.substr(last_doublecolons+2)
1632  // fn is a constructor, so keep class name and use "::" as glue
1633  ? LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "::")
1634  // looks like a method name. Strip off the class name. Also use an internal
1635  // glue to indicate a logical level.
1636  : LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "()", "/")
1637  );
1638  }
1639  static inline constexpr std::size_t afterprelast_doublecolons(std::size_t prelast_doublecolons_found)
1640  {
1641  return (prelast_doublecolons_found == std::string::npos) ? 0 : prelast_doublecolons_found+2;
1642  }
1643  static inline constexpr LocalLoggerOriginSpec step1(const Tools::conststr fn, std::size_t last_doublecolons)
1644  {
1645  return last_doublecolons == std::string::npos || last_doublecolons == 0
1646  ? LocalLoggerOriginSpec(fn, "()", "/") // looks like simple function name with no parent scope
1647  : step2(fn, last_doublecolons, afterprelast_doublecolons(fn.rfind("::", last_doublecolons-1)));
1648  }
1649 
1650  static inline constexpr LocalLoggerOriginSpec extract_from_func_name(const Tools::conststr fn)
1651  {
1652  return step1(fn, fn.rfind("::"));
1653  }
1654 };
1655 
1657 constexpr const LocalLoggerOriginSpec extractTomoOrigin(const Tools::conststr fn)
1658 {
1659  return extractTomoOrigin_helper::extract_from_func_name(Tomographer::Tools::extractFuncName(fn));
1660 }
1661 
1662 } // namespace tomo_internal
1663 
1664 
1669 #define TOMO_ORIGIN Tomographer::Logger::tomo_internal::extractTomoOrigin(TOMO_FUNCTION)
1670 
1671 
1672 
1673 
1674 template<typename BaseLoggerType_> class LocalLogger;
1675 
1676 
1677 namespace tomo_internal {
1679 template<typename BaseLoggerType>
1680 struct is_local_logger {
1681  enum { value = 0 };
1682 };
1683 template<typename BaseLoggerType>
1684 struct is_local_logger<LocalLogger<BaseLoggerType> > {
1685  enum { value = 1 };
1686 };
1688 template<typename BaseLoggerType>
1689 struct local_logger_parent {
1690  typedef BaseLoggerType ParentType;
1691 };
1692 template<typename BaseLoggerType>
1693 struct local_logger_parent<LocalLogger<BaseLoggerType> > {
1694  typedef typename local_logger_parent<BaseLoggerType>::ParentType ParentType;
1695 };
1696 } // namespace tomo_internal
1697 
1699 template<typename BaseLoggerType_>
1700 struct LoggerTraits<LocalLogger<BaseLoggerType_> > : public LoggerTraits<BaseLoggerType_>
1701 {
1702  enum {
1704  HasOwnGetLevel = 1
1705  };
1706 };
1707 
1708 
1767 template<typename BaseLoggerType_>
1768 class TOMOGRAPHER_EXPORT LocalLogger
1769  : public LoggerBase<LocalLogger<BaseLoggerType_> >
1770 {
1771 public:
1773  typedef BaseLoggerType_ BaseLoggerType;
1774 
1775 private:
1777 
1779  const std::string _origin_prefix;
1781  const std::string _glue;
1782 
1783  BaseLoggerType & _baselogger;
1784 
1785 public:
1796  LocalLogger(const std::string & origin_fn_name, BaseLoggerType & logger_)
1797  : Base_(), _origin_prefix(origin_fn_name), _glue("::"), _baselogger(logger_)
1798  {
1799  this->longdebug("[begin]");
1800  }
1807  LocalLogger(const std::string & origin_prefix, const std::string & glue, BaseLoggerType & logger_)
1808  : Base_(), _origin_prefix(origin_prefix), _glue(glue), _baselogger(logger_)
1809  {
1810  this->longdebug("[begin]");
1811  }
1817  LocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & logger_)
1818  : Base_(), _origin_prefix(spec.origin_prefix.to_string()+spec.origin_prefix_add.to_string()),
1819  _glue(spec.glue.to_string()), _baselogger(logger_)
1820  {
1821  this->longdebug("[begin]");
1822  }
1823 
1828  : Base_(), _origin_prefix(std::move(movecopy._origin_prefix)), _glue(std::move(movecopy._glue)),
1829  _baselogger(movecopy._baselogger)
1830  {
1831  this->longdebug("[logger moved]");
1832  }
1834  LocalLogger(const LocalLogger & other)
1835  : Base_(), _origin_prefix(other._origin_prefix), _glue(other._glue),
1836  _baselogger(other._baselogger)
1837  {
1838  this->longdebug("[logger copied]");
1839  }
1840 
1841  ~LocalLogger()
1842  {
1843  this->longdebug("[done]");
1844  }
1845 
1854  inline std::string originPrefix() const { return _origin_prefix; }
1855 
1858  inline std::string glue() const { return _glue; }
1859 
1865  inline BaseLoggerType & baseLogger() { return _baselogger; }
1866 
1867 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
1868 
1873  typedef _PARENT_LOGGER_TYPE ParentLoggerType;
1874 
1882  ParentLoggerType & parentLogger() { }
1883 #else
1884 
1885  typedef typename tomo_internal::local_logger_parent<BaseLoggerType>::ParentType ParentLoggerType;
1886 
1888  inline ParentLoggerType & parentLogger()
1889  {
1890  return baseLogger();
1891  }
1893  inline ParentLoggerType & parentLogger() {
1894  return baseLogger().parentLogger();
1895  }
1896 #endif
1897 
1908  {
1909  return LocalLogger<LocalLogger<BaseLoggerType> >(new_prefix, *this);
1910  }
1918  const std::string & new_glue)
1919  {
1920  return LocalLogger<LocalLogger<BaseLoggerType> >(new_prefix, new_glue, *this);
1921  }
1928  {
1929  return LocalLogger<LocalLogger<BaseLoggerType> >(spec, *this);
1930  }
1931 
1936  PRINTF2_ARGS_SAFE inline void longdebug(const char * fmt, ...)
1937  { va_list ap; va_start(ap, fmt); log<LONGDEBUG>(fmt, ap); va_end(ap); }
1942  PRINTF2_ARGS_SAFE inline void debug(const char * fmt, ...)
1943  { va_list ap; va_start(ap, fmt); log<DEBUG>(fmt, ap); va_end(ap); }
1948  PRINTF2_ARGS_SAFE inline void info(const char * fmt, ...)
1949  { va_list ap; va_start(ap, fmt); log<INFO>(fmt, ap); va_end(ap); }
1954  PRINTF2_ARGS_SAFE inline void warning(const char * fmt, ...)
1955  { va_list ap; va_start(ap, fmt); log<WARNING>(fmt, ap); va_end(ap); }
1960  PRINTF2_ARGS_SAFE inline void error(const char * fmt, ...)
1961  { va_list ap; va_start(ap, fmt); log<ERROR>(fmt, ap); va_end(ap); }
1962 
1967  template<typename... Args>
1968  inline void longdebug(Args &&... a) { log<Tomographer::Logger::LONGDEBUG>(std::forward<Args>(a)...); }
1973  template<typename... Args>
1974  inline void debug(Args &&... a) { log<Tomographer::Logger::DEBUG>(std::forward<Args>(a)...); }
1979  template<typename... Args>
1980  inline void info(Args &&... a) { log<Tomographer::Logger::INFO>(std::forward<Args>(a)...); }
1985  template<typename... Args>
1986  inline void warning(Args &&... a) { log<Tomographer::Logger::WARNING>(std::forward<Args>(a)...); }
1991  template<typename... Args>
1992  inline void error(Args &&... a) { log<Tomographer::Logger::ERROR>(std::forward<Args>(a)...); }
1993 
1998  template<int Level, typename... Args>
1999  inline void log(Args... args)
2000  {
2001  Base_::template log<Level>("", args...);
2002  }
2003 
2004 
2005  // relay calls to base logger
2006 
2015  inline std::string getSubOrigin(const char * origin) const
2016  {
2017  return ( origin == NULL || origin[0] == 0
2018  ? _origin_prefix
2019  : _origin_prefix + _glue + origin );
2020  }
2021 
2023  inline void emitLog(int level, const char * origin, const std::string& msg)
2024  {
2025  // this might also be called if we have a sublogger. In that case, if we have a
2026  // sublogger, then use their prefix.
2027  _baselogger.emitLog(level, getSubOrigin(origin).c_str(), msg);
2028  }
2029 
2031  inline int level() const
2032  {
2033  return _baselogger.level();
2034  }
2035 
2038  inline bool filterByOrigin(int level, const char * origin)
2039  {
2040  return _baselogger.filterByOrigin(level, getSubOrigin(origin).c_str());
2041  }
2042 };
2043 
2044 
2045 
2062 template<typename BaseLoggerType>
2063 inline LocalLogger<BaseLoggerType> makeLocalLogger(const std::string & origin_fn_name, BaseLoggerType & baselogger)
2064 {
2065  return LocalLogger<BaseLoggerType>(origin_fn_name, baselogger);
2066 }
2067 
2073 template<typename BaseLoggerType>
2074 inline LocalLogger<BaseLoggerType> makeLocalLogger(const std::string & origin_prefix, const std::string & glue,
2075  BaseLoggerType & baselogger)
2076 {
2077  return LocalLogger<BaseLoggerType>(origin_prefix, glue, baselogger);
2078 }
2079 
2085 template<typename BaseLoggerType>
2086 inline LocalLogger<BaseLoggerType> makeLocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & baselogger)
2087 {
2088  return LocalLogger<BaseLoggerType>(spec, baselogger);
2089 }
2090 
2091 
2092 
2093 
2094 
2095 } // namespace Logger
2096 } // namespace Tomographer
2097 
2098 
2099 
2100 #endif
Utilities for formatting strings.
std::string originPrefix() const
The fixed origin specified at the constructor.
Definition: loggers.h:1854
Simple logger class which logs everything into a given FILE pointer.
Definition: loggers.h:1202
static bool staticallyEnabledFor(int level)
Check whether the logger is statically disabled for some levels.
Definition: loggers.h:741
Local logger: avoid having to repeat origin at each emitted message.
Definition: loggers.h:1674
Lowest severity possible.
Definition: loggers.h:145
void debug(Args &&... a)
Generate a log message with level Logger::DEBUG.
Definition: loggers.h:1974
void info(Args &&... a)
Generate a log message with level Logger::INFO.
Definition: loggers.h:1980
Log messages into an internal memory buffer.
Definition: loggers.h:1327
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:1621
void clear()
Clears the internal memory buffer.
Definition: loggers.h:1356
void setDomainLevel(const std::string &origin_pattern, int level)
Set a rule to log messages based on their origin.
Definition: loggers.h:1525
std::string vfmts(const char *fmt, va_list vl)
printf- formatting to a std::string, with va_list pointer
Definition: fmt.h:87
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log message (relay to base logger).
Definition: loggers.h:1562
LocalLogger< BaseLoggerType > makeLocalLogger(const std::string &origin_fn_name, BaseLoggerType &baselogger)
Create a local logger.
Definition: loggers.h:2063
void setLevel(std::string s)
Set the level to the given level name. See class doc.
Definition: loggers.h:208
LocalLogger(const std::string &origin_prefix, const std::string &glue, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1807
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:1120
Highest severity possible.
Definition: loggers.h:137
Error logging level.
Definition: loggers.h:89
const Tools::conststr glue
the glue to use in the local logger
Definition: loggers.h:1615
Logger that discards all messages.
Definition: loggers.h:1289
STL namespace.
Object which stores a log level and can initialize from a string.
Definition: loggers.h:164
T end(T... args)
Base logger class.
Definition: loggers.h:437
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:2031
void error(const char *origin, const char *fmt,...)
emit an error message
Definition: loggers.h:1003
int level() const
Get the stored level code. See LogLevelCode.
Definition: loggers.h:176
bool filterByOrigin(int level, const char *origin) const
Message filtering by origin implementation.
Definition: loggers.h:1574
OriginFilteredLogger(BaseLogger &baselogger_)
Constructor based on a base logger reference.
Definition: loggers.h:1509
ParentLoggerType & parentLogger()
The parent logger responsible for actually emitting the messages in some useful way.
Definition: loggers.h:1882
STL class.
void setLevel(int level)
Set the level to the given level code. See class doc and LogLevelCode.
Definition: loggers.h:195
void removeDomainSetting(const std::string &s)
Remove a rule set by setDomainLevel()
Definition: loggers.h:1535
void longdebug(Args &&... a)
Generate a log message with level Logger::LONGDEBUG.
Definition: loggers.h:1968
void setLogLevel(int level)
Store a new run-time log level.
Definition: loggers.h:839
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:2015
std::string levelName() const
Get the stored level name.
Definition: loggers.h:182
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix)
Create a sub-logger.
Definition: loggers.h:1907
Helper for statically determining if Level is at least as severe as BaseLevel.
Definition: loggers.h:267
BaseLoggerType & baseLogger()
The base logger type specified to the constructor.
Definition: loggers.h:1865
std::string glue() const
The "glue" string to use to concatenate origins from sub-loggers.
Definition: loggers.h:1858
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:1426
bool enabledFor(int level_) const
Check whether messages at the given log level are enabled.
Definition: loggers.h:768
void warning(Args &&... a)
Generate a log message with level Logger::WARNING.
Definition: loggers.h:1986
Logger which statically discards any messages less important than a fixed severity.
Definition: loggers.h:1375
constexpr LocalLoggerOriginSpec(const Tools::conststr &s, const Tools::conststr &gl)
constructor. origin_prefix_add is left blank.
Definition: loggers.h:1618
BaseLoggerType_ BaseLoggerType
The base logger type (see class documentation)
Definition: loggers.h:1773
MinimumSeverityLogger(BaseLogger &baselogger_)
Constructor from a base logger.
Definition: loggers.h:1414
T erase(T... args)
void setDisplayOrigin(bool display_origin_)
Definition: loggers.h:1229
Tool to specify arguments to LocalLogger.
Definition: loggers.h:1609
void error(Args &&... a)
Generate a log message with level Logger::ERROR.
Definition: loggers.h:1992
const Tools::conststr origin_prefix
Origin prefix for the local logger.
Definition: loggers.h:1611
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:2023
T str(T... args)
std::ostream & operator<<(std::ostream &str, const LogLevel &l)
C++ output stream operator for LogLevel.
Definition: loggers.h:237
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix, const std::string &new_glue)
Create a sub-logger.
Definition: loggers.h:1917
void warning(const char *origin, const char *fmt,...)
emit a warning message
Definition: loggers.h:1027
A constexpr string type, suitable for basic compile-time string processing.
void debug(const char *origin, const char *fmt,...)
emit an debug message
Definition: loggers.h:1073
LocalLogger(const LocalLogger &other)
Make the local-logger copyable – there&#39;s nothing wrong with that.
Definition: loggers.h:1834
Default traits for Logger implementations.
Definition: loggers.h:294
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:1420
static bool staticallyEnabledFor()
Static version of staticallyEnabledFor()
Definition: loggers.h:750
T find(T... args)
void log(Args... args)
Generate a log message with level Level.
Definition: loggers.h:1999
void longdebug(const char *origin, const char *fmt,...)
emit a very verbose debugging message
Definition: loggers.h:1096
void setLevel(int level)
Changes the runtime log level to a new value.
Definition: loggers.h:1346
bool isAtLeastOfSeverity(int level, int baselevel)
Helper to compare severity levels.
Definition: loggers.h:254
void info(const char *origin, const char *fmt,...)
emit an information/notice message
Definition: loggers.h:1050
T begin(T... args)
Traits template struct to be specialized for specific Logger implementations.
Definition: loggers.h:357
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)
Warning logging level.
Definition: loggers.h:98
_PARENT_LOGGER_TYPE ParentLoggerType
Type of the parent logger type, ultimately responsible for actually emitting the messages in some use...
Definition: loggers.h:1873
LocalLogger(const LocalLoggerOriginSpec &spec, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1817
std::istream & operator>>(std::istream &str, LogLevel &l)
C++ input stream operator for LogLevel.
Definition: loggers.h:229
std::enable_if< dummy &&LoggerTraits< BaseLogger >::HasFilterByOrigin, bool > filterByOrigin(int level, const char *origin)
If relevant for the base logger, filter the messages by origin from the base logger.
Definition: loggers.h:1434
LoggerBase(int level_=INFO)
Construct the base logger object.
Definition: loggers.h:465
LogLevelCode
Possible logging levels.
Definition: loggers.h:82
const Tools::conststr origin_prefix_add
optionally some string to append to origin_prefix
Definition: loggers.h:1613
Long Debug logging level.
Definition: loggers.h:128
std::string getContents() const
get the contents of the internal buffer
Definition: loggers.h:1366
constexpr conststr extractFuncName(const conststr &funcname)
Extract the function name from its signature.
Definition: cxxutil.h:569
LogLevel(const char *s)
Construct a level using a string level name.
Definition: loggers.h:171
int level() const
Unconditionally return LOWEST_SEVERITY_LEVEL for the underlying logging engine.
Definition: loggers.h:1553
LogLevel(int level_=INFO)
Construct a level using an integer level code. See LogLevelCode.
Definition: loggers.h:169
int level() const
Get the log level set for this logger.
Definition: loggers.h:790
LogLevel(const std::string &s)
Construct a level using a string level name.
Definition: loggers.h:173
LocalLogger(const std::string &origin_fn_name, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1796
A constexpr string type.
Definition: conststr.h:55
T fprintf(T... args)
STL class.
LocalLogger(LocalLogger &&movecopy)
Definition: loggers.h:1827
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const LocalLoggerOriginSpec &spec)
Create a sub-logger.
Definition: loggers.h:1927
Debug logging level.
Definition: loggers.h:118
Information logging level.
Definition: loggers.h:106
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:84
A logger which filters entries according to where they originated from.
Definition: loggers.h:1459