scc 2026.07
SystemC components library
report.h
1/*******************************************************************************
2 * Copyright 2016, 2018 MINRES Technologies GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17#ifndef _SCC_REPORT_H_
18#define _SCC_REPORT_H_
19
20#include "utilities.h"
21#include <cci_configuration>
22#include <cstring>
23#include <iomanip>
24#include <iostream>
25#include <mutex>
26#include <sstream>
27#include <stdexcept>
28#include <sysc/kernel/sc_time.h>
29#include <sysc/utils/sc_report.h>
30#include <unordered_map>
31#include <util/ities.h>
32
33#if defined(_MSC_VER) && defined(ERROR)
34#undef ERROR
35#endif
36
78#define SCC_LOG_LEVEL_PARAM_NAME "log_level"
79#define SCC_LOG_LEVEL_PARAM_NAME_LEN 9
80
86namespace scc {
88enum class log { NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, TRACEALL, DBGTRACE = TRACEALL };
89namespace {
91static std::array<const char* const, 8> log_level_names = {{"NONE", "FATAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE", "TRACEALL"}};
92static const std::unordered_map<std::string, scc::log> log_level_lut = {
93 {"NONE", scc::log::NONE}, {"FATAL", scc::log::FATAL}, {"ERROR", scc::log::ERROR}, {"WARNING", scc::log::WARNING},
94 {"INFO", scc::log::INFO}, {"DEBUG", scc::log::DEBUG}, {"TRACE", scc::log::TRACE}, {"TRACEALL", scc::log::TRACEALL}};
95} // namespace
103inline log as_log(int logLevel) {
104 assert(logLevel >= static_cast<int>(log::NONE) && logLevel <= static_cast<int>(log::TRACEALL));
105 std::array<const log, 8> m = {{log::NONE, log::FATAL, log::ERROR, log::WARNING, log::INFO, log::DEBUG, log::TRACE, log::TRACEALL}};
106 return m[logLevel];
107}
108
116inline std::istream& operator>>(std::istream& is, log& val) {
117 std::string buf;
118 is >> buf;
119 auto it = scc::log_level_lut.find(buf);
120 if(it == std::end(scc::log_level_lut))
121 throw std::out_of_range(std::string("Illegal log level value: ") + buf);
122 val = it->second;
123 return is;
124}
125
133inline std::ostream& operator<<(std::ostream& os, log const& val) {
134 os << log_level_names[static_cast<unsigned>(val)];
135 return os;
136}
137
145void init_logging(log level = log::WARNING, unsigned type_field_width = 24, bool print_time = false);
151void reinit_logging();
158void reinit_logging(log level);
165struct LogConfig {
166 log level{log::WARNING};
167 unsigned msg_type_field_width{24};
168 bool print_sys_time{false};
169 bool print_sim_time{true};
170 bool print_delta{false};
171 bool print_severity{true};
172 bool colored_output{true};
173 std::string log_file_name{""};
174 std::string log_filter_regex{""};
175 bool log_async{true};
176 bool dont_create_broker{false};
177 bool report_only_first_error{false};
178 bool instance_based_log_levels{true};
179 bool install_handler{true};
180
192 LogConfig& msgTypeFieldWidth(unsigned);
198 LogConfig& printSysTime(bool = true);
204 LogConfig& printSimTime(bool = true);
210 LogConfig& printDelta(bool = true);
216 LogConfig& printSeverity(bool = true);
222 LogConfig& coloredOutput(bool = true);
228 LogConfig& logFileName(std::string&&);
234 LogConfig& logFileName(const std::string&);
240 LogConfig& logFilterRegex(std::string&&);
246 LogConfig& logFilterRegex(const std::string&);
252 LogConfig& logAsync(bool = true);
258 LogConfig& dontCreateBroker(bool = true);
264 LogConfig& reportOnlyFirstError(bool = true);
270 LogConfig& instanceBasedLogLevels(bool = true);
276 LogConfig& installHandler(bool = true);
277};
278
284void init_logging(const LogConfig& log_config);
298void set_logging_level(log level);
314void set_cycle_base(sc_core::sc_time period);
319extern std::mutex verbosity_mtx;
326inline sc_core::sc_verbosity get_log_verbosity() {
327 return static_cast<sc_core::sc_verbosity>(::sc_core::sc_report_handler::get_verbosity_level());
328}
329
339sc_core::sc_verbosity get_log_verbosity(char const* t);
350inline sc_core::sc_verbosity get_log_verbosity(std::string const& t) { return get_log_verbosity(t.c_str()); }
359template <sc_core::sc_severity SEVERITY> struct ScLogger {
368 ScLogger(const char* file, int line, int verbosity = sc_core::SC_MEDIUM)
369 : t(nullptr)
370 , file(file)
371 , line(line)
372 , level(verbosity){};
373
374 ScLogger() = delete;
375
376 ScLogger(const ScLogger&) = delete;
377
378 ScLogger(ScLogger&&) = delete;
379
380 ScLogger& operator=(const ScLogger&) = delete;
381
382 ScLogger& operator=(ScLogger&&) = delete;
388 virtual ~ScLogger() noexcept(false) {
389 int verb = 100;
390 {
391 std::lock_guard<std::mutex> lock(verbosity_mtx);
392 verb = ::sc_core::sc_report_handler::set_verbosity_level(1000);
393 }
394 ::sc_core::sc_report_handler::report(SEVERITY, t ? t : "SystemC", os.str().c_str(), level, file, line);
395 {
396 std::lock_guard<std::mutex> lock(verbosity_mtx);
397 ::sc_core::sc_report_handler::set_verbosity_level(verb);
398 }
399 }
400
406 inline ScLogger& type() {
407 this->t = nullptr;
408 return *this;
409 }
410
417 inline ScLogger& type(char const* t) {
418 this->t = const_cast<char*>(t);
419 return *this;
420 }
421
428 inline ScLogger& type(std::string const& t) {
429 this->t = const_cast<char*>(t.c_str());
430 return *this;
431 }
432
438 inline std::ostream& get() { return os; };
439
440protected:
441 std::ostringstream os{};
442 char* t{nullptr};
443 const char* file;
444 const int line;
445 const int level;
446};
447
452#define SCCLOG(lvl, ...) ::scc::ScLogger<::sc_core::SC_INFO>(__FILE__, __LINE__, lvl).type(__VA_ARGS__).get()
454#define SCCTRACEALL(...) \
455 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_DEBUG) \
456 SCCLOG(sc_core::SC_DEBUG, __VA_ARGS__)
458#define SCCTRACE(...) \
459 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_FULL) \
460 SCCLOG(sc_core::SC_FULL, __VA_ARGS__)
462#define SCCDEBUG(...) \
463 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_HIGH) \
464 SCCLOG(sc_core::SC_HIGH, __VA_ARGS__)
466#define SCCINFO(...) \
467 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_MEDIUM) \
468 SCCLOG(sc_core::SC_MEDIUM, __VA_ARGS__)
470#define SCCWARN(...) \
471 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_LOW) \
472 ::scc::ScLogger<::sc_core::SC_WARNING>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
474#define SCCERR(...) ::scc::ScLogger<::sc_core::SC_ERROR>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
476#define SCCFATAL(...) ::scc::ScLogger<::sc_core::SC_FATAL>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
477
478#ifdef NDEBUG
479#define SCC_ASSERT(expr) ((void)0)
480#else
481#define SCC_ASSERT(expr) ((void)((expr) ? 0 : (SC_REPORT_FATAL(::sc_core::SC_ID_ASSERTION_FAILED_, #expr), 0)))
482#endif
484#ifndef SCMOD
485#define SCMOD this->name()
486#endif
487#ifndef SCOBJ
488#define SCOBJ this->name()
489#endif
497class stream_redirection : public std::stringbuf {
498public:
506 stream_redirection(std::ostream& os, log level);
507
508 stream_redirection(stream_redirection const&) = delete;
509
510 stream_redirection& operator=(stream_redirection const&) = delete;
511
513
514 stream_redirection& operator=(stream_redirection&&) = delete;
526 void reset();
527
528protected:
529 std::streamsize xsputn(const char_type* s, std::streamsize n) override;
530 int sync() override;
531 std::ostream& os;
532 log level;
533 std::streambuf* old_buf{nullptr};
534};
535
536} // namespace scc // end of scc-sysc
538namespace cci {
539template <> inline bool cci_value_converter<scc::log>::pack(cci_value::reference dst, scc::log const& src) {
540 dst.set_string(scc::log_level_names[static_cast<unsigned>(src)]);
541 return true;
542}
543template <> inline bool cci_value_converter<scc::log>::unpack(scc::log& dst, cci_value::const_reference src) {
544 // Highly defensive unpacker; probably could check less
545 if(!src.is_string())
546 return false;
547 auto it = scc::log_level_lut.find(src.get_string());
548 if(it != std::end(scc::log_level_lut)) {
549 dst = it->second;
550 return true;
551 }
552 return false;
553}
554} // namespace cci
555#endif /* _SCC_REPORT_H_ */
~stream_redirection()
destructor restoring the output stream buffer
Definition report.cpp:341
void reset()
reset the stream redirection and restore output buffer of the stream
Definition report.cpp:345
stream_redirection(std::ostream &os, log level)
constructor redirecting the given stream to a SystemC log message of given llog level
SCC TLM utilities.
std::istream & operator>>(std::istream &is, log &val)
read a log level from input stream e.g. used by boost::lexical_cast
Definition report.h:116
void set_logging_level(log level)
sets the SystemC logging level
Definition report.cpp:524
void init_logging(log level=log::WARNING, unsigned type_field_width=24, bool print_time=false)
initializes the SystemC logging system with a particular logging level
Definition report.cpp:510
log as_log(int logLevel)
safely convert an integer into a log level
Definition report.h:103
bool is_logging_initialized()
get the state of the SCC logging system
Definition report.cpp:508
void set_cycle_base(sc_core::sc_time period)
sets the cycle base for cycle based logging
log get_logging_level()
get the SystemC logging level
Definition report.cpp:533
sc_core::sc_verbosity get_log_verbosity()
get the global verbosity level
Definition report.h:326
std::ostream & operator<<(std::ostream &os, log const &val)
output the textual representation of the log level
Definition report.h:133
log
enum defining the log levels
Definition report.h:88
std::mutex verbosity_mtx
a mutex needed to syncronize verbosity manipulations
Definition report.cpp:333
the configuration class for the logging setup
Definition report.h:165
LogConfig & printSeverity(bool=true)
Definition report.cpp:562
LogConfig & printSysTime(bool=true)
Definition report.cpp:547
LogConfig & reportOnlyFirstError(bool=true)
Definition report.cpp:602
LogConfig & coloredOutput(bool=true)
Definition report.cpp:577
LogConfig & logFileName(std::string &&)
LogConfig & dontCreateBroker(bool=true)
Definition report.cpp:597
LogConfig & logFilterRegex(const std::string &)
LogConfig & logFileName(const std::string &)
LogConfig & logLevel(log)
Definition report.cpp:537
LogConfig & msgTypeFieldWidth(unsigned)
Definition report.cpp:542
LogConfig & printSimTime(bool=true)
Definition report.cpp:552
LogConfig & logAsync(bool=true)
Definition report.cpp:592
LogConfig & printDelta(bool=true)
Definition report.cpp:557
LogConfig & instanceBasedLogLevels(bool=true)
Definition report.cpp:606
LogConfig & installHandler(bool=true)
Definition report.cpp:610
LogConfig & logFilterRegex(std::string &&)
the logger class
Definition report.h:359
ScLogger & type(char const *t)
set the category of the log entry
Definition report.h:417
virtual ~ScLogger() noexcept(false)
the destructor generating the SystemC report
Definition report.h:388
ScLogger & type(std::string const &t)
set the category of the log entry
Definition report.h:428
std::ostream & get()
get the underlying ostringstream
Definition report.h:438
ScLogger & type()
reset the category of the log entry
Definition report.h:406
ScLogger(const char *file, int line, int verbosity=sc_core::SC_MEDIUM)
Definition report.h:368