Browse Source

Added report filtering capabilities - first implementation

Eyck Jentzsch 1 month ago
parent
commit
a61f5e2782
2 changed files with 65 additions and 11 deletions
  1. 3
    0
      incl/scc/report.h
  2. 62
    11
      src/report.cpp

+ 3
- 0
incl/scc/report.h View File

@@ -46,6 +46,7 @@ struct LogConfig {
46 46
   bool print_severity{true};
47 47
   bool colored_output{true};
48 48
   std::string log_file_name{""};
49
+  std::string log_filter_regex{""};
49 50
 
50 51
   LogConfig& logLevel(logging::log_level);
51 52
   LogConfig& fieldWidth( unsigned);
@@ -55,6 +56,8 @@ struct LogConfig {
55 56
   LogConfig& coloredOutput(bool);
56 57
   LogConfig& logFileName(std::string&&);
57 58
   LogConfig& logFileName(std::string&);
59
+  LogConfig& logFilterRegex(std::string&&);
60
+  LogConfig& logFilterRegex(std::string&);
58 61
 };
59 62
 /**
60 63
  * initializes the SystemC logging system with a particular configuration

+ 62
- 11
src/report.cpp View File

@@ -29,6 +29,18 @@
29 29
 #include <array>
30 30
 #include <chrono>
31 31
 #include <thread>
32
+#ifdef __GNUC__
33
+  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100  + __GNUC_PATCHLEVEL__)
34
+  #if GCC_VERSION < 40900
35
+    #define USE_C_REGEX
36
+  #endif
37
+#endif
38
+
39
+#ifdef USE_C_REGEX
40
+  #include <regex.h>
41
+#else
42
+  #include <regex>
43
+#endif
32 44
 
33 45
 using namespace std;
34 46
 using namespace sc_core;
@@ -38,10 +50,22 @@ namespace {
38 50
 struct ExtLogConfig: public scc::LogConfig {
39 51
   shared_ptr<spdlog::logger> file_logger;
40 52
   shared_ptr<spdlog::logger> console_logger;
53
+#ifdef USE_C_REGEX
54
+  regex_t start_state;
55
+#else
56
+  regex reg_ex;
57
+#endif
41 58
   ExtLogConfig& operator=(const scc::LogConfig& o){
42 59
     scc::LogConfig::operator=(o);
43 60
     return *this;
44 61
   }
62
+  bool match(const char* type){
63
+#ifdef USE_C_REGEX
64
+    return regexec(&start_state, type, 0, NULL, 0)==0;
65
+#else
66
+    return regex_search(type, reg_ex);
67
+#endif
68
+  }
45 69
 } log_cfg;
46 70
 
47 71
 tuple<sc_core::sc_time::value_type, sc_core::sc_time_unit> get_tuple(const sc_core::sc_time& t){
@@ -94,7 +118,8 @@ string time2string(const sc_core::sc_time &t) {
94 118
     return oss.str();
95 119
 }
96 120
 
97
-const string compose_message(const sc_report &rep) {
121
+const string compose_message(const sc_report &rep, bool force=false) {
122
+  if(log_cfg.log_filter_regex.length()==0 || force || log_cfg.match(rep.get_msg_type())){
98 123
     stringstream os;
99 124
     if(log_cfg.print_sim_time) os << "[" << setw(20) << time2string(sc_core::sc_time_stamp()) << "] ";
100 125
     if (rep.get_id() >= 0)
@@ -111,6 +136,8 @@ const string compose_message(const sc_report &rep) {
111 136
         }
112 137
     }
113 138
     return os.str();
139
+  } else
140
+    return "";
114 141
 }
115 142
 
116 143
 inline log_level verbosity2log(int verb) {
@@ -124,21 +151,29 @@ inline void log2logger(spdlog::logger& logger, const sc_report &rep){
124 151
   case SC_INFO:
125 152
     switch(rep.get_verbosity()){
126 153
     case sc_core::SC_DEBUG:
127
-    case sc_core::SC_FULL:
128
-      logger.trace(compose_message(rep));
154
+    case sc_core::SC_FULL:{
155
+      auto msg = compose_message(rep);
156
+      if(msg.size()) logger.trace(msg);
129 157
       return;
130
-    case sc_core::SC_HIGH:
131
-      logger.debug(compose_message(rep));
158
+    }
159
+    case sc_core::SC_HIGH:{
160
+      auto msg = compose_message(rep);
161
+      if(msg.size()) logger.debug(msg);
132 162
       return;
133
-    default:
134
-      logger.info(compose_message(rep));
163
+    }
164
+    default:{
165
+      auto msg = compose_message(rep);
166
+      if(msg.size()) logger.info(msg);
167
+      return;
168
+    }
135 169
     }
136 170
     return;
137
-  case SC_WARNING: logger.warn(compose_message(rep));return;
138
-  case SC_ERROR:   logger.error(compose_message(rep));return;
139
-  case SC_FATAL:   logger.critical(compose_message(rep));return;
171
+    case SC_WARNING: logger.warn(compose_message(rep, true));return;
172
+    case SC_ERROR:   logger.error(compose_message(rep, true));return;
173
+    case SC_FATAL:   logger.critical(compose_message(rep, true));return;
140 174
   }
141 175
 }
176
+
142 177
 inline void log2logger(spdlog::logger& logger, logging::log_level lvl, const string& msg){
143 178
   switch(lvl){
144 179
   case logging::DBGTRACE:
@@ -159,7 +194,7 @@ void report_handler(const sc_report &rep, const sc_actions &actions) {
159 194
     if (actions & SC_ABORT) {
160 195
       log_cfg.console_logger->flush();
161 196
       if(log_cfg.file_logger) log_cfg.file_logger->flush();
162
-      std::this_thread::sleep_for(std::chrono::milliseconds(10));
197
+      this_thread::sleep_for(chrono::milliseconds(10));
163 198
       abort();
164 199
     }
165 200
     if (actions & SC_THROW) throw rep;
@@ -232,6 +267,13 @@ static void configure_logging() {
232 267
       log_cfg.file_logger->set_level(
233 268
           static_cast<spdlog::level::level_enum>(SPDLOG_LEVEL_OFF - min<int>(SPDLOG_LEVEL_OFF, log_cfg.level)));
234 269
     }
270
+    if(log_cfg.log_filter_regex.size()){
271
+#ifdef USE_C_REGEX
272
+     regcomp(&log_cfg.start_state, log_cfg.log_filter_regex.c_str(), REG_EXTENDED);
273
+#else
274
+      log_cfg.reg_ex=regex(log_cfg.log_filter_regex, regex::basic|regex::icase);
275
+#endif
276
+    }
235 277
 }
236 278
 
237 279
 void scc::init_logging(logging::log_level level, unsigned type_field_width, bool print_time) {
@@ -286,3 +328,12 @@ scc::LogConfig& scc::LogConfig::coloredOutput(bool enable) {
286 328
   return *this;
287 329
 }
288 330
 
331
+scc::LogConfig& scc::LogConfig::logFilterRegex(string&& expr) {
332
+  this->log_filter_regex=expr;
333
+  return *this;
334
+}
335
+
336
+scc::LogConfig& scc::LogConfig::logFilterRegex(string& expr) {
337
+  this->log_filter_regex=expr;
338
+  return *this;
339
+}