File indexing completed on 2025-01-18 10:13:53
0001
0002 #ifndef MESSAGELOGGER_H
0003 #define MESSAGELOGGER_H
0004
0005 #include "VecGeom/base/Global.h"
0006 #include <stdio.h>
0007 #include <stdarg.h>
0008 #include <string>
0009 #include <mutex>
0010 #include <iostream>
0011 #ifndef VECCORE_CUDA
0012 #include <map>
0013 #else
0014 #include "VecGeom/base/Map.h"
0015 #endif
0016
0017 namespace vecgeom {
0018 inline namespace VECGEOM_IMPL_NAMESPACE {
0019
0020
0021
0022
0023 class MessageLogger {
0024 public:
0025 typedef enum { kInfo = 0, kWarning, kError, kFatal, kDebug } logging_severity;
0026 #ifndef VECCORE_CUDA
0027 using Map_t = std::map<logging_severity, std::map<std::string, std::map<std::string, int>>>;
0028 #else
0029
0030 using Map_t = vecgeom::map<logging_severity, vecgeom::map<std::string, map<std::string, int>>>;
0031 #endif
0032
0033 static MessageLogger *I()
0034 {
0035 static std::mutex mtx;
0036 mtx.lock();
0037 if (!gMessageLogger) gMessageLogger = new MessageLogger();
0038 mtx.unlock();
0039 return gMessageLogger;
0040 }
0041 std::ostream &message(std::ostream &os, const char *classname, const char *methodname, logging_severity sev,
0042 const char *const fmt, ...)
0043 {
0044 static std::mutex mtx;
0045 va_list ap;
0046 va_start(ap, fmt);
0047 char line[1024];
0048 vsnprintf(line, 1023, fmt, ap);
0049 va_end(ap);
0050 line[1023] = '\0';
0051 mtx.lock();
0052 os << sevname[sev] << "=>" << classname << "::" << methodname << ": " << line;
0053 os.flush();
0054 #ifndef VECCORE_CUDA
0055 gMessageCount[sev][std::string(classname) + "::" + methodname][line] += 1;
0056 #endif
0057 mtx.unlock();
0058 return os;
0059 }
0060
0061 #ifndef VECCORE_CUDA
0062 void summary(std::ostream &os, const std::string opt) const
0063 {
0064 if (opt.find("a") != std::string::npos) {
0065 os << std::string("\n================================== Detailed summary of messages "
0066 "=======================================\n");
0067 for (auto it = gMessageCount.begin(); it != gMessageCount.end(); ++it)
0068 for (auto jt = it->second.begin(); jt != it->second.end(); ++jt)
0069 for (auto kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
0070 os << sevname[it->first] << "=>" << jt->first << ":" << kt->first << " # ";
0071 os << kt->second << std::endl;
0072 }
0073 }
0074 os << std::string(
0075 "================================================================================================="
0076 "======\n");
0077 }
0078 #endif
0079
0080 private:
0081 const char *const sevname[5] = {"Information", "Warning ", "Error ", "Fatal ", "Debug "};
0082 MessageLogger() {}
0083 MessageLogger(const MessageLogger &);
0084 MessageLogger &operator=(const MessageLogger &);
0085 static MessageLogger *gMessageLogger;
0086 #ifndef VECCORE_CUDA
0087 static Map_t gMessageCount;
0088 #endif
0089 };
0090 }
0091 }
0092
0093 #define log_information(os, ...) \
0094 vecgeom::MessageLogger::I()->message(os, ClassName(), __func__, vecgeom::MessageLogger::kInfo, __VA_ARGS__)
0095 #define log_warning(os, ...) \
0096 vecgeom::MessageLogger::I()->message(os, ClassName(), __func__, vecgeom::MessageLogger::kWarning, __VA_ARGS__)
0097 #define log_error(os, ...) \
0098 vecgeom::MessageLogger::I()->message(os, ClassName(), __func__, vecgeom::MessageLogger::kError, __VA_ARGS__)
0099 #define log_fatal(os, ...) \
0100 vecgeom::MessageLogger::I()->message(os, ClassName(), __func__, vecgeom::MessageLogger::kFatal, __VA_ARGS__)
0101 #define log_debug(os, ...) \
0102 vecgeom::MessageLogger::I()->message(os, ClassName(), __func__, vecgeom::MessageLogger::kDebug, __VA_ARGS__)
0103
0104 #endif