From 9a607474bdd66dd716635cfed7f2c832c39b4523 Mon Sep 17 00:00:00 2001 From: Andy Wortman Date: Thu, 14 Mar 2019 15:52:30 -0700 Subject: add qhy headers......... --- include/qhy/log4z.h | 630 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 include/qhy/log4z.h (limited to 'include/qhy/log4z.h') diff --git a/include/qhy/log4z.h b/include/qhy/log4z.h new file mode 100644 index 0000000..a1995f1 --- /dev/null +++ b/include/qhy/log4z.h @@ -0,0 +1,630 @@ +/* + * Log4z License + * ----------- + * + * Log4z is licensed under the terms of the MIT license reproduced below. + * This means that Log4z is free software and can be used for both academic + * and commercial purposes at absolutely no cost. + * + * + * =============================================================================== + * + * Copyright (C) 2010-2014 YaweiZhang . + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * =============================================================================== + * + * (end of COPYRIGHT) + */ + + +/* + * AUTHORS: YaweiZhang + * VERSION: 3.0.0 + * PURPOSE: A lightweight library for error reporting and logging to file and screen . + * CREATION: 2010.10.4 + * LCHANGE: 2014.12.19 + * LICENSE: Expat/MIT License, See Copyright Notice at the begin of this file. + */ + + +/* + * contact me: + * tencent qq group: 19811947 + * mail: yawei_zhang@foxmail.com + */ + + +/* + * UPDATES LOG + * + * VERSION 0.1.0 + * create the first project. + * It support put log to screen and files, + * support log level, support one day one log file. + * support multi-thread, cross-platform. + * + * VERSION .... + * ... + * + * VERSION 0.9.0 + * support config files. + * support color text in screen. + * support multiple output to different files. + * + * VERSION 1.0.0 + * support comments in the config file. + * add a advanced demo in the ./project + * fix some details. + * + * VERSION 1.0.1 + * change and add some Comments in the log4z + * simplify the 'fast_test' demo projects. + * + * VERSION 1.1.0 + * the method Start will wait for the logger thread started. + * config and add method change. + * namespace change. + * + * VERSION 1.1.1 + * add status info method. + * optimize. + * + * VERSION 1.2.0 + * add stress test demo + * rewrite Stream module,better performance. + * + * VERSION 1.2.1 + * fixed type name 'long' stream format on 64/32 operation system. + * logger will not loss any log on process normal exit. + * + * VERSION 2.0.0 + * new interface: + * merge some Main interface and Dynamic interface + * add Change Logger Attribute method by thread-safe + * new config design. + * log file name append process id. + * + * VERSION 2.1 + * support binary text output + * rewrite write file module, support vs2005 open Chinese characters path + * + * VERSION 2.2 + * optimized binary stream output view + * support wchar * string. + * + * VERSION 2.3 + * adjust output file named. + * support different month different directory. + * adjust some detail. + * + * VERSION 2.4 + * support rolling log file. + * support hot update configure + * used precision time in log. + * micro set default logger attribute + * fix tls bug in windows xp dll + * + * VERSION 2.5 + * screen output can choice synchronous or not + * fix sometimes color will disorder on windows. + * eliminate some compiler warning + * fix sem_timewait in linux + * add format-style method at input log, cannot support vs2003 and VC6. + * fix WCHAR String cannot output + * optimize std::string, binary log input, and support std::wstring. + * clean code, better readability + * + * VERSION 2.6 + * add PrePushLog + * better performance when log is filter out. + * interface replace std::string because it's in shared library is unsafe. + * add log level 'trace' + * + * VERSION 2.6.1 + * fix bug from defined _MSC_VER + * + * VERSION 2.7 + * compatible mac machine, now log4z can working in linux/windows/mac. + * + * VERSION 2.8 + * support synchronous written to file and thread-safe + * fix compatibility on MinGW. a constant value suffix. + * ignore utf-8 file BOM when load configure file + * use macro WIN32_LEAN_AND_MEAN replace head file winsock2.h + * new naming notations + * + * VERSION 3.0 + * new naming notations + * support for reading config from a string. + * remove all TLS code, used dispatch_semaphore in apple OS. + * support system: windows, linux, mac, iOS + * + */ + + +#pragma once +#ifndef _ZSUMMER_LOG4Z_H_ +#define _ZSUMMER_LOG4Z_H_ + +#include +#include +#include +#include +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + +//! logger ID type. DO NOT TOUCH +typedef int LoggerId; + +//! the invalid logger id. DO NOT TOUCH +const int LOG4Z_INVALID_LOGGER_ID = -1; + +//! the main logger id. DO NOT TOUCH +//! can use this id to set the main logger's attribute. +//! example: +//! ILog4zManager::getPtr()->setLoggerLevel(LOG4Z_MAIN_LOGGER_ID, LOG_LEVEL_WARN); +//! ILog4zManager::getPtr()->setLoggerDisplay(LOG4Z_MAIN_LOGGER_ID, false); +const int LOG4Z_MAIN_LOGGER_ID = 0; + +//! the main logger name. DO NOT TOUCH +const char*const LOG4Z_MAIN_LOGGER_KEY = "Main"; + +//! check VC VERSION. DO NOT TOUCH +//! format micro cannot support VC6 or VS2003, please use stream input log, like LOGI, LOGD, LOG_DEBUG, LOG_STREAM ... +#if _MSC_VER >= 1400 //MSVC >= VS2005 +#define LOG4Z_FORMAT_INPUT_ENABLE +#endif + +#ifndef WIN32 +#define LOG4Z_FORMAT_INPUT_ENABLE +#endif + +//! LOG Level +enum ENUM_LOG_LEVEL +{ + LOG_LEVEL_TRACE = 0, + LOG_LEVEL_DEBUG, + LOG_LEVEL_INFO, + LOG_LEVEL_WARN, + LOG_LEVEL_ERROR, + LOG_LEVEL_ALARM, + LOG_LEVEL_FATAL, +}; + +////////////////////////////////////////////////////////////////////////// +//! -----------------default logger config, can change on this.----------- +////////////////////////////////////////////////////////////////////////// +//! the max logger count. +const int LOG4Z_LOGGER_MAX = 10; +//! the max log content length. +const int LOG4Z_LOG_BUF_SIZE = 2048; + +//! all logger synchronous output or not +const bool LOG4Z_ALL_SYNCHRONOUS_OUTPUT = false; +//! all logger synchronous display to the windows debug output +const bool LOG4Z_ALL_DEBUGOUTPUT_DISPLAY = false; + +//! default logger output file. +const char* const LOG4Z_DEFAULT_PATH = "./log/"; +//! default log filter level +const int LOG4Z_DEFAULT_LEVEL = LOG_LEVEL_DEBUG; +//! default logger display +const bool LOG4Z_DEFAULT_DISPLAY = true; +//! default logger output to file +const bool LOG4Z_DEFAULT_OUTFILE = true; +//! default logger month dir used status +const bool LOG4Z_DEFAULT_MONTHDIR = false; +//! default logger output file limit size, unit M byte. +const int LOG4Z_DEFAULT_LIMITSIZE = 100; +//! default logger show suffix (file name and line number) +const bool LOG4Z_DEFAULT_SHOWSUFFIX = true; + +/////////////////////////////////////////////////////////////////////////// +//! ----------------------------------------------------------------------- +////////////////////////////////////////////////////////////////////////// + + + + + +#ifndef _ZSUMMER_BEGIN +#define _ZSUMMER_BEGIN namespace zsummer { +#endif +#ifndef _ZSUMMER_LOG4Z_BEGIN +#define _ZSUMMER_LOG4Z_BEGIN namespace log4z { +#endif +_ZSUMMER_BEGIN +_ZSUMMER_LOG4Z_BEGIN + + + + +//! log4z class +class ILog4zManager +{ +public: + ILog4zManager(){}; + virtual ~ILog4zManager(){}; + + //! Log4z Singleton + + static ILog4zManager * getInstance(); + inline static ILog4zManager & getRef(){return *getInstance();} + inline static ILog4zManager * getPtr(){return getInstance();} + + //! Config or overwrite configure + //! Needs to be called before ILog4zManager::Start,, OR Do not call. + virtual bool config(const char * configPath) = 0; + virtual bool configFromString(const char * configContent) = 0; + + //! Create or overwrite logger. + //! Needs to be called before ILog4zManager::Start, OR Do not call. + virtual LoggerId createLogger(const char* key) = 0; + + //! Start Log Thread. This method can only be called once by one process. + virtual bool start() = 0; + + //! Default the method will be calling at process exit auto. + //! Default no need to call and no recommended. + virtual bool stop() = 0; + + //! Find logger. thread safe. + virtual LoggerId findLogger(const char* key) =0; + + //pre-check the log filter. if filter out return false. + virtual bool prePushLog(LoggerId id, int level) = 0; + //! Push log, thread safe. + virtual bool pushLog(LoggerId id, int level, const char * log, const char * file = NULL, int line = 0) = 0; + + //! set logger's attribute, thread safe. + virtual bool enableLogger(LoggerId id, bool enable) = 0; + virtual bool setLoggerName(LoggerId id, const char * name) = 0; + virtual bool setLoggerPath(LoggerId id, const char * path) = 0; + virtual bool setLoggerLevel(LoggerId id, int nLevel) = 0; + virtual bool setLoggerFileLine(LoggerId id, bool enable) = 0; + virtual bool setLoggerDisplay(LoggerId id, bool enable) = 0; + virtual bool setLoggerOutFile(LoggerId id, bool enable) = 0; + virtual bool setLoggerLimitsize(LoggerId id, unsigned int limitsize) = 0; + virtual bool setLoggerMonthdir(LoggerId id, bool enable) = 0; + + + //! Update logger's attribute from config file, thread safe. + virtual bool setAutoUpdate(int interval/*per second, 0 is disable auto update*/) = 0; + virtual bool updateConfig() = 0; + + //! Log4z status statistics, thread safe. + virtual bool isLoggerEnable(LoggerId id) = 0; + virtual unsigned long long getStatusTotalWriteCount() = 0; + virtual unsigned long long getStatusTotalWriteBytes() = 0; + virtual unsigned long long getStatusWaitingCount() = 0; + virtual unsigned int getStatusActiveLoggers() = 0; +}; + +class Log4zStream; +class Log4zBinary; + +#ifndef _ZSUMMER_END +#define _ZSUMMER_END } +#endif +#ifndef _ZSUMMER_LOG4Z_END +#define _ZSUMMER_LOG4Z_END } +#endif + +_ZSUMMER_LOG4Z_END +_ZSUMMER_END + + + +//! base micro. +#define LOG_STREAM(id, level, log)\ +{\ + if (zsummer::log4z::ILog4zManager::getPtr()->prePushLog(id,level)) \ + {\ + char logBuf[LOG4Z_LOG_BUF_SIZE];\ + zsummer::log4z::Log4zStream ss(logBuf, LOG4Z_LOG_BUF_SIZE);\ + ss << log;\ + zsummer::log4z::ILog4zManager::getPtr()->pushLog(id, level, logBuf, __FILE__, __LINE__);\ + }\ +} + + +//! fast micro +#define LOG_TRACE(id, log) LOG_STREAM(id, LOG_LEVEL_TRACE, log) +#define LOG_DEBUG(id, log) LOG_STREAM(id, LOG_LEVEL_DEBUG, log) +#define LOG_INFO(id, log) LOG_STREAM(id, LOG_LEVEL_INFO, log) +#define LOG_WARN(id, log) LOG_STREAM(id, LOG_LEVEL_WARN, log) +#define LOG_ERROR(id, log) LOG_STREAM(id, LOG_LEVEL_ERROR, log) +#define LOG_ALARM(id, log) LOG_STREAM(id, LOG_LEVEL_ALARM, log) +#define LOG_FATAL(id, log) LOG_STREAM(id, LOG_LEVEL_FATAL, log) + +//! super micro. +#define LOGT( log ) LOG_TRACE(LOG4Z_MAIN_LOGGER_ID, log ) +#define LOGD( log ) LOG_DEBUG(LOG4Z_MAIN_LOGGER_ID, log ) +#define LOGI( log ) LOG_INFO(LOG4Z_MAIN_LOGGER_ID, log ) +#define LOGW( log ) LOG_WARN(LOG4Z_MAIN_LOGGER_ID, log ) +#define LOGE( log ) LOG_ERROR(LOG4Z_MAIN_LOGGER_ID, log ) +#define LOGA( log ) LOG_ALARM(LOG4Z_MAIN_LOGGER_ID, log ) +#define LOGF( log ) LOG_FATAL(LOG4Z_MAIN_LOGGER_ID, log ) + + +//! format input log. +#ifdef LOG4Z_FORMAT_INPUT_ENABLE +#ifdef WIN32 +#define LOG_FORMAT(id, level, logformat, ...) \ +{ \ + if (zsummer::log4z::ILog4zManager::getPtr()->prePushLog(id,level)) \ + {\ + char logbuf[LOG4Z_LOG_BUF_SIZE]; \ + _snprintf_s(logbuf, LOG4Z_LOG_BUF_SIZE, _TRUNCATE, logformat, ##__VA_ARGS__); \ + zsummer::log4z::ILog4zManager::getPtr()->pushLog(id, level, logbuf, __FILE__, __LINE__); \ + }\ + } +#else +#define LOG_FORMAT(id, level, logformat, ...) \ +{ \ + if (zsummer::log4z::ILog4zManager::getPtr()->prePushLog(id,level)) \ + {\ + char logbuf[LOG4Z_LOG_BUF_SIZE]; \ + snprintf(logbuf, LOG4Z_LOG_BUF_SIZE,logformat, ##__VA_ARGS__); \ + zsummer::log4z::ILog4zManager::getPtr()->pushLog(id, level, logbuf, __FILE__, __LINE__); \ + } \ +} +#endif +//!format string +#define LOGFMT_TRACE(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__) +#define LOGFMT_DEBUG(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__) +#define LOGFMT_INFO(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_INFO, fmt, ##__VA_ARGS__) +#define LOGFMT_WARN(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_WARN, fmt, ##__VA_ARGS__) +#define LOGFMT_ERROR(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__) +#define LOGFMT_ALARM(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_ALARM, fmt, ##__VA_ARGS__) +#define LOGFMT_FATAL(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_FATAL, fmt, ##__VA_ARGS__) +#define LOGFMTT( fmt, ...) LOGFMT_TRACE(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#define LOGFMTD( fmt, ...) LOGFMT_DEBUG(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#define LOGFMTI( fmt, ...) LOGFMT_INFO(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#define LOGFMTW( fmt, ...) LOGFMT_WARN(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#define LOGFMTE( fmt, ...) LOGFMT_ERROR(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#define LOGFMTA( fmt, ...) LOGFMT_ALARM(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#define LOGFMTF( fmt, ...) LOGFMT_FATAL(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__) +#else +inline void empty_log_format_function1(LoggerId id, const char*, ...){} +inline void empty_log_format_function2(const char*, ...){} +#define LOGFMT_TRACE empty_log_format_function1 +#define LOGFMT_DEBUG LOGFMT_TRACE +#define LOGFMT_INFO LOGFMT_TRACE +#define LOGFMT_WARN LOGFMT_TRACE +#define LOGFMT_ERROR LOGFMT_TRACE +#define LOGFMT_ALARM LOGFMT_TRACE +#define LOGFMT_FATAL LOGFMT_TRACE +#define LOGFMTT empty_log_format_function2 +#define LOGFMTD LOGFMTT +#define LOGFMTI LOGFMTT +#define LOGFMTW LOGFMTT +#define LOGFMTE LOGFMTT +#define LOGFMTA LOGFMTT +#define LOGFMTF LOGFMTT +#endif + + +_ZSUMMER_BEGIN +_ZSUMMER_LOG4Z_BEGIN + +//! optimze from std::stringstream to Log4zStream +#ifdef WIN32 +#pragma warning(push) +#pragma warning(disable:4996) +#endif +class Log4zBinary +{ +public: + Log4zBinary(const char * buf, int len) + { + _buf = buf; + _len = len; + } + const char * _buf; + int _len; +}; +class Log4zStream +{ +public: + inline Log4zStream(char * buf, int len); + inline int getCurrentLen(){return (int)(_cur - _begin);} +private: + template + inline Log4zStream & writeData(const char * ft, T t); + inline Log4zStream & writeLongLong(long long t); + inline Log4zStream & writeULongLong(unsigned long long t); + inline Log4zStream & writePointer(const void * t); + inline Log4zStream & writeString(const wchar_t* t){ return writeData("%s", t); } + inline Log4zStream & writeWString(const wchar_t* t); + inline Log4zStream & writeBinary(const Log4zBinary & t); +public: + inline Log4zStream & operator <<(const void * t){ return writePointer(t); } + + inline Log4zStream & operator <<(const char * t){return writeData("%s", t);} +#ifdef WIN32 + inline Log4zStream & operator <<(const wchar_t * t){ return writeWString(t);} +#endif + inline Log4zStream & operator <<(bool t){ return (t ? writeData("%s", "true") : writeData("%s", "false"));} + + inline Log4zStream & operator <<(char t){return writeData("%c", t);} + + inline Log4zStream & operator <<(unsigned char t){return writeData("%u",(unsigned int)t);} + + inline Log4zStream & operator <<(short t){ return writeData("%d", (int)t); } + + inline Log4zStream & operator <<(unsigned short t){ return writeData("%u", (unsigned int)t); } + + inline Log4zStream & operator <<(int t){return writeData("%d", t);} + + inline Log4zStream & operator <<(unsigned int t){return writeData("%u", t);} + + inline Log4zStream & operator <<(long t) { return writeLongLong(t); } + + inline Log4zStream & operator <<(unsigned long t){ return writeULongLong(t); } + + inline Log4zStream & operator <<(long long t) { return writeLongLong(t); } + + inline Log4zStream & operator <<(unsigned long long t){ return writeULongLong(t); } + + inline Log4zStream & operator <<(float t){return writeData("%.4f", t);} + + inline Log4zStream & operator <<(double t){return writeData("%.4lf", t);} + + template //support std::string, std::wstring + inline Log4zStream & operator <<(const std::basic_string<_Elem, _Traits, _Alloc> & t){ return *this << t.c_str(); } + + inline Log4zStream & operator << (const zsummer::log4z::Log4zBinary & binary){ return writeBinary(binary); } + +private: + Log4zStream(){} + Log4zStream(Log4zStream &){} + char * _begin; + char * _end; + char * _cur; +}; + +inline Log4zStream::Log4zStream(char * buf, int len) +{ + _begin = buf; + _end = buf + len; + _cur = _begin; +} + +template +inline Log4zStream& Log4zStream::writeData(const char * ft, T t) +{ + if (_cur < _end) + { + int len = 0; + int count = (int)(_end - _cur); +#ifdef WIN32 + len = _snprintf(_cur, count, ft, t); + if (len == count || (len == -1 && errno == ERANGE)) + { + len = count; + *(_end - 1) = '\0'; + } + else if (len < 0) + { + *_cur = '\0'; + len = 0; + } +#else + len = snprintf(_cur, count, ft, t); + if (len < 0) + { + *_cur = '\0'; + len = 0; + } + else if (len >= count) + { + len = count; + *(_end - 1) = '\0'; + } +#endif + _cur += len; + } + return *this; +} + +inline Log4zStream & Log4zStream::writeLongLong(long long t) +{ +#ifdef WIN32 + writeData("%I64d", t); +#else + writeData("%lld", t); +#endif + return *this; +} + +inline Log4zStream & Log4zStream::writeULongLong(unsigned long long t) +{ +#ifdef WIN32 + writeData("%I64u", t); +#else + writeData("%llu", t); +#endif + return *this; +} + +inline Log4zStream & Log4zStream::writePointer(const void * t) +{ +#ifdef WIN32 + sizeof(t) == 8 ? writeData("%016I64x", (unsigned long long)t) : writeData("%08I64x", (unsigned long long)t); +#else + sizeof(t) == 8 ? writeData("%016llx", (unsigned long long)t) : writeData("%08llx", (unsigned long long)t); +#endif + return *this; +} + +inline Log4zStream & Log4zStream::writeBinary(const Log4zBinary & t) +{ + writeData("%s", "\r\n\t["); + for (int i = 0; i < t._len; i++) + { + if (i % 16 == 0) + { + writeData("%s", "\r\n\t"); + *this << (void*)(t._buf + i); + writeData("%s", ": "); + } + writeData("%02x ", (unsigned char)t._buf[i]); + } + writeData("%s", "\r\n\t]\r\n\t"); + return *this; +} + +inline zsummer::log4z::Log4zStream & zsummer::log4z::Log4zStream::writeWString(const wchar_t* t) +{ +#ifdef WIN32 + DWORD dwLen = WideCharToMultiByte(CP_ACP, 0, t, -1, NULL, 0, NULL, NULL); + if (dwLen < LOG4Z_LOG_BUF_SIZE) + { + std::string str; + str.resize(dwLen, '\0'); + dwLen = WideCharToMultiByte(CP_ACP, 0, t, -1, &str[0], dwLen, NULL, NULL); + if (dwLen > 0) + { + writeData("%s", str.c_str()); + } + } +#else + //not support +#endif + return *this; +} + + +#ifdef WIN32 +#pragma warning(pop) +#endif + +_ZSUMMER_LOG4Z_END +_ZSUMMER_END + +#endif + + + + -- cgit v1.1