log4z.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. /*
  2. * Log4z License
  3. * -----------
  4. *
  5. * Log4z is licensed under the terms of the MIT license reproduced below.
  6. * This means that Log4z is free software and can be used for both academic
  7. * and commercial purposes at absolutely no cost.
  8. *
  9. *
  10. * ===============================================================================
  11. *
  12. * Copyright (C) 2010-2017 YaweiZhang <yawei.zhang@foxmail.com>.
  13. *
  14. * Permission is hereby granted, free of charge, to any person obtaining a copy
  15. * of this software and associated documentation files (the "Software"), to deal
  16. * in the Software without restriction, including without limitation the rights
  17. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. * copies of the Software, and to permit persons to whom the Software is
  19. * furnished to do so, subject to the following conditions:
  20. *
  21. * The above copyright notice and this permission notice shall be included in
  22. * all copies or substantial portions of the Software.
  23. *
  24. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30. * THE SOFTWARE.
  31. *
  32. * ===============================================================================
  33. *
  34. * (end of COPYRIGHT)
  35. */
  36. /*
  37. * AUTHORS: YaweiZhang <yawei.zhang@foxmail.com>
  38. * VERSION: 3.5.0
  39. * PURPOSE: A lightweight library for error reporting and logging to file and screen .
  40. * CREATION: 2010.10.4
  41. * LCHANGE: 2017.08.20
  42. * LICENSE: Expat/MIT License, See Copyright Notice at the begin of this file.
  43. */
  44. /*
  45. * contact me:
  46. * tencent qq group: 19811947
  47. * mail: yawei.zhang@foxmail.com
  48. */
  49. /*
  50. * UPDATES LOG
  51. *
  52. * VERSION 0.1.0 <DATE: 2010.10.4>
  53. * create the first project.
  54. * It support put log to screen and files,
  55. * support log level, support one day one log file.
  56. * support multi-thread, cross-platform.
  57. *
  58. * VERSION .... <DATE: ...>
  59. * ...
  60. *
  61. * VERSION 0.9.0 <DATE: 2012.12.24>
  62. * support config files.
  63. * support color text in screen.
  64. * support multiple output to different files.
  65. *
  66. * VERSION 1.0.0 <DATE: 2012.12.29>
  67. * support comments in the config file.
  68. * add a advanced demo in the ./project
  69. * fix some details.
  70. *
  71. * VERSION 1.0.1 <DATE: 2013.01.01>
  72. * change and add some Comments in the log4z
  73. * simplify the 'fast_test' demo projects.
  74. *
  75. * VERSION 1.1.0 <DATE: 2013.01.24>
  76. * the method Start will wait for the logger thread started.
  77. * config and add method change.
  78. * namespace change.
  79. *
  80. * VERSION 1.1.1 <DATE: 2013.02.23>
  81. * add status info method.
  82. * optimize.
  83. *
  84. * VERSION 1.2.0 <DATE: 2013.04.05>
  85. * add stress test demo
  86. * rewrite Stream module,better performance.
  87. *
  88. * VERSION 1.2.1 <DATE: 2013.04.13>
  89. * fixed type name 'long' stream format on 64/32 operation system.
  90. * logger will not loss any log on process normal exit.
  91. *
  92. * VERSION 2.0.0 <DATE: 2013.04.25>
  93. * new interface:
  94. * merge some Main interface and Dynamic interface
  95. * add Change Logger Attribute method by thread-safe
  96. * new config design.
  97. * log file name append process id.
  98. *
  99. * VERSION 2.1 <DATE: 2013.05.22>
  100. * support binary text output
  101. * rewrite write file module, support vs2005 open Chinese characters path
  102. *
  103. * VERSION 2.2 <DATE: 2013.07.08>
  104. * optimized binary stream output view
  105. * support wchar * string.
  106. *
  107. * VERSION 2.3 <DATE: 2013.08.29>
  108. * adjust output file named.
  109. * support different month different directory.
  110. * adjust some detail.
  111. *
  112. * VERSION 2.4 <DATE: 2013.10.07>
  113. * support rolling log file.
  114. * support hot update configure
  115. * used precision time in log.
  116. * micro set default logger attribute
  117. * fix tls bug in windows xp dll
  118. *
  119. * VERSION 2.5 <DATE: 2014.03.25>
  120. * screen output can choice synchronous or not
  121. * fix sometimes color will disorder on windows.
  122. * eliminate some compiler warning
  123. * fix sem_timewait in linux
  124. * add format-style method at input log, cannot support vs2003 and VC6.
  125. * fix WCHAR String cannot output
  126. * optimize std::string, binary log input, and support std::wstring.
  127. * clean code, better readability
  128. *
  129. * VERSION 2.6 <DATE: 2014.08.19>
  130. * add PrePushLog
  131. * better performance when log is filter out.
  132. * interface replace std::string because it's in shared library is unsafe.
  133. * add log level 'trace'
  134. *
  135. * VERSION 2.6.1 <DATE: 2014.08.22>
  136. * fix bug from defined _MSC_VER
  137. *
  138. * VERSION 2.7 <DATE: 2014.09.21>
  139. * compatible mac machine, now log4z can working in linux/windows/mac.
  140. *
  141. * VERSION 2.8 <DATE: 2014.09.27>
  142. * support synchronous written to file and thread-safe
  143. * fix compatibility on MinGW. a constant value suffix.
  144. * ignore utf-8 file BOM when load configure file
  145. * use macro WIN32_LEAN_AND_MEAN replace head file winsock2.h
  146. * new naming notations
  147. *
  148. * VERSION 3.0 <DATE: 2014.12.19>
  149. * new naming notations
  150. * support for reading config from a string.
  151. * remove all TLS code, used dispatch_semaphore in apple OS.
  152. * support system: windows, linux, mac, iOS
  153. *
  154. * VERSION 3.1 <DATE: 2014.12.19>
  155. * add method enable/disable logger by specific logger id
  156. * add method enable/disable log suffix line number.
  157. * add method enable/disable log output to file.
  158. *
  159. * VERSION 3.2 <DATE: 2014.12.19>
  160. * add interface setLoggerName,setLoggerPath,setAutoUpdate
  161. * support auto update from configure file
  162. *
  163. * VERSION 3.3 <DATE: 2014.12.19>
  164. * support map vector list
  165. * support continuum via travis.
  166. * new hot change design, all change realize need via push log flow.
  167. * support oem string convert.
  168. * new method to read whole content of file.
  169. * check configure's checksum when auto update it.
  170. * some other optimize.
  171. *
  172. * VERSION 3.5 <DATE: 2017.08.20>
  173. * optimization
  174. *
  175. */
  176. #pragma once
  177. #ifndef _ZSUMMER_LOG4Z_H_
  178. #define _ZSUMMER_LOG4Z_H_
  179. #include <string>
  180. #include <errno.h>
  181. #include <stdio.h>
  182. #include <string.h>
  183. #include <math.h>
  184. #include <cmath>
  185. #include <stdlib.h>
  186. #ifdef WIN32
  187. #define WIN32_LEAN_AND_MEAN
  188. #include <Windows.h>
  189. #endif
  190. #include <vector>
  191. #include <map>
  192. #include <list>
  193. #include <queue>
  194. #include <deque>
  195. //! logger ID type. DO NOT TOUCH
  196. typedef int LoggerId;
  197. //! the invalid logger id. DO NOT TOUCH
  198. const int LOG4Z_INVALID_LOGGER_ID = -1;
  199. //! the main logger id. DO NOT TOUCH
  200. //! can use this id to set the main logger's attribute.
  201. //! example:
  202. //! ILog4zManager::getPtr()->setLoggerLevel(LOG4Z_MAIN_LOGGER_ID, LOG_LEVEL_WARN);
  203. //! ILog4zManager::getPtr()->setLoggerDisplay(LOG4Z_MAIN_LOGGER_ID, false);
  204. const int LOG4Z_MAIN_LOGGER_ID = 0;
  205. //! the main logger name. DO NOT TOUCH
  206. const char*const LOG4Z_MAIN_LOGGER_KEY = "Main";
  207. //! check VC VERSION. DO NOT TOUCH
  208. //! format micro cannot support VC6 or VS2003, please use stream input log, like LOGI, LOGD, LOG_DEBUG, LOG_STREAM ...
  209. #if _MSC_VER >= 1400 //MSVC >= VS2005
  210. #define LOG4Z_FORMAT_INPUT_ENABLE
  211. #endif
  212. #ifndef WIN32
  213. #define LOG4Z_FORMAT_INPUT_ENABLE
  214. #endif
  215. //! LOG Level
  216. enum ENUM_LOG_LEVEL
  217. {
  218. LOG_LEVEL_TRACE = 0,
  219. LOG_LEVEL_DEBUG,
  220. LOG_LEVEL_INFO,
  221. LOG_LEVEL_WARN,
  222. LOG_LEVEL_ERROR,
  223. LOG_LEVEL_ALARM,
  224. LOG_LEVEL_FATAL,
  225. };
  226. //////////////////////////////////////////////////////////////////////////
  227. //! -----------------default logger config, can change on this.-----------
  228. //////////////////////////////////////////////////////////////////////////
  229. //! the max logger count.
  230. const int LOG4Z_LOGGER_MAX = 20;
  231. //! the max log content length.
  232. const int LOG4Z_LOG_BUF_SIZE = 1024 * 8;
  233. //! the max stl container depth.
  234. const int LOG4Z_LOG_CONTAINER_DEPTH = 5;
  235. //! the log queue length limit size.
  236. const int LOG4Z_LOG_QUEUE_LIMIT_SIZE = 20000;
  237. //! all logger synchronous output or not
  238. const bool LOG4Z_ALL_SYNCHRONOUS_OUTPUT = false;
  239. //! all logger synchronous display to the windows debug output
  240. const bool LOG4Z_ALL_DEBUGOUTPUT_DISPLAY = false;
  241. //! default logger output file.
  242. const char* const LOG4Z_DEFAULT_PATH = "./log/";
  243. //! default log filter level
  244. const int LOG4Z_DEFAULT_LEVEL = LOG_LEVEL_DEBUG;
  245. //! default logger display
  246. const bool LOG4Z_DEFAULT_DISPLAY = true;
  247. //! default logger output to file
  248. const bool LOG4Z_DEFAULT_OUTFILE = true;
  249. //! default logger month dir used status
  250. const bool LOG4Z_DEFAULT_MONTHDIR = false;
  251. //! default logger output file limit size, unit M byte.
  252. const int LOG4Z_DEFAULT_LIMITSIZE = 100;
  253. //! default logger show suffix (file name and line number)
  254. const bool LOG4Z_DEFAULT_SHOWSUFFIX = true;
  255. //! support ANSI->OEM console conversion on Windows
  256. #undef LOG4Z_OEM_CONSOLE
  257. //! default logger force reserve log file count.
  258. const size_t LOG4Z_FORCE_RESERVE_FILE_COUNT = 7;
  259. ///////////////////////////////////////////////////////////////////////////
  260. //! -----------------------------------------------------------------------
  261. //////////////////////////////////////////////////////////////////////////
  262. #ifndef _ZSUMMER_BEGIN
  263. #define _ZSUMMER_BEGIN namespace zsummer {
  264. #endif
  265. #ifndef _ZSUMMER_LOG4Z_BEGIN
  266. #define _ZSUMMER_LOG4Z_BEGIN namespace log4z {
  267. #endif
  268. _ZSUMMER_BEGIN
  269. _ZSUMMER_LOG4Z_BEGIN
  270. struct __declspec(dllexport) LogData
  271. {
  272. LoggerId _id; //dest logger id
  273. int _type; //type.
  274. int _typeval;
  275. int _level; //log level
  276. time_t _time; //create time
  277. unsigned int _precise; //create time
  278. unsigned int _threadID;
  279. int _contentLen;
  280. char _content[1]; //content
  281. };
  282. //! log4z class
  283. class __declspec(dllexport) ILog4zManager
  284. {
  285. public:
  286. ILog4zManager(){};
  287. virtual ~ILog4zManager(){};
  288. //! Log4z Singleton
  289. static ILog4zManager * getInstance();
  290. inline static ILog4zManager & getRef(){return *getInstance();}
  291. inline static ILog4zManager * getPtr(){return getInstance();}
  292. //! Config or overwrite configure
  293. //! Needs to be called before ILog4zManager::Start,, OR Do not call.
  294. virtual bool config(const char * configPath) = 0;
  295. virtual bool configFromString(const char * configContent) = 0;
  296. //! Create or overwrite logger.
  297. //! Needs to be called before ILog4zManager::Start, OR Do not call.
  298. virtual LoggerId createLogger(const char* key) = 0;
  299. //! Start Log Thread. This method can only be called once by one process.
  300. virtual bool start() = 0;
  301. //! Default the method will be calling at process exit auto.
  302. //! Default no need to call and no recommended.
  303. virtual bool stop() = 0;
  304. //! Find logger. thread safe.
  305. virtual LoggerId findLogger(const char* key) =0;
  306. //pre-check the log filter. if filter out return false.
  307. virtual bool prePushLog(LoggerId id, int level) = 0;
  308. //! Push log, thread safe.
  309. virtual bool pushLog(LogData * pLog, const char * file = NULL, int line = 0) = 0;
  310. //! set logger's attribute, thread safe.
  311. virtual bool enableLogger(LoggerId id, bool enable) = 0; // immediately when enable, and queue up when disable.
  312. virtual bool setLoggerName(LoggerId id, const char * name) = 0;
  313. virtual bool setLoggerPath(LoggerId id, const char * path) = 0;
  314. virtual bool setLoggerLevel(LoggerId id, int nLevel) = 0; // immediately when enable, and queue up when disable.
  315. virtual bool setLoggerFileLine(LoggerId id, bool enable) = 0;
  316. virtual bool setLoggerDisplay(LoggerId id, bool enable) = 0;
  317. virtual bool setLoggerOutFile(LoggerId id, bool enable) = 0;
  318. virtual bool setLoggerLimitsize(LoggerId id, unsigned int limitsize) = 0;
  319. virtual bool setLoggerMonthdir(LoggerId id, bool enable) = 0;
  320. virtual bool setLoggerReserveTime(LoggerId id, time_t sec) = 0;
  321. //! Update logger's attribute from config file, thread safe.
  322. virtual bool setAutoUpdate(int interval/*per second, 0 is disable auto update*/) = 0;
  323. virtual bool updateConfig() = 0;
  324. //! Log4z status statistics, thread safe.
  325. virtual bool isLoggerEnable(LoggerId id) = 0;
  326. virtual unsigned long long getStatusTotalWriteCount() = 0;
  327. virtual unsigned long long getStatusTotalWriteBytes() = 0;
  328. virtual unsigned long long getStatusTotalPushQueue() = 0;
  329. virtual unsigned long long getStatusTotalPopQueue() = 0;
  330. virtual unsigned int getStatusActiveLoggers() = 0;
  331. virtual LogData * makeLogData(LoggerId id, int level) = 0;
  332. virtual void freeLogData(LogData * log) = 0;
  333. };
  334. class Log4zStream;
  335. class Log4zBinary;
  336. #ifndef _ZSUMMER_END
  337. #define _ZSUMMER_END }
  338. #endif
  339. #ifndef _ZSUMMER_LOG4Z_END
  340. #define _ZSUMMER_LOG4Z_END }
  341. #endif
  342. _ZSUMMER_LOG4Z_END
  343. _ZSUMMER_END
  344. //! base macro.
  345. #define LOG_STREAM(id, level, file, line, log)\
  346. do{\
  347. if (zsummer::log4z::ILog4zManager::getPtr()->prePushLog(id,level)) \
  348. {\
  349. zsummer::log4z::LogData * __pLog = zsummer::log4z::ILog4zManager::getPtr()->makeLogData(id, level); \
  350. zsummer::log4z::Log4zStream __ss(__pLog->_content + __pLog->_contentLen, LOG4Z_LOG_BUF_SIZE - __pLog->_contentLen);\
  351. __ss << log;\
  352. __pLog->_contentLen += __ss.getCurrentLen(); \
  353. zsummer::log4z::ILog4zManager::getPtr()->pushLog(__pLog, file, line);\
  354. }\
  355. } while (0)
  356. //! fast macro
  357. #define LOG_TRACE(id, log) LOG_STREAM(id, LOG_LEVEL_TRACE, __FILE__, __LINE__, log)
  358. #define LOG_DEBUG(id, log) LOG_STREAM(id, LOG_LEVEL_DEBUG, __FILE__, __LINE__, log)
  359. #define LOG_INFO(id, log) LOG_STREAM(id, LOG_LEVEL_INFO, __FILE__, __LINE__, log)
  360. #define LOG_WARN(id, log) LOG_STREAM(id, LOG_LEVEL_WARN, __FILE__, __LINE__, log)
  361. #define LOG_ERROR(id, log) LOG_STREAM(id, LOG_LEVEL_ERROR, __FILE__, __LINE__, log)
  362. #define LOG_ALARM(id, log) LOG_STREAM(id, LOG_LEVEL_ALARM, __FILE__, __LINE__, log)
  363. #define LOG_FATAL(id, log) LOG_STREAM(id, LOG_LEVEL_FATAL, __FILE__, __LINE__, log)
  364. //! super macro.
  365. #define LOGT( log ) LOG_TRACE(LOG4Z_MAIN_LOGGER_ID, log )
  366. #define LOGD( log ) LOG_DEBUG(LOG4Z_MAIN_LOGGER_ID, log )
  367. #define LOGI( log ) LOG_INFO(LOG4Z_MAIN_LOGGER_ID, log )
  368. #define LOGW( log ) LOG_WARN(LOG4Z_MAIN_LOGGER_ID, log )
  369. #define LOGE( log ) LOG_ERROR(LOG4Z_MAIN_LOGGER_ID, log )
  370. #define LOGA( log ) LOG_ALARM(LOG4Z_MAIN_LOGGER_ID, log )
  371. #define LOGF( log ) LOG_FATAL(LOG4Z_MAIN_LOGGER_ID, log )
  372. //! format input log.
  373. #ifdef LOG4Z_FORMAT_INPUT_ENABLE
  374. #ifdef WIN32
  375. #define LOG_FORMAT(id, level, file, line, logformat, ...) \
  376. do{ \
  377. if (zsummer::log4z::ILog4zManager::getPtr()->prePushLog(id,level)) \
  378. {\
  379. zsummer::log4z::LogData * __pLog = zsummer::log4z::ILog4zManager::getPtr()->makeLogData(id, level); \
  380. int __logLen = _snprintf_s(__pLog->_content + __pLog->_contentLen, LOG4Z_LOG_BUF_SIZE - __pLog->_contentLen, _TRUNCATE, logformat, ##__VA_ARGS__); \
  381. if (__logLen < 0) __logLen = LOG4Z_LOG_BUF_SIZE - __pLog->_contentLen; \
  382. __pLog->_contentLen += __logLen; \
  383. zsummer::log4z::ILog4zManager::getPtr()->pushLog(__pLog, file, line); \
  384. }\
  385. } while (0)
  386. #else
  387. #define LOG_FORMAT(id, level, file, line, logformat, ...) \
  388. do{ \
  389. if (zsummer::log4z::ILog4zManager::getPtr()->prePushLog(id,level)) \
  390. {\
  391. zsummer::log4z::LogData * __pLog = zsummer::log4z::ILog4zManager::getPtr()->makeLogData(id, level); \
  392. int __logLen = snprintf(__pLog->_content + __pLog->_contentLen, LOG4Z_LOG_BUF_SIZE - __pLog->_contentLen,logformat, ##__VA_ARGS__); \
  393. if (__logLen < 0) __logLen = 0; \
  394. if (__logLen > LOG4Z_LOG_BUF_SIZE - __pLog->_contentLen) __logLen = LOG4Z_LOG_BUF_SIZE - __pLog->_contentLen; \
  395. __pLog->_contentLen += __logLen; \
  396. zsummer::log4z::ILog4zManager::getPtr()->pushLog(__pLog, file, line); \
  397. } \
  398. }while(0)
  399. #endif
  400. //!format string
  401. #define LOGFMT_TRACE(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_TRACE, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  402. #define LOGFMT_DEBUG(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  403. #define LOGFMT_INFO(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_INFO, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  404. #define LOGFMT_WARN(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_WARN, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  405. #define LOGFMT_ERROR(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_ERROR, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  406. #define LOGFMT_ALARM(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_ALARM, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  407. #define LOGFMT_FATAL(id, fmt, ...) LOG_FORMAT(id, LOG_LEVEL_FATAL, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
  408. #define LOGFMTT( fmt, ...) LOGFMT_TRACE(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  409. #define LOGFMTD( fmt, ...) LOGFMT_DEBUG(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  410. #define LOGFMTI( fmt, ...) LOGFMT_INFO(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  411. #define LOGFMTW( fmt, ...) LOGFMT_WARN(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  412. #define LOGFMTE( fmt, ...) LOGFMT_ERROR(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  413. #define LOGFMTA( fmt, ...) LOGFMT_ALARM(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  414. #define LOGFMTF( fmt, ...) LOGFMT_FATAL(LOG4Z_MAIN_LOGGER_ID, fmt, ##__VA_ARGS__)
  415. #else
  416. inline void empty_log_format_function1(LoggerId id, const char*, ...){}
  417. inline void empty_log_format_function2(const char*, ...){}
  418. #define LOGFMT_TRACE empty_log_format_function1
  419. #define LOGFMT_DEBUG LOGFMT_TRACE
  420. #define LOGFMT_INFO LOGFMT_TRACE
  421. #define LOGFMT_WARN LOGFMT_TRACE
  422. #define LOGFMT_ERROR LOGFMT_TRACE
  423. #define LOGFMT_ALARM LOGFMT_TRACE
  424. #define LOGFMT_FATAL LOGFMT_TRACE
  425. #define LOGFMTT empty_log_format_function2
  426. #define LOGFMTD LOGFMTT
  427. #define LOGFMTI LOGFMTT
  428. #define LOGFMTW LOGFMTT
  429. #define LOGFMTE LOGFMTT
  430. #define LOGFMTA LOGFMTT
  431. #define LOGFMTF LOGFMTT
  432. #endif
  433. _ZSUMMER_BEGIN
  434. _ZSUMMER_LOG4Z_BEGIN
  435. //! optimze from std::stringstream to Log4zStream
  436. #ifdef WIN32
  437. #pragma warning(push)
  438. #pragma warning(disable:4996)
  439. #endif
  440. class __declspec(dllexport) Log4zBinary
  441. {
  442. public:
  443. Log4zBinary(const void * buf, size_t len)
  444. {
  445. this->buf = (const char *)buf;
  446. this->len = len;
  447. }
  448. const char * buf;
  449. size_t len;
  450. };
  451. class __declspec(dllexport) Log4zString
  452. {
  453. public:
  454. Log4zString(const char * buf, size_t len)
  455. {
  456. this->buf = (const char *)buf;
  457. this->len = len;
  458. }
  459. const char * buf;
  460. size_t len;
  461. };
  462. class __declspec(dllexport) Log4zStream
  463. {
  464. public:
  465. inline Log4zStream(char * buf, int len);
  466. inline int getCurrentLen(){return (int)(_cur - _begin);}
  467. public:
  468. inline Log4zStream & writeLongLong(long long t, int width = 0, int dec = 10);
  469. inline Log4zStream & writeULongLong(unsigned long long t, int width = 0, int dec = 10);
  470. inline Log4zStream & writeDouble(double t, bool isSimple);
  471. inline Log4zStream & writePointer(const void * t);
  472. inline Log4zStream & writeString(const char * t) { return writeString(t, strlen(t)); };
  473. inline Log4zStream & writeString(const char * t, size_t len);
  474. inline Log4zStream & writeChar(char ch);
  475. inline Log4zStream & writeBinary(const Log4zBinary & t);
  476. public:
  477. inline Log4zStream & operator <<(const void * t){ return writePointer(t); }
  478. inline Log4zStream & operator <<(const char * t){return writeString(t);}
  479. inline Log4zStream & operator <<(bool t){ return (t ? writeString("true", 4) : writeString("false", 5));}
  480. inline Log4zStream & operator <<(char t){return writeChar(t);}
  481. inline Log4zStream & operator <<(unsigned char t){return writeULongLong(t);}
  482. inline Log4zStream & operator <<(short t){ return writeLongLong(t); }
  483. inline Log4zStream & operator <<(unsigned short t){ return writeULongLong(t); }
  484. inline Log4zStream & operator <<(int t){return writeLongLong(t);}
  485. inline Log4zStream & operator <<(unsigned int t){return writeULongLong(t);}
  486. inline Log4zStream & operator <<(long t) { return writeLongLong(t); }
  487. inline Log4zStream & operator <<(unsigned long t){ return writeULongLong(t); }
  488. inline Log4zStream & operator <<(long long t) { return writeLongLong(t); }
  489. inline Log4zStream & operator <<(unsigned long long t){ return writeULongLong(t); }
  490. inline Log4zStream & operator <<(float t){return writeDouble(t, true);}
  491. inline Log4zStream & operator <<(double t){return writeDouble(t, false);}
  492. template<class _Elem,class _Traits,class _Alloc> //support std::string, std::wstring
  493. inline Log4zStream & operator <<(const std::basic_string<_Elem, _Traits, _Alloc> & t){ return writeString(t.c_str(), t.length()); }
  494. inline Log4zStream & operator << (const zsummer::log4z::Log4zBinary & binary) { return writeBinary(binary); }
  495. inline Log4zStream & operator << (const zsummer::log4z::Log4zString & str) { return writeString(str.buf, str.len); }
  496. template<class _Ty1, class _Ty2>
  497. inline Log4zStream & operator <<(const std::pair<_Ty1, _Ty2> & t){ return *this << "pair(" << t.first << ":" << t.second << ")"; }
  498. template<class _Elem, class _Alloc>
  499. inline Log4zStream & operator <<(const std::vector<_Elem, _Alloc> & t)
  500. {
  501. *this << "vector(" << t.size() << ")[";
  502. int inputCount = 0;
  503. for (typename std::vector<_Elem, _Alloc>::const_iterator iter = t.begin(); iter != t.end(); iter++)
  504. {
  505. inputCount++;
  506. if (inputCount > LOG4Z_LOG_CONTAINER_DEPTH)
  507. {
  508. *this << "..., ";
  509. break;
  510. }
  511. *this << *iter << ", ";
  512. }
  513. if (!t.empty())
  514. {
  515. _cur -= 2;
  516. }
  517. return *this << "]";
  518. }
  519. template<class _Elem, class _Alloc>
  520. inline Log4zStream & operator <<(const std::list<_Elem, _Alloc> & t)
  521. {
  522. *this << "list(" << t.size() << ")[";
  523. int inputCount = 0;
  524. for (typename std::list<_Elem, _Alloc>::const_iterator iter = t.begin(); iter != t.end(); iter++)
  525. {
  526. inputCount++;
  527. if (inputCount > LOG4Z_LOG_CONTAINER_DEPTH)
  528. {
  529. *this << "..., ";
  530. break;
  531. }
  532. *this << *iter << ", ";
  533. }
  534. if (!t.empty())
  535. {
  536. _cur -= 2;
  537. }
  538. return *this << "]";
  539. }
  540. template<class _Elem, class _Alloc>
  541. inline Log4zStream & operator <<(const std::deque<_Elem, _Alloc> & t)
  542. {
  543. *this << "deque(" << t.size() << ")[";
  544. int inputCount = 0;
  545. for (typename std::deque<_Elem, _Alloc>::const_iterator iter = t.begin(); iter != t.end(); iter++)
  546. {
  547. inputCount++;
  548. if (inputCount > LOG4Z_LOG_CONTAINER_DEPTH)
  549. {
  550. *this << "..., ";
  551. break;
  552. }
  553. *this << *iter << ", ";
  554. }
  555. if (!t.empty())
  556. {
  557. _cur -= 2;
  558. }
  559. return *this << "]";
  560. }
  561. template<class _Elem, class _Alloc>
  562. inline Log4zStream & operator <<(const std::queue<_Elem, _Alloc> & t)
  563. {
  564. *this << "queue(" << t.size() << ")[";
  565. int inputCount = 0;
  566. for (typename std::queue<_Elem, _Alloc>::const_iterator iter = t.begin(); iter != t.end(); iter++)
  567. {
  568. inputCount++;
  569. if (inputCount > LOG4Z_LOG_CONTAINER_DEPTH)
  570. {
  571. *this << "..., ";
  572. break;
  573. }
  574. *this << *iter << ", ";
  575. }
  576. if (!t.empty())
  577. {
  578. _cur -= 2;
  579. }
  580. return *this << "]";
  581. }
  582. template<class _K, class _V, class _Pr, class _Alloc>
  583. inline Log4zStream & operator <<(const std::map<_K, _V, _Pr, _Alloc> & t)
  584. {
  585. *this << "map(" << t.size() << ")[";
  586. int inputCount = 0;
  587. for (typename std::map < _K, _V, _Pr, _Alloc>::const_iterator iter = t.begin(); iter != t.end(); iter++)
  588. {
  589. inputCount++;
  590. if (inputCount > LOG4Z_LOG_CONTAINER_DEPTH)
  591. {
  592. *this << "..., ";
  593. break;
  594. }
  595. *this << *iter << ", ";
  596. }
  597. if (!t.empty())
  598. {
  599. _cur -= 2;
  600. }
  601. return *this << "]";
  602. }
  603. private:
  604. Log4zStream(){}
  605. Log4zStream(Log4zStream &){}
  606. char * _begin;
  607. char * _end;
  608. char * _cur;
  609. };
  610. inline Log4zStream::Log4zStream(char * buf, int len)
  611. {
  612. _begin = buf;
  613. _end = buf + len;
  614. _cur = _begin;
  615. }
  616. inline Log4zStream & Log4zStream::writeLongLong(long long t, int width, int dec)
  617. {
  618. if (t < 0 )
  619. {
  620. t = -t;
  621. writeChar('-');
  622. }
  623. writeULongLong((unsigned long long)t, width, dec);
  624. return *this;
  625. }
  626. inline Log4zStream & Log4zStream::writeULongLong(unsigned long long t, int width, int dec)
  627. {
  628. static const char * lut =
  629. "0123456789abcdef";
  630. static const char *lutDec =
  631. "00010203040506070809"
  632. "10111213141516171819"
  633. "20212223242526272829"
  634. "30313233343536373839"
  635. "40414243444546474849"
  636. "50515253545556575859"
  637. "60616263646566676869"
  638. "70717273747576777879"
  639. "80818283848586878889"
  640. "90919293949596979899";
  641. static const char *lutHex =
  642. "000102030405060708090A0B0C0D0E0F"
  643. "101112131415161718191A1B1C1D1E1F"
  644. "202122232425262728292A2B2C2D2E2F"
  645. "303132333435363738393A3B3C3D3E3F"
  646. "404142434445464748494A4B4C4D4E4F"
  647. "505152535455565758595A5B5C5D5E5F"
  648. "606162636465666768696A6B6C6D6E6F"
  649. "707172737475767778797A7B7C7D7E7F"
  650. "808182838485868788898A8B8C8D8E8F"
  651. "909192939495969798999A9B9C9D9E9F"
  652. "A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"
  653. "B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"
  654. "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"
  655. "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"
  656. "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
  657. "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
  658. const unsigned long long cacheSize = 64;
  659. if ((unsigned long long)(_end - _cur) > cacheSize)
  660. {
  661. char buf[cacheSize];
  662. unsigned long long val = t;
  663. unsigned long long i = cacheSize;
  664. unsigned long long digit = 0;
  665. if (dec == 10)
  666. {
  667. do
  668. {
  669. const unsigned long long m2 = (unsigned long long)((val % 100) * 2);
  670. *(buf + i - 1) = lutDec[m2 + 1];
  671. *(buf + i - 2) = lutDec[m2];
  672. i -= 2;
  673. val /= 100;
  674. digit += 2;
  675. } while (val && i >= 2);
  676. if (digit >= 2 && buf[cacheSize - digit] == '0')
  677. {
  678. digit--;
  679. }
  680. }
  681. else if (dec == 16)
  682. {
  683. do
  684. {
  685. const unsigned long long m2 = (unsigned long long)((val % 256) * 2);
  686. *(buf + i - 1) = lutHex[m2 + 1];
  687. *(buf + i - 2) = lutHex[m2];
  688. i -= 2;
  689. val /= 256;
  690. digit += 2;
  691. } while (val && i >= 2);
  692. if (digit >= 2 && buf[cacheSize - digit] == '0')
  693. {
  694. digit--;
  695. }
  696. }
  697. else
  698. {
  699. do
  700. {
  701. buf[--i] = lut[val % dec];
  702. val /= dec;
  703. digit++;
  704. } while (val && i > 0);
  705. }
  706. while (digit < (unsigned long long)width)
  707. {
  708. digit++;
  709. buf[cacheSize - digit] = '0';
  710. }
  711. writeString(buf + (cacheSize - digit), (size_t)digit);
  712. }
  713. return *this;
  714. }
  715. inline Log4zStream & Log4zStream::writeDouble(double t, bool isSimple)
  716. {
  717. #if __cplusplus >= 201103L
  718. using std::isnan;
  719. using std::isinf;
  720. #endif
  721. if (isnan(t))
  722. {
  723. writeString("nan", 3);
  724. return *this;
  725. }
  726. else if (isinf(t))
  727. {
  728. writeString("inf", 3);
  729. return *this;
  730. }
  731. size_t count = _end - _cur;
  732. double fabst = fabs(t);
  733. if (count > 30)
  734. {
  735. if ( fabst < 0.0001 || (!isSimple && fabst > 4503599627370495ULL) || (isSimple && fabst > 8388607))
  736. {
  737. gcvt(t, isSimple ? 7 : 16, _cur);
  738. size_t len = strlen(_cur);
  739. if (len > count) len = count;
  740. _cur += len;
  741. return *this;
  742. }
  743. else
  744. {
  745. if (t < 0.0)
  746. {
  747. writeChar('-');
  748. }
  749. double intpart = 0;
  750. unsigned long long fractpart = (unsigned long long)(modf(fabst, &intpart) * 10000);
  751. writeULongLong((unsigned long long)intpart);
  752. if (fractpart > 0)
  753. {
  754. writeChar('.');
  755. writeULongLong(fractpart, 4);
  756. }
  757. }
  758. }
  759. return *this;
  760. }
  761. inline Log4zStream & Log4zStream::writePointer(const void * t)
  762. {
  763. sizeof(t) == 8 ? writeULongLong((unsigned long long)t, 16, 16): writeULongLong((unsigned long long)t, 8, 16);
  764. return *this;
  765. }
  766. inline Log4zStream & Log4zStream::writeBinary(const Log4zBinary & t)
  767. {
  768. writeString("\r\n\t[");
  769. for (size_t i=0; i<(t.len / 32)+1; i++)
  770. {
  771. writeString("\r\n\t");
  772. *this << (void*)(t.buf + i*32);
  773. writeString(": ");
  774. for (size_t j = i * 32; j < (i + 1) * 32 && j < t.len; j++)
  775. {
  776. if (isprint((unsigned char)t.buf[j]))
  777. {
  778. writeChar(' ');
  779. writeChar(t.buf[j]);
  780. writeChar(' ');
  781. }
  782. else
  783. {
  784. *this << " . ";
  785. }
  786. }
  787. writeString("\r\n\t");
  788. *this << (void*)(t.buf + i * 32);
  789. writeString(": ");
  790. for (size_t j = i * 32; j < (i + 1) * 32 && j < t.len; j++)
  791. {
  792. writeULongLong((unsigned long long)(unsigned char)t.buf[j], 2, 16);
  793. writeChar(' ');
  794. }
  795. }
  796. writeString("\r\n\t]\r\n\t");
  797. return *this;
  798. }
  799. inline Log4zStream & zsummer::log4z::Log4zStream::writeChar(char ch)
  800. {
  801. if (_end - _cur > 1)
  802. {
  803. _cur[0] = ch;
  804. _cur++;
  805. }
  806. return *this;
  807. }
  808. inline Log4zStream & zsummer::log4z::Log4zStream::writeString(const char * t, size_t len)
  809. {
  810. size_t count = _end - _cur;
  811. if (len > count)
  812. {
  813. len = count;
  814. }
  815. if (len > 0)
  816. {
  817. memcpy(_cur, t, len);
  818. _cur += len;
  819. }
  820. return *this;
  821. }
  822. //////////////////////////////////////////////////////////////////////////
  823. //! LockHelper
  824. //////////////////////////////////////////////////////////////////////////
  825. class __declspec(dllexport) LockHelper
  826. {
  827. public:
  828. LockHelper();
  829. virtual ~LockHelper();
  830. public:
  831. void lock();
  832. void unLock();
  833. private:
  834. #ifdef WIN32
  835. CRITICAL_SECTION _crit;
  836. #else
  837. pthread_mutex_t _crit;
  838. #endif
  839. };
  840. //////////////////////////////////////////////////////////////////////////
  841. //! AutoLock
  842. //////////////////////////////////////////////////////////////////////////
  843. class __declspec(dllexport) AutoLock
  844. {
  845. public:
  846. explicit AutoLock(LockHelper & lk) :_lock(lk){ _lock.lock(); }
  847. ~AutoLock(){ _lock.unLock(); }
  848. private:
  849. LockHelper & _lock;
  850. };
  851. #ifdef WIN32
  852. #pragma warning(pop)
  853. #endif
  854. _ZSUMMER_LOG4Z_END
  855. _ZSUMMER_END
  856. using namespace zsummer::log4z;
  857. #endif