mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Refactor logging
- Add warning log level - Change debug_log_level setting to enumeration string - Map Irrlicht log events to MT log events - Encapsulate log_* functions and global variables into a class, Logger - Unify dstream with standard logging mechanism - Unify core.debug() with standard core.log() script API
This commit is contained in:
parent
e0b57c1140
commit
2139d7d45f
25 changed files with 599 additions and 652 deletions
194
src/log.h
194
src/log.h
|
@ -20,83 +20,177 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef LOG_HEADER
|
||||
#define LOG_HEADER
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include "threads.h"
|
||||
|
||||
/*
|
||||
Use this for logging everything.
|
||||
class ILogOutput;
|
||||
|
||||
If you need to explicitly print something, use dstream or cout or cerr.
|
||||
*/
|
||||
|
||||
enum LogMessageLevel {
|
||||
LMT_ERROR, /* Something failed ("invalid map data on disk, block (2,2,1)") */
|
||||
LMT_ACTION, /* In-game actions ("celeron55 placed block at (12,4,-5)") */
|
||||
LMT_INFO, /* More deep info ("saving map on disk (only_modified=true)") */
|
||||
LMT_VERBOSE, /* Flood-style ("loaded block (2,2,2) from disk") */
|
||||
LMT_NUM_VALUES,
|
||||
enum LogLevel {
|
||||
LL_NONE, // Special level that is always printed
|
||||
LL_ERROR,
|
||||
LL_WARNING,
|
||||
LL_ACTION, // In-game actions
|
||||
LL_INFO,
|
||||
LL_VERBOSE,
|
||||
LL_MAX,
|
||||
};
|
||||
|
||||
class ILogOutput
|
||||
{
|
||||
class Logger {
|
||||
public:
|
||||
ILogOutput() :
|
||||
silence(false)
|
||||
{}
|
||||
void addOutput(ILogOutput *out);
|
||||
void addOutput(ILogOutput *out, LogLevel lev);
|
||||
void addOutputMaxLevel(ILogOutput *out, LogLevel lev);
|
||||
void removeOutput(ILogOutput *out);
|
||||
void setLevelSilenced(LogLevel lev, bool silenced);
|
||||
|
||||
/* line: Full line with timestamp, level and thread */
|
||||
virtual void printLog(const std::string &line){};
|
||||
/* line: Full line with timestamp, level and thread */
|
||||
virtual void printLog(const std::string &line, enum LogMessageLevel lev){};
|
||||
/* line: Only actual printed text */
|
||||
virtual void printLog(enum LogMessageLevel lev, const std::string &line){};
|
||||
void registerThread(const std::string &name);
|
||||
void deregisterThread();
|
||||
|
||||
bool silence;
|
||||
void log(LogLevel lev, const std::string &text);
|
||||
// Logs without a prefix
|
||||
void logRaw(LogLevel lev, const std::string &text);
|
||||
|
||||
void setTraceEnabled(bool enable) { m_trace_enabled = enable; }
|
||||
bool getTraceEnabled() { return m_trace_enabled; }
|
||||
|
||||
static LogLevel stringToLevel(const std::string &name);
|
||||
|
||||
private:
|
||||
void logToSystem(LogLevel, const std::string &text);
|
||||
void logToOutputs(LogLevel, const std::string &text);
|
||||
|
||||
const std::string getLevelLabel(LogLevel lev);
|
||||
const std::string getThreadName();
|
||||
|
||||
std::vector<ILogOutput *> m_outputs[LL_MAX];
|
||||
|
||||
// Should implement atomic loads and stores (even though it's only
|
||||
// written to when one thread has access currently).
|
||||
// Works on all known architectures (x86, ARM, MIPS).
|
||||
volatile bool m_silenced_levels[LL_MAX];
|
||||
std::map<threadid_t, std::string> m_thread_names;
|
||||
mutable Mutex m_mutex;
|
||||
bool m_trace_enabled;
|
||||
};
|
||||
|
||||
void log_add_output(ILogOutput *out, enum LogMessageLevel lev);
|
||||
void log_add_output_maxlev(ILogOutput *out, enum LogMessageLevel lev);
|
||||
void log_add_output_all_levs(ILogOutput *out);
|
||||
void log_remove_output(ILogOutput *out);
|
||||
void log_set_lev_silence(enum LogMessageLevel lev, bool silence);
|
||||
class ILogOutput {
|
||||
public:
|
||||
virtual void log(const std::string &line) = 0;
|
||||
};
|
||||
|
||||
void log_register_thread(const std::string &name);
|
||||
void log_deregister_thread();
|
||||
class StreamLogOutput : public ILogOutput {
|
||||
public:
|
||||
StreamLogOutput(std::ostream &stream) :
|
||||
stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
void log_printline(enum LogMessageLevel lev, const std::string &text);
|
||||
void log(const std::string &line)
|
||||
{
|
||||
stream << line << std::endl;
|
||||
}
|
||||
|
||||
#define LOGLINEF(lev, ...)\
|
||||
{\
|
||||
char buf[10000];\
|
||||
snprintf(buf, 10000, __VA_ARGS__);\
|
||||
log_printline(lev, buf);\
|
||||
}
|
||||
private:
|
||||
std::ostream &stream;
|
||||
};
|
||||
|
||||
extern std::ostream errorstream;
|
||||
extern std::ostream actionstream;
|
||||
extern std::ostream infostream;
|
||||
extern std::ostream verbosestream;
|
||||
class FileLogOutput : public ILogOutput {
|
||||
public:
|
||||
void open(const std::string &filename);
|
||||
|
||||
extern bool log_trace_level_enabled;
|
||||
void log(const std::string &line)
|
||||
{
|
||||
stream << line << std::endl;
|
||||
}
|
||||
|
||||
#define TRACESTREAM(x){ if(log_trace_level_enabled) verbosestream x; }
|
||||
#define TRACEDO(x){ if(log_trace_level_enabled){ x ;} }
|
||||
private:
|
||||
std::ofstream stream;
|
||||
};
|
||||
|
||||
class LogOutputBuffer : public ILogOutput {
|
||||
public:
|
||||
LogOutputBuffer(Logger &logger, LogLevel lev) :
|
||||
logger(logger)
|
||||
{
|
||||
logger.addOutput(this, lev);
|
||||
}
|
||||
|
||||
~LogOutputBuffer()
|
||||
{
|
||||
logger.removeOutput(this);
|
||||
}
|
||||
|
||||
virtual void log(const std::string &line)
|
||||
{
|
||||
buffer.push(line);
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return buffer.empty();
|
||||
}
|
||||
|
||||
std::string get()
|
||||
{
|
||||
if (empty())
|
||||
return "";
|
||||
std::string s = buffer.front();
|
||||
buffer.pop();
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<std::string> buffer;
|
||||
Logger &logger;
|
||||
};
|
||||
|
||||
|
||||
extern StreamLogOutput stdout_output;
|
||||
extern StreamLogOutput stderr_output;
|
||||
extern std::ostream null_stream;
|
||||
|
||||
extern std::ostream *dout_con_ptr;
|
||||
extern std::ostream *derr_con_ptr;
|
||||
extern std::ostream *dout_server_ptr;
|
||||
extern std::ostream *derr_server_ptr;
|
||||
|
||||
#ifndef SERVER
|
||||
extern std::ostream *dout_client_ptr;
|
||||
extern std::ostream *derr_client_ptr;
|
||||
#endif
|
||||
|
||||
extern Logger g_logger;
|
||||
|
||||
// Writes directly to all LL_NONE log outputs for g_logger with no prefix.
|
||||
extern std::ostream rawstream;
|
||||
|
||||
extern std::ostream errorstream;
|
||||
extern std::ostream warningstream;
|
||||
extern std::ostream actionstream;
|
||||
extern std::ostream infostream;
|
||||
extern std::ostream verbosestream;
|
||||
extern std::ostream dstream;
|
||||
|
||||
#define TRACEDO(x) do { \
|
||||
if (g_logger.getTraceEnabled()) { \
|
||||
x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TRACESTREAM(x) TRACEDO(verbosestream x)
|
||||
|
||||
#define dout_con (*dout_con_ptr)
|
||||
#define derr_con (*derr_con_ptr)
|
||||
#define dout_server (*dout_server_ptr)
|
||||
#define derr_server (*derr_server_ptr)
|
||||
|
||||
#ifndef SERVER
|
||||
extern std::ostream *dout_client_ptr;
|
||||
extern std::ostream *derr_client_ptr;
|
||||
#define dout_client (*dout_client_ptr)
|
||||
#define derr_client (*derr_client_ptr)
|
||||
|
||||
#define dout_client (*dout_client_ptr)
|
||||
#define derr_client (*derr_client_ptr)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue