RunicVTT Open Source Virtual Tabletop for TTRPG using P2P
Loading...
Searching...
No Matches
Logger Class Reference

#include <Logger.h>

Collaboration diagram for Logger:

Classes

class  LineToLoggerBuf
 
struct  LogEntry
 
class  OstreamRedirect
 

Public Types

enum class  Level : uint8_t {
  Trace , Debug , Info , Warn ,
  Error , Success
}
 
using Sink = std::function<void(const std::string& channel, const LogEntry& e)>
 

Public Member Functions

void log (const std::string &channel, const std::string &line)
 
void log (const std::string &channel, Level lvl, const std::string &line)
 
std::vector< LogEntrygetChannel (const std::string &channel)
 
std::vector< std::string > channels () const
 
void clearChannel (const std::string &channel)
 
void setChannelCapacity (size_t cap)
 
int addSink (const Sink &s)
 
void removeSink (int id)
 
void clearSinks ()
 
void installStdCapture ()
 
void uninstallStdCapture ()
 

Static Public Member Functions

static Loggerinstance ()
 
static std::string formatTs (uint64_t ms)
 

Private Member Functions

 Logger ()=default
 
void ensureSeed_ ()
 
void commit_ (const std::string &channel, LogEntry e)
 

Static Private Member Functions

static uint64_t nowMs_ ()
 
static Level autoDetect_ (const std::string &s)
 

Private Attributes

std::mutex m_
 
size_t capacity_ = 4000
 
std::unordered_map< std::string, std::deque< LogEntry > > channels_
 
int nextSinkId_ = 0
 
std::vector< std::pair< int, Sink > > sinks_
 
bool seeded_ = false
 
std::unique_ptr< OstreamRedirectcoutRedirect_
 
std::unique_ptr< OstreamRedirectcerrRedirect_
 

Detailed Description

Definition at line 15 of file Logger.h.

Member Typedef Documentation

◆ Sink

using Logger::Sink = std::function<void(const std::string& channel, const LogEntry& e)>

Definition at line 37 of file Logger.h.

Member Enumeration Documentation

◆ Level

enum class Logger::Level : uint8_t
strong
Enumerator
Trace 
Debug 
Info 
Warn 
Error 
Success 

Definition at line 18 of file Logger.h.

Constructor & Destructor Documentation

◆ Logger()

Logger::Logger ( )
privatedefault

Member Function Documentation

◆ addSink()

int Logger::addSink ( const Sink & s)
inline

Definition at line 96 of file Logger.h.

97 {
98 std::lock_guard<std::mutex> lk(m_);
99 int id = ++nextSinkId_;
100 sinks_.emplace_back(id, s);
101 return id;
102 }
std::vector< std::pair< int, Sink > > sinks_
Definition Logger.h:310
std::mutex m_
Definition Logger.h:306
int nextSinkId_
Definition Logger.h:309

◆ autoDetect_()

static Level Logger::autoDetect_ ( const std::string & s)
inlinestaticprivate

Definition at line 268 of file Logger.h.

269 {
270 // very small heuristics (case-insensitive): [error], error:, fail, warn, etc.
271 auto has = [&](const char* needle)
272 {
273 auto it = std::search(
274 s.begin(), s.end(),
275 needle, needle + std::strlen(needle),
276 [](char a, char b)
277 { return std::tolower((unsigned char)a) == std::tolower((unsigned char)b); });
278 return it != s.end();
279 };
280 if (has("[error]") || has(" error") || has("failed") || has("exception"))
281 return Level::Error;
282 if (has("[warn]") || has(" warning"))
283 return Level::Warn;
284 // If you wish, detect [debug] → Debug, [trace] → Trace
285 if (has("[debug]"))
286 return Level::Debug;
287 if (has("[trace]"))
288 return Level::Trace;
289 return Level::Info;
290 }
Here is the caller graph for this function:

◆ channels()

std::vector< std::string > Logger::channels ( ) const
inline

Definition at line 73 of file Logger.h.

74 {
75 std::lock_guard<std::mutex> lk(m_);
76 std::vector<std::string> names;
77 names.reserve(channels_.size());
78 for (auto& kv : channels_)
79 names.push_back(kv.first);
80 return names;
81 }
std::unordered_map< std::string, std::deque< LogEntry > > channels_
Definition Logger.h:308
Here is the caller graph for this function:

◆ clearChannel()

void Logger::clearChannel ( const std::string & channel)
inline

Definition at line 83 of file Logger.h.

84 {
85 std::lock_guard<std::mutex> lk(m_);
86 channels_[channel].clear();
87 }
Here is the caller graph for this function:

◆ clearSinks()

void Logger::clearSinks ( )
inline

Definition at line 111 of file Logger.h.

112 {
113 std::lock_guard<std::mutex> lk(m_);
114 sinks_.clear();
115 }

◆ commit_()

void Logger::commit_ ( const std::string & channel,
LogEntry e )
inlineprivate

Definition at line 292 of file Logger.h.

293 {
294 std::lock_guard<std::mutex> lk(m_);
295 auto& q = channels_[channel];
296 q.emplace_back(std::move(e));
297 while (q.size() > capacity_)
298 q.pop_front();
299 // fan-out sinks
300 auto& back = q.back();
301 for (auto& [id, s] : sinks_)
302 s(channel, back);
303 }
size_t capacity_
Definition Logger.h:307
Here is the caller graph for this function:

◆ ensureSeed_()

void Logger::ensureSeed_ ( )
inlineprivate

Definition at line 252 of file Logger.h.

253 {
254 if (!seeded_)
255 {
256 channels_["main"];
257 channels_["localtunnel"];
258 seeded_ = true;
259 }
260 }
bool seeded_
Definition Logger.h:311
Here is the caller graph for this function:

◆ formatTs()

static std::string Logger::formatTs ( uint64_t ms)
inlinestatic

Definition at line 135 of file Logger.h.

136 {
137 using namespace std::chrono;
138 auto tp = time_point<system_clock, milliseconds>(milliseconds(ms));
139 auto t = system_clock::to_time_t(tp);
140 auto ms_part = (int)(ms % 1000);
141 struct tm bt;
142#if defined(_WIN32)
143 localtime_s(&bt, &t);
144#else
145 localtime_r(&t, &bt);
146#endif
147 char buf[32];
148 std::snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03d", bt.tm_hour, bt.tm_min, bt.tm_sec, ms_part);
149 return std::string(buf);
150 }
Here is the caller graph for this function:

◆ getChannel()

std::vector< LogEntry > Logger::getChannel ( const std::string & channel)
inline

Definition at line 64 of file Logger.h.

65 {
66 std::lock_guard<std::mutex> lk(m_);
67 auto it = channels_.find(channel);
68 if (it == channels_.end())
69 return {};
70 return {it->second.begin(), it->second.end()};
71 }
Here is the caller graph for this function:

◆ installStdCapture()

void Logger::installStdCapture ( )
inline

Definition at line 118 of file Logger.h.

119 {
120 std::lock_guard<std::mutex> lk(m_);
121 if (!coutRedirect_)
122 coutRedirect_ = std::make_unique<OstreamRedirect>(std::cout, "main", Level::Debug);
123 if (!cerrRedirect_)
124 cerrRedirect_ = std::make_unique<OstreamRedirect>(std::cerr, "main", Level::Error);
125 ensureSeed_();
126 }
std::unique_ptr< OstreamRedirect > cerrRedirect_
Definition Logger.h:313
void ensureSeed_()
Definition Logger.h:252
std::unique_ptr< OstreamRedirect > coutRedirect_
Definition Logger.h:312
Here is the call graph for this function:
Here is the caller graph for this function:

◆ instance()

static Logger & Logger::instance ( )
inlinestatic

Definition at line 39 of file Logger.h.

40 {
41 static Logger L;
42 return L;
43 }
Here is the caller graph for this function:

◆ log() [1/2]

void Logger::log ( const std::string & channel,
const std::string & line )
inline

Definition at line 48 of file Logger.h.

49 {
50 log(channel, Level::Info, line);
51 }
void log(const std::string &channel, const std::string &line)
Definition Logger.h:48
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log() [2/2]

void Logger::log ( const std::string & channel,
Level lvl,
const std::string & line )
inline

Definition at line 54 of file Logger.h.

55 {
56 LogEntry e{line, lvl, nowMs_(), {}};
57 // auto-detect if level was Info but looks like warn/error
58 if (lvl == Level::Info)
59 e.level = autoDetect_(line);
60 commit_(channel, std::move(e));
61 }
void commit_(const std::string &channel, LogEntry e)
Definition Logger.h:292
static Level autoDetect_(const std::string &s)
Definition Logger.h:268
static uint64_t nowMs_()
Definition Logger.h:262
Here is the call graph for this function:

◆ nowMs_()

static uint64_t Logger::nowMs_ ( )
inlinestaticprivate

Definition at line 262 of file Logger.h.

263 {
264 using namespace std::chrono;
265 return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
266 }
Here is the caller graph for this function:

◆ removeSink()

void Logger::removeSink ( int id)
inline

Definition at line 103 of file Logger.h.

104 {
105 std::lock_guard<std::mutex> lk(m_);
106 sinks_.erase(std::remove_if(sinks_.begin(), sinks_.end(),
107 [id](auto& p)
108 { return p.first == id; }),
109 sinks_.end());
110 }

◆ setChannelCapacity()

void Logger::setChannelCapacity ( size_t cap)
inline

Definition at line 89 of file Logger.h.

90 {
91 std::lock_guard<std::mutex> lk(m_);
92 capacity_ = cap;
93 }

◆ uninstallStdCapture()

void Logger::uninstallStdCapture ( )
inline

Definition at line 127 of file Logger.h.

128 {
129 std::lock_guard<std::mutex> lk(m_);
130 cerrRedirect_.reset();
131 coutRedirect_.reset();
132 }

Member Data Documentation

◆ capacity_

size_t Logger::capacity_ = 4000
private

Definition at line 307 of file Logger.h.

◆ cerrRedirect_

std::unique_ptr<OstreamRedirect> Logger::cerrRedirect_
private

Definition at line 313 of file Logger.h.

◆ channels_

std::unordered_map<std::string, std::deque<LogEntry> > Logger::channels_
private

Definition at line 308 of file Logger.h.

◆ coutRedirect_

std::unique_ptr<OstreamRedirect> Logger::coutRedirect_
private

Definition at line 312 of file Logger.h.

◆ m_

std::mutex Logger::m_
mutableprivate

Definition at line 306 of file Logger.h.

◆ nextSinkId_

int Logger::nextSinkId_ = 0
private

Definition at line 309 of file Logger.h.

◆ seeded_

bool Logger::seeded_ = false
private

Definition at line 311 of file Logger.h.

◆ sinks_

std::vector<std::pair<int, Sink> > Logger::sinks_
private

Definition at line 310 of file Logger.h.


The documentation for this class was generated from the following file: