39 #include <unordered_set>
42 #include <system_error>
49 using namespace scc::util;
53 class LogStreambuf :
public std::streambuf
59 unsigned int m_multmax;
60 unsigned int m_multcur;
61 unsigned int m_maxline;
69 std::unordered_set<std::shared_ptr<std::ostream>> m_strms;
71 LogStreambuf(
const LogStreambuf&) =
delete;
72 void operator=(
const LogStreambuf&) =
delete;
77 if (!m_on || m_line.empty())
return;
81 std::stringstream out;
85 if (m_id.empty() && m_ts.empty())
93 if (m_multmax > 0 && (m_line[0] ==
'\t' || m_line[0] ==
' '))
95 if (++m_multcur < m_multmax)
110 out <<
"[" << m_id <<
"] ";
115 auto t = std::time(
nullptr);
119 out << std::put_time(gmtime_r(&t, &tbuf), m_ts.c_str());
123 out << std::put_time(localtime_r(&t, &tbuf), m_ts.c_str());
129 out << m_line <<
'\n';
133 std::cout << out.str();
139 std::cerr << out.str();
145 std::clog << out.str();
149 std::lock_guard<std::mutex> lk(s_mx);
150 for (
auto os : m_strms)
159 int_type overflow(int_type c)
161 if (traits_type::eq_int_type(traits_type::eof(), c))
181 if (m_line.size() == m_maxline)
206 LogStreambuf(
unsigned int max)
211 virtual ~LogStreambuf() {}
213 void add(
const std::shared_ptr<std::ostream>& os)
215 std::lock_guard<std::mutex> lk(s_mx);
216 if (m_strms.find(os) == m_strms.end())
222 void remove(
const std::shared_ptr<std::ostream>& os)
224 std::lock_guard<std::mutex> lk(s_mx);
225 auto it = m_strms.find(os);
226 if (it != m_strms.end())
237 void dup(
void* rdbufp)
239 LogStreambuf& b = *
static_cast<LogStreambuf*
>(rdbufp);
245 m_multmax = b.m_multmax;
246 m_multcur = b.m_multcur;
248 m_maxline = b.m_maxline;
249 m_line.reserve(m_maxline);
256 std::lock_guard<std::mutex> lk(s_mx);
260 void clear(
int max = 256)
271 m_line.reserve(m_maxline);
278 std::lock_guard<std::mutex> lk(s_mx);
282 void id(
const std::string& i)
286 std::string id()
const
291 void timestamp(
const std::string& ts)
295 std::string timestamp()
const
318 void multiline(
unsigned int max)
323 unsigned multiline()
const
328 void max_line(
unsigned v)
332 unsigned max_line()
const
342 throw std::runtime_error(
"logger max line length must be non-zero");
345 rdbuf(
new LogStreambuf(max));
355 rdbuf(
new LogStreambuf());
356 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
362 rdbuf(
new LogStreambuf());
363 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
370 rdbuf(
new LogStreambuf());
371 LogStreambuf* rba =
static_cast<LogStreambuf*
>(rdbuf());
372 LogStreambuf* rbb =
static_cast<LogStreambuf*
>(b.rdbuf());
381 LogStreambuf* rba =
static_cast<LogStreambuf*
>(rdbuf());
382 LogStreambuf* rbb =
static_cast<LogStreambuf*
>(b.rdbuf());
390 void Logger::dup(
const Logger& b)
392 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
399 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
406 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
413 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
420 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
427 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
434 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
441 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
448 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
450 return rb->timestamp();
455 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
462 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
469 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
476 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
483 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
490 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
492 return rb->multiline();
497 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
504 LogStreambuf* rb =
static_cast<LogStreambuf*
>(rdbuf());
506 return rb->max_line();
Thread-safe stream logger.
Logger(unsigned int=256)
Create a logger with maximum line length (default 256).
void remove(const std::shared_ptr< std::ostream > &)
Remove shared stream.
Logger & operator=(const Logger &)
Copy assign logger, using original streams and settings.
void add(const std::shared_ptr< std::ostream > &)
Add a shared stream.
std::string id() const
Get the current id string.
unsigned int max_line() const
Get the maximum line length.
bool utc() const
Get utc mode.
unsigned int multiline() const
Get maximum number of multiline lines.
bool enable() const
Is the logger enabled?
void clear()
Clear the logger and reset to defaults.
std::string timestamp() const
Get the current timestamp format.
void add_cout()
Add std::cout console stream.