Tomographer  v2.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) 2015 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_TOOLS_LOGGERS_H
28 #define TOMOGRAPHER_TOOLS_LOGGERS_H
29 
30 #include <cstdio>
31 #include <cstdarg>
32 
33 #include <string>
34 #include <sstream> // std::stringstream
35 #include <iostream>
36 #include <functional> // std::function
37 #include <type_traits> // std::enable_if
38 #include <map>
39 
40 #include <boost/algorithm/string.hpp> // to_upper()
41 
42 #include <tomographer2/tools/fmt.h>
44 
45 
54 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
55 
56 #define ENABLE_IF_Fn_CALLABLE_OSTREAM \
57  typename std::enable_if<std::is_convertible<Fn,std::function<void(std::ostream&)> >::value, void>::type
58 
59 #endif
60 
61 
62 namespace Tomographer
63 {
64 
68 namespace Logger
69 {
70 
77 {
83  ERROR = 0,
84 
93 
101 
113 
123 
124 
132 
140 };
141 
142 
143 
158 class LogLevel
159 {
160  int _level;
161 public:
163  LogLevel(int level_ = INFO) { setLevel(level_); }
165  LogLevel(const char * s) { setLevel(s); }
167  LogLevel(const std::string& s) { setLevel(s); }
168 
170  inline int level() const { return _level; }
171 
173  inline operator int() const { return _level; }
174 
176  inline std::string levelName() const
177  {
178  switch (_level) {
179  case LONGDEBUG: return std::string("LONGDEBUG");
180  case DEBUG: return std::string("DEBUG");
181  case INFO: return std::string("INFO");
182  case WARNING: return std::string("WARNING");
183  case ERROR: return std::string("ERROR");
184  default: return std::string("<INVALID LEVEL>");
185  };
186  }
187 
189  inline void setLevel(int level)
190  {
191  if (level != LONGDEBUG &&
192  level != DEBUG &&
193  level != INFO &&
194  level != WARNING &&
195  level != ERROR) {
196  throw std::invalid_argument("Invalid level code: "+std::to_string(level));
197  }
198  _level = level;
199  }
200 
202  inline void setLevel(std::string s)
203  {
204  // NOT const string `s`! we need our copy for to_upper():
205  boost::to_upper(s);
206  if (s == "LONGDEBUG") {
207  _level = LONGDEBUG;
208  } else if (s == "DEBUG") {
209  _level = DEBUG;
210  } else if (s == "INFO") {
211  _level = INFO;
212  } else if (s == "WARNING") {
213  _level = WARNING;
214  } else if (s == "ERROR") {
215  _level = ERROR;
216  } else {
217  throw std::invalid_argument("Invalid log level: '"+s+"'");
218  }
219  }
220 };
221 
224 {
225  std::string s;
226  str >> s;
227  l.setLevel(s);
228  return str;
229 }
231 inline std::ostream & operator<<(std::ostream & str, const LogLevel &l)
232 {
233  return str << l.levelName();
234 }
235 
236 
237 
248 inline bool isAtLeastOfSeverity(int level, int baselevel)
249 {
250  return (level <= baselevel);
251 }
252 
260 template<int Level, int BaseLevel>
262  enum {
263  value = (Level <= BaseLevel)
264  };
265 };
266 
267 
289 {
290  enum {
296  IsThreadSafe = 0,
297 
310  StaticMinimumSeverityLevel = LOWEST_SEVERITY_LEVEL,
311 
323  HasOwnGetLevel = 0,
324 
337  HasFilterByOrigin = 0
338  };
339 };
340 
350 template<typename LoggerType>
352 {
353  // by default, contains nothing and will produce errors if used unspecialized.
354 };
355 
356 
357 
358 namespace tomo_internal {
362 template<bool hasOwnGetLevel>
363 class LoggerRuntimeLevel {
364 public:
365  LoggerRuntimeLevel(int level)
366  : _level(level)
367  {
368  }
369 
370  inline int level() const
371  {
372  return _level;
373  }
374 
375 protected:
376  inline void setLogLevel(int level)
377  {
378  _level = level;
379  }
380 
381 private:
382  int _level;
383 };
384 //
385 // Specialization for those classes which provide their own level() method. Do nothing.
386 //
387 template<>
388 class LoggerRuntimeLevel<true> {
389 public:
390  LoggerRuntimeLevel(int /*level*/)
391  {
392  }
393 
394  inline void setLogLevel(int) {
395  tomographer_assert(0 && "Call to LoggerRuntimeLevel::setLogLevel() for Logger which defines HasOwnGetLevel=1!");
396  }
397 };
398 }
399 
400 
426 template<typename Derived>
428 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
429  : public tomo_internal::LoggerRuntimeLevel<LoggerTraits<Derived>::HasOwnGetLevel>
430 #endif
431 {
432 public:
435  enum {
444  };
445 
455  LoggerBase(int level_ = INFO)
456  : tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>(level_)
457  {
458  }
459 
467  PRINTF3_ARGS_SAFE
468  inline void error(const char * origin, const char * fmt, ...);
476  inline void error(const char * origin, const std::string & msg);
483  template<typename Fn>
484  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
485  error(const char * origin, Fn f);
486 
494  PRINTF3_ARGS_SAFE
495  inline void warning(const char * origin, const char * fmt, ...);
503  inline void warning(const char * origin, const std::string & msg);
510  template<typename Fn>
511  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
512  warning(const char * origin, Fn f);
513 
521  PRINTF3_ARGS_SAFE
522  inline void info(const char * origin, const char * fmt, ...);
530  inline void info(const char * origin, const std::string & msg);
537  template<typename Fn>
538  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
539  info(const char * origin, Fn f);
540 
558  PRINTF3_ARGS_SAFE
559  inline void debug(const char * origin, const char * fmt, ...);
560 
577  inline void debug(const char * origin, const std::string & msg);
606  template<typename Fn>
607  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
608  debug(const char * origin, Fn f);
609 
617  PRINTF3_ARGS_SAFE
618  inline void longdebug(const char * origin, const char * fmt, ...);
626  inline void longdebug(const char * origin, const std::string & msg);
633  template<typename Fn>
634  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
635  longdebug(const char * origin, Fn f);
636 
637 
647  PRINTF4_ARGS_SAFE
648  inline void log(int level, const char * origin, const char * fmt, ...);
658  inline void log(int level, const char * origin, const std::string & msg);
668  template<typename Fn>
669  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
670  log(int level, const char * origin, Fn f);
671 
672 
673 
682  template<int Level>
683  PRINTF3_ARGS_SAFE
684  inline void log(const char * origin, const char * fmt, ...);
694  template<int Level>
695  inline void log(const char * origin, const char * fmt, va_list ap);
704  template<int Level>
705  inline void log(const char * origin, const std::string & msg);
714  template<int Level, typename Fn>
715  inline ENABLE_IF_Fn_CALLABLE_OSTREAM
716  log(const char * origin, Fn f);
717 
718 
731  static inline bool staticallyEnabledFor(int level)
732  {
733  return ( isAtLeastOfSeverity(level, StaticMinimumSeverityLevel) );
734  }
735 
739  template<int Level>
740  static inline bool staticallyEnabledFor()
741  {
742  return ( StaticIsAtLeastOfSeverity<
743  Level,
744  StaticMinimumSeverityLevel
745  >::value ) ;
746  }
747 
758  inline bool enabledFor(int level_) const
759  {
760  return derived()->staticallyEnabledFor(level_) &&
761  isAtLeastOfSeverity(level_, getLevel());
762  };
763 
764 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
765  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
766  // exposed in the case where the logger doesn't define its own method. This is important
767  // to avoid "ambiguous calls to `level()`".
768 
780  inline int level() const
781  {
782  }
783 #endif
784 
785 
786 protected:
787 
788  // version in case we store our own level
789  TOMOGRAPHER_ENABLED_IF(!HasOwnGetLevel)
790  inline int getLevel() const
791  {
792  // use base class' implementation
793  return tomo_internal::LoggerRuntimeLevel<HasOwnGetLevel>::level();
794  }
795  // version in case we delegate to derived class' level()
796  TOMOGRAPHER_ENABLED_IF(HasOwnGetLevel)
797  inline int getLevel() const
798  {
799  return derived()->level();
800  }
801 
802 
803  inline Derived * derived()
804  {
805  return static_cast<Derived*>(this);
806  }
807  inline const Derived * derived() const
808  {
809  return static_cast<const Derived*>(this);
810  }
811 
812 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
813  // this method is actually implemented by the base class LoggerRuntimeLevel, and is only
814  // exposed in the case where the logger can actually set a new level.
815 
829  inline void setLogLevel(int level)
830  {
831  }
832 #endif
833 
834 private:
835 };
836 
837 
838 namespace tomo_internal {
841  template<typename Derived, bool derivedHasFilterByOrigin>
842  struct LoggerBaseHelperFilterByOrigin {
843  static inline bool test_logger_filter(LoggerBase<Derived> * /*loggerbase*/, int /*level*/,
844  const char * /*origin*/)
845  {
846  // do nothing by default
847  return true;
848  }
849  };
850  //
851  // specialization for loggers with filtering by origin
852  //
853  template<typename Derived>
854  struct LoggerBaseHelperFilterByOrigin<Derived, true> {
855  static inline bool test_logger_filter(LoggerBase<Derived> * loggerbase, int level,
856  const char * origin)
857  {
858  return static_cast<const Derived*>(loggerbase)->filterByOrigin(level, origin);
859  }
860  };
866  template<typename Derived>
867  struct LoggerBaseHelperDynamic {
868  static inline void call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
869  const std::string & msg) throw()
870  {
871  try {
872  //printf("Calling emit_log(%d,\"%s\",\"%s\") on object %p\n", level, origin, msg.c_str(), loggerbase);
873  static_cast<Derived*>(loggerbase)->emitLog(level, origin, msg);
874  } catch (const std::exception & e) {
875  std::fprintf(stderr,
876  "Warning in LoggerBaseHelperDynamic::call_emit_log(%d, \"%s\", msg):"
877  " Exception caught: %s\n",
878  level, origin, e.what());
879  }
880  }
881  static inline bool test_should_emit(LoggerBase<Derived> * loggerbase, int level, const char * origin)
882  {
883  if ( ! static_cast<const Derived*>(loggerbase)->enabledFor(level) ) {
884  return false;
885  }
886  if ( ! LoggerBaseHelperFilterByOrigin<Derived, LoggerTraits<Derived>::HasFilterByOrigin>
887  ::test_logger_filter(loggerbase, level, origin) ) {
888  return false;
889  }
890  return true;
891  }
892 
893  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
894  const std::string & msg) throw()
895  {
896  if ( ! test_should_emit(loggerbase, level, origin) ) {
897  return;
898  }
899 
900  call_emit_log(loggerbase, level, origin, msg);
901  }
902  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin,
903  const char * fmt, va_list ap) throw()
904  {
905  if ( ! test_should_emit(loggerbase, level, origin) ) {
906  return;
907  }
908 
909  try {
910  const std::string msg = Tools::vfmts(fmt, ap);
911  call_emit_log(loggerbase, level, origin, msg);
912  } catch (const std::exception & e) {
913  std::fprintf(stderr,
914  "Warning in LoggerBase::test_and_call_emit_log(%d, \"%s\", \"%s\", ...):"
915  " Exception caught for vfmts(): %s\n",
916  level, origin, fmt, e.what());
917  }
918  }
919  template<typename Fn>
920  static inline
921  ENABLE_IF_Fn_CALLABLE_OSTREAM
922  test_and_call_emit_log(LoggerBase<Derived> * loggerbase, int level, const char * origin, Fn f) throw()
923  {
924  if ( ! test_should_emit(loggerbase, level, origin) ) {
925  return;
926  }
927 
928  try {
929  std::ostringstream sstr;
930  f(sstr);
931  call_emit_log(loggerbase, level, origin, sstr.str());
932  } catch (const std::exception & e) {
933  std::fprintf(stderr, "Warning in LoggerBase::test_and_call_emit_log(%d, \"%s\", f(ostream)):"
934  " Exception caught: %s\n",
935  level, origin, e.what());
936  }
937  }
938  };
939 
946  template<typename Derived, int Level, bool isStaticallyDiscarded = false>
947  struct LoggerBaseHelperStatic2 {
948  template<typename... Args>
949  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, const char * origin,
950  Args... args) throw()
951  {
952  LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(loggerbase, Level, origin, args...);
953  }
954  };
955  // specialization for calls where the message should be statically discarded
956  template<typename Derived, int Level>
957  struct LoggerBaseHelperStatic2<Derived, Level, true> {
958  template<typename... Args>
959  static inline void test_and_call_emit_log(LoggerBase<Derived> *, const char *, Args...) throw()
960  {
961  // discard logging message.
962  }
963  };
964 
968  template<typename Derived, int Level>
969  struct LoggerBaseHelperStatic {
970  template<typename... Args>
971  static inline void test_and_call_emit_log(LoggerBase<Derived> * loggerbase, const char * origin,
972  Args... args) throw()
973  {
974  // call the default or specialized version of our second helper, which will either
975  // relay the call the dynamic version or discard the message.
976  //std::fprintf(stderr,
977  // "LoggerBaseHelperStatic<Derived,Level=%d>::test_and_call_emit_log(...). StaticMinimumSeverityLevel=%d\n",
978  // (int)Level, (int)(LoggerTraits<Derived>::StaticMinimumSeverityLevel));
979  LoggerBaseHelperStatic2<
980  Derived, Level,
982  >::test_and_call_emit_log(
983  loggerbase, origin, args...
984  );
985  }
986  };
987 
988 
989 } // namespace tomo_internal
990 
991 
992 template<typename Derived>
993 inline void LoggerBase<Derived>::error(const char * origin, const char * fmt, ...)
994 {
995  va_list ap;
996  va_start(ap, fmt);
997  derived()->template log<ERROR>(origin, fmt, ap);
998  va_end(ap);
999 }
1000 
1001 template<typename Derived>
1002 inline void LoggerBase<Derived>::error(const char * origin, const std::string & msg)
1003 {
1004  derived()->template log<ERROR>(origin, msg);
1005 }
1006 
1007 template<typename Derived>
1008 template<typename Fn>
1009 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1010 LoggerBase<Derived>::error(const char * origin, Fn f)
1011 {
1012  derived()->template log<ERROR>(origin, f);
1013 }
1014 
1015 
1016 template<typename Derived>
1017 inline void LoggerBase<Derived>::warning(const char * origin, const char * fmt, ...)
1018 {
1019  va_list ap;
1020  va_start(ap, fmt);
1021  derived()->template log<WARNING>(origin, fmt, ap);
1022  va_end(ap);
1023 }
1024 
1025 template<typename Derived>
1026 inline void LoggerBase<Derived>::warning(const char * origin, const std::string & msg)
1027 {
1028  derived()->template log<WARNING>(origin, msg);
1029 }
1030 
1031 template<typename Derived>
1032 template<typename Fn>
1033 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1034 LoggerBase<Derived>::warning(const char * origin, Fn f)
1035 {
1036  derived()->template log<WARNING>(origin, f);
1037 }
1038 
1039 template<typename Derived>
1040 inline void LoggerBase<Derived>::info(const char * origin, const char * fmt, ...)
1041 {
1042  va_list ap;
1043  va_start(ap, fmt);
1044  derived()->template log<INFO>(origin, fmt, ap);
1045  va_end(ap);
1046 }
1047 
1048 template<typename Derived>
1049 inline void LoggerBase<Derived>::info(const char * origin, const std::string & msg)
1050 {
1051  derived()->template log<INFO>(origin, msg);
1052 }
1053 
1054 template<typename Derived>
1055 template<typename Fn>
1056 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1057 LoggerBase<Derived>::info(const char * origin, Fn f)
1058 {
1059  derived()->template log<INFO>(origin, f);
1060 }
1061 
1062 template<typename Derived>
1063 inline void LoggerBase<Derived>::debug(const char * origin, const char * fmt, ...)
1064 {
1065  va_list ap;
1066  va_start(ap, fmt);
1067  derived()->template log<DEBUG>(origin, fmt, ap);
1068  va_end(ap);
1069 }
1070 
1071 template<typename Derived>
1072 inline void LoggerBase<Derived>::debug(const char * origin, const std::string & msg)
1073 {
1074  derived()->template log<DEBUG>(origin, msg);
1075 }
1076 
1077 template<typename Derived>
1078 template<typename Fn>
1079 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1080 LoggerBase<Derived>::debug(const char * origin, Fn f)
1081 {
1082  derived()->template log<DEBUG>(origin, f);
1083 }
1084 
1085 template<typename Derived>
1086 inline void LoggerBase<Derived>::longdebug(const char * origin, const char * fmt, ...)
1087 {
1088  va_list ap;
1089  va_start(ap, fmt);
1090  derived()->template log<LONGDEBUG>(origin, fmt, ap);
1091  va_end(ap);
1092 }
1093 
1094 template<typename Derived>
1095 inline void LoggerBase<Derived>::longdebug(const char * origin, const std::string & msg)
1096 {
1097  derived()->template log<LONGDEBUG>(origin, msg);
1098 }
1099 
1100 template<typename Derived>
1101 template<typename Fn>
1102 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1103 LoggerBase<Derived>::longdebug(const char * origin, Fn f)
1104 {
1105  derived()->template log<LONGDEBUG>(origin, f);
1106 }
1107 
1108 
1109 template<typename Derived>
1110 inline void LoggerBase<Derived>::log(int level, const char * origin, const char * fmt, ...)
1111 {
1112  va_list ap;
1113  va_start(ap, fmt);
1114  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, fmt, ap);
1115  va_end(ap);
1116 }
1117 
1118 template<typename Derived>
1119 inline void LoggerBase<Derived>::log(int level, const char * origin, const std::string & msg)
1120 {
1121  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, msg);
1122 }
1123 
1124 template<typename Derived>
1125 template<typename Fn>
1126 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1127 LoggerBase<Derived>::log(int level, const char * origin, Fn f)
1128 {
1129  tomo_internal::LoggerBaseHelperDynamic<Derived>::test_and_call_emit_log(this, level, origin, f);
1130 }
1131 
1132 
1133 template<typename Derived>
1134 template<int Level>
1135 inline void LoggerBase<Derived>::log(const char * origin, const char * fmt, ...)
1136 {
1137  va_list ap;
1138  va_start(ap, fmt);
1139  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, fmt, ap);
1140  va_end(ap);
1141 }
1142 
1143 template<typename Derived>
1144 template<int Level>
1145 inline void LoggerBase<Derived>::log(const char * origin, const char * fmt, va_list ap)
1146 {
1147  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, fmt, ap);
1148 }
1149 
1150 template<typename Derived>
1151 template<int Level>
1152 inline void LoggerBase<Derived>::log(const char * origin, const std::string & msg)
1153 {
1154  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, msg);
1155 }
1156 
1157 template<typename Derived>
1158 template<int Level, typename Fn>
1159 inline ENABLE_IF_Fn_CALLABLE_OSTREAM
1160 LoggerBase<Derived>::log(const char * origin, Fn f)
1161 {
1162  tomo_internal::LoggerBaseHelperStatic<Derived, Level>::test_and_call_emit_log(this, origin, f);
1163 }
1164 
1165 
1166 
1167 
1168 class FileLogger;
1173 template<>
1175 {
1177  enum {
1178  IsThreadSafe = 1
1179  };
1180 };
1181 
1192 class FileLogger : public LoggerBase<FileLogger>
1193 {
1194 public:
1195  FileLogger(FILE * fp_, int level = INFO, bool display_origin_ = true)
1196  : LoggerBase<FileLogger>(level), fp(fp_), display_origin(display_origin_)
1197  {
1198  }
1199 
1203  inline void setFp(FILE * fp_)
1204  {
1205  fp = fp_;
1206  }
1207 
1211  inline void setLevel(int level)
1212  {
1213  setLogLevel(level);
1214  }
1215 
1219  inline void setDisplayOrigin(bool display_origin_)
1220  {
1221  display_origin = display_origin_;
1222  }
1223 
1224  inline void emitLog(int level, const char * origin, const std::string & msg)
1225  {
1226  static const std::string level_prefixes[] = {
1227  std::string("\n\n*** ERROR -- "),
1228  std::string("\n*** Warning: ")
1229  };
1230 
1231  std::string finalmsg = (
1233  ? level_prefixes[level] : std::string() )
1234  + ((display_origin && origin && origin[0]) ? "["+std::string(origin)+"] " : std::string())
1235  + msg
1236  );
1237 
1238  // display the log message
1239  std::fprintf(fp, "%s\n", finalmsg.c_str());
1240 
1241  if (isAtLeastOfSeverity(level, WARNING)) {
1242  // force output also on stderr for warnings and errors if we are being redirected to a
1243  // file, or at least flush the buffer.
1244  std::fflush(fp);
1245  if (fp != stdout && fp != stderr) {
1246  std::fprintf(stderr, "%s\n", finalmsg.c_str());
1247  }
1248  }
1249  }
1250 
1251 private:
1252  std::FILE * fp;
1253  bool display_origin;
1254 };
1255 
1256 
1257 
1258 
1259 
1260 class VacuumLogger;
1265 template<>
1267 {
1269  enum {
1270  IsThreadSafe = 1,
1271  StaticMinimumSeverityLevel = -1
1272  };
1273 };
1274 
1279 class VacuumLogger : public LoggerBase<VacuumLogger>
1280 {
1281 public:
1282  inline void emitLog(int /*level*/, const char * /*origin*/, const std::string & /*msg*/)
1283  {
1284  }
1285 
1286 };
1287 
1293 static VacuumLogger vacuum_logger;
1294 
1295 
1296 
1297 
1298 class BufferLogger;
1303 template<>
1305 {
1307  enum {
1308  IsThreadSafe = 0
1309  };
1310 };
1311 
1317 class BufferLogger : public LoggerBase<BufferLogger>
1318 {
1319  std::ostringstream buffer;
1320 public:
1321  BufferLogger(int level)
1323  {
1324  }
1325 
1326  inline void emitLog(int /*level*/, const char * origin, const std::string& msg)
1327  {
1328  buffer << (origin&&origin[0] ? "["+std::string(origin)+"] " : std::string())
1329  << msg.c_str() << "\n";
1330  }
1331 
1336  inline void setLevel(int level)
1337  {
1338  setLogLevel(level);
1339  }
1340 
1346  inline void clear()
1347  {
1348  buffer.clear();
1349  buffer.str(std::string());
1350  }
1351 
1356  inline std::string getContents() const
1357  {
1358  return buffer.str();
1359  }
1360 };
1361 
1362 
1363 
1364 
1365 template<typename, int> class MinimumSeverityLogger;
1368 template<typename BaseLogger, int Level>
1369 struct LoggerTraits<MinimumSeverityLogger<BaseLogger,Level> > : public LoggerTraits<BaseLogger>
1370 {
1372  enum {
1373 
1375  StaticMinimumSeverityLevel = Level,
1376 
1378  HasOwnGetLevel = 1
1379 
1380  // Note: filter by origin flag is inherited from base logger.
1381  };
1382 };
1383 
1393 template<typename BaseLogger, int Level>
1394 class MinimumSeverityLogger : public LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >
1395 {
1397  BaseLogger & baselogger;
1398 public:
1404  MinimumSeverityLogger(BaseLogger & baselogger_)
1405  : LoggerBase<MinimumSeverityLogger<BaseLogger,Level> >(), baselogger(baselogger_)
1406  {
1407  }
1408 
1410  inline void emitLog(int level, const char * origin, const std::string& msg)
1411  {
1412  baselogger.emitLog(level, origin, msg);
1413  }
1414 
1416  inline int level() const
1417  {
1418  return baselogger.level();
1419  }
1420 
1422  template<bool dummy = true>
1424  filterByOrigin(int level, const char * origin)
1425  {
1426  return baselogger.filterByOrigin(level, origin);
1427  }
1428 };
1429 
1430 
1431 namespace tomo_internal {
1432 
1438 inline int matched_length(const std::string & s, const std::string & pattern)
1439 {
1440  std::size_t k = 0;
1441  while (s[k] == pattern[k]) {
1442  ++k;
1443  }
1444  return k;
1445 }
1446 
1447 } // namespace tomo_internal
1448 
1449 template<typename BaseLogger> class OriginFilteredLogger;
1453 template<typename BaseLogger>
1454 struct LoggerTraits<OriginFilteredLogger<BaseLogger> > : public LoggerTraits<BaseLogger>
1455 {
1457  enum {
1458  HasOwnGetLevel = 1,
1459  HasFilterByOrigin = 1
1460  };
1461 };
1462 
1483 template<typename BaseLogger>
1484 class OriginFilteredLogger : public Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >
1485 {
1487  BaseLogger & baselogger;
1488 
1490  std::map<std::string,int> levels_set;
1491 public:
1492 
1498  OriginFilteredLogger(BaseLogger & baselogger_)
1499  : Tomographer::Logger::LoggerBase<OriginFilteredLogger<BaseLogger> >(),
1500  baselogger(baselogger_),
1501  levels_set()
1502  {
1503  }
1504 
1514  inline void setDomainLevel(const std::string& origin_pattern, int level)
1515  {
1516  levels_set[origin_pattern] = level;
1517  }
1518 
1524  inline void removeDomainSetting(const std::string& s)
1525  {
1526  auto it = levels_set.find(s);
1527  if (it == levels_set.end()) {
1528  this->warning("OriginFilteredLogger<BaseLogger>::removeDomainSetting", "domain not set: `%s'", s.c_str());
1529  return;
1530  }
1531  levels_set.erase(it);
1532  }
1533 
1542  inline int level() const
1543  {
1544  return LOWEST_SEVERITY_LEVEL;
1545  }
1546 
1551  inline void emitLog(int level, const char * origin, const std::string& msg)
1552  {
1553  baselogger.emitLog(level, origin, msg);
1554  }
1555 
1563  inline bool filterByOrigin(int level, const char * origin) const
1564  {
1565  typedef std::map<std::string, int>::const_iterator ConstIterator;
1566 
1567  std::string s(origin);
1568 
1569  int loglevel = -1;
1570  int last_matched_length = 0;
1571  for (ConstIterator it = levels_set.begin(); it != levels_set.end(); ++it) {
1572  const int mlen = tomo_internal::matched_length((*it).first, s);
1573  if (mlen > last_matched_length) {
1574  loglevel = (*it).second;
1575  last_matched_length = mlen;
1576  }
1577  }
1578  if (loglevel == -1) {
1579  // default logger level
1580  loglevel = baselogger.level();
1581  }
1582  return isAtLeastOfSeverity(level, loglevel);
1583  }
1584 
1585 };
1586 
1587 
1588 
1589 
1590 
1591 // --------------------------------------------------
1592 
1593 
1594 
1595 
1596 
1605 
1608  : origin_prefix(s), origin_prefix_add(""), glue(gl) { }
1610  constexpr LocalLoggerOriginSpec(const Tools::conststr& s, const Tools::conststr& s2, const Tools::conststr& gl)
1611  : origin_prefix(s), origin_prefix_add(s2), glue(gl) { }
1612 };
1613 
1614 namespace tomo_internal {
1616 struct extractTomoOrigin_helper {
1617  static inline constexpr LocalLoggerOriginSpec step2(const Tools::conststr fn, std::size_t last_doublecolons,
1618  std::size_t after_prelast_doublecolons)
1619  {
1620  return ( fn.substr_e(after_prelast_doublecolons, last_doublecolons) == fn.substr(last_doublecolons+2)
1621  // fn is a constructor, so keep class name and use "::" as glue
1622  ? LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "::")
1623  // looks like a method name. Strip off the class name. Also use an internal
1624  // glue to indicate a logical level.
1625  : LocalLoggerOriginSpec(fn.substr(last_doublecolons+2), "()", "/")
1626  );
1627  }
1628  static inline constexpr std::size_t afterprelast_doublecolons(std::size_t prelast_doublecolons_found)
1629  {
1630  return (prelast_doublecolons_found == std::string::npos) ? 0 : prelast_doublecolons_found+2;
1631  }
1632  static inline constexpr LocalLoggerOriginSpec step1(const Tools::conststr fn, std::size_t last_doublecolons)
1633  {
1634  return last_doublecolons == std::string::npos || last_doublecolons == 0
1635  ? LocalLoggerOriginSpec(fn, "()", "/") // looks like simple function name with no parent scope
1636  : step2(fn, last_doublecolons, afterprelast_doublecolons(fn.rfind("::", last_doublecolons-1)));
1637  }
1638 
1639  static inline constexpr LocalLoggerOriginSpec extract_from_func_name(const Tools::conststr fn)
1640  {
1641  return step1(fn, fn.rfind("::"));
1642  }
1643 };
1644 
1646 constexpr const LocalLoggerOriginSpec extractTomoOrigin(const Tools::conststr fn)
1647 {
1648  return extractTomoOrigin_helper::extract_from_func_name(Tomographer::Tools::extractFuncName(fn));
1649 }
1650 
1651 } // namespace tomo_internal
1652 
1653 
1658 #define TOMO_ORIGIN Tomographer::Logger::tomo_internal::extractTomoOrigin(TOMO_FUNCTION)
1659 
1660 
1661 
1662 
1663 template<typename BaseLoggerType_> class LocalLogger;
1664 
1665 
1666 namespace tomo_internal {
1668 template<typename BaseLoggerType>
1669 struct is_local_logger {
1670  enum { value = 0 };
1671 };
1672 template<typename BaseLoggerType>
1673 struct is_local_logger<LocalLogger<BaseLoggerType> > {
1674  enum { value = 1 };
1675 };
1677 template<typename BaseLoggerType>
1678 struct local_logger_parent {
1679  typedef BaseLoggerType ParentType;
1680 };
1681 template<typename BaseLoggerType>
1682 struct local_logger_parent<LocalLogger<BaseLoggerType> > {
1683  typedef typename local_logger_parent<BaseLoggerType>::ParentType ParentType;
1684 };
1685 } // namespace tomo_internal
1686 
1688 template<typename BaseLoggerType_>
1689 struct LoggerTraits<LocalLogger<BaseLoggerType_> > : public LoggerTraits<BaseLoggerType_>
1690 {
1691  enum {
1693  HasOwnGetLevel = 1
1694  };
1695 };
1696 
1697 
1756 template<typename BaseLoggerType_>
1757 class LocalLogger : public Tomographer::Logger::LoggerBase<LocalLogger<BaseLoggerType_> >
1758 {
1759 public:
1761  typedef BaseLoggerType_ BaseLoggerType;
1762 
1763 private:
1765 
1767  const std::string _origin_prefix;
1769  const std::string _glue;
1770 
1771  BaseLoggerType & _baselogger;
1772 
1773 public:
1784  LocalLogger(const std::string & origin_fn_name, BaseLoggerType & logger_)
1785  : _origin_prefix(origin_fn_name), _glue("::"), _baselogger(logger_)
1786  {
1787  }
1794  LocalLogger(const std::string & origin_prefix, const std::string & glue, BaseLoggerType & logger_)
1795  : _origin_prefix(origin_prefix), _glue(glue), _baselogger(logger_)
1796  {
1797  }
1803  LocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & logger_)
1804  : _origin_prefix(spec.origin_prefix.to_string()+spec.origin_prefix_add.to_string()),
1805  _glue(spec.glue.to_string()), _baselogger(logger_)
1806  {
1807  }
1808 
1813  : _origin_prefix(movecopy._origin_prefix), _glue(movecopy._glue),
1814  _baselogger(movecopy._baselogger)
1815  {
1816  }
1818  LocalLogger(const LocalLogger & other) = delete;
1819 
1828  inline std::string originPrefix() const { return _origin_prefix; }
1829 
1832  inline std::string glue() const { return _glue; }
1833 
1839  inline BaseLoggerType & baseLogger() { return _baselogger; }
1840 
1841 #ifdef TOMOGRAPHER_PARSED_BY_DOXYGEN
1842 
1847  typedef _PARENT_LOGGER_TYPE ParentLoggerType;
1848 
1856  ParentLoggerType & parentLogger() { }
1857 #else
1858 
1859  typedef typename tomo_internal::local_logger_parent<BaseLoggerType>::ParentType ParentLoggerType;
1860 
1862  inline ParentLoggerType & parentLogger()
1863  {
1864  return baseLogger();
1865  }
1867  inline ParentLoggerType & parentLogger() {
1868  return baseLogger().parentLogger();
1869  }
1870 #endif
1871 
1882  {
1883  return LocalLogger<LocalLogger<BaseLoggerType> >(new_prefix, *this);
1884  }
1892  const std::string & new_glue)
1893  {
1894  return LocalLogger<LocalLogger<BaseLoggerType> >(new_prefix, new_glue, *this);
1895  }
1902  {
1903  return LocalLogger<LocalLogger<BaseLoggerType> >(spec, *this);
1904  }
1905 
1910  PRINTF2_ARGS_SAFE inline void longdebug(const char * fmt, ...)
1911  { va_list ap; va_start(ap, fmt); log<LONGDEBUG>(fmt, ap); va_end(ap); }
1916  PRINTF2_ARGS_SAFE inline void debug(const char * fmt, ...)
1917  { va_list ap; va_start(ap, fmt); log<DEBUG>(fmt, ap); va_end(ap); }
1922  PRINTF2_ARGS_SAFE inline void info(const char * fmt, ...)
1923  { va_list ap; va_start(ap, fmt); log<INFO>(fmt, ap); va_end(ap); }
1928  PRINTF2_ARGS_SAFE inline void warning(const char * fmt, ...)
1929  { va_list ap; va_start(ap, fmt); log<WARNING>(fmt, ap); va_end(ap); }
1934  PRINTF2_ARGS_SAFE inline void error(const char * fmt, ...)
1935  { va_list ap; va_start(ap, fmt); log<ERROR>(fmt, ap); va_end(ap); }
1936 
1941  template<typename... Args>
1942  inline void longdebug(Args &&... a) { log<Tomographer::Logger::LONGDEBUG>(std::forward<Args>(a)...); }
1947  template<typename... Args>
1948  inline void debug(Args &&... a) { log<Tomographer::Logger::DEBUG>(std::forward<Args>(a)...); }
1953  template<typename... Args>
1954  inline void info(Args &&... a) { log<Tomographer::Logger::INFO>(std::forward<Args>(a)...); }
1959  template<typename... Args>
1960  inline void warning(Args &&... a) { log<Tomographer::Logger::WARNING>(std::forward<Args>(a)...); }
1965  template<typename... Args>
1966  inline void error(Args &&... a) { log<Tomographer::Logger::ERROR>(std::forward<Args>(a)...); }
1967 
1972  template<int Level, typename... Args>
1973  inline void log(Args... args)
1974  {
1975  Base_::template log<Level>("", args...);
1976  }
1977 
1978 
1979  // relay calls to base logger
1980 
1989  inline std::string getSubOrigin(const char * origin) const
1990  {
1991  return ( origin == NULL || origin[0] == 0
1992  ? _origin_prefix
1993  : _origin_prefix + _glue + origin );
1994  }
1995 
1997  inline void emitLog(int level, const char * origin, const std::string& msg)
1998  {
1999  // this might also be called if we have a sublogger. In that case, if we have a
2000  // sublogger, then use their prefix.
2001  _baselogger.emitLog(level, getSubOrigin(origin).c_str(), msg);
2002  }
2003 
2005  inline int level() const
2006  {
2007  return _baselogger.level();
2008  }
2009 
2012  inline bool filterByOrigin(int level, const char * origin)
2013  {
2014  return _baselogger.filterByOrigin(level, getSubOrigin(origin).c_str());
2015  }
2016 };
2017 
2018 
2019 
2036 template<typename BaseLoggerType>
2037 LocalLogger<BaseLoggerType> makeLocalLogger(const std::string & origin_fn_name, BaseLoggerType & baselogger)
2038 {
2039  return LocalLogger<BaseLoggerType>(origin_fn_name, baselogger);
2040 }
2041 
2047 template<typename BaseLoggerType>
2049  BaseLoggerType & baselogger)
2050 {
2051  return LocalLogger<BaseLoggerType>(origin_prefix, glue, baselogger);
2052 }
2053 
2059 template<typename BaseLoggerType>
2060 LocalLogger<BaseLoggerType> makeLocalLogger(const LocalLoggerOriginSpec & spec, BaseLoggerType & baselogger)
2061 {
2062  return LocalLogger<BaseLoggerType>(spec, baselogger);
2063 }
2064 
2065 
2066 
2067 
2068 
2069 } // namespace Logger
2070 } // namespace Tomographer
2071 
2072 
2073 
2074 #endif
Utilities for formatting strings.
Simple logger class which logs everything into a given FILE pointer.
Definition: loggers.h:1192
static bool staticallyEnabledFor(int level)
Check whether the logger is statically disabled for some levels.
Definition: loggers.h:731
Local logger: avoid having to repeat origin at each emitted message.
Definition: loggers.h:1663
Lowest severity possible.
Definition: loggers.h:139
Log messages into an internal memory buffer.
Definition: loggers.h:1317
Base namespace for the Tomographer project.
Definition: densellh.h:44
void debug(const char *fmt,...)
Generate a log message with level Logger::DEBUG (printf-like syntax)
Definition: loggers.h:1916
constexpr LocalLoggerOriginSpec(const Tools::conststr &s, const Tools::conststr &s2, const Tools::conststr &gl)
complete constructor.
Definition: loggers.h:1610
void clear()
Clears the internal memory buffer.
Definition: loggers.h:1346
std::string originPrefix() const
The fixed origin specified at the constructor.
Definition: loggers.h:1828
void debug(Args &&...a)
Generate a log message with level Logger::DEBUG.
Definition: loggers.h:1948
void setDomainLevel(const std::string &origin_pattern, int level)
Set a rule to log messages based on their origin.
Definition: loggers.h:1514
std::string vfmts(const char *fmt, va_list vl)
printf- formatting to a std::string, with va_list pointer
Definition: fmt.h:83
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log message (relay to base logger).
Definition: loggers.h:1551
LocalLogger< BaseLoggerType > makeLocalLogger(const std::string &origin_fn_name, BaseLoggerType &baselogger)
Create a local logger.
Definition: loggers.h:2037
void setLevel(std::string s)
Set the level to the given level name. See class doc.
Definition: loggers.h:202
int level() const
Get the log level set for this logger.
Definition: loggers.h:780
LocalLogger(const std::string &origin_prefix, const std::string &glue, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1794
std::string getContents() const
get the contents of the internal buffer
Definition: loggers.h:1356
void error(const char *fmt,...)
Generate a log message with level Logger::ERROR (printf-like syntax)
Definition: loggers.h:1934
std::string getSubOrigin(const char *origin) const
The full origin string to use for a sub-logger.
Definition: loggers.h:1989
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:1110
Highest severity possible.
Definition: loggers.h:131
Error logging level.
Definition: loggers.h:83
void longdebug(Args &&...a)
Generate a log message with level Logger::LONGDEBUG.
Definition: loggers.h:1942
const Tools::conststr glue
the glue to use in the local logger
Definition: loggers.h:1604
void log(Args...args)
Generate a log message with level Level.
Definition: loggers.h:1973
Logger that discards all messages.
Definition: loggers.h:1279
std::string glue() const
The "glue" string to use to concatenate origins from sub-loggers.
Definition: loggers.h:1832
Object which stores a log level and can initialize from a string.
Definition: loggers.h:158
T end(T...args)
Base logger class.
Definition: loggers.h:427
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:1416
void error(const char *origin, const char *fmt,...)
emit an error message
Definition: loggers.h:993
bool filterByOrigin(int level, const char *origin) const
Message filtering by origin implementation.
Definition: loggers.h:1563
OriginFilteredLogger(BaseLogger &baselogger_)
Constructor based on a base logger reference.
Definition: loggers.h:1498
ParentLoggerType & parentLogger()
The parent logger responsible for actually emitting the messages in some useful way.
Definition: loggers.h:1856
STL class.
void setLevel(int level)
Set the level to the given level code. See class doc and LogLevelCode.
Definition: loggers.h:189
void removeDomainSetting(const std::string &s)
Remove a rule set by setDomainLevel()
Definition: loggers.h:1524
void setLogLevel(int level)
Store a new run-time log level.
Definition: loggers.h:829
T fflush(T...args)
STL class.
void error(Args &&...a)
Generate a log message with level Logger::ERROR.
Definition: loggers.h:1966
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix)
Create a sub-logger.
Definition: loggers.h:1881
Helper for statically determining if Level is at least as severe as BaseLevel.
Definition: loggers.h:261
BaseLoggerType & baseLogger()
The base logger type specified to the constructor.
Definition: loggers.h:1839
T what(T...args)
void longdebug(const char *fmt,...)
Generate a log message with level Logger::LONGDEBUG (printf-like syntax)
Definition: loggers.h:1910
Logger which statically discards any messages less important than a fixed severity.
Definition: loggers.h:1365
constexpr LocalLoggerOriginSpec(const Tools::conststr &s, const Tools::conststr &gl)
constructor. origin_prefix_add is left blank.
Definition: loggers.h:1607
void warning(Args &&...a)
Generate a log message with level Logger::WARNING.
Definition: loggers.h:1960
int level() const
Get the base logger&#39;s set level.
Definition: loggers.h:2005
BaseLoggerType_ BaseLoggerType
The base logger type (see class documentation)
Definition: loggers.h:1761
MinimumSeverityLogger(BaseLogger &baselogger_)
Constructor from a base logger.
Definition: loggers.h:1404
T erase(T...args)
void setDisplayOrigin(bool display_origin_)
Definition: loggers.h:1219
Tool to specify arguments to LocalLogger.
Definition: loggers.h:1598
const Tools::conststr origin_prefix
Origin prefix for the local logger.
Definition: loggers.h:1600
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:1997
std::ostream & operator<<(std::ostream &str, const LogLevel &l)
C++ output stream operator for LogLevel.
Definition: loggers.h:231
void info(const char *fmt,...)
Generate a log message with level Logger::INFO (printf-like syntax)
Definition: loggers.h:1922
void info(Args &&...a)
Generate a log message with level Logger::INFO.
Definition: loggers.h:1954
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix, const std::string &new_glue)
Create a sub-logger.
Definition: loggers.h:1891
void warning(const char *origin, const char *fmt,...)
emit a warning message
Definition: loggers.h:1017
A constexpr string type, suitable for basic compile-time string processing.
T clear(T...args)
void debug(const char *origin, const char *fmt,...)
emit an debug message
Definition: loggers.h:1063
STL class.
Default traits for Logger implementations.
Definition: loggers.h:288
void emitLog(int level, const char *origin, const std::string &msg)
Emit a log by relaying to the base logger.
Definition: loggers.h:1410
static bool staticallyEnabledFor()
Static version of staticallyEnabledFor()
Definition: loggers.h:740
int level() const
Get the stored level code. See LogLevelCode.
Definition: loggers.h:170
T find(T...args)
void longdebug(const char *origin, const char *fmt,...)
emit a very verbose debugging message
Definition: loggers.h:1086
void setLevel(int level)
Changes the runtime log level to a new value.
Definition: loggers.h:1336
bool isAtLeastOfSeverity(int level, int baselevel)
Helper to compare severity levels.
Definition: loggers.h:248
void info(const char *origin, const char *fmt,...)
emit an information/notice message
Definition: loggers.h:1040
T begin(T...args)
Traits template struct to be specialized for specific Logger implementations.
Definition: loggers.h:351
VarValueDecoder< T >::RetType value(const Var &var)
Access the value of the given variable, as a C++ type.
Definition: ezmatio.h:854
T c_str(T...args)
Warning logging level.
Definition: loggers.h:92
bool enabledFor(int level_) const
Check whether messages at the given log level are enabled.
Definition: loggers.h:758
_PARENT_LOGGER_TYPE ParentLoggerType
Type of the parent logger type, ultimately responsible for actually emitting the messages in some use...
Definition: loggers.h:1847
LocalLogger(const LocalLoggerOriginSpec &spec, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1803
std::istream & operator>>(std::istream &str, LogLevel &l)
C++ input stream operator for LogLevel.
Definition: loggers.h:223
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:1424
LoggerBase(int level_=INFO)
Construct the base logger object.
Definition: loggers.h:455
LogLevelCode
Possible logging levels.
Definition: loggers.h:76
const Tools::conststr origin_prefix_add
optionally some string to append to origin_prefix
Definition: loggers.h:1602
Long Debug logging level.
Definition: loggers.h:122
constexpr conststr extractFuncName(const conststr &funcname)
Extract the function name from its signature.
Definition: cxxutil.h:584
LogLevel(const char *s)
Construct a level using a string level name.
Definition: loggers.h:165
LogLevel(int level_=INFO)
Construct a level using an integer level code. See LogLevelCode.
Definition: loggers.h:163
LogLevel(const std::string &s)
Construct a level using a string level name.
Definition: loggers.h:167
LocalLogger(const std::string &origin_fn_name, BaseLoggerType &logger_)
Construct a local logger.
Definition: loggers.h:1784
int level() const
Unconditionally return LOWEST_SEVERITY_LEVEL for the underlying logging engine.
Definition: loggers.h:1542
A constexpr string type.
Definition: conststr.h:54
T fprintf(T...args)
STL class.
LocalLogger(LocalLogger &&movecopy)
Definition: loggers.h:1812
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const LocalLoggerOriginSpec &spec)
Create a sub-logger.
Definition: loggers.h:1901
Debug logging level.
Definition: loggers.h:112
Information logging level.
Definition: loggers.h:100
std::string levelName() const
Get the stored level name.
Definition: loggers.h:176
A logger which filters entries according to where they originated from.
Definition: loggers.h:1449
void warning(const char *fmt,...)
Generate a log message with level Logger::WARNING (printf-like syntax)
Definition: loggers.h:1928