Loading [MathJax]/extensions/tex2jax.js
Tomographerv4.1
Tomographer C++ Framework Documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 namespace Tomographer
64 {
65 
69 namespace Logger
70 {
71 
78 {
84  ERROR = 0,
85 
94 
102 
114 
124 
125 
133 
141 };
142 
143 
144 
159 TOMOGRAPHER_EXPORT class LogLevel
160 {
161  int _level;
162 public:
164  LogLevel(int level_ = INFO) { setLevel(level_); }
166  LogLevel(const char * s) { setLevel(s); }
168  LogLevel(const std::string& s) { setLevel(s); }
169 
171  inline int level() const { return _level; }
172 
174  inline operator int() const { return _level; }
175 
177  inline std::string levelName() const
178  {
179  switch (_level) {
180  case LONGDEBUG: return std::string("LONGDEBUG");
181  case DEBUG: return std::string("DEBUG");
182  case INFO: return std::string("INFO");
183  case WARNING: return std::string("WARNING");
184  case ERROR: return std::string("ERROR");
185  default: return std::string("<INVALID LEVEL>");
186  };
187  }
188 
190  inline void setLevel(int level)
191  {
192  if (level != LONGDEBUG &&
193  level != DEBUG &&
194  level != INFO &&
195  level != WARNING &&
196  level != ERROR) {
197  throw std::invalid_argument("Invalid level code: "+std::to_string(level));
198  }
199  _level = level;
200  }
201 
203  inline void setLevel(std::string s)
204  {
205  // NOT const string `s`! we need our copy for to_upper():
206  boost::to_upper(s);
207  if (s == "LONGDEBUG") {
208  _level = LONGDEBUG;
209  } else if (s == "DEBUG") {
210  _level = DEBUG;
211  } else if (s == "INFO") {
212  _level = INFO;
213  } else if (s == "WARNING") {
214  _level = WARNING;
215  } else if (s == "ERROR") {
216  _level = ERROR;
217  } else {
218  throw std::invalid_argument("Invalid log level: '"+s+"'");
219  }
220  }
221 };
222 
225 {
226  std::string s;
227  str >> s;
228  l.setLevel(s);
229  return str;
230 }
232 inline std::ostream & operator<<(std::ostream & str, const LogLevel &l)
233 {
234  return str << l.levelName();
235 }
236 
237 
238 
249 inline bool isAtLeastOfSeverity(int level, int baselevel)
250 {
251  return (level <= baselevel);
252 }
253 
261 template<int Level, int BaseLevel>
263  enum {
264  value = (Level <= BaseLevel)
265  };
266 };
267 
268 
289 TOMOGRAPHER_EXPORT struct DefaultLoggerTraits
290 {
291  enum {
297  IsThreadSafe = 0,
298 
311  StaticMinimumSeverityLevel = LOWEST_SEVERITY_LEVEL,
312 
324  HasOwnGetLevel = 0,
325 
338  HasFilterByOrigin = 0
339  };
340 };
341 
351 template<typename LoggerType>
353 {
354  // by default, contains nothing and will produce errors if used unspecialized.
355 };
356 
357 
358 
359 namespace tomo_internal {
363 template<bool hasOwnGetLevel>
364 class LoggerRuntimeLevel {
365 public:
366  LoggerRuntimeLevel(int level)
367  : _level(level)
368  {
369  }
370 
371  inline int level() const
372  {
373  return _level;
374  }
375 
376 protected:
377  inline void setLogLevel(int level)
378  {
379  _level = level;
380  }
381 
382 private:
383  int _level;
384 };
385 //
386 // Specialization for those classes which provide their own level() method. Do nothing.
387 //
388 template<>
389 class LoggerRuntimeLevel<true> {
390 public:
391  LoggerRuntimeLevel(int /*level*/)
392  {
393  }
394 
395  inline void setLogLevel(int) {
396  tomographer_assert(0 && "Call to LoggerRuntimeLevel::setLogLevel() for Logger which defines HasOwnGetLevel=1!");
397  }
398 };
399 }
400 
401 
427 template<typename Derived>
428 TOMOGRAPHER_EXPORT class LoggerBase
429 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
430  : public tomo_internal::LoggerRuntimeLevel<LoggerTraits<Derived>::HasOwnGetLevel>
431 #endif
432 {
433 public:
436  enum {
445  };
446 
456  LoggerBase(int level_ = INFO)
457  : tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>(level_)
458  {
459  }
460 
468  PRINTF3_ARGS_SAFE
469  inline void error(const char * origin, const char * fmt, ...);
477  inline void error(const char * origin, const std::string & msg);
484  template<typename Fn>
485  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
486  error(const char * origin, Fn f);
487 
495  PRINTF3_ARGS_SAFE
496  inline void warning(const char * origin, const char * fmt, ...);
504  inline void warning(const char * origin, const std::string & msg);
511  template<typename Fn>
512  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
513  warning(const char * origin, Fn f);
514 
522  PRINTF3_ARGS_SAFE
523  inline void info(const char * origin, const char * fmt, ...);
531  inline void info(const char * origin, const std::string & msg);
538  template<typename Fn>
539  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
540  info(const char * origin, Fn f);
541 
559  PRINTF3_ARGS_SAFE
560  inline void debug(const char * origin, const char * fmt, ...);
561 
578  inline void debug(const char * origin, const std::string & msg);
607  template<typename Fn>
608  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
609  debug(const char * origin, Fn f);
610 
618  PRINTF3_ARGS_SAFE
619  inline void longdebug(const char * origin, const char * fmt, ...);
627  inline void longdebug(const char * origin, const std::string & msg);
634  template<typename Fn>
635  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
636  longdebug(const char * origin, Fn f);
637 
638 
648  PRINTF4_ARGS_SAFE
649  inline void log(int level, const char * origin, const char * fmt, ...);
659  inline void log(int level, const char * origin, const std::string & msg);
669  template<typename Fn>
670  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
671  log(int level, const char * origin, Fn f);
672 
673 
674 
683  template<int Level>
684  PRINTF3_ARGS_SAFE
685  inline void log(const char * origin, const char * fmt, ...);
695  template<int Level>
696  inline void log(const char * origin, const char * fmt, va_list ap);
705  template<int Level>
706  inline void log(const char * origin, const std::string & msg);
715  template<int Level, typename Fn>
716  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
717  log(const char * origin, Fn f);
718 
719 
732  static inline bool staticallyEnabledFor(int level)
733  {
734  return ( isAtLeastOfSeverity(level, StaticMinimumSeverityLevel) );
735  }
736 
740  template<int Level>
741  static inline bool staticallyEnabledFor()
742  {
743  return ( StaticIsAtLeastOfSeverity<
744  Level,
745  StaticMinimumSeverityLevel
746  >::value ) ;
747  }
748 
759  inline bool enabledFor(int level_) const
760  {
761  return derived()->staticallyEnabledFor(level_) &&
762  isAtLeastOfSeverity(level_, getLevel());
763  };
764 
765 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
766  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
767  // exposed in the case where the logger doesn't define its own method. This is important
768  // to avoid "ambiguous calls to `level()`".
769 
781  inline int level() const
782  {
783  }
784 #endif
785 
786 
787 protected:
788 
789  // version in case we store our own level
790  TOMOGRAPHER_ENABLED_IF(!HasOwnGetLevel)
791  inline int getLevel() const
792  {
793  // use base class' implementation
794  return tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>::level();
795  }
796  // version in case we delegate to derived class' level()
797  TOMOGRAPHER_ENABLED_IF(HasOwnGetLevel)
798  inline int getLevel() const
799  {
800  return derived()->level();
801  }
802 
803 
804  inline Derived * derived()
805  {
806  return static_cast<Derived*>(this);
807  }
808  inline const Derived * derived() const
809  {
810  return static_cast<const Derived*>(this);
811  }
812 
813 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
814  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
815  // exposed in the case where the logger can actually set a new level.
816 
830  inline void setLogLevel(int level)
831  {
832  }
833 #endif
834 
835 private:
836 };
837 
838 
839 namespace tomo_internal {
842  template<typename Derived, bool derivedHasFilterByOrigin>
843  struct LoggerBaseHelperFilterByOrigin {
844  static inline bool test_logger_filter(LoggerBase<Derived> * /*loggerbase*/, int /*level*/,
845  const char * /*origin*/)
846  {
847  // do nothing by default
848  return true;
849  }
850  };
851  //
852  // specialization for loggers with filtering by origin
853  //
854  template<typename Derived>
855  struct LoggerBaseHelperFilterByOrigin<Derived, true> {
856  static inline bool test_logger_filter(LoggerBase<Derived> * loggerbase, int level,
857  const char * origin)
858  {
859  return static_cast<const Derived*>(loggerbase)->filterByOrigin(level, origin);
860  }
861  };
867  template<typename Derived>
868  struct LoggerBaseHelperDynamic {
869  static inline void call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
870  const std::string & msg)
871  {
872  // try {
873  //printf("Calling emit_log(%d,\"%s\",\"%s\") on object %p\n", level, origin, msg.c_str(), loggerbase);
874  static_cast<Derived*>(loggerbase)->emitLog(level, origin, msg);
875  // } catch (const std::exception & e) {
876  // std::fprintf(stderr,
877  // "Warning in LoggerBaseHelperDynamic::call_emit_log(%d, \"%s\", \"%s\"):"
878  // " Exception caught: %s\n",
879  // level, origin, msg.c_str(), e.what());
880  // }
881  }
882  static inline bool test_should_emit(LoggerBase<Derived> * loggerbase, int level, const char * origin)
883  {
884  if ( ! static_cast<const Derived*>(loggerbase)->enabledFor(level) ) {
885  return false;
886  }
887  if ( ! LoggerBaseHelperFilterByOrigin<Derived, LoggerTraits<Derived>::HasFilterByOrigin>
888  ::test_logger_filter(loggerbase, level, origin) ) {
889  return false;
890  }
891  return true;
892  }
893 
894  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
895  const std::string & msg)
896  {
897  if ( ! test_should_emit(loggerbase, level, origin) ) {
898  return;
899  }
900 
901  call_emit_log(loggerbase, level, origin, msg);
902  }
903  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
904  const char * fmt, va_list ap)
905  {
906  if ( ! test_should_emit(loggerbase, level, origin) ) {
907  return;
908  }
909 
910  // try {
911  const std::string msg = Tools::vfmts(fmt, ap);
912  call_emit_log(loggerbase, level, origin, msg);
913  // } catch (const std::exception & e) {
914  // std::fprintf(stderr,
915  // "Warning in LoggerBase::test_and_call_emit_log(%d, \"%s\", \"%s\", ...):"
916  // " Exception caught: %s\n",
917  // level, origin, fmt, e.what());
918  // }
919  }
920  template<typename Fn>
921  static inline
922  ENABLE_IF_Fn_CALLABLE_OSTREAM
923  test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin, Fn f)
924  {
925  if ( ! test_should_emit(loggerbase, level, origin) ) {
926  return;
927  }
928 
929  // try {
930  std::ostringstream sstr;
931  f(sstr);
932  call_emit_log(loggerbase, level, origin, sstr.str());
933  // } catch (const std::exception & e) {
934  // std::fprintf(stderr, "Warning in LoggerBase::test_and_call_emit_log(%d, \"%s\", f(ostream)):"
935  // " Exception caught: %s\n",
936  // level, origin, e.what());
937  // }
938  }
939  };
940 
947  template<typename Derived, int Level, bool isStaticallyDiscarded = false>
948  struct LoggerBaseHelperStatic2 {
949  template<typename... Args>
950  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, const char * origin,
951  Args... args)
952  {
953  LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(loggerbase, Level, origin, args...);
954  }
955  };
956  // specialization for calls where the message should be statically discarded
957  template<typename Derived, int Level>
958  struct LoggerBaseHelperStatic2<Derived, Level, true> {
959  template<typename... Args>
960  static inline void test_and_call_emit_log(LoggerBase<Derived> *, const char *, Args...)
961  {
962  // discard logging message.
963  }
964  };
965 
969  template<typename Derived, int Level>
970  struct LoggerBaseHelperStatic {
971  template<typename... Args>
972  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, const char * origin,
973  Args... args)
974  {
975  // call the default or specialized version of our second helper, which will either
976  // relay the call the dynamic version or discard the message.
977  //std::fprintf(stderr,
978  // "LoggerBaseHelperStatic<Derived,Level=%d>::test_and_call_emit_log(...). StaticMinimumSeverityLevel=%d\n",
979  // (int)Level, (int)(LoggerTraits<Derived>::StaticMinimumSeverityLevel));
980  LoggerBaseHelperStatic2<
981  Derived, Level,
983  >::test_and_call_emit_log(
984  loggerbase, origin, args...
985  );
986  }
987  };
988 
989 
990 } // namespace tomo_internal
991 
992 
993 template<typename Derived>
994 inline void LoggerBase<Derived>::error(const char * origin, const char * fmt, ...)
995 {
996  va_list ap;
997  va_start(ap, fmt);
998  derived()->template log<ERROR>(origin, fmt, ap);
999  va_end(ap);
1000 }
1001 
1002 template<typename Derived>
1003 inline void LoggerBase<Derived>::error(const char * origin, const std::string & msg)
1004 {
1005  derived()->template log<ERROR>(origin, msg);
1006 }
1007 
1008 template<typename Derived>
1009 template<typename Fn>
1010 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1011 LoggerBase<Derived>::error(const char * origin, Fn f)
1012 {
1013  derived()->template log<ERROR>(origin, f);
1014 }
1015 
1016 
1017 template<typename Derived>
1018 inline void LoggerBase<Derived>::warning(const char * origin, const char * fmt, ...)
1019 {
1020  va_list ap;
1021  va_start(ap, fmt);
1022  derived()->template log<WARNING>(origin, fmt, ap);
1023  va_end(ap);
1024 }
1025 
1026 template<typename Derived>
1027 inline void LoggerBase<Derived>::warning(const char * origin, const std::string & msg)
1028 {
1029  derived()->template log<WARNING>(origin, msg);
1030 }
1031 
1032 template<typename Derived>
1033 template<typename Fn>
1034 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1035 LoggerBase<Derived>::warning(const char * origin, Fn f)
1036 {
1037  derived()->template log<WARNING>(origin, f);
1038 }
1039 
1040 template<typename Derived>
1041 inline void LoggerBase<Derived>::info(const char * origin, const char * fmt, ...)
1042 {
1043  va_list ap;
1044  va_start(ap, fmt);
1045  derived()->template log<INFO>(origin, fmt, ap);
1046  va_end(ap);
1047 }
1048 
1049 template<typename Derived>
1050 inline void LoggerBase<Derived>::info(const char * origin, const std::string & msg)
1051 {
1052  derived()->template log<INFO>(origin, msg);
1053 }
1054 
1055 template<typename Derived>
1056 template<typename Fn>
1057 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1058 LoggerBase<Derived>::info(const char * origin, Fn f)
1059 {
1060  derived()->template log<INFO>(origin, f);
1061 }
1062 
1063 template<typename Derived>
1064 inline void LoggerBase<Derived>::debug(const char * origin, const char * fmt, ...)
1065 {
1066  va_list ap;
1067  va_start(ap, fmt);
1068  derived()->template log<DEBUG>(origin, fmt, ap);
1069  va_end(ap);
1070 }
1071 
1072 template<typename Derived>
1073 inline void LoggerBase<Derived>::debug(const char * origin, const std::string & msg)
1074 {
1075  derived()->template log<DEBUG>(origin, msg);
1076 }
1077 
1078 template<typename Derived>
1079 template<typename Fn>
1080 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1081 LoggerBase<Derived>::debug(const char * origin, Fn f)
1082 {
1083  derived()->template log<DEBUG>(origin, f);
1084 }
1085 
1086 template<typename Derived>
1087 inline void LoggerBase<Derived>::longdebug(const char * origin, const char * fmt, ...)
1088 {
1089  va_list ap;
1090  va_start(ap, fmt);
1091  derived()->template log<LONGDEBUG>(origin, fmt, ap);
1092  va_end(ap);
1093 }
1094 
1095 template<typename Derived>
1096 inline void LoggerBase<Derived>::longdebug(const char * origin, const std::string & msg)
1097 {
1098  derived()->template log<LONGDEBUG>(origin, msg);
1099 }
1100 
1101 template<typename Derived>
1102 template<typename Fn>
1103 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1104 LoggerBase<Derived>::longdebug(const char * origin, Fn f)
1105 {
1106  derived()->template log<LONGDEBUG>(origin, f);
1107 }
1108 
1109 
1110 template<typename Derived>
1111 inline void LoggerBase<Derived>::log(int level, const char * origin, const char * fmt, ...)
1112 {
1113  va_list ap;
1114  va_start(ap, fmt);
1115  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, fmt, ap);
1116  va_end(ap);
1117 }
1118 
1119 template<typename Derived>
1120 inline void LoggerBase<Derived>::log(int level, const char * origin, const std::string & msg)
1121 {
1122  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, msg);
1123 }
1124 
1125 template<typename Derived>
1126 template<typename Fn>
1127 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1128 LoggerBase<Derived>::log(int level, const char * origin, Fn f)
1129 {
1130  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, f);
1131 }
1132 
1133 
1134 template<typename Derived>
1135 template<int Level>
1136 inline void LoggerBase<Derived>::log(const char * origin, const char * fmt, ...)
1137 {
1138  va_list ap;
1139  va_start(ap, fmt);
1140  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, fmt, ap);
1141  va_end(ap);
1142 }
1143 
1144 template<typename Derived>
1145 template<int Level>
1146 inline void LoggerBase<Derived>::log(const char * origin, const char * fmt, va_list ap)
1147 {
1148  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, fmt, ap);
1149 }
1150 
1151 template<typename Derived>
1152 template<int Level>
1153 inline void LoggerBase<Derived>::log(const char * origin, const std::string & msg)
1154 {
1155  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, msg);
1156 }
1157 
1158 template<typename Derived>
1159 template<int Level, typename Fn>
1160 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1161 LoggerBase<Derived>::log(const char * origin, Fn f)
1162 {
1163  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, f);
1164 }
1165 
1166 
1167 
1168 
1169 class FileLogger;
1174 template<>
1176 {
1178  enum {
1179  IsThreadSafe = 1
1180  };
1181 };
1182 
1193 TOMOGRAPHER_EXPORT class FileLogger : public LoggerBase<FileLogger>
1194 {
1195 public:
1196  FileLogger(FILE * fp_, int level = INFO, bool display_origin_ = true)
1197  : LoggerBase<FileLogger>(level), fp(fp_), display_origin(display_origin_)
1198  {
1199  }
1200 
1204  inline void setFp(FILE * fp_)
1205  {
1206  fp = fp_;
1207  }
1208 
1212  inline void setLevel(int level)
1213  {
1214  setLogLevel(level);
1215  }
1216 
1220  inline void setDisplayOrigin(bool display_origin_)
1221  {
1222  display_origin = display_origin_;
1223  }
1224 
1225  inline void emitLog(int level, const char * origin, const std::string & msg)
1226  {
1227  static const std::string level_prefixes[] = {
1228  std::string("\n\n*** ERROR -- "),
1229  std::string("\n*** Warning: ")
1230  };
1231 
1232  std::string finalmsg = (
1234  ? level_prefixes[level] : std::string() )
1235  + ((display_origin && origin && origin[0]) ? "["+std::string(origin)+"] " : std::string())
1236  + msg
1237  );
1238 
1239  // display the log message
1240  std::fprintf(fp, "%s\n", finalmsg.c_str());
1241 
1242  if (isAtLeastOfSeverity(level, WARNING)) {
1243  // force output also on stderr for warnings and errors if we are being redirected to a
1244  // file, or at least flush the buffer.
1245  std::fflush(fp);
1246  if (fp != stdout && fp != stderr) {
1247  std::fprintf(stderr, "%s\n", finalmsg.c_str());
1248  }
1249  }
1250  }
1251 
1252 private:
1253  std::FILE * fp;
1254  bool display_origin;
1255 };
1256 
1257 
1258 
1259 
1260 
1261 class VacuumLogger;
1266 template<>
1268 {
1270  enum {
1271  IsThreadSafe = 1,
1272  StaticMinimumSeverityLevel = -1
1273  };
1274 };
1275 
1280 TOMOGRAPHER_EXPORT class VacuumLogger : public LoggerBase<VacuumLogger>
1281 {
1282 public:
1283  inline void emitLog(int /*level*/, const char * /*origin*/, const std::string & /*msg*/)
1284  {
1285  }
1286 
1287 };
1288 
1294 static VacuumLogger vacuum_logger;
1295 
1296 
1297 
1298 
1299 class BufferLogger;
1304 template<>
1306 {
1308  enum {
1309  IsThreadSafe = 0
1310  };
1311 };
1312 
1318 TOMOGRAPHER_EXPORT class BufferLogger : public LoggerBase<BufferLogger>
1319 {
1320  std::ostringstream buffer;
1321 public:
1322  BufferLogger(int level)
1324  {
1325  }
1326 
1327  inline void emitLog(int /*level*/, const char * origin, const std::string& msg)
1328  {
1329  buffer << (origin&&origin[0] ? "["+std::string(origin)+"] " : std::string())
1330  << msg.c_str() << "\n";
1331  }
1332 
1337  inline void setLevel(int level)
1338  {
1339  setLogLevel(level);
1340  }
1341 
1347  inline void clear()
1348  {
1349  buffer.clear();
1350  buffer.str(std::string());
1351  }
1352 
1357  inline std::string getContents() const
1358  {
1359  return buffer.str();
1360  }
1361 };
1362 
1363 
1364 
1365 
1366 template<typename, int> class MinimumSeverityLogger;
1369 template<typename BaseLogger, int Level>
1370 struct LoggerTraits<MinimumSeverityLogger<BaseLogger,Level> > : public LoggerTraits<BaseLogger>
1371 {
1373  enum {
1374 
1376  StaticMinimumSeverityLevel = Level,
1377 
1379  HasOwnGetLevel = 1
1380 
1381  // Note: filter by origin flag is inherited from base logger.
1382  };
1383 };
1384 
1394 template<typename BaseLogger, int Level>
1395 TOMOGRAPHER_EXPORT class MinimumSeverityLogger : public LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >
1396 {
1398  BaseLogger & baselogger;
1399 public:
1405  MinimumSeverityLogger(BaseLogger & baselogger_)
1406  : LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >(), baselogger(baselogger_)
1407  {
1408  }
1409 
1411  inline void emitLog(int level, const char * origin, const std::string& msg)
1412  {
1413  baselogger.emitLog(level, origin, msg);
1414  }
1415 
1417  inline int level() const
1418  {
1419  return baselogger.level();
1420  }
1421 
1423  template<bool dummy = true>
1425  filterByOrigin(int level, const char * origin)
1426  {
1427  return baselogger.filterByOrigin(level, origin);
1428  }
1429 };
1430 
1431 
1432 namespace tomo_internal {
1433 
1439 inline std::size_t matched_length(const std::string & s, const std::string & pattern)
1440 {
1441  std::size_t k = 0;
1442  while (s[k] == pattern[k]) {
1443  ++k;
1444  }
1445  return k;
1446 }
1447 
1448 } // namespace tomo_internal
1449 
1450 template<typename BaseLogger> class OriginFilteredLogger;
1454 template<typename BaseLogger>
1455 struct LoggerTraits<OriginFilteredLogger<BaseLogger> > : public LoggerTraits<BaseLogger>
1456 {
1458  enum {
1459  HasOwnGetLevel = 1,
1460  HasFilterByOrigin = 1
1461  };
1462 };
1463 
1484 template<typename BaseLogger>
1485 TOMOGRAPHER_EXPORT class OriginFilteredLogger
1486  : public Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >
1487 {
1489  BaseLogger & baselogger;
1490 
1492  std::map<std::string,int> levels_set;
1493 public:
1494 
1500  OriginFilteredLogger(BaseLogger & baselogger_)
1501  : Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >(),
1502  baselogger(baselogger_),
1503  levels_set()
1504  {
1505  }
1506 
1516  inline void setDomainLevel(const std::string& origin_pattern, int level)
1517  {
1518  levels_set[origin_pattern] = level;
1519  }
1520 
1526  inline void removeDomainSetting(const std::string& s)
1527  {
1528  auto it = levels_set.find(s);
1529  if (it == levels_set.end()) {
1530  this->warning("OriginFilteredLogger<BaseLogger>::removeDomainSetting", "domain not set: `%s'", s.c_str());
1531  return;
1532  }
1533  levels_set.erase(it);
1534  }
1535 
1544  inline int level() const
1545  {
1546  return LOWEST_SEVERITY_LEVEL;
1547  }
1548 
1553  inline void emitLog(int level, const char * origin, const std::string& msg)
1554  {
1555  baselogger.emitLog(level, origin, msg);
1556  }
1557 
1565  inline bool filterByOrigin(int level, const char * origin) const
1566  {
1567  typedef std::map<std::string, int>::const_iterator ConstIterator;
1568 
1569  std::string s(origin);
1570 
1571  int loglevel = -1;
1572  std::size_t last_matched_length = 0;
1573  for (ConstIterator it = levels_set.begin(); it != levels_set.end(); ++it) {
1574  const std::size_t mlen = tomo_internal::matched_length((*it).first, s);
1575  if (mlen > last_matched_length) {
1576  loglevel = (*it).second;
1577  last_matched_length = mlen;
1578  }
1579  }
1580  if (loglevel == -1) {
1581  // default logger level
1582  loglevel = baselogger.level();
1583  }
1584  return isAtLeastOfSeverity(level, loglevel);
1585  }
1586 
1587 };
1588 
1589 
1590 
1591 
1592 
1593 // --------------------------------------------------
1594 
1595 
1596 
1597 
1598 
1607 
1610  : origin_prefix(s), origin_prefix_add(""), glue(gl) { }
1612  constexpr LocalLoggerOriginSpec(const Tools::conststr& s, const Tools::conststr& s2, const Tools::conststr& gl)
1613  : origin_prefix(s), origin_prefix_add(s2), glue(gl) { }
1614 };
1615 
1616 namespace tomo_internal {
1618 struct extractTomoOrigin_helper {
1619  static inline constexpr LocalLoggerOriginSpec step2(const Tools::conststr fn, std::size_t last_doublecolons,
1620  std::size_t after_prelast_doublecolons)
1621  {
1622  return ( fn.substr_e(after_prelast_doublecolons, last_doublecolons) == fn.substr(last_doublecolons+2)
1623  // fn is a constructor, so keep class name and use "::" as glue
1624  ? LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "::")
1625  // looks like a method name. Strip off the class name. Also use an internal
1626  // glue to indicate a logical level.
1627  : LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "()", "/")
1628  );
1629  }
1630  static inline constexpr std::size_t afterprelast_doublecolons(std::size_t prelast_doublecolons_found)
1631  {
1632  return (prelast_doublecolons_found == std::string::npos) ? 0 : prelast_doublecolons_found+2;
1633  }
1634  static inline constexpr LocalLoggerOriginSpec step1(const Tools::conststr fn, std::size_t last_doublecolons)
1635  {
1636  return last_doublecolons == std::string::npos || last_doublecolons == 0
1637  ? LocalLoggerOriginSpec(fn, "()", "/") // looks like simple function name with no parent scope
1638  : step2(fn, last_doublecolons, afterprelast_doublecolons(fn.rfind("::", last_doublecolons-1)));
1639  }
1640 
1641  static inline constexpr LocalLoggerOriginSpec extract_from_func_name(const Tools::conststr fn)
1642  {
1643  return step1(fn, fn.rfind("::"));
1644  }
1645 };
1646 
1648 constexpr const LocalLoggerOriginSpec extractTomoOrigin(const Tools::conststr fn)
1649 {
1650  return extractTomoOrigin_helper::extract_from_func_name(Tomographer::Tools::extractFuncName(fn));
1651 }
1652 
1653 } // namespace tomo_internal
1654 
1655 
1660 #define TOMO_ORIGIN Tomographer::Logger::tomo_internal::extractTomoOrigin(TOMO_FUNCTION)
1661 
1662 
1663 
1664 
1665 template<typename BaseLoggerType_> class LocalLogger;
1666 
1667 
1668 namespace tomo_internal {
1670 template<typename BaseLoggerType>
1671 struct is_local_logger {
1672  enum { value = 0 };
1673 };
1674 template<typename BaseLoggerType>
1675 struct is_local_logger<LocalLogger<BaseLoggerType> > {
1676  enum { value = 1 };
1677 };
1679 template<typename BaseLoggerType>
1680 struct local_logger_parent {
1681  typedef BaseLoggerType ParentType;
1682 };
1683 template<typename BaseLoggerType>
1684 struct local_logger_parent<LocalLogger<BaseLoggerType> > {
1685  typedef typename local_logger_parent<BaseLoggerType>::ParentType ParentType;
1686 };
1687 } // namespace tomo_internal
1688 
1690 template<typename BaseLoggerType_>
1691 struct LoggerTraits<LocalLogger<BaseLoggerType_> > : public LoggerTraits<BaseLoggerType_>
1692 {
1693  enum {
1695  HasOwnGetLevel = 1
1696  };
1697 };
1698 
1699 
1758 template<typename BaseLoggerType_>
1759 TOMOGRAPHER_EXPORT class LocalLogger
1760  : public LoggerBase<LocalLogger<BaseLoggerType_> >
1761 {
1762 public:
1764  typedef BaseLoggerType_ BaseLoggerType;
1765 
1766 private:
1768 
1770  const std::string _origin_prefix;
1772  const std::string _glue;
1773 
1774  BaseLoggerType & _baselogger;
1775 
1776 public:
1787  LocalLogger(const std::string & origin_fn_name, BaseLoggerType & logger_)
1788  : Base_(), _origin_prefix(origin_fn_name), _glue("::"), _baselogger(logger_)
1789  {
1790  this->longdebug("[begin]");
1791  }
1798  LocalLogger(const std::string & origin_prefix, const std::string & glue, BaseLoggerType & logger_)
1799  : Base_(), _origin_prefix(origin_prefix), _glue(glue), _baselogger(logger_)
1800  {
1801  this->longdebug("[begin]");
1802  }
1808  LocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & logger_)
1809  : Base_(), _origin_prefix(spec.origin_prefix.to_string()+spec.origin_prefix_add.to_string()),
1810  _glue(spec.glue.to_string()), _baselogger(logger_)
1811  {
1812  this->longdebug("[begin]");
1813  }
1814 
1819  : Base_(), _origin_prefix(std::move(movecopy._origin_prefix)), _glue(std::move(movecopy._glue)),
1820  _baselogger(movecopy._baselogger)
1821  {
1822  this->longdebug("[logger moved]");
1823  }
1825  LocalLogger(const LocalLogger & other)
1826  : Base_(), _origin_prefix(other._origin_prefix), _glue(other._glue),
1827  _baselogger(other._baselogger)
1828  {
1829  this->longdebug("[logger copied]");
1830  }
1831 
1832  ~LocalLogger()
1833  {
1834  this->longdebug("[done]");
1835  }
1836 
1845  inline std::string originPrefix() const { return _origin_prefix; }
1846 
1849  inline std::string glue() const { return _glue; }
1850 
1856  inline BaseLoggerType & baseLogger() { return _baselogger; }
1857 
1858 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
1859 
1864  typedef _PARENT_LOGGER_TYPE ParentLoggerType;
1865 
1873  ParentLoggerType & parentLogger() { }
1874 #else
1875 
1876  typedef typename tomo_internal::local_logger_parent<BaseLoggerType>::ParentType ParentLoggerType;
1877 
1879  inline ParentLoggerType & parentLogger()
1880  {
1881  return baseLogger();
1882  }
1884  inline ParentLoggerType & parentLogger() {
1885  return baseLogger().parentLogger();
1886  }
1887 #endif
1888 
1899  {
1900  return LocalLogger<LocalLogger<BaseLoggerType> >(new_prefix, *this);
1901  }
1909  const std::string & new_glue)
1910  {
1911  return LocalLogger<LocalLogger<BaseLoggerType> >(new_prefix, new_glue, *this);
1912  }
1919  {
1920  return LocalLogger<LocalLogger<BaseLoggerType> >(spec, *this);
1921  }
1922 
1927  PRINTF2_ARGS_SAFE inline void longdebug(const char * fmt, ...)
1928  { va_list ap; va_start(ap, fmt); log<LONGDEBUG>(fmt, ap); va_end(ap); }
1933  PRINTF2_ARGS_SAFE inline void debug(const char * fmt, ...)
1934  { va_list ap; va_start(ap, fmt); log<DEBUG>(fmt, ap); va_end(ap); }
1939  PRINTF2_ARGS_SAFE inline void info(const char * fmt, ...)
1940  { va_list ap; va_start(ap, fmt); log<INFO>(fmt, ap); va_end(ap); }
1945  PRINTF2_ARGS_SAFE inline void warning(const char * fmt, ...)
1946  { va_list ap; va_start(ap, fmt); log<WARNING>(fmt, ap); va_end(ap); }
1951  PRINTF2_ARGS_SAFE inline void error(const char * fmt, ...)
1952  { va_list ap; va_start(ap, fmt); log<ERROR>(fmt, ap); va_end(ap); }
1953 
1958  template<typename... Args>
1959  inline void longdebug(Args &&... a) { log<Tomographer::Logger::LONGDEBUG>(std::forward<Args>(a)...); }
1964  template<typename... Args>
1965  inline void debug(Args &&... a) { log<Tomographer::Logger::DEBUG>(std::forward<Args>(a)...); }
1970  template<typename... Args>
1971  inline void info(Args &&... a) { log<Tomographer::Logger::INFO>(std::forward<Args>(a)...); }
1976  template<typename... Args>
1977  inline void warning(Args &&... a) { log<Tomographer::Logger::WARNING>(std::forward<Args>(a)...); }
1982  template<typename... Args>
1983  inline void error(Args &&... a) { log<Tomographer::Logger::ERROR>(std::forward<Args>(a)...); }
1984 
1989  template<int Level, typename... Args>
1990  inline void log(Args... args)
1991  {
1992  Base_::template log<Level>("", args...);
1993  }
1994 
1995 
1996  // relay calls to base logger
1997 
2006  inline std::string getSubOrigin(const char * origin) const
2007  {
2008  return ( origin == NULL || origin[0] == 0
2009  ? _origin_prefix
2010  : _origin_prefix + _glue + origin );
2011  }
2012 
2014  inline void emitLog(int level, const char * origin, const std::string& msg)
2015  {
2016  // this might also be called if we have a sublogger. In that case, if we have a
2017  // sublogger, then use their prefix.
2018  _baselogger.emitLog(level, getSubOrigin(origin).c_str(), msg);
2019  }
2020 
2022  inline int level() const
2023  {
2024  return _baselogger.level();
2025  }
2026 
2029  inline bool filterByOrigin(int level, const char * origin)
2030  {
2031  return _baselogger.filterByOrigin(level, getSubOrigin(origin).c_str());
2032  }
2033 };
2034 
2035 
2036 
2053 template<typename BaseLoggerType>
2054 inline LocalLogger<BaseLoggerType> makeLocalLogger(const std::string & origin_fn_name, BaseLoggerType & baselogger)
2055 {
2056  return LocalLogger<BaseLoggerType>(origin_fn_name, baselogger);
2057 }
2058 
2064 template<typename BaseLoggerType>
2065 inline LocalLogger<BaseLoggerType> makeLocalLogger(const std::string & origin_prefix, const std::string & glue,
2066  BaseLoggerType & baselogger)
2067 {
2068  return LocalLogger<BaseLoggerType>(origin_prefix, glue, baselogger);
2069 }
2070 
2076 template<typename BaseLoggerType>
2077 inline LocalLogger<BaseLoggerType> makeLocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & baselogger)
2078 {
2079  return LocalLogger<BaseLoggerType>(spec, baselogger);
2080 }
2081 
2082 
2083 
2084 
2085 
2086 } // namespace Logger
2087 } // namespace Tomographer
2088 
2089 
2090 
2091 #endif
Utilities for formatting strings.
std::string originPrefix() const
The fixed origin specified at the constructor.
Definition: loggers.h:1845
Simple logger class which logs everything into a given FILE pointer.
Definition: loggers.h:1193
static bool staticallyEnabledFor(int level)
Check whether the logger is statically disabled for some levels.
Definition: loggers.h:732
Local logger: avoid having to repeat origin at each emitted message.
Definition: loggers.h:1665
Lowest severity possible.
Definition: loggers.h:140
void debug(Args &&... a)
Generate a log message with level Logger::DEBUG.
Definition: loggers.h:1965
void info(Args &&... a)
Generate a log message with level Logger::INFO.
Definition: loggers.h:1971
Log messages into an internal memory buffer.
Definition: loggers.h:1318
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:1612
void clear()
Clears the internal memory buffer.
Definition: loggers.h:1347
void setDomainLevel(const std::string &origin_pattern, int level)
Set a rule to log messages based on their origin.
Definition: loggers.h:1516
std::string vfmts(const char *fmt, va_list vl)
printf- formatting to a std::string, with va_list pointer
Definition: fmt.h:84
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log message (relay to base logger).
Definition: loggers.h:1553
LocalLogger< BaseLoggerType > makeLocalLogger(const std::string &origin_fn_name, BaseLoggerType &baselogger)
Create a local logger.
Definition: loggers.h:2054
void setLevel(std::string s)
Set the level to the given level name. See class doc.
Definition: loggers.h:203
LocalLogger(const std::string &origin_prefix, const std::string &glue, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1798
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:1111
Highest severity possible.
Definition: loggers.h:132
Error logging level.
Definition: loggers.h:84
const Tools::conststr glue
the glue to use in the local logger
Definition: loggers.h:1606
Logger that discards all messages.
Definition: loggers.h:1280
STL namespace.
Object which stores a log level and can initialize from a string.
Definition: loggers.h:159
T end(T... args)
Base logger class.
Definition: loggers.h:428
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:2022
void error(const char *origin, const char *fmt,...)
emit an error message
Definition: loggers.h:994
int level() const
Get the stored level code. See LogLevelCode.
Definition: loggers.h:171
bool filterByOrigin(int level, const char *origin) const
Message filtering by origin implementation.
Definition: loggers.h:1565
OriginFilteredLogger(BaseLogger &baselogger_)
Constructor based on a base logger reference.
Definition: loggers.h:1500
ParentLoggerType & parentLogger()
The parent logger responsible for actually emitting the messages in some useful way.
Definition: loggers.h:1873
STL class.
void setLevel(int level)
Set the level to the given level code. See class doc and LogLevelCode.
Definition: loggers.h:190
void removeDomainSetting(const std::string &s)
Remove a rule set by setDomainLevel()
Definition: loggers.h:1526
void longdebug(Args &&... a)
Generate a log message with level Logger::LONGDEBUG.
Definition: loggers.h:1959
void setLogLevel(int level)
Store a new run-time log level.
Definition: loggers.h:830
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:2006
std::string levelName() const
Get the stored level name.
Definition: loggers.h:177
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix)
Create a sub-logger.
Definition: loggers.h:1898
Helper for statically determining if Level is at least as severe as BaseLevel.
Definition: loggers.h:262
BaseLoggerType & baseLogger()
The base logger type specified to the constructor.
Definition: loggers.h:1856
std::string glue() const
The "glue" string to use to concatenate origins from sub-loggers.
Definition: loggers.h:1849
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:1417
bool enabledFor(int level_) const
Check whether messages at the given log level are enabled.
Definition: loggers.h:759
void warning(Args &&... a)
Generate a log message with level Logger::WARNING.
Definition: loggers.h:1977
Logger which statically discards any messages less important than a fixed severity.
Definition: loggers.h:1366
constexpr LocalLoggerOriginSpec(const Tools::conststr &s, const Tools::conststr &gl)
constructor. origin_prefix_add is left blank.
Definition: loggers.h:1609
BaseLoggerType_ BaseLoggerType
The base logger type (see class documentation)
Definition: loggers.h:1764
MinimumSeverityLogger(BaseLogger &baselogger_)
Constructor from a base logger.
Definition: loggers.h:1405
T erase(T... args)
void setDisplayOrigin(bool display_origin_)
Definition: loggers.h:1220
Tool to specify arguments to LocalLogger.
Definition: loggers.h:1600
void error(Args &&... a)
Generate a log message with level Logger::ERROR.
Definition: loggers.h:1983
const Tools::conststr origin_prefix
Origin prefix for the local logger.
Definition: loggers.h:1602
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:2014
T str(T... args)
std::ostream & operator<<(std::ostream &str, const LogLevel &l)
C++ output stream operator for LogLevel.
Definition: loggers.h:232
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix, const std::string &new_glue)
Create a sub-logger.
Definition: loggers.h:1908
void warning(const char *origin, const char *fmt,...)
emit a warning message
Definition: loggers.h:1018
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:1064
LocalLogger(const LocalLogger &other)
Make the local-logger copyable – there&#39;s nothing wrong with that.
Definition: loggers.h:1825
Default traits for Logger implementations.
Definition: loggers.h:289
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:1411
static bool staticallyEnabledFor()
Static version of staticallyEnabledFor()
Definition: loggers.h:741
T find(T... args)
void log(Args... args)
Generate a log message with level Level.
Definition: loggers.h:1990
void longdebug(const char *origin, const char *fmt,...)
emit a very verbose debugging message
Definition: loggers.h:1087
void setLevel(int level)
Changes the runtime log level to a new value.
Definition: loggers.h:1337
bool isAtLeastOfSeverity(int level, int baselevel)
Helper to compare severity levels.
Definition: loggers.h:249
void info(const char *origin, const char *fmt,...)
emit an information/notice message
Definition: loggers.h:1041
T begin(T... args)
Traits template struct to be specialized for specific Logger implementations.
Definition: loggers.h:352
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:93
_PARENT_LOGGER_TYPE ParentLoggerType
Type of the parent logger type, ultimately responsible for actually emitting the messages in some use...
Definition: loggers.h:1864
LocalLogger(const LocalLoggerOriginSpec &spec, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1808
std::istream & operator>>(std::istream &str, LogLevel &l)
C++ input stream operator for LogLevel.
Definition: loggers.h:224
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:1425
LoggerBase(int level_=INFO)
Construct the base logger object.
Definition: loggers.h:456
LogLevelCode
Possible logging levels.
Definition: loggers.h:77
const Tools::conststr origin_prefix_add
optionally some string to append to origin_prefix
Definition: loggers.h:1604
Long Debug logging level.
Definition: loggers.h:123
std::string getContents() const
get the contents of the internal buffer
Definition: loggers.h:1357
constexpr conststr extractFuncName(const conststr &funcname)
Extract the function name from its signature.
Definition: cxxutil.h:529
LogLevel(const char *s)
Construct a level using a string level name.
Definition: loggers.h:166
int level() const
Unconditionally return LOWEST_SEVERITY_LEVEL for the underlying logging engine.
Definition: loggers.h:1544
LogLevel(int level_=INFO)
Construct a level using an integer level code. See LogLevelCode.
Definition: loggers.h:164
int level() const
Get the log level set for this logger.
Definition: loggers.h:781
LogLevel(const std::string &s)
Construct a level using a string level name.
Definition: loggers.h:168
LocalLogger(const std::string &origin_fn_name, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1787
A constexpr string type.
Definition: conststr.h:55
T fprintf(T... args)
STL class.
LocalLogger(LocalLogger &&movecopy)
Definition: loggers.h:1818
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const LocalLoggerOriginSpec &spec)
Create a sub-logger.
Definition: loggers.h:1918
Debug logging level.
Definition: loggers.h:113
Information logging level.
Definition: loggers.h:101
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:83
A logger which filters entries according to where they originated from.
Definition: loggers.h:1450