You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
spdlog/spdloglb/spdloglb.cpp

950 lines
28 KiB
C++

// spdloglb.cpp : Definiert die exportierten Funktionen für die DLL-Anwendung.
//
#include "stdafx.h"
#include "spdlog/spdloglb_VarArg.h"
#include "spdlog/spdloglb_ostream.h"
#include "spdlog/cstyle/sink_handle.h"
#include "spdlog/cstyle/logger_handle.h"
#include "spdloglb_helpers.h"
//#include "Sink_mgr.h"
//#include "BaumEventLog_ResourceList.h"
namespace spdlog
{
DWORD g_InstanceCount = 0;
void logger_error_handler(const std::string &err_msg);
class spdloglib_error_manager
{
private:
error_callback* _callback;
public:
spdloglib_error_manager()
{
_callback = NULL;
}
void init(error_callback* lp_err_clb)
{
if (lp_err_clb)
free();
_callback = lp_err_clb;
if (_callback)
{
spdlog::set_error_handler(logger_error_handler);
}
}
void free(void)
{
spdlog::set_error_handler(NULL);
}
void on_error(const char* lpMsg)
{
if (_callback)
_callback->on_error(lpMsg);
}
}g_spdloglib_error_manager;
void logger_error_handler(const std::string &err_msg)
{
g_spdloglib_error_manager.on_error(err_msg.c_str());
}
// Initialize the library and define some per instance modes
// The library may get loaded and initialized by more than one modules of the current process. But the "per instance" values
// has to be unique for one instance (one running exe). So this values are stored at the first call, the next call returns
// BevlInitReturn_WasInitialized to indicate that this settings was not incorperated at all. So there are the following rules:
//
// * AsyncMode with all its settings (QueueSize ...) has to be defined unique to one application
// * If any of the logs are accessed by more than one thread, it is required to set "MultiThreaded" to true.
// Missing this may cause really bad side effects (missing synchronisation)
// * Never use the same logfile from two different applications (EXE-Files)
// * Not really sure about the impact, but I think it is a good idea to write different logfiles for each instance,
// if the program supports more than one instance.
//
// Parameters:
// AsyncMode: Speeds up logging by creating a queue for the log messages
// QueuSize: Size of the queue that gets created for each logger
// OverflowPolicy: Defines what to do if a queue is full.
// 0 -> hold/sleep the program until the queue has space again
// 1 -> discard the message
// FlushIntervalMs: Defines the interval to perform automatic flush operations on a queue
SPDLOGLB_API spdlog::InitReturn SpdLog_Init(bool AsyncMode, unsigned long QueueSize, unsigned long OverflowPolicy, unsigned long FlushIntervalMs, error_callback* lp_err_clb)
{
if (g_InstanceCount++ == 0)
{
g_spdloglib_error_manager.init(lp_err_clb);
spdlog::async_overflow_policy opc = spdlog::async_overflow_policy::block_retry;
switch (OverflowPolicy)
{
case unsigned long(spdlog::async_overflow_policy::block_retry) :
opc = spdlog::async_overflow_policy::block_retry;
break;
case unsigned long(spdlog::async_overflow_policy::discard_log_msg) :
opc = spdlog::async_overflow_policy::discard_log_msg;
break;
}
std::chrono::milliseconds fims = std::chrono::milliseconds::zero();
fims += std::chrono::milliseconds(FlushIntervalMs);
if (AsyncMode)
spdlog::details::registry::instance().set_async_mode(QueueSize, opc, NULL, fims, NULL);
else
spdlog::details::registry::instance().set_sync_mode();
return InitReturn_Succeed;
}
else
return InitReturn_WasInitialized;
}
SPDLOGLB_API bool SpdLog_Free(void)
{
if (--g_InstanceCount == 0)
{
g_InstanceCount = 0;
// Free all remaining objects
sink_handle_factory::drop_all();
logger_handle_factory::drop_all();
spdlog::details::registry::instance().drop_all();
spdlog::details::registry::instance().set_sync_mode();
g_spdloglib_error_manager.free();
return true;
}
return false;
}
// Ther is a rule for all filebased sinks: they should never point to the same file!
// So all this functions look for a existing sink with the same name before a new one is created.
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateFileSink(const spdlog::filename_char_t* file_name, bool force_flush, bool MultiThreaded)
{
CBevlFnConverter fnc(file_name);
spdlog::log_handle_t ret_val = NULL;
try
{
ret_val = sink_handle_factory::create_simple_file_sink(fnc, force_flush, MultiThreaded);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return ret_val;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateRotatingFileSink(const spdlog::filename_char_t* FileName, const spdlog::filename_char_t* FileExt, size_t max_file_size, size_t max_files, bool MultiThreaded)
{
CBevlFnConverter fnc(FileName);
CBevlFnConverter fnx(FileExt);
spdlog::log_handle_t ret_val = NULL;
try
{
ret_val = sink_handle_factory::create_rotating_file_sink(fnc, fnx, MultiThreaded, max_file_size, max_files);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return ret_val;
// return sink_handle_factory::create_rotating_file_sink(fnc, fnx, force_flush, MultiThreaded, max_file_size, max_files);
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateDailyFileSink(const spdlog::filename_char_t* FileName, const spdlog::filename_char_t* FileExt, int rotation_hour, int rotation_minute, bool MultiThreaded)
{
CBevlFnConverter fnc(FileName);
CBevlFnConverter fnx(FileExt);
try
{
return sink_handle_factory::create_daily_file_sink(fnc, fnx, rotation_hour, rotation_minute, MultiThreaded);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return NULL;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateMsvcSink(bool MultiThreaded)
{
try
{
return sink_handle_factory::create_msvc_sink(MultiThreaded);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return NULL;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateStdoutSink(bool MultiThreaded, bool UseColor)
{
try
{
return sink_handle_factory::create_stdout_sink(MultiThreaded, UseColor);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return NULL;
// return sink_handle_factory::create_stdout_sink(MultiThreaded, UseColor);
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateStderrSink(bool MultiThreaded, bool UseColor)
{
try
{
return sink_handle_factory::create_stderr_sink(MultiThreaded, UseColor);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return NULL;
// return sink_handle_factory::create_stderr_sink(MultiThreaded, UseColor);
}
// The sink handle is only required to make the calls to "SpdLog_CreateLogger". After you have created
// your logger, you may call SpdLog_FreeSink to free your reference to the sink. Sinks taken by created loggers
// get freed at the point when the logger is destroyed itself, completely behind your back.
SPDLOGLB_API bool SpdLog_FreeSink(spdlog::log_handle_t hSink)
{
return sink_handle_factory::free_sink(hSink);
}
// Creates a logger.
// Need 1-n output sinks that get created before with the appropriate functions
// LoggerName has to be a unique name for each logger.
// FormatString is the base format for each log entry, decorating it with timestamps ...
// log_level is the current level from BevlLogLevel_trace to BevlLogLevel_off, all messages with lower LogLEvels are thrown away.
// LogBitMask is the mask to filter out message classes in functions that uses a bit flag to indicate the message class
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateLogger(spdlog::log_handle_t* lpSinks, const unsigned long nSinks, const char* LoggerName, const spdlog::log_char_t* FormatString, unsigned long log_level, unsigned long LogBitMask)
{
try
{
logger_handle* lph = logger_handle_factory::create_logger_p(lpSinks, nSinks, LoggerName);
if (lph)
{
lph->set_level(CBevlLogLevelConverter(log_level));
lph->set_pattern(CBevlFormatstringConverter(FormatString));
#ifdef SPDLOG_BITMASK_LOG_FILTER
lph->set_enable_bit_mask(LogBitMask);
#endif
return lph->GetHandle();
}
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
// Finds a existing logger. The logger list is valid for the complete process, so a logger may be used by more than one module at a time.
// In this case it is best to query first for the logger using this function, because it is not possible to create two loggers
// with the same name.
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetLogger(const char* LoggerName)
{
return logger_handle_factory::get_logger(LoggerName);
}
SPDLOGLB_API bool SpdLog_DeleteLogger(spdlog::log_handle_t hLogger)
{
return logger_handle_factory::delete_logger(hLogger);
}
SPDLOGLB_API bool SpdLog_IsValidLoggerHandle(spdlog::log_handle_t hLogger)
{
return logger_handle_factory::validate_logger_handle(hLogger);
}
// Sets the basic log output pattern. It is a format string according to https://github.com/gabime/spdlog/wiki/3.-Custom-formatting.
// Use this format string to do the base setup for the log output lines.
// Attention: if called with hLogger == NULL, it resets the fomat pattern of all existing Loggers!
SPDLOGLB_API bool SpdLog_SetLoggerFormatPattern(spdlog::log_handle_t hLogger, spdlog::fmt_formatchar_t* lpPattern)
{
return logger_handle_factory::set_logger_format_pattern(hLogger, lpPattern);
}
SPDLOGLB_API bool SpdLog_SetLoggerLevel(spdlog::log_handle_t hLogger, unsigned long log_level)
{
return logger_handle_factory::set_level(hLogger, CBevlLogLevelConverter(log_level));
}
SPDLOGLB_API bool SpdLog_SetLoggerBitMask(spdlog::log_handle_t hLogger, unsigned long BitMask)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
return logger_handle_factory::set_logger_enable_bitmask(hLogger, BitMask);
#else
return false;
#endif
}
// Flushes the log if a message that matches the LogLEvel was loggt.
SPDLOGLB_API bool SpdLog_SetLoggerAutomaticFlush(spdlog::log_handle_t hLogger, unsigned long log_level)
{
return logger_handle_factory::set_logger_automatic_flush(hLogger, CBevlLogLevelConverter(log_level));
}
// Flushes the log file (to disk ...)
SPDLOGLB_API bool SpdLog_LoggerFlush(spdlog::log_handle_t hLogger)
{
return logger_handle_factory::logger_flush(hLogger);
}
SPDLOGLB_API unsigned long SpdLog_GetLoggerLevel(spdlog::log_handle_t hLogger)
{
return logger_handle_factory::get_level(hLogger);
}
SPDLOGLB_API unsigned long SpdLog_GetLoggerBitMask(spdlog::log_handle_t hLogger)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
return logger_handle_factory::get_logger_enable_bitmask(hLogger);
#else
return 0;
#endif
}
SPDLOGLB_API unsigned long SpdLog_GetLoggerAutomaticFlush(spdlog::log_handle_t hLogger)
{
return logger_handle_factory::get_logger_automatic_flush(hLogger);
}
SPDLOGLB_API bool SpdLog_GetLoggerName(spdlog::log_handle_t hLogger, char* lpBuffer, unsigned long BufSize)
{
if (lpBuffer == NULL)
return false;
if (BufSize == 0)
return false;
std::string s;
if (logger_handle_factory::get_logger_name(hLogger, s))
{
unsigned long cpLen = s.length();
if (cpLen >= BufSize)
cpLen = BufSize - 1;
strncpy_s(lpBuffer,BufSize, s.data(), cpLen);
lpBuffer[cpLen] = '\0';
return true;
}
return false;
}
SPDLOGLB_API bool SpdLog_SetLoggerErrorHandler(spdlog::log_handle_t hLogger, log_err_handler ErrorHandler)
{
return logger_handle_factory::set_error_handler(hLogger, ErrorHandler);
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateSimpleFileLogger(const char* logger_name,
const spdlog::filename_char_t* file_name,
bool force_flush,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
logger_handle* lpLh = logger_handle_factory::create_simple_file_logger_p(logger_name, file_name, force_flush, MultiThreaded);
if (lpLh == nullptr)
return nullptr;
if (lp_prop)
{
if (lp_prop->FormatString)
lpLh->set_pattern(lp_prop->FormatString);
lpLh->set_level(lp_prop->Level);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetOrCreateSimpleFileLogger(const char* logger_name,
const spdlog::filename_char_t* file_name,
bool force_flush,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateSimpleFileLogger(logger_name, file_name, force_flush, MultiThreaded, lp_prop);
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateRotatingFileLogger(const char* logger_name,
const spdlog::filename_char_t* file_name,
const spdlog::filename_char_t* file_ext,
size_t max_file_size,
size_t max_files,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
logger_handle* lpLh = logger_handle_factory::create_rotating_file_logger_p(logger_name, file_name, file_ext, max_file_size, max_files, MultiThreaded);
if (lpLh == nullptr)
return nullptr;
if (lp_prop)
{
lpLh->set_level(lp_prop->Level);
if (lp_prop->FormatString)
lpLh->set_pattern(lp_prop->FormatString);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
// Creates a rotating logfile restricted in file size and number of renamed files
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateOrGetRotatingFileLogger(const char* logger_name,
const spdlog::filename_char_t* file_name,
const spdlog::filename_char_t* file_ext,
size_t max_file_size,
size_t max_files,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateRotatingFileLogger(logger_name, file_name, file_ext, max_file_size, max_files, MultiThreaded, lp_prop);
}
// Creates a logfile that switch over to another file after a specified time.
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateDaylyFileLogger(const char* logger_name,
const spdlog::filename_char_t* file_name,
const spdlog::filename_char_t* file_ext,
int rotation_hour,
int rotation_minute,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
logger_handle* lpLh = logger_handle_factory::create_dayly_file_logger_p(logger_name, file_name, file_ext, rotation_hour, rotation_minute, MultiThreaded);
if (lpLh == NULL)
return nullptr;
if (lp_prop)
{
lpLh->set_level(lp_prop->Level);
if (lp_prop->FormatString)
lpLh->set_pattern(lp_prop->FormatString);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetOrCreateDaylyFileLogger(const char* logger_name,
const spdlog::filename_char_t* file_name,
const spdlog::filename_char_t* file_ext,
int rotation_hour,
int rotation_minute,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateDaylyFileLogger(logger_name, file_name, file_ext, rotation_hour, rotation_minute, MultiThreaded, lp_prop);
}
// Logger for Microsoft Visual Studio (OutputDebugString)
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateMsvcLogger(const char* logger_name,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
logger_handle* lpLh = logger_handle_factory::create_msvc_logger_p(logger_name, MultiThreaded);
if (lpLh == NULL)
return nullptr;
if (lp_prop)
{
lpLh->set_level(lp_prop->Level);
if (lp_prop->FormatString)
lpLh->set_pattern(lp_prop->FormatString);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetOrCreateMsvcLogger(const char* logger_name,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateMsvcLogger(logger_name, MultiThreaded, lp_prop);
}
// Logger mit Ausgabe nach stdout (console)
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateStdoutLogger(const char* logger_name,
bool use_color,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
logger_handle* lpLh = logger_handle_factory::create_stdout_logger_p(logger_name, use_color, MultiThreaded);
if (lpLh == NULL)
return nullptr;
if (lp_prop)
{
lpLh->set_level(lp_prop->Level);
if (lp_prop->FormatString)
lpLh->set_pattern(lp_prop->FormatString);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetOrCreateStdoutLogger(const char* logger_name,
bool use_color,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateStdoutLogger(logger_name, use_color, MultiThreaded, lp_prop);
}
// Logger mit Ausgabe nach stderr (console)
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateStderrLogger(const char* logger_name,
bool use_color,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
logger_handle* lpLh = logger_handle_factory::create_stderr_logger_p(logger_name, use_color, MultiThreaded);
if (lpLh == NULL)
return nullptr;
if (lp_prop)
{
lpLh->set_level(lp_prop->Level);
if (lp_prop->FormatString)
lpLh->set_pattern(lp_prop->FormatString);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetOrCreateStderrLogger(const char* logger_name,
bool use_color,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateStderrLogger(logger_name, use_color, MultiThreaded, lp_prop);
}
// The log functions has the following common parameters:
// log_level: is a value from BevlLogLevelEnum. If this value is lower than the loggers loglevel, the message is filtered out.
// log_bit_flag: this value is compared to the mask from the logger and filtered out if the bit is not set.
SPDLOGLB_API bool SpdLog_LogBf(spdlog::log_handle_t hLogger, unsigned long log_level, unsigned long log_bit_flag, const spdlog::log_char_t* log_string)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
// Direct cast to the enum
return logger_handle_factory::log_bf(hLogger, spdlog::level::level_enum(log_level), log_bit_flag, log_string);
return false;
#else
return false;
#endif
}
SPDLOGLB_API bool SpdLog_LogBfo(spdlog::log_handle_t hLogger, unsigned long log_bit_flag, const spdlog::log_char_t* log_string)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
return logger_handle_factory::log_bfo(hLogger, log_bit_flag, log_string);
#else
return false;
#endif
}
SPDLOGLB_API bool SpdLog_Log(spdlog::log_handle_t hLogger, unsigned long log_level, const spdlog::log_char_t* log_string)
{
return logger_handle_factory::log(hLogger, spdlog::level::level_enum(log_level), log_string);
}
// Formats the log output using printf format style. It uses the original printf functions, is not type safe and does
// not use the format library of Victor Zvervovich, althogh it does supports printf style formating. To use this,
// there are functions in "SpdLog_VarArg" that provide a way to handle variable parameter list in a typesafe way.
SPDLOGLB_API bool SpdLog_LogPrintf(spdlog::log_handle_t hLogger, unsigned long log_level, const spdlog::log_char_t* log_string, ...)
{
va_list args;
va_start(args, log_string);
return SpdLog_vLogPrintf(hLogger, log_level, log_string, args);
}
SPDLOGLB_API bool SpdLog_vLogPrintf(spdlog::log_handle_t hLogger, unsigned long log_level, const spdlog::log_char_t* log_string, va_list args)
{
const unsigned long BUF_SIZE = 1024;
spdlog::log_char_t Buffer[BUF_SIZE];
#ifdef SPDLOG_WCHAR_LOGGING
_vsnwprintf_s(Buffer, BUF_SIZE, log_string, args);
#else
_vsnprintf_s(Buffer, BUF_SIZE, log_string, args);
#endif
return logger_handle_factory::log(hLogger, spdlog::level::level_enum(log_level), Buffer);
}
SPDLOGLB_API bool SpdLog_LogPrintfBf(spdlog::log_handle_t hLogger, unsigned long log_level, unsigned long log_bit_flag, const spdlog::log_char_t* log_string, ...)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
va_list args;
va_start(args, log_string);
return SpdLog_vLogPrintfBf(hLogger, log_level, log_bit_flag, log_string, args);
#else
return false;
#endif // SPDLOG_BITMASK_LOG_FILTER
}
SPDLOGLB_API bool SpdLog_vLogPrintfBf(spdlog::log_handle_t hLogger, unsigned long log_level, unsigned long log_bit_flag, const spdlog::log_char_t* log_string, va_list args)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
const unsigned long BUF_SIZE = 1024;
spdlog::log_char_t Buffer[BUF_SIZE+1];
#ifdef SPDLOG_WCHAR_LOGGING
_vsnwprintf_s(Buffer, BUF_SIZE,_TRUNCATE, log_string, args);
#else
_vsnprintf_s(Buffer, BUF_SIZE, _TRUNCATE, log_string, args);
#endif
return logger_handle_factory::log_bf(hLogger, spdlog::level::level_enum(log_level), log_bit_flag, Buffer);
#else // SPDLOG_BITMASK_LOG_FILTER
return false;
#endif // SPDLOG_BITMASK_LOG_FILTER
}
SPDLOGLB_API bool SpdLog_LogPrintfBfo(spdlog::log_handle_t hLogger, unsigned long log_bit_flag, const spdlog::log_char_t* log_string, ...)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
va_list args;
va_start(args, log_string);
return SpdLog_vLogPrintfBfo(hLogger, log_bit_flag, log_string, args);
#else
return false;
#endif
}
SPDLOGLB_API bool SpdLog_vLogPrintfBfo(spdlog::log_handle_t hLogger, unsigned long log_bit_flag, const spdlog::log_char_t* log_string, va_list args)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
const unsigned long BUF_SIZE = 1024;
spdlog::log_char_t Buffer[BUF_SIZE];
#ifdef SPDLOG_WCHAR_LOGGING
_vsnwprintf_s(Buffer, BUF_SIZE, _TRUNCATE, log_string, args);
#else
_vsnprintf_s(Buffer, BUF_SIZE, _TRUNCATE, log_string, args);
#endif
return logger_handle_factory::log_bfo(hLogger, log_bit_flag, Buffer);
#else // SPDLOG_BITMASK_LOG_FILTER
return false;
#endif // SPDLOG_BITMASK_LOG_FILTER
}
SPDLOGLB_API bool SpdLog_LogFormat(spdlog::log_handle_t hLogger, unsigned long log_level, const spdlog::log_char_t* log_string, vararg_list& args)
{
return logger_handle_factory::log_format(hLogger, spdlog::level::level_enum(log_level), log_string, args);
}
SPDLOGLB_API bool SpdLog_LogFormatBf(spdlog::log_handle_t hLogger, unsigned long log_level, unsigned long log_bit_flag, const spdlog::log_char_t* log_string, vararg_list& args)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
return logger_handle_factory::log_format_bf(hLogger, spdlog::level::level_enum(log_level), log_bit_flag, log_string, args);
#else
return false;
#endif
}
SPDLOGLB_API bool SpdLog_LogFormatBfo(spdlog::log_handle_t hLogger, unsigned long log_bit_flag, const spdlog::log_char_t* log_string, vararg_list& args)
{
#ifdef SPDLOG_BITMASK_LOG_FILTER
return logger_handle_factory::log_format_bfo(hLogger, log_bit_flag, log_string, args);
#else
return false;
#endif
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateOstreamSink(spdlog::std_ostream_t& os, bool force_flush, bool MultiThreaded)
{
try
{
return spdlog::sink_handle_factory::create_ostream_sink(os, MultiThreaded, force_flush);
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_CreateOstreamLogger(const char* logger_name,
spdlog::std_ostream_t& os,
bool force_flush,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
try
{
spdlog::logger_handle* lpLh = logger_handle_factory::create_ostream_logger_p(logger_name, os, force_flush, MultiThreaded);
if (lpLh)
{
if (lp_prop)
{
lpLh->set_pattern(lp_prop->FormatString);
lpLh->set_level(lp_prop->Level);
#ifdef SPDLOG_BITMASK_LOG_FILTER
lpLh->set_enable_bit_mask(lp_prop->LogBitMask);
#endif
}
return lpLh->GetHandle();
}
return nullptr;
}
catch (const std::exception &ex)
{
g_spdloglib_error_manager.on_error(ex.what());
}
catch (...)
{
g_spdloglib_error_manager.on_error("Unknown exception");
}
return nullptr;
}
SPDLOGLB_API spdlog::log_handle_t SpdLog_GetOrCreateOstreamLogger(const char* logger_name,
spdlog::std_ostream_t& os,
bool force_flush,
bool MultiThreaded,
SPDLOGLB_CREATELOGGER_PARAM* lp_prop)
{
spdlog::log_handle_t hExt = logger_handle_factory::get_logger(logger_name);
if (hExt != nullptr)
return hExt;
return SpdLog_CreateOstreamLogger(logger_name, os, force_flush, MultiThreaded, lp_prop);
}
// Have trouble to make it compile using the current buildin format library. Works with tester of the current format
// library. Cancelled at the moment.
//// The same way, just with the printf style format syntax of the format library.
//// Attention: the format specifiers are not neccessarily the same that you know from "printf", look into the doku
//// of the format library. For example, "%S" for a string of the opposite character format (char/wchar) is not supported.
//SPDLOGLB_API bool SpdLog_LogFormatPrintf(spdlog::log_handle_t hLogger, unsigned long log_level, spdlog::log_char_t* log_string, vararg_list& args);
//SPDLOGLB_API bool SpdLog_LogFormatPrintfBf(spdlog::log_handle_t hLogger, unsigned long log_level, unsigned long log_bit_flag, spdlog::log_char_t* log_string, vararg_list& args);
//SPDLOGLB_API bool SpdLog_LogFormatPrintfBfo(spdlog::log_handle_t hLogger, unsigned long log_bit_flag, spdlog::log_char_t* log_string, vararg_list& args);
} // namespace spdlog