24 const std::string &msg,
25 const std::map<std::string, std::any> *details) {
26 std::scoped_lock<std::mutex> lock(
mutex);
27 logImpl(level, subsystem, msg, details);
32 outStream(std::cout), errorStream(std::cerr) {}
35 const std::string &msg,
36 const std::map<std::string, std::any> *details) {
40 unsigned indentSpaces = 0;
61 if (!subsystem.empty()) {
62 os <<
"[" << subsystem <<
"] ";
63 indentSpaces += subsystem.size() + 3;
65 os << msg << std::endl;
69 std::string indent(indentSpaces,
' ');
70 for (
const auto &
detail : *details)
75 if (value.type() ==
typeid(std::string))
76 return std::any_cast<std::string>(value);
77 if (value.type() ==
typeid(
int))
78 return std::to_string(std::any_cast<int>(value));
79 if (value.type() ==
typeid(
long))
80 return std::to_string(std::any_cast<long>(value));
81 if (value.type() ==
typeid(
unsigned))
82 return std::to_string(std::any_cast<unsigned>(value));
83 if (value.type() ==
typeid(
unsigned long))
84 return std::to_string(std::any_cast<unsigned long>(value));
85 if (value.type() ==
typeid(
bool))
86 return std::any_cast<bool>(value) ?
"true" :
"false";
87 if (value.type() ==
typeid(
double))
88 return std::to_string(std::any_cast<double>(value));
89 if (value.type() ==
typeid(
float))
90 return std::to_string(std::any_cast<float>(value));
91 if (value.type() ==
typeid(
const char *))
92 return std::string(std::any_cast<const char *>(value));
93 if (value.type() ==
typeid(
char))
94 return std::string(1, std::any_cast<char>(value));
96 return std::any_cast<MessageData>(value).toHex();
A logical chunk of data representing serialized data.
Level minLevel
The minimum log level to emit.
void logImpl(Level level, const std::string &subsystem, const std::string &msg, const std::map< std::string, std::any > *details) override
Subclasses must implement this method to log messages.
std::ostream & outStream
Everything except errors goes here.
std::ostream & errorStream
Just for errors.
StreamLogger(Level minLevel, std::ostream &out, std::ostream &error)
Create a stream logger that logs to the given output stream and error output stream.
A thread-safe logger which calls functions implemented by subclasses.
std::mutex mutex
Mutex to protect the stream from interleaved logging writes.
virtual void logImpl(Level level, const std::string &subsystem, const std::string &msg, const std::map< std::string, std::any > *details)=0
Subclasses must implement this method to log messages.
void log(Level level, const std::string &subsystem, const std::string &msg, const std::map< std::string, std::any > *details) override final
Grabs the lock and calls logImpl.
std::string toString(const std::any &a)
'Stringify' a std::any. This is used to log std::any values by some loggers.