namespace FNLog
{
inline void EnterProcDevice(Logger& logger, int channel_id, int deviceid, LogData & log)
{
Channel& channel = logger.shm->channels_[channelid];
Device& device = channel.devices[device_id];
//async promise only single thread proc. needn't lock.
Logger::ReadGuard rg(logger.readlocks[channel_id], channel.channeltype == CHANNEL_ASYNC);
switch (device.outtype)
{
case DEVICE_OUT_FILE:
EnterProcOutFileDevice(logger, channel_id, device_id, log);
break;
case DEVICE_OUT_SCREEN:
EnterProcOutScreenDevice(logger, channel_id, device_id, log);
break;
case DEVICE_OUT_UDP:
EnterProcOutUDPDevice(logger, channel_id, device_id, log);
break;
default:
break;
}
}
inline void DispatchLog(Logger & logger, Channel& channel, LogData& log)
{
for (int device_id = 0; device_id < channel.device_size_; device_id++)
{
Device& device = channel.devices_[device_id];
if (!AtomicLoadC(device, DEVICE_CFG_ABLE))
{
continue;
}
if (log.priority_ < AtomicLoadC(device, DEVICE_CFG_PRIORITY))
{
continue;
}
if (AtomicLoadC(device, DEVICE_CFG_CATEGORY) > 0)
{
if (log.category_ < AtomicLoadC(device, DEVICE_CFG_CATEGORY)
|| log.category_ > AtomicLoadC(device, DEVICE_CFG_CATEGORY) + AtomicLoadC(device, DEVICE_CFG_CATEGORY_EXTEND))
{
continue;
}
}
EnterProcDevice(logger, channel.channel_id_, device_id, log);
}
}
inline void EnterProcChannel(Logger& logger, int channel_id)
{
Channel& channel = logger.shm_->channels_[channel_id];
RingBuffer& ring_buffer = logger.shm_->ring_buffers_[channel_id];
do
{
int local_write_count = 0;
do
{
int old_idx = ring_buffer.proc_idx_.load(std::memory_order_acquire);
int next_idx = (old_idx + 1) % RingBuffer::BUFFER_LEN;
if (old_idx == ring_buffer.write_idx_.load(std::memory_order_acquire))
{
//empty branch
break;
}
//set proc index
if (!ring_buffer.proc_idx_.compare_exchange_strong(old_idx, next_idx))
{
//only one thread get log. this branch will not hit.
break;
}
auto& cur_log = ring_buffer.buffer_[old_idx];
DispatchLog(logger, channel, cur_log);
cur_log.data_mark_ = 0;
AtomicAddL(channel, CHANNEL_LOG_PROCESSED);
local_write_count ++;
do
{
//set read index to proc index
old_idx = ring_buffer.read_idx_.load(std::memory_order_acquire);
next_idx = (old_idx + 1) % RingBuffer::BUFFER_LEN;
if (old_idx == ring_buffer.proc_idx_.load(std::memory_order_acquire))
{
break;
}
if (ring_buffer.buffer_[old_idx].data_mark_.load(std::memory_order_acquire) != MARK_INVALID)
{
break;
}
ring_buffer.read_idx_.compare_exchange_strong(old_idx, next_idx);
} while (true);
//if want the high log security can reduce this threshold or enable shared memory queue.
if (local_write_count > 10000)
{
local_write_count = 0;
for (int i = 0; i < channel.device_size_; i++)
{
if (channel.devices_[i].out_type_ == DEVICE_OUT_FILE)
{
logger.file_handles_[channel_id * Channel::MAX_DEVICE_SIZE + i].flush();
}
}
}
} while (true);
if (channel.channel_state_ == CHANNEL_STATE_NULL)
{
channel.channel_state_ = CHANNEL_STATE_RUNNING;
}
if (local_write_count)
{
for (int i = 0; i < channel.device_size_; i++)
{
if (channel.devices_[i].out_type_ == DEVICE_OUT_FILE)
{
logger.file_handles_[channel_id * Channel::MAX_DEVICE_SIZE + i].flush();
}
}
}
HotUpdateLogger(logger, channel.channel_id_);
if (channel.channel_type_ == CHANNEL_ASYNC)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
} while (channel.channel_type_ == CHANNEL_ASYNC
&& (channel.channel_state_ == CHANNEL_STATE_RUNNING || ring_buffer.write_idx_ != ring_buffer.read_idx_));
if (channel.channel_type_ == CHANNEL_ASYNC)
{
channel.channel_state_ = CHANNEL_STATE_FINISH;
}
}
inline void InitLogData(Logger& logger, LogData& log, int channel_id, int priority, int category, unsigned int prefix)
{
log.channel_id_ = channel_id;
log.priority_ = priority;
log.category_ = category;
log.content_len_ = 0;
log.content_[log.content_len_] = '\0';
ifdef WIN32
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
unsigned long long now = ft.dwHighDateTime;
now <<= 32;
now |= ft.dwLowDateTime;
now /= 10;
now -= 11644473600000000ULL;
now /= 1000;
log.timestamp_ = now / 1000;
log.precise_ = (unsigned int)(now % 1000);
用 borland clang 编译器不通过,对 fn_log.h 做了适当修改宏 , `/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_FILEH
define _FN_LOG_FILEH
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
ifdef _WIN32
define WIN32
endif
ifdef WIN32
ifndef KEEP_INPUT_QUICK_EDIT
define KEEP_INPUT_QUICK_EDIT false
endif
define WIN32_LEAN_AND_MEAN
include
include
include
include
include
pragma comment(lib, "shlwapi")
pragma comment(lib, "User32.lib")
pragma comment(lib,"ws2_32.lib")
pragma warning(disable:4996)
else
include
include <netinet/in.h>
include <arpa/inet.h>
include <sys/types.h>
include <sys/socket.h>
include <sys/time.h>
include <sys/stat.h>
include
include
include
include <sys/syscall.h>
include <sys/ipc.h>
include <sys/shm.h>
#
endif
ifdef APPLE
include "TargetConditionals.h"
include <dispatch/dispatch.h>
if !TARGET_OS_IPHONE
define NFLOG_HAVE_LIBPROC
include
endif
endif
ifdef BORLANDC
include
include <sys/stat.h>
define atoll _atoi64
ifndef DEF_FUNC_BUILTIN
define DEF_FUNC_BUILTIN
unsigned char _BitScanReverse64(unsigned long Index, unsigned long long Mask ) { Index = sizeof(Mask) * 8 - __builtin_clzll(Mask);
}
endif
define isinf _isinf
define isnan _isnan
define fpclassify _fpclass
define FP_NAN _FPCLASS_SNAN
define FP_INFINITE _FPCLASS_NINF
define _snprintf_s(a,b,c,d,...) snprintf_s(a,b,d,##__VA_ARGS__)
endif
namespace FNLog { using namespace std; static const int CHUNK_SIZE = 128; class FileHandler { public: inline FileHandler(); inline ~FileHandler(); inline bool is_open(); inline long open(const char path, const char mod, struct stat& file_stat); inline void close(); inline void write(const char* data, size_t len); inline void flush();
if !defined(APPLE) && !defined(WIN32)
endif
ifdef WIN32
else
endif
ifdef WIN32
else
endif
ifdef WIN32
else
endif
ifdef WIN32
else
endif
ifdef WIN32
elif defined(APPLE)
else
endif
ifdef WIN32
if _MSC_VER < 1400 //VS2003
else //vs2005->vs2013->
endif
else //linux
endif
}
class UDPHandler { public:
ifndef WIN32
endif
public: UDPHandler() { handler_ = INVALIDSOCKET; } ~UDPHandler() { if (handler != INVALID_SOCKET) { close(); } }
ifndef WIN32
else
endif
public: char chunk1[128]; SOCKET handler_; };
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_DATAH
define _FN_LOG_DATAH
ifndef FN_LOG_MAX_CHANNEL_SIZE
define FN_LOG_MAX_CHANNEL_SIZE 2
endif
ifndef FN_LOG_MAX_LOG_SIZE
define FN_LOG_MAX_LOG_SIZE 1000
endif
ifndef FN_LOG_MAX_LOG_QUEUE_SIZE //the size need big than push log thread count
define FN_LOG_MAX_LOG_QUEUE_SIZE 10000
endif
ifndef FN_LOG_HOTUPDATE_INTERVEL
define FN_LOG_HOTUPDATE_INTERVEL 5
endif
ifndef FN_LOG_USE_SHM
define FN_LOG_USE_SHM 0
endif
ifndef FN_LOG_SHM_KEY
define FN_LOG_SHM_KEY 0x9110
endif
namespace FNLog { enum LogPriority { PRIORITY_TRACE = 0, PRIORITY_DEBUG, PRIORITY_INFO, PRIORITY_WARN, PRIORITY_ERROR, PRIORITY_ALARM, PRIORITY_FATAL, PRIORITY_MAX }; enum LogPrefix { LOG_PREFIX_NULL = 0x0, LOG_PREFIX_TIMESTAMP = 0x1, LOG_PREFIX_PRIORITY = 0x2, LOG_PREFIX_THREAD = 0x4, LOG_PREFIX_FILE = 0x8, LOG_PREFIX_FUNCTION = 0x10, LOG_PREFIX_ALL = 0xff };
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_PARSEH
define _FN_LOG_PARSEH
namespace FNLog { enum ParseErrorCode { PEC_NONE, PEC_ERROR, PEC_ILLEGAL_CHARACTER, PEC_ILLEGAL_KEY, PEC_NOT_CLOSURE, PEC_ILLEGAL_ADDR_IP, PEC_ILLEGAL_ADDR_PORT,
if GNUG && GNUC >= 5
pragma GCC diagnostic push
pragma GCC diagnostic ignored "-Wclass-memaccess"
endif
if GNUG && GNUC >= 5
pragma GCC diagnostic pop
endif
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_FMTH
define _FN_LOG_FMTH
namespace FNLog {
ifndef WIN32
else
endif
ifndef WIN32
else
endif
ifndef WIN32
else
endif
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_LOADH
define _FN_LOG_LOADH
include
namespace FNLog {
if GNUG && GNUC >= 5
pragma GCC diagnostic push
pragma GCC diagnostic ignored "-Wclass-memaccess"
endif
if GNUG && GNUC >= 5
pragma GCC diagnostic pop
endif
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_OUT_FILE_DEVICEH
define _FN_LOG_OUT_FILE_DEVICEH
namespace FNLog {
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_OUT_UDP_DEVICEH
define _FN_LOG_OUT_UDP_DEVICEH
namespace FNLog {
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_OUT_SCREEN_DEVICEH
define _FN_LOG_OUT_SCREEN_DEVICEH
namespace FNLog {
ifndef WIN32
else
endif
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_CHANNELH
define _FN_LOG_CHANNELH
namespace FNLog { inline void EnterProcDevice(Logger& logger, int channel_id, int deviceid, LogData & log) { Channel& channel = logger.shm->channels_[channelid]; Device& device = channel.devices[device_id]; //async promise only single thread proc. needn't lock. Logger::ReadGuard rg(logger.readlocks[channel_id], channel.channeltype == CHANNEL_ASYNC); switch (device.outtype) { case DEVICE_OUT_FILE: EnterProcOutFileDevice(logger, channel_id, device_id, log); break; case DEVICE_OUT_SCREEN: EnterProcOutScreenDevice(logger, channel_id, device_id, log); break; case DEVICE_OUT_UDP: EnterProcOutUDPDevice(logger, channel_id, device_id, log); break; default: break; } }
ifdef WIN32
else
endif
ifdef WIN32
elif defined(APPLE)
else
endif
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_COREH
define _FN_LOG_COREH
namespace FNLog {
if GNUG && GNUC >= 5
pragma GCC diagnostic push
pragma GCC diagnostic ignored "-Wclass-memaccess"
endif
if FN_LOG_USE_SHM && !defined(WIN32)
else
endif
if FN_LOG_USE_SHM && !defined(WIN32)
else
endif
if ((defined WIN32) && !KEEP_INPUT_QUICK_EDIT)
endif
if GNUG && GNUC >= 5
pragma GCC diagnostic pop
endif
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_STREAMH
define _FN_LOG_STREAMH
namespace FNLog { class LogStream { public: static const int MAX_CONTAINERDEPTH = 5; public: LogStream(const LogStream& other) = delete; LogStream(LogStream&& other) noexcept { logger = other.logger_; logdata = other.logdata; holdidx = other.holdidx; other.logger_ = nullptr; other.logdata = nullptr; other.holdidx = -1; }
}
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_MACROH
define _FN_LOG_MACROH
namespace FNLog {
default channel 0
write full log to pname.log
write error log to pname_error.log
view info log to screen
sync channel 1
write full log to pname.log
write info log to pname_info.log
view info log to screen
channel: 1 sync: sync -device: 0 disable: false out_type: file file: "$PNAME_sync" rollback: 4 limit_size: 100 m #only support M byte -device: 1 disable: false out_type: file priority: info file: "$PNAME_sync_info" rollback: 4 limit_size: 100 m #only support M byte -device:2 disable: false out_type: screen priority: info )----"; return FastStartDefaultLogger(default_config_text); }
inline int FastStartDebugLogger() { int ret = FastStartDefaultLogger(); if (ret == 0) { BatchSetDeviceConfig(GetDefaultLogger(), DEVICE_OUT_FILE, DEVICE_CFG_PRIORITY, PRIORITY_TRACE); SetDeviceConfig(GetDefaultLogger(), 0, 1, DEVICE_CFG_PRIORITY, PRIORITY_ERROR); //error file is still error file
BatchSetDeviceConfig(GetDefaultLogger(), DEVICE_OUT_SCREEN, DEVICE_CFG_PRIORITY, PRIORITY_DEBUG); } return ret; } }
//--------------------BASE STREAM MACRO ---------------------------
define LOG_STREAM_ORIGIN(logger, channel, priority, category, prefix) \
FNLog::LogStream(logger, channel, priority, category, \ FILE, sizeof(FILE) - 1, \ LINE, FUNCTION, sizeof(FUNCTION) -1, prefix)
define LOG_STREAM_DEFAULT_LOGGER(channel, priority, category, prefix) \
define LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel, priority, category) \
//--------------------CPP STREAM STYLE FORMAT ---------------------------
define LogTraceStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_TRACE, category)
define LogDebugStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_DEBUG, category)
define LogInfoStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_INFO, category)
define LogWarnStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_WARN, category)
define LogErrorStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_ERROR, category)
define LogAlarmStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_ALARM, category)
define LogFatalStream(channel_id, category) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_FATAL, category)
define LogTrace() LogTraceStream(0, 0)
define LogDebug() LogDebugStream(0, 0)
define LogInfo() LogInfoStream(0, 0)
define LogWarn() LogWarnStream(0, 0)
define LogError() LogErrorStream(0, 0)
define LogAlarm() LogAlarmStream(0, 0)
define LogFatal() LogFatalStream(0, 0)
//--------------------CPP TEMPLATE STYLE FORMAT --------------------------- inline FNLog::LogStream& LogTemplatePack(FNLog::LogStream&& ls) { return ls; } template<typename ... Args> FNLog::LogStream& LogTemplatePack(FNLog::LogStream&& ls, Args&& ... args) { char buff[] = { (ls << args, '\0') ... }; (void)buff; return ls; }
define LogTracePack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_TRACE, category), ##__VA_ARGS__)
define LogDebugPack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_DEBUG, category), ##__VA_ARGS__)
define LogInfoPack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_INFO, category), ##__VA_ARGS__)
define LogWarnPack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_WARN, category), ##__VA_ARGS__)
define LogErrorPack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_ERROR, category), ##__VA_ARGS__)
define LogAlarmPack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_ALARM, category), ##__VA_ARGS__)
define LogFatalPack(channel_id, category, ...) LogTemplatePack(LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_FATAL, category), ##__VA_ARGS__)
define PackTrace(...) LogTracePack(0, 0, ##__VA_ARGS__)
define PackDebug(...) LogDebugPack(0, 0, ##__VA_ARGS__)
define PackInfo( ...) LogInfoPack( 0, 0, ##__VA_ARGS__)
define PackWarn( ...) LogWarnPack( 0, 0, ##__VA_ARGS__)
define PackError(...) LogErrorPack(0, 0, ##__VA_ARGS__)
define PackAlarm(...) LogAlarmPack(0, 0, ##__VA_ARGS__)
define PackFatal(...) LogFatalPack(0, 0, ##__VA_ARGS__)
//--------------------CPP MACRO STREAM STYLE FORMAT ---------------------------
define LOG_TRACE(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_TRACE, category) << log
define LOG_DEBUG(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_DEBUG, category) << log
define LOG_INFO(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_INFO, category) << log
define LOG_WARN(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_WARN, category) << log
define LOG_ERROR(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_ERROR, category) << log
define LOG_ALARM(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_ALARM, category) << log
define LOG_FATAL(channel_id, category, log) LOG_STREAM_DEFAULT_LOGGER_WITH_PREFIX(channel_id, FNLog::PRIORITY_FATAL, category) << log
define LOGT(log) LOG_TRACE(0, 0, log)
define LOGD(log) LOG_DEBUG(0, 0, log)
define LOGI(log) LOG_INFO(0, 0, log)
define LOGW(log) LOG_WARN(0, 0, log)
define LOGE(log) LOG_ERROR(0, 0, log)
define LOGA(log) LOG_ALARM(0, 0, log)
define LOGF(log) LOG_FATAL(0, 0, log)
//--------------------C STYLE FORMAT ---------------------------
ifdef WIN32
define LOG_FORMAT(channel_id, priority, category, prefix, logformat, ...) \
do{ \ if (FNLog::FastCheckPriorityPass(FNLog::GetDefaultLogger(), channel_id, priority, category)) \ { \ break; \ } \ FNLog::LogStream log_stream(LOG_STREAM_DEFAULT_LOGGER(channel_id, priority, category, prefix));\ if (__log_stream.logdata)\ {\ int log_len = _snprintf_s(log_stream.logdata ->content_ + log_stream.logdata ->contentlen, FNLog::LogData::LOG_SIZE - log_stream.logdata ->contentlen, _TRUNCATE, logformat, ##VA_ARGS); \ if (log_len < 0) log_len = 0; \ __log_stream.logdata ->contentlen += log_len; \ }\ } while (0)
else
define LOG_FORMAT(channel_id, priority, category, prefix, logformat, ...) \
do{ \ if (FNLog::FastCheckPriorityPass(FNLog::GetDefaultLogger(), channel_id, priority, category)) \ { \ break; \ } \ FNLog::LogStream log_stream(LOG_STREAM_DEFAULT_LOGGER(channel_id, priority, category, prefix));\ if (__log_stream.logdata)\ {\ int log_len = snprintf(log_stream.logdata ->content_ + log_stream.logdata ->contentlen, FNLog::LogData::LOG_SIZE - log_stream.logdata ->contentlen, logformat, ##__VA_ARGS); \ if (log_len < 0) __log_len = 0; \ log_stream.logdata ->contentlen += __log_len; \ }\ } while (0)
endif
define LOGFMT_TRACE(channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_TRACE, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMT_DEBUG(channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_DEBUG, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMT_INFO( channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_INFO, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMT_WARN( channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_WARN, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMT_ERROR(channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_ERROR, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMT_ALARM(channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_ALARM, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMT_FATAL(channel_id, category, fmt, ...) LOG_FORMAT(channel_id, FNLog::PRIORITY_FATAL, category, FNLog::LOG_PREFIX_ALL, fmt, ##__VA_ARGS__)
define LOGFMTT(fmt, ...) LOGFMT_TRACE(0, 0, fmt, ##__VA_ARGS__)
define LOGFMTD(fmt, ...) LOGFMT_DEBUG(0, 0, fmt, ##__VA_ARGS__)
define LOGFMTI(fmt, ...) LOGFMT_INFO( 0, 0, fmt, ##__VA_ARGS__)
define LOGFMTW(fmt, ...) LOGFMT_WARN( 0, 0, fmt, ##__VA_ARGS__)
define LOGFMTE(fmt, ...) LOGFMT_ERROR(0, 0, fmt, ##__VA_ARGS__)
define LOGFMTA(fmt, ...) LOGFMT_ALARM(0, 0, fmt, ##__VA_ARGS__)
define LOGFMTF(fmt, ...) LOGFMT_FATAL(0, 0, fmt, ##__VA_ARGS__)
endif
/
(end of COPYRIGHT) */
/*
pragma once
ifndef _FN_LOG_LOGH
define _FN_LOG_LOGH
namespace FNLog
{
define BatchSetChannelCategoryMacro(begin, count) \
define BatchSetDeviceCategoryMacro(out_type, begin, count) \
}
endif`