log4z.cpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034
  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. #include "stdafx.h"
  37. #include "log4z.h"
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <errno.h>
  41. #include <time.h>
  42. #include <string.h>
  43. #include <math.h>
  44. #include <string>
  45. #include <vector>
  46. #include <map>
  47. #include <list>
  48. #include <algorithm>
  49. #include <iostream>
  50. #ifdef WIN32
  51. #include <io.h>
  52. #include <shlwapi.h>
  53. #include <process.h>
  54. #pragma comment(lib, "shlwapi")
  55. #pragma comment(lib, "User32.lib")
  56. #pragma warning(disable:4996)
  57. #else
  58. #include <unistd.h>
  59. #include <netinet/in.h>
  60. #include <arpa/inet.h>
  61. #include <sys/types.h>
  62. #include <sys/socket.h>
  63. #include<pthread.h>
  64. #include <sys/time.h>
  65. #include <sys/stat.h>
  66. #include <dirent.h>
  67. #include <fcntl.h>
  68. #include <semaphore.h>
  69. #include <sys/syscall.h>
  70. #endif
  71. #ifdef __APPLE__
  72. #include "TargetConditionals.h"
  73. #include <dispatch/dispatch.h>
  74. #if !TARGET_OS_IPHONE
  75. #define LOG4Z_HAVE_LIBPROC
  76. #include <libproc.h>
  77. #endif
  78. #endif
  79. _ZSUMMER_BEGIN
  80. _ZSUMMER_LOG4Z_BEGIN
  81. static const char *const LOG_STRING[]=
  82. {
  83. "LOG_TRACE",
  84. "LOG_DEBUG",
  85. "LOG_INFO ",
  86. "LOG_WARN ",
  87. "LOG_ERROR",
  88. "LOG_ALARM",
  89. "LOG_FATAL",
  90. };
  91. static const size_t LOG_STRING_LEN[] =
  92. {
  93. sizeof("LOG_TRACE") - 1,
  94. sizeof("LOG_DEBUG") - 1,
  95. sizeof("LOG_INFO") - 1,
  96. sizeof("LOG_WARN") - 1,
  97. sizeof("LOG_ERROR") - 1,
  98. sizeof("LOG_ALARM") - 1,
  99. sizeof("LOG_FATAL") - 1,
  100. };
  101. #ifdef WIN32
  102. const static WORD LOG_COLOR[LOG_LEVEL_FATAL + 1] = {
  103. 0,
  104. 0,
  105. FOREGROUND_BLUE | FOREGROUND_GREEN,
  106. FOREGROUND_GREEN | FOREGROUND_RED,
  107. FOREGROUND_RED,
  108. FOREGROUND_GREEN,
  109. FOREGROUND_RED | FOREGROUND_BLUE };
  110. #else
  111. const static char LOG_COLOR[LOG_LEVEL_FATAL + 1][50] = {
  112. "\e[0m",
  113. "\e[0m",
  114. "\e[34m\e[1m",//hight blue
  115. "\e[33m", //yellow
  116. "\e[31m", //red
  117. "\e[32m", //green
  118. "\e[35m" };
  119. #endif
  120. //////////////////////////////////////////////////////////////////////////
  121. //! Log4zFileHandler
  122. //////////////////////////////////////////////////////////////////////////
  123. class Log4zFileHandler
  124. {
  125. public:
  126. Log4zFileHandler(){ _file = NULL; }
  127. ~Log4zFileHandler(){ close(); }
  128. inline bool isOpen(){ return _file != NULL; }
  129. inline long open(const char *path, const char * mod)
  130. {
  131. if (_file != NULL){fclose(_file);_file = NULL;}
  132. _file = fopen(path, mod);
  133. if (_file)
  134. {
  135. long tel = 0;
  136. long cur = ftell(_file);
  137. fseek(_file, 0L, SEEK_END);
  138. tel = ftell(_file);
  139. fseek(_file, cur, SEEK_SET);
  140. return tel;
  141. }
  142. return -1;
  143. }
  144. inline void clean(int index, int len)
  145. {
  146. #if !defined(__APPLE__) && !defined(WIN32)
  147. if (_file != NULL)
  148. {
  149. int fd = fileno(_file);
  150. fsync(fd);
  151. posix_fadvise(fd, index, len, POSIX_FADV_DONTNEED);
  152. fsync(fd);
  153. }
  154. #endif
  155. }
  156. inline void close()
  157. {
  158. if (_file != NULL){clean(0, 0); fclose(_file);_file = NULL;}
  159. }
  160. inline void write(const char * data, size_t len)
  161. {
  162. if (_file && len > 0)
  163. {
  164. if (fwrite(data, 1, len, _file) != len)
  165. {
  166. close();
  167. }
  168. }
  169. }
  170. inline void flush(){ if (_file) fflush(_file); }
  171. inline std::string readLine()
  172. {
  173. char buf[500] = { 0 };
  174. if (_file && fgets(buf, 500, _file) != NULL)
  175. {
  176. return std::string(buf);
  177. }
  178. return std::string();
  179. }
  180. inline const std::string readContent();
  181. inline bool removeFile(const std::string & path) { return ::remove(path.c_str()) == 0; }
  182. public:
  183. FILE *_file;
  184. };
  185. //////////////////////////////////////////////////////////////////////////
  186. //! UTILITY
  187. //////////////////////////////////////////////////////////////////////////
  188. static void fixPath(std::string &path);
  189. static void trimLogConfig(std::string &str, std::string extIgnore = std::string());
  190. static std::pair<std::string, std::string> splitPairString(const std::string & str, const std::string & delimiter);
  191. static bool isDirectory(std::string path);
  192. static bool createRecursionDir(std::string path);
  193. static std::string getProcessID();
  194. static std::string getProcessName();
  195. //////////////////////////////////////////////////////////////////////////
  196. //! SemHelper
  197. //////////////////////////////////////////////////////////////////////////
  198. class SemHelper
  199. {
  200. public:
  201. SemHelper();
  202. virtual ~SemHelper();
  203. public:
  204. bool create(int initcount);
  205. bool wait(int timeout = 0);
  206. bool post();
  207. private:
  208. #ifdef WIN32
  209. HANDLE _hSem;
  210. #elif defined(__APPLE__)
  211. dispatch_semaphore_t _semid;
  212. #else
  213. sem_t _semid;
  214. bool _isCreate;
  215. #endif
  216. };
  217. //////////////////////////////////////////////////////////////////////////
  218. //! ThreadHelper
  219. //////////////////////////////////////////////////////////////////////////
  220. #ifdef WIN32
  221. static unsigned int WINAPI threadProc(LPVOID lpParam);
  222. #else
  223. static void * threadProc(void * pParam);
  224. #endif
  225. class ThreadHelper
  226. {
  227. public:
  228. ThreadHelper(){_hThreadID = 0;}
  229. virtual ~ThreadHelper(){}
  230. public:
  231. bool start();
  232. bool wait();
  233. virtual void run() = 0;
  234. private:
  235. unsigned long long _hThreadID;
  236. #ifndef WIN32
  237. pthread_t _phtreadID;
  238. #endif
  239. };
  240. #ifdef WIN32
  241. unsigned int WINAPI threadProc(LPVOID lpParam)
  242. {
  243. ThreadHelper * p = (ThreadHelper *) lpParam;
  244. p->run();
  245. return 0;
  246. }
  247. #else
  248. void * threadProc(void * pParam)
  249. {
  250. ThreadHelper * p = (ThreadHelper *) pParam;
  251. p->run();
  252. return NULL;
  253. }
  254. #endif
  255. //////////////////////////////////////////////////////////////////////////
  256. //! LogData
  257. //////////////////////////////////////////////////////////////////////////
  258. enum LogDataType
  259. {
  260. LDT_GENERAL,
  261. LDT_ENABLE_LOGGER,
  262. LDT_SET_LOGGER_NAME,
  263. LDT_SET_LOGGER_PATH,
  264. LDT_SET_LOGGER_LEVEL,
  265. LDT_SET_LOGGER_FILELINE,
  266. LDT_SET_LOGGER_DISPLAY,
  267. LDT_SET_LOGGER_OUTFILE,
  268. LDT_SET_LOGGER_LIMITSIZE,
  269. LDT_SET_LOGGER_MONTHDIR,
  270. LDT_SET_LOGGER_RESERVETIME,
  271. // LDT_SET_LOGGER_,
  272. };
  273. //////////////////////////////////////////////////////////////////////////
  274. //! LoggerInfo
  275. //////////////////////////////////////////////////////////////////////////
  276. struct LoggerInfo
  277. {
  278. //! attribute
  279. std::string _key; //logger key
  280. std::string _name; // one logger one name.
  281. std::string _path; //path for log file.
  282. int _level; //filter level
  283. bool _display; //display to screen
  284. bool _outfile; //output to file
  285. bool _monthdir; //create directory per month
  286. unsigned int _limitsize; //limit file's size, unit Million byte.
  287. bool _enable; //logger is enable
  288. bool _fileLine; //enable/disable the log's suffix.(file name:line number)
  289. time_t _logReserveTime; //log file reserve time. unit is time second.
  290. //! runtime info
  291. time_t _curFileCreateTime; //file create time
  292. time_t _curFileCreateDay; //file create day time
  293. unsigned int _curFileIndex; //rolling file index
  294. unsigned int _curWriteLen; //current file length
  295. Log4zFileHandler _handle; //file handle.
  296. //!history
  297. std::list<std::pair<time_t, std::string> > _historyLogs;
  298. LoggerInfo()
  299. {
  300. _enable = false;
  301. _path = LOG4Z_DEFAULT_PATH;
  302. _level = LOG4Z_DEFAULT_LEVEL;
  303. _display = LOG4Z_DEFAULT_DISPLAY;
  304. _outfile = LOG4Z_DEFAULT_OUTFILE;
  305. _monthdir = LOG4Z_DEFAULT_MONTHDIR;
  306. _limitsize = LOG4Z_DEFAULT_LIMITSIZE;
  307. _fileLine = LOG4Z_DEFAULT_SHOWSUFFIX;
  308. _curFileCreateTime = 0;
  309. _curFileCreateDay = 0;
  310. _curFileIndex = 0;
  311. _curWriteLen = 0;
  312. _logReserveTime = 0;
  313. }
  314. };
  315. //////////////////////////////////////////////////////////////////////////
  316. //! LogerManager
  317. //////////////////////////////////////////////////////////////////////////
  318. class LogerManager : public ThreadHelper, public ILog4zManager
  319. {
  320. public:
  321. LogerManager();
  322. virtual ~LogerManager();
  323. bool configFromStringImpl(std::string content, bool isUpdate);
  324. //! 读取配置文件并覆写
  325. virtual bool config(const char* configPath);
  326. virtual bool configFromString(const char* configContent);
  327. //! 覆写式创建
  328. virtual LoggerId createLogger(const char* key);
  329. virtual bool start();
  330. virtual bool stop();
  331. virtual bool prePushLog(LoggerId id, int level);
  332. virtual bool pushLog(LogData * pLog, const char * file, int line);
  333. //! 查找ID
  334. virtual LoggerId findLogger(const char* key);
  335. bool hotChange(LoggerId id, LogDataType ldt, int num, const std::string & text);
  336. virtual bool enableLogger(LoggerId id, bool enable);
  337. virtual bool setLoggerName(LoggerId id, const char * name);
  338. virtual bool setLoggerPath(LoggerId id, const char * path);
  339. virtual bool setLoggerLevel(LoggerId id, int nLevel);
  340. virtual bool setLoggerFileLine(LoggerId id, bool enable);
  341. virtual bool setLoggerDisplay(LoggerId id, bool enable);
  342. virtual bool setLoggerOutFile(LoggerId id, bool enable);
  343. virtual bool setLoggerLimitsize(LoggerId id, unsigned int limitsize);
  344. virtual bool setLoggerMonthdir(LoggerId id, bool enable);
  345. virtual bool setLoggerReserveTime(LoggerId id, time_t sec);
  346. virtual bool setAutoUpdate(int interval);
  347. virtual bool updateConfig();
  348. virtual bool isLoggerEnable(LoggerId id);
  349. virtual unsigned long long getStatusTotalWriteCount(){return _ullStatusTotalWriteFileCount;}
  350. virtual unsigned long long getStatusTotalWriteBytes() { return _ullStatusTotalWriteFileBytes; }
  351. virtual unsigned long long getStatusTotalPushQueue() { return _ullStatusTotalPushLog; }
  352. virtual unsigned long long getStatusTotalPopQueue() { return _ullStatusTotalPopLog; }
  353. virtual unsigned int getStatusActiveLoggers();
  354. protected:
  355. virtual LogData * makeLogData(LoggerId id, int level);
  356. virtual void freeLogData(LogData * log);
  357. void showColorText(const char *text, int level = LOG_LEVEL_DEBUG);
  358. bool onHotChange(LoggerId id, LogDataType ldt, int num, const std::string & text);
  359. bool openLogger(LogData * log);
  360. bool closeLogger(LoggerId id);
  361. bool popLog(LogData *& log);
  362. virtual void run();
  363. private:
  364. //! thread status.
  365. bool _runing;
  366. //! wait thread started.
  367. SemHelper _semaphore;
  368. //! hot change name or path for one logger
  369. int _hotUpdateInterval;
  370. unsigned int _checksum;
  371. //! the process info.
  372. std::string _pid;
  373. std::string _proName;
  374. //! config file name
  375. std::string _configFile;
  376. //! logger id manager, [logger name]:[logger id].
  377. std::map<std::string, LoggerId> _ids;
  378. // the last used id of _loggers
  379. LoggerId _lastId;
  380. LoggerInfo _loggers[LOG4Z_LOGGER_MAX];
  381. //! log queue
  382. char _chunk1[256];
  383. LockHelper _logLock;
  384. std::deque<LogData *> _logs;
  385. unsigned long long _ullStatusTotalPushLog;
  386. char _chunk2[256];
  387. LockHelper _freeLock;
  388. std::vector<LogData*> _freeLogDatas;
  389. char _chunk3[256];
  390. //show color lock
  391. LockHelper _scLock;
  392. //status statistics
  393. //write file
  394. char _chunk4[256];
  395. std::deque<LogData *> _logsCache;
  396. unsigned long long _ullStatusTotalPopLog;
  397. unsigned long long _ullStatusTotalWriteFileCount;
  398. unsigned long long _ullStatusTotalWriteFileBytes;
  399. };
  400. //////////////////////////////////////////////////////////////////////////
  401. //! Log4zFileHandler
  402. //////////////////////////////////////////////////////////////////////////
  403. const std::string Log4zFileHandler::readContent()
  404. {
  405. std::string content;
  406. if (!_file)
  407. {
  408. return content;
  409. }
  410. char buf[BUFSIZ];
  411. size_t ret = 0;
  412. do
  413. {
  414. ret = fread(buf, sizeof(char), BUFSIZ, _file);
  415. content.append(buf, ret);
  416. }
  417. while (ret == BUFSIZ);
  418. return content;
  419. }
  420. //////////////////////////////////////////////////////////////////////////
  421. //! utility
  422. //////////////////////////////////////////////////////////////////////////
  423. static inline void sleepMillisecond(unsigned int ms)
  424. {
  425. #ifdef WIN32
  426. ::Sleep(ms);
  427. #else
  428. usleep(1000*ms);
  429. #endif
  430. }
  431. static inline struct tm timeToTm(time_t t)
  432. {
  433. #ifdef WIN32
  434. #if _MSC_VER < 1400 //VS2003
  435. return * localtime(&t);
  436. #else //vs2005->vs2013->
  437. struct tm tt = { 0 };
  438. localtime_s(&tt, &t);
  439. return tt;
  440. #endif
  441. #else //linux
  442. struct tm tt = { 0 };
  443. localtime_r(&t, &tt);
  444. return tt;
  445. #endif
  446. }
  447. static void fixPath(std::string &path)
  448. {
  449. if (path.empty()){return;}
  450. for (std::string::iterator iter = path.begin(); iter != path.end(); ++iter)
  451. {
  452. if (*iter == '\\'){*iter = '/';}
  453. }
  454. if (path.at(path.length()-1) != '/'){path.append("/");}
  455. }
  456. static void trimLogConfig(std::string &str, std::string extIgnore)
  457. {
  458. if (str.empty()){return;}
  459. extIgnore += "\r\n\t ";
  460. int length = (int)str.length();
  461. int posBegin = 0;
  462. int posEnd = 0;
  463. //trim utf8 file bom
  464. if (str.length() >= 3
  465. && (unsigned char)str[0] == 0xef
  466. && (unsigned char)str[1] == 0xbb
  467. && (unsigned char)str[2] == 0xbf)
  468. {
  469. posBegin = 3;
  470. }
  471. //trim character
  472. for (int i = posBegin; i<length; i++)
  473. {
  474. bool bCheck = false;
  475. for (int j = 0; j < (int)extIgnore.length(); j++)
  476. {
  477. if (str[i] == extIgnore[j])
  478. {
  479. bCheck = true;
  480. }
  481. }
  482. if (bCheck)
  483. {
  484. if (i == posBegin)
  485. {
  486. posBegin++;
  487. }
  488. }
  489. else
  490. {
  491. posEnd = i + 1;
  492. }
  493. }
  494. if (posBegin < posEnd)
  495. {
  496. str = str.substr(posBegin, posEnd-posBegin);
  497. }
  498. else
  499. {
  500. str.clear();
  501. }
  502. }
  503. //split
  504. static std::pair<std::string, std::string> splitPairString(const std::string & str, const std::string & delimiter)
  505. {
  506. std::string::size_type pos = str.find(delimiter.c_str());
  507. if (pos == std::string::npos)
  508. {
  509. return std::make_pair(str, "");
  510. }
  511. return std::make_pair(str.substr(0, pos), str.substr(pos+delimiter.length()));
  512. }
  513. static bool parseConfigLine(const std::string& line, int curLineNum, std::string & key, std::map<std::string, LoggerInfo> & outInfo)
  514. {
  515. std::pair<std::string, std::string> kv = splitPairString(line, "=");
  516. if (kv.first.empty())
  517. {
  518. return false;
  519. }
  520. trimLogConfig(kv.first);
  521. trimLogConfig(kv.second);
  522. if (kv.first.empty() || kv.first.at(0) == '#')
  523. {
  524. return true;
  525. }
  526. if (kv.first.at(0) == '[')
  527. {
  528. trimLogConfig(kv.first, "[]");
  529. key = kv.first;
  530. {
  531. std::string tmpstr = kv.first;
  532. std::transform(tmpstr.begin(), tmpstr.end(), tmpstr.begin(), ::tolower);
  533. if (tmpstr == "main")
  534. {
  535. key = "Main";
  536. }
  537. }
  538. std::map<std::string, LoggerInfo>::iterator iter = outInfo.find(key);
  539. if (iter == outInfo.end())
  540. {
  541. LoggerInfo li;
  542. li._enable = true;
  543. li._key = key;
  544. li._name = key;
  545. outInfo.insert(std::make_pair(li._key, li));
  546. }
  547. else
  548. {
  549. printf("log4z configure warning: duplicate logger key:[%s] at line: %d \r\n", key.c_str(), curLineNum);
  550. }
  551. return true;
  552. }
  553. trimLogConfig(kv.first);
  554. trimLogConfig(kv.second);
  555. std::map<std::string, LoggerInfo>::iterator iter = outInfo.find(key);
  556. if (iter == outInfo.end())
  557. {
  558. printf("log4z configure warning: not found current logger name:[%s] at line:%d, key=%s, value=%s \r\n",
  559. key.c_str(), curLineNum, kv.first.c_str(), kv.second.c_str());
  560. return true;
  561. }
  562. std::transform(kv.first.begin(), kv.first.end(), kv.first.begin(), ::tolower);
  563. //! path
  564. if (kv.first == "path")
  565. {
  566. iter->second._path = kv.second;
  567. return true;
  568. }
  569. else if (kv.first == "name")
  570. {
  571. iter->second._name = kv.second;
  572. return true;
  573. }
  574. std::transform(kv.second.begin(), kv.second.end(), kv.second.begin(), ::tolower);
  575. //! level
  576. if (kv.first == "level")
  577. {
  578. if (kv.second == "trace" || kv.second == "all")
  579. {
  580. iter->second._level = LOG_LEVEL_TRACE;
  581. }
  582. else if (kv.second == "debug")
  583. {
  584. iter->second._level = LOG_LEVEL_DEBUG;
  585. }
  586. else if (kv.second == "info")
  587. {
  588. iter->second._level = LOG_LEVEL_INFO;
  589. }
  590. else if (kv.second == "warn" || kv.second == "warning")
  591. {
  592. iter->second._level = LOG_LEVEL_WARN;
  593. }
  594. else if (kv.second == "error")
  595. {
  596. iter->second._level = LOG_LEVEL_ERROR;
  597. }
  598. else if (kv.second == "alarm")
  599. {
  600. iter->second._level = LOG_LEVEL_ALARM;
  601. }
  602. else if (kv.second == "fatal")
  603. {
  604. iter->second._level = LOG_LEVEL_FATAL;
  605. }
  606. }
  607. //! display
  608. else if (kv.first == "display")
  609. {
  610. if (kv.second == "false" || kv.second == "0")
  611. {
  612. iter->second._display = false;
  613. }
  614. else
  615. {
  616. iter->second._display = true;
  617. }
  618. }
  619. //! output to file
  620. else if (kv.first == "outfile")
  621. {
  622. if (kv.second == "false" || kv.second == "0")
  623. {
  624. iter->second._outfile = false;
  625. }
  626. else
  627. {
  628. iter->second._outfile = true;
  629. }
  630. }
  631. //! monthdir
  632. else if (kv.first == "monthdir")
  633. {
  634. if (kv.second == "false" || kv.second == "0")
  635. {
  636. iter->second._monthdir = false;
  637. }
  638. else
  639. {
  640. iter->second._monthdir = true;
  641. }
  642. }
  643. //! limit file size
  644. else if (kv.first == "limitsize")
  645. {
  646. iter->second._limitsize = atoi(kv.second.c_str());
  647. }
  648. //! display log in file line
  649. else if (kv.first == "fileline")
  650. {
  651. if (kv.second == "false" || kv.second == "0")
  652. {
  653. iter->second._fileLine = false;
  654. }
  655. else
  656. {
  657. iter->second._fileLine = true;
  658. }
  659. }
  660. //! enable/disable one logger
  661. else if (kv.first == "enable")
  662. {
  663. if (kv.second == "false" || kv.second == "0")
  664. {
  665. iter->second._enable = false;
  666. }
  667. else
  668. {
  669. iter->second._enable = true;
  670. }
  671. }
  672. //! set reserve time
  673. else if (kv.first == "reserve")
  674. {
  675. iter->second._logReserveTime = atoi(kv.second.c_str());
  676. }
  677. return true;
  678. }
  679. static bool parseConfigFromString(std::string content, std::map<std::string, LoggerInfo> & outInfo)
  680. {
  681. std::string key;
  682. int curLine = 1;
  683. std::string line;
  684. std::string::size_type curPos = 0;
  685. if (content.empty())
  686. {
  687. return true;
  688. }
  689. do
  690. {
  691. std::string::size_type pos = std::string::npos;
  692. for (std::string::size_type i = curPos; i < content.length(); ++i)
  693. {
  694. //support linux/unix/windows LRCF
  695. if (content[i] == '\r' || content[i] == '\n')
  696. {
  697. pos = i;
  698. break;
  699. }
  700. }
  701. line = content.substr(curPos, pos - curPos);
  702. parseConfigLine(line, curLine, key, outInfo);
  703. curLine++;
  704. if (pos == std::string::npos)
  705. {
  706. break;
  707. }
  708. else
  709. {
  710. curPos = pos+1;
  711. }
  712. } while (1);
  713. return true;
  714. }
  715. bool isDirectory(std::string path)
  716. {
  717. #ifdef WIN32
  718. return PathIsDirectoryA(path.c_str()) ? true : false;
  719. #else
  720. DIR * pdir = opendir(path.c_str());
  721. if (pdir == NULL)
  722. {
  723. return false;
  724. }
  725. else
  726. {
  727. closedir(pdir);
  728. pdir = NULL;
  729. return true;
  730. }
  731. #endif
  732. }
  733. bool createRecursionDir(std::string path)
  734. {
  735. if (path.length() == 0) return true;
  736. std::string sub;
  737. fixPath(path);
  738. std::string::size_type pos = path.find('/');
  739. while (pos != std::string::npos)
  740. {
  741. std::string cur = path.substr(0, pos-0);
  742. if (cur.length() > 0 && !isDirectory(cur))
  743. {
  744. bool ret = false;
  745. #ifdef WIN32
  746. ret = CreateDirectoryA(cur.c_str(), NULL) ? true : false;
  747. #else
  748. ret = (mkdir(cur.c_str(), S_IRWXU|S_IRWXG|S_IRWXO) == 0);
  749. #endif
  750. if (!ret)
  751. {
  752. return false;
  753. }
  754. }
  755. pos = path.find('/', pos+1);
  756. }
  757. return true;
  758. }
  759. std::string getProcessID()
  760. {
  761. std::string pid = "0";
  762. char buf[260] = {0};
  763. #ifdef WIN32
  764. DWORD winPID = GetCurrentProcessId();
  765. sprintf(buf, "%06u", winPID);
  766. pid = buf;
  767. #else
  768. sprintf(buf, "%06d", getpid());
  769. pid = buf;
  770. #endif
  771. return pid;
  772. }
  773. std::string getProcessName()
  774. {
  775. std::string name = "process";
  776. char buf[260] = {0};
  777. #ifdef WIN32
  778. if (GetModuleFileNameA(NULL, buf, 259) > 0)
  779. {
  780. name = buf;
  781. }
  782. std::string::size_type pos = name.rfind("\\");
  783. if (pos != std::string::npos)
  784. {
  785. name = name.substr(pos+1, std::string::npos);
  786. }
  787. pos = name.rfind(".");
  788. if (pos != std::string::npos)
  789. {
  790. name = name.substr(0, pos-0);
  791. }
  792. #elif defined(LOG4Z_HAVE_LIBPROC)
  793. proc_name(getpid(), buf, 260);
  794. name = buf;
  795. return name;;
  796. #else
  797. sprintf(buf, "/proc/%d/cmdline", (int)getpid());
  798. Log4zFileHandler i;
  799. i.open(buf, "rb");
  800. if (!i.isOpen())
  801. {
  802. return name;
  803. }
  804. name = i.readLine();
  805. i.close();
  806. std::string::size_type pos = name.rfind("/");
  807. if (pos != std::string::npos)
  808. {
  809. name = name.substr(pos+1, std::string::npos);
  810. }
  811. #endif
  812. return name;
  813. }
  814. //////////////////////////////////////////////////////////////////////////
  815. // LockHelper
  816. //////////////////////////////////////////////////////////////////////////
  817. LockHelper::LockHelper()
  818. {
  819. #ifdef WIN32
  820. InitializeCriticalSection(&_crit);
  821. #else
  822. //_crit = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
  823. pthread_mutexattr_t attr;
  824. pthread_mutexattr_init(&attr);
  825. //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP);
  826. //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  827. pthread_mutex_init(&_crit, &attr);
  828. pthread_mutexattr_destroy(&attr);
  829. #endif
  830. }
  831. LockHelper::~LockHelper()
  832. {
  833. #ifdef WIN32
  834. DeleteCriticalSection(&_crit);
  835. #else
  836. pthread_mutex_destroy(&_crit);
  837. #endif
  838. }
  839. void LockHelper::lock()
  840. {
  841. #ifdef WIN32
  842. EnterCriticalSection(&_crit);
  843. #else
  844. pthread_mutex_lock(&_crit);
  845. #endif
  846. }
  847. void LockHelper::unLock()
  848. {
  849. #ifdef WIN32
  850. LeaveCriticalSection(&_crit);
  851. #else
  852. pthread_mutex_unlock(&_crit);
  853. #endif
  854. }
  855. //////////////////////////////////////////////////////////////////////////
  856. // SemHelper
  857. //////////////////////////////////////////////////////////////////////////
  858. SemHelper::SemHelper()
  859. {
  860. #ifdef WIN32
  861. _hSem = NULL;
  862. #elif defined(__APPLE__)
  863. _semid = NULL;
  864. #else
  865. _isCreate = false;
  866. #endif
  867. }
  868. SemHelper::~SemHelper()
  869. {
  870. #ifdef WIN32
  871. if (_hSem != NULL)
  872. {
  873. CloseHandle(_hSem);
  874. _hSem = NULL;
  875. }
  876. #elif defined(__APPLE__)
  877. if (_semid)
  878. {
  879. dispatch_release(_semid);
  880. _semid = NULL;
  881. }
  882. #else
  883. if (_isCreate)
  884. {
  885. _isCreate = false;
  886. sem_destroy(&_semid);
  887. }
  888. #endif
  889. }
  890. bool SemHelper::create(int initcount)
  891. {
  892. if (initcount < 0)
  893. {
  894. initcount = 0;
  895. }
  896. #ifdef WIN32
  897. if (initcount > 64)
  898. {
  899. return false;
  900. }
  901. _hSem = CreateSemaphore(NULL, initcount, 64, NULL);
  902. if (_hSem == NULL)
  903. {
  904. return false;
  905. }
  906. #elif defined(__APPLE__)
  907. _semid = dispatch_semaphore_create(initcount);
  908. if (!_semid)
  909. {
  910. return false;
  911. }
  912. #else
  913. if (sem_init(&_semid, 0, initcount) != 0)
  914. {
  915. return false;
  916. }
  917. _isCreate = true;
  918. #endif
  919. return true;
  920. }
  921. bool SemHelper::wait(int timeout)
  922. {
  923. #ifdef WIN32
  924. if (timeout <= 0)
  925. {
  926. timeout = INFINITE;
  927. }
  928. if (WaitForSingleObject(_hSem, timeout) != WAIT_OBJECT_0)
  929. {
  930. return false;
  931. }
  932. #elif defined(__APPLE__)
  933. if (dispatch_semaphore_wait(_semid, dispatch_time(DISPATCH_TIME_NOW, timeout*1000)) != 0)
  934. {
  935. return false;
  936. }
  937. #else
  938. if (timeout <= 0)
  939. {
  940. return (sem_wait(&_semid) == 0);
  941. }
  942. else
  943. {
  944. struct timeval tm;
  945. gettimeofday(&tm, NULL);
  946. long long endtime = tm.tv_sec *1000 + tm.tv_usec/1000 + timeout;
  947. do
  948. {
  949. sleepMillisecond(50);
  950. int ret = sem_trywait(&_semid);
  951. if (ret == 0)
  952. {
  953. return true;
  954. }
  955. struct timeval tv_cur;
  956. gettimeofday(&tv_cur, NULL);
  957. if (tv_cur.tv_sec*1000 + tv_cur.tv_usec/1000 > endtime)
  958. {
  959. return false;
  960. }
  961. if (ret == -1 && errno == EAGAIN)
  962. {
  963. continue;
  964. }
  965. else
  966. {
  967. return false;
  968. }
  969. } while (true);
  970. return false;
  971. }
  972. #endif
  973. return true;
  974. }
  975. bool SemHelper::post()
  976. {
  977. #ifdef WIN32
  978. return ReleaseSemaphore(_hSem, 1, NULL) ? true : false;
  979. #elif defined(__APPLE__)
  980. return dispatch_semaphore_signal(_semid) == 0;
  981. #else
  982. return (sem_post(&_semid) == 0);
  983. #endif
  984. }
  985. //////////////////////////////////////////////////////////////////////////
  986. //! ThreadHelper
  987. //////////////////////////////////////////////////////////////////////////
  988. bool ThreadHelper::start()
  989. {
  990. #ifdef WIN32
  991. unsigned long long ret = _beginthreadex(NULL, 0, threadProc, (void *) this, 0, NULL);
  992. if (ret == -1 || ret == 0)
  993. {
  994. printf("log4z: create log4z thread error! \r\n");
  995. return false;
  996. }
  997. _hThreadID = ret;
  998. #else
  999. int ret = pthread_create(&_phtreadID, NULL, threadProc, (void*)this);
  1000. if (ret != 0)
  1001. {
  1002. printf("log4z: create log4z thread error! \r\n");
  1003. return false;
  1004. }
  1005. #endif
  1006. return true;
  1007. }
  1008. bool ThreadHelper::wait()
  1009. {
  1010. #ifdef WIN32
  1011. if (WaitForSingleObject((HANDLE)_hThreadID, INFINITE) != WAIT_OBJECT_0)
  1012. {
  1013. return false;
  1014. }
  1015. #else
  1016. if (pthread_join(_phtreadID, NULL) != 0)
  1017. {
  1018. return false;
  1019. }
  1020. #endif
  1021. return true;
  1022. }
  1023. //////////////////////////////////////////////////////////////////////////
  1024. //! LogerManager
  1025. //////////////////////////////////////////////////////////////////////////
  1026. LogerManager::LogerManager()
  1027. {
  1028. _runing = false;
  1029. _lastId = LOG4Z_MAIN_LOGGER_ID;
  1030. _hotUpdateInterval = 0;
  1031. _ullStatusTotalPushLog = 0;
  1032. _ullStatusTotalPopLog = 0;
  1033. _ullStatusTotalWriteFileCount = 0;
  1034. _ullStatusTotalWriteFileBytes = 0;
  1035. _pid = getProcessID();
  1036. _proName = getProcessName();
  1037. _loggers[LOG4Z_MAIN_LOGGER_ID]._enable = true;
  1038. _ids[LOG4Z_MAIN_LOGGER_KEY] = LOG4Z_MAIN_LOGGER_ID;
  1039. _loggers[LOG4Z_MAIN_LOGGER_ID]._key = LOG4Z_MAIN_LOGGER_KEY;
  1040. _loggers[LOG4Z_MAIN_LOGGER_ID]._name = LOG4Z_MAIN_LOGGER_KEY;
  1041. _chunk1[0] = '\0';
  1042. _chunk2[1] = '\0';
  1043. _chunk3[2] = '\0';
  1044. _chunk4[3] = '\0';
  1045. }
  1046. LogerManager::~LogerManager()
  1047. {
  1048. stop();
  1049. }
  1050. LogData * LogerManager::makeLogData(LoggerId id, int level)
  1051. {
  1052. LogData * pLog = NULL;
  1053. if (true)
  1054. {
  1055. if (!_freeLogDatas.empty())
  1056. {
  1057. AutoLock l(_freeLock);
  1058. if (!_freeLogDatas.empty())
  1059. {
  1060. pLog = _freeLogDatas.back();
  1061. _freeLogDatas.pop_back();
  1062. }
  1063. }
  1064. if (pLog == NULL)
  1065. {
  1066. pLog = new(malloc(sizeof(LogData) + LOG4Z_LOG_BUF_SIZE-1))LogData();
  1067. }
  1068. }
  1069. //append precise time to log
  1070. if (true)
  1071. {
  1072. pLog->_id = id;
  1073. pLog->_level = level;
  1074. pLog->_type = LDT_GENERAL;
  1075. pLog->_typeval = 0;
  1076. pLog->_threadID = 0;
  1077. pLog->_contentLen = 0;
  1078. #ifdef WIN32
  1079. FILETIME ft;
  1080. GetSystemTimeAsFileTime(&ft);
  1081. unsigned long long now = ft.dwHighDateTime;
  1082. now <<= 32;
  1083. now |= ft.dwLowDateTime;
  1084. now /= 10;
  1085. now -= 11644473600000000ULL;
  1086. now /= 1000;
  1087. pLog->_time = now / 1000;
  1088. pLog->_precise = (unsigned int)(now % 1000);
  1089. #else
  1090. struct timeval tm;
  1091. gettimeofday(&tm, NULL);
  1092. pLog->_time = tm.tv_sec;
  1093. pLog->_precise = tm.tv_usec / 1000;
  1094. #endif
  1095. #ifdef WIN32
  1096. pLog->_threadID = GetCurrentThreadId();
  1097. #elif defined(__APPLE__)
  1098. unsigned long long tid = 0;
  1099. pthread_threadid_np(NULL, &tid);
  1100. pLog->_threadID = (unsigned int) tid;
  1101. #else
  1102. pLog->_threadID = (unsigned int)syscall(SYS_gettid);
  1103. #endif
  1104. }
  1105. //format log
  1106. if (true)
  1107. {
  1108. #ifdef WIN32
  1109. static __declspec(thread) tm g_tt = { 0 };
  1110. static __declspec(thread) time_t g_curDayTime = 0 ;
  1111. #else
  1112. static __thread tm g_tt = { 0 };
  1113. static __thread time_t g_curDayTime = 0;
  1114. #endif // WIN32
  1115. if (pLog->_time < g_curDayTime || pLog->_time >= g_curDayTime + 24*3600)
  1116. {
  1117. g_tt = timeToTm(pLog->_time);
  1118. g_tt.tm_hour = 0;
  1119. g_tt.tm_min = 0;
  1120. g_tt.tm_sec = 0;
  1121. g_curDayTime = mktime(&g_tt);
  1122. }
  1123. time_t sec = pLog->_time - g_curDayTime;
  1124. Log4zStream ls(pLog->_content, LOG4Z_LOG_BUF_SIZE);
  1125. ls.writeULongLong(g_tt.tm_year + 1900, 4);
  1126. ls.writeChar('-');
  1127. ls.writeULongLong(g_tt.tm_mon + 1, 2);
  1128. ls.writeChar('-');
  1129. ls.writeULongLong(g_tt.tm_mday, 2);
  1130. ls.writeChar(' ');
  1131. ls.writeULongLong(sec/3600, 2);
  1132. ls.writeChar(':');
  1133. ls.writeULongLong((sec % 3600)/60 , 2);
  1134. ls.writeChar(':');
  1135. ls.writeULongLong(sec % 60, 2);
  1136. ls.writeChar('.');
  1137. ls.writeULongLong(pLog->_precise, 3);
  1138. ls.writeChar(' ');
  1139. ls.writeChar('[');
  1140. ls.writeULongLong(pLog->_threadID, 4);
  1141. ls.writeChar(']');
  1142. ls.writeChar(' ');
  1143. ls.writeString(LOG_STRING[pLog->_level], LOG_STRING_LEN[pLog->_level]);
  1144. ls.writeChar(' ');
  1145. pLog->_contentLen = ls.getCurrentLen();
  1146. }
  1147. return pLog;
  1148. }
  1149. void LogerManager::freeLogData(LogData * log)
  1150. {
  1151. if (_freeLogDatas.size() < 200)
  1152. {
  1153. AutoLock l(_freeLock);
  1154. _freeLogDatas.push_back(log);
  1155. }
  1156. else
  1157. {
  1158. log->~LogData();
  1159. free( log);
  1160. }
  1161. }
  1162. void LogerManager::showColorText(const char *text, int level)
  1163. {
  1164. #if defined(WIN32) && defined(LOG4Z_OEM_CONSOLE)
  1165. char oem[LOG4Z_LOG_BUF_SIZE] = { 0 };
  1166. CharToOemBuffA(text, oem, LOG4Z_LOG_BUF_SIZE);
  1167. #endif
  1168. if (level <= LOG_LEVEL_DEBUG || level > LOG_LEVEL_FATAL)
  1169. {
  1170. #if defined(WIN32) && defined(LOG4Z_OEM_CONSOLE)
  1171. printf("%s", oem);
  1172. #else
  1173. printf("%s", text);
  1174. #endif
  1175. return;
  1176. }
  1177. #ifndef WIN32
  1178. printf("%s%s\e[0m", LOG_COLOR[level], text);
  1179. #else
  1180. AutoLock l(_scLock);
  1181. HANDLE hStd = ::GetStdHandle(STD_OUTPUT_HANDLE);
  1182. if (hStd == INVALID_HANDLE_VALUE) return;
  1183. CONSOLE_SCREEN_BUFFER_INFO oldInfo;
  1184. if (!GetConsoleScreenBufferInfo(hStd, &oldInfo))
  1185. {
  1186. return;
  1187. }
  1188. else
  1189. {
  1190. SetConsoleTextAttribute(hStd, LOG_COLOR[level]);
  1191. #ifdef LOG4Z_OEM_CONSOLE
  1192. printf("%s", oem);
  1193. #else
  1194. printf("%s", text);
  1195. #endif
  1196. SetConsoleTextAttribute(hStd, oldInfo.wAttributes);
  1197. }
  1198. #endif
  1199. return;
  1200. }
  1201. bool LogerManager::configFromStringImpl(std::string content, bool isUpdate)
  1202. {
  1203. unsigned int sum = 0;
  1204. for (std::string::iterator iter = content.begin(); iter != content.end(); ++iter)
  1205. {
  1206. sum += (unsigned char)*iter;
  1207. }
  1208. if (sum == _checksum)
  1209. {
  1210. return true;
  1211. }
  1212. _checksum = sum;
  1213. std::map<std::string, LoggerInfo> loggerMap;
  1214. if (!parseConfigFromString(content, loggerMap))
  1215. {
  1216. printf(" !!! !!! !!! !!!\r\n");
  1217. printf(" !!! !!! log4z load config file error \r\n");
  1218. printf(" !!! !!! !!! !!!\r\n");
  1219. return false;
  1220. }
  1221. for (std::map<std::string, LoggerInfo>::iterator iter = loggerMap.begin(); iter != loggerMap.end(); ++iter)
  1222. {
  1223. LoggerId id = LOG4Z_INVALID_LOGGER_ID;
  1224. id = findLogger(iter->second._key.c_str());
  1225. if (id == LOG4Z_INVALID_LOGGER_ID)
  1226. {
  1227. if (isUpdate)
  1228. {
  1229. continue;
  1230. }
  1231. else
  1232. {
  1233. id = createLogger(iter->second._key.c_str());
  1234. if (id == LOG4Z_INVALID_LOGGER_ID)
  1235. {
  1236. continue;
  1237. }
  1238. }
  1239. }
  1240. enableLogger(id, iter->second._enable);
  1241. setLoggerName(id, iter->second._name.c_str());
  1242. setLoggerPath(id, iter->second._path.c_str());
  1243. setLoggerLevel(id, iter->second._level);
  1244. setLoggerFileLine(id, iter->second._fileLine);
  1245. setLoggerDisplay(id, iter->second._display);
  1246. setLoggerOutFile(id, iter->second._outfile);
  1247. setLoggerLimitsize(id, iter->second._limitsize);
  1248. setLoggerMonthdir(id, iter->second._monthdir);
  1249. }
  1250. return true;
  1251. }
  1252. //! read configure and create with overwriting
  1253. bool LogerManager::config(const char* configPath)
  1254. {
  1255. if (!_configFile.empty())
  1256. {
  1257. printf(" !!! !!! !!! !!!\r\n");
  1258. printf(" !!! !!! log4z configure error: too many calls to Config. the old config file=%s, the new config file=%s !!! !!! \r\n"
  1259. , _configFile.c_str(), configPath);
  1260. printf(" !!! !!! !!! !!!\r\n");
  1261. return false;
  1262. }
  1263. _configFile = configPath;
  1264. Log4zFileHandler f;
  1265. f.open(_configFile.c_str(), "rb");
  1266. if (!f.isOpen())
  1267. {
  1268. printf(" !!! !!! !!! !!!\r\n");
  1269. printf(" !!! !!! log4z load config file error. filename=%s !!! !!! \r\n", configPath);
  1270. printf(" !!! !!! !!! !!!\r\n");
  1271. return false;
  1272. }
  1273. return configFromStringImpl(f.readContent().c_str(), false);
  1274. }
  1275. //! read configure and create with overwriting
  1276. bool LogerManager::configFromString(const char* configContent)
  1277. {
  1278. return configFromStringImpl(configContent, false);
  1279. }
  1280. //! create with overwriting
  1281. LoggerId LogerManager::createLogger(const char* key)
  1282. {
  1283. if (key == NULL)
  1284. {
  1285. return LOG4Z_INVALID_LOGGER_ID;
  1286. }
  1287. std::string copyKey = key;
  1288. trimLogConfig(copyKey);
  1289. LoggerId newID = LOG4Z_INVALID_LOGGER_ID;
  1290. {
  1291. std::map<std::string, LoggerId>::iterator iter = _ids.find(copyKey);
  1292. if (iter != _ids.end())
  1293. {
  1294. newID = iter->second;
  1295. }
  1296. }
  1297. if (newID == LOG4Z_INVALID_LOGGER_ID)
  1298. {
  1299. if (_lastId +1 >= LOG4Z_LOGGER_MAX)
  1300. {
  1301. showColorText("log4z: CreateLogger can not create|writeover, because loggerid need < LOGGER_MAX! \r\n", LOG_LEVEL_FATAL);
  1302. return LOG4Z_INVALID_LOGGER_ID;
  1303. }
  1304. newID = ++ _lastId;
  1305. _ids[copyKey] = newID;
  1306. _loggers[newID]._enable = true;
  1307. _loggers[newID]._key = copyKey;
  1308. _loggers[newID]._name = copyKey;
  1309. }
  1310. return newID;
  1311. }
  1312. bool LogerManager::start()
  1313. {
  1314. if (_runing)
  1315. {
  1316. showColorText("log4z already start \r\n", LOG_LEVEL_FATAL);
  1317. return false;
  1318. }
  1319. _semaphore.create(0);
  1320. bool ret = ThreadHelper::start();
  1321. return ret && _semaphore.wait(3000);
  1322. }
  1323. bool LogerManager::stop()
  1324. {
  1325. if (_runing)
  1326. {
  1327. showColorText("log4z stopping \r\n", LOG_LEVEL_FATAL);
  1328. _runing = false;
  1329. wait();
  1330. while (!_freeLogDatas.empty())
  1331. {
  1332. delete _freeLogDatas.back();
  1333. _freeLogDatas.pop_back();
  1334. }
  1335. return true;
  1336. }
  1337. return false;
  1338. }
  1339. bool LogerManager::prePushLog(LoggerId id, int level)
  1340. {
  1341. if (id < 0 || id > _lastId || !_runing || !_loggers[id]._enable)
  1342. {
  1343. return false;
  1344. }
  1345. if (level < _loggers[id]._level)
  1346. {
  1347. return false;
  1348. }
  1349. size_t count = _logs.size();
  1350. if (count > LOG4Z_LOG_QUEUE_LIMIT_SIZE)
  1351. {
  1352. size_t rate = (count - LOG4Z_LOG_QUEUE_LIMIT_SIZE) * 100 / LOG4Z_LOG_QUEUE_LIMIT_SIZE;
  1353. if (rate > 100)
  1354. {
  1355. rate = 100;
  1356. }
  1357. if ((size_t)rand() % 100 < rate)
  1358. {
  1359. if (rate > 50)
  1360. {
  1361. AutoLock l(_logLock);
  1362. count = _logs.size();
  1363. }
  1364. if (count > LOG4Z_LOG_QUEUE_LIMIT_SIZE)
  1365. {
  1366. sleepMillisecond((unsigned int)(rate));
  1367. }
  1368. }
  1369. }
  1370. return true;
  1371. }
  1372. bool LogerManager::pushLog(LogData * pLog, const char * file, int line)
  1373. {
  1374. // discard log
  1375. if (pLog->_id < 0 || pLog->_id > _lastId || !_runing || !_loggers[pLog->_id]._enable)
  1376. {
  1377. freeLogData(pLog);
  1378. return false;
  1379. }
  1380. //filter log
  1381. if (pLog->_level < _loggers[pLog->_id]._level)
  1382. {
  1383. freeLogData(pLog);
  1384. return false;
  1385. }
  1386. if (_loggers[pLog->_id]._fileLine && file)
  1387. {
  1388. const char * pNameEnd = file + strlen(file);
  1389. const char * pNameBegin = pNameEnd;
  1390. do
  1391. {
  1392. if (*pNameBegin == '\\' || *pNameBegin == '/') { pNameBegin++; break; }
  1393. if (pNameBegin == file) { break; }
  1394. pNameBegin--;
  1395. } while (true);
  1396. zsummer::log4z::Log4zStream ss(pLog->_content + pLog->_contentLen, LOG4Z_LOG_BUF_SIZE - pLog->_contentLen);
  1397. ss.writeChar(' ');
  1398. ss.writeString(pNameBegin, pNameEnd - pNameBegin);
  1399. ss.writeChar(':');
  1400. ss.writeULongLong((unsigned long long)line);
  1401. pLog->_contentLen += ss.getCurrentLen();
  1402. }
  1403. if (pLog->_contentLen +3 > LOG4Z_LOG_BUF_SIZE ) pLog->_contentLen = LOG4Z_LOG_BUF_SIZE - 3;
  1404. pLog->_content[pLog->_contentLen + 0] = '\r';
  1405. pLog->_content[pLog->_contentLen + 1] = '\n';
  1406. pLog->_content[pLog->_contentLen + 2] = '\0';
  1407. pLog->_contentLen += 2;
  1408. if (_loggers[pLog->_id]._display && LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
  1409. {
  1410. showColorText(pLog->_content, pLog->_level);
  1411. }
  1412. if (LOG4Z_ALL_DEBUGOUTPUT_DISPLAY && LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
  1413. {
  1414. #ifdef WIN32
  1415. OutputDebugStringA(pLog->_content);
  1416. #endif
  1417. }
  1418. if (_loggers[pLog->_id]._outfile && LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
  1419. {
  1420. AutoLock l(_logLock);
  1421. if (openLogger(pLog))
  1422. {
  1423. _loggers[pLog->_id]._handle.write(pLog->_content, pLog->_contentLen);
  1424. _loggers[pLog->_id]._curWriteLen += (unsigned int)pLog->_contentLen;
  1425. closeLogger(pLog->_id);
  1426. _ullStatusTotalWriteFileCount++;
  1427. _ullStatusTotalWriteFileBytes += pLog->_contentLen;
  1428. }
  1429. }
  1430. if (LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
  1431. {
  1432. freeLogData(pLog);
  1433. return true;
  1434. }
  1435. AutoLock l(_logLock);
  1436. _logs.push_back(pLog);
  1437. _ullStatusTotalPushLog ++;
  1438. return true;
  1439. }
  1440. //! 查找ID
  1441. LoggerId LogerManager::findLogger(const char * key)
  1442. {
  1443. std::map<std::string, LoggerId>::iterator iter;
  1444. iter = _ids.find(key);
  1445. if (iter != _ids.end())
  1446. {
  1447. return iter->second;
  1448. }
  1449. return LOG4Z_INVALID_LOGGER_ID;
  1450. }
  1451. bool LogerManager::hotChange(LoggerId id, LogDataType ldt, int num, const std::string & text)
  1452. {
  1453. if (id <0 || id > _lastId) return false;
  1454. if (text.length() >= LOG4Z_LOG_BUF_SIZE) return false;
  1455. if (!_runing || LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
  1456. {
  1457. return onHotChange(id, ldt, num, text);
  1458. }
  1459. LogData * pLog = makeLogData(id, LOG4Z_DEFAULT_LEVEL);
  1460. pLog->_id = id;
  1461. pLog->_type = ldt;
  1462. pLog->_typeval = num;
  1463. memcpy(pLog->_content, text.c_str(), text.length());
  1464. pLog->_contentLen = (int)text.length();
  1465. AutoLock l(_logLock);
  1466. _logs.push_back(pLog);
  1467. return true;
  1468. }
  1469. bool LogerManager::onHotChange(LoggerId id, LogDataType ldt, int num, const std::string & text)
  1470. {
  1471. if (id < LOG4Z_MAIN_LOGGER_ID || id > _lastId)
  1472. {
  1473. return false;
  1474. }
  1475. LoggerInfo & logger = _loggers[id];
  1476. if (ldt == LDT_ENABLE_LOGGER) logger._enable = num != 0;
  1477. else if (ldt == LDT_SET_LOGGER_NAME) logger._name = text;
  1478. else if (ldt == LDT_SET_LOGGER_PATH) logger._path = text;
  1479. else if (ldt == LDT_SET_LOGGER_LEVEL) logger._level = num;
  1480. else if (ldt == LDT_SET_LOGGER_FILELINE) logger._fileLine = num != 0;
  1481. else if (ldt == LDT_SET_LOGGER_DISPLAY) logger._display = num != 0;
  1482. else if (ldt == LDT_SET_LOGGER_OUTFILE) logger._outfile = num != 0;
  1483. else if (ldt == LDT_SET_LOGGER_LIMITSIZE) logger._limitsize = num;
  1484. else if (ldt == LDT_SET_LOGGER_MONTHDIR) logger._monthdir = num != 0;
  1485. else if (ldt == LDT_SET_LOGGER_RESERVETIME) logger._logReserveTime = num >= 0 ? num : 0;
  1486. return true;
  1487. }
  1488. bool LogerManager::enableLogger(LoggerId id, bool enable)
  1489. {
  1490. if (id < 0 || id > _lastId) return false;
  1491. if (enable)
  1492. {
  1493. _loggers[id]._enable = true;
  1494. return true;
  1495. }
  1496. return hotChange(id, LDT_ENABLE_LOGGER, false, "");
  1497. }
  1498. bool LogerManager::setLoggerLevel(LoggerId id, int level)
  1499. {
  1500. if (id < 0 || id > _lastId) return false;
  1501. if (level <= _loggers[id]._level)
  1502. {
  1503. _loggers[id]._level = level;
  1504. return true;
  1505. }
  1506. return hotChange(id, LDT_SET_LOGGER_LEVEL, level, "");
  1507. }
  1508. bool LogerManager::setLoggerDisplay(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_DISPLAY, enable, ""); }
  1509. bool LogerManager::setLoggerOutFile(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_OUTFILE, enable, ""); }
  1510. bool LogerManager::setLoggerMonthdir(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_MONTHDIR, enable, ""); }
  1511. bool LogerManager::setLoggerFileLine(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_FILELINE, enable, ""); }
  1512. bool LogerManager::setLoggerReserveTime(LoggerId id, time_t sec) { return hotChange(id, LDT_SET_LOGGER_RESERVETIME, (int)sec, ""); }
  1513. bool LogerManager::setLoggerLimitsize(LoggerId id, unsigned int limitsize)
  1514. {
  1515. if (limitsize == 0 ) {limitsize = (unsigned int)-1;}
  1516. return hotChange(id, LDT_SET_LOGGER_LIMITSIZE, limitsize, "");
  1517. }
  1518. bool LogerManager::setLoggerName(LoggerId id, const char * name)
  1519. {
  1520. if (id <0 || id > _lastId) return false;
  1521. //the name by main logger is the process name and it's can't change.
  1522. // if (id == LOG4Z_MAIN_LOGGER_ID) return false;
  1523. if (name == NULL || strlen(name) == 0)
  1524. {
  1525. return false;
  1526. }
  1527. return hotChange(id, LDT_SET_LOGGER_NAME, 0, name);
  1528. }
  1529. bool LogerManager::setLoggerPath(LoggerId id, const char * path)
  1530. {
  1531. if (id <0 || id > _lastId) return false;
  1532. if (path == NULL || strlen(path) == 0) return false;
  1533. std::string copyPath = path;
  1534. {
  1535. char ch = copyPath.at(copyPath.length() - 1);
  1536. if (ch != '\\' && ch != '/')
  1537. {
  1538. copyPath.append("/");
  1539. }
  1540. }
  1541. return hotChange(id, LDT_SET_LOGGER_PATH, 0, copyPath);
  1542. }
  1543. bool LogerManager::setAutoUpdate(int interval)
  1544. {
  1545. _hotUpdateInterval = interval;
  1546. return true;
  1547. }
  1548. bool LogerManager::updateConfig()
  1549. {
  1550. if (_configFile.empty())
  1551. {
  1552. //LOGW("log4z update config file error. filename is empty.");
  1553. return false;
  1554. }
  1555. Log4zFileHandler f;
  1556. f.open(_configFile.c_str(), "rb");
  1557. if (!f.isOpen())
  1558. {
  1559. printf(" !!! !!! !!! !!!\r\n");
  1560. printf(" !!! !!! log4z load config file error. filename=%s !!! !!! \r\n", _configFile.c_str());
  1561. printf(" !!! !!! !!! !!!\r\n");
  1562. return false;
  1563. }
  1564. return configFromStringImpl(f.readContent().c_str(), true);
  1565. }
  1566. bool LogerManager::isLoggerEnable(LoggerId id)
  1567. {
  1568. if (id <0 || id > _lastId) return false;
  1569. return _loggers[id]._enable;
  1570. }
  1571. unsigned int LogerManager::getStatusActiveLoggers()
  1572. {
  1573. unsigned int actives = 0;
  1574. for (int i=0; i<= _lastId; i++)
  1575. {
  1576. if (_loggers[i]._enable)
  1577. {
  1578. actives ++;
  1579. }
  1580. }
  1581. return actives;
  1582. }
  1583. bool LogerManager::openLogger(LogData * pLog)
  1584. {
  1585. int id = pLog->_id;
  1586. if (id < 0 || id >_lastId)
  1587. {
  1588. showColorText("log4z: openLogger can not open, invalide logger id! \r\n", LOG_LEVEL_FATAL);
  1589. return false;
  1590. }
  1591. LoggerInfo * pLogger = &_loggers[id];
  1592. if (!pLogger->_enable || !pLogger->_outfile || pLog->_level < pLogger->_level)
  1593. {
  1594. return false;
  1595. }
  1596. bool sameday = pLog->_time >= pLogger->_curFileCreateDay && pLog->_time - pLogger->_curFileCreateDay < 24*3600;
  1597. bool needChageFile = pLogger->_curWriteLen > pLogger->_limitsize * 1024 * 1024;
  1598. if (!sameday || needChageFile)
  1599. {
  1600. if (!sameday)
  1601. {
  1602. pLogger->_curFileIndex = 0;
  1603. }
  1604. else
  1605. {
  1606. pLogger->_curFileIndex++;
  1607. }
  1608. if (pLogger->_handle.isOpen())
  1609. {
  1610. pLogger->_handle.close();
  1611. }
  1612. }
  1613. if (!pLogger->_handle.isOpen())
  1614. {
  1615. pLogger->_curFileCreateTime = pLog->_time;
  1616. pLogger->_curWriteLen = 0;
  1617. tm t = timeToTm(pLogger->_curFileCreateTime);
  1618. if (true) //process day time
  1619. {
  1620. tm day = t;
  1621. day.tm_hour = 0;
  1622. day.tm_min = 0;
  1623. day.tm_sec = 0;
  1624. pLogger->_curFileCreateDay = mktime(&day);
  1625. }
  1626. std::string name;
  1627. std::string path;
  1628. name = pLogger->_name;
  1629. path = pLogger->_path;
  1630. char buf[500] = { 0 };
  1631. if (pLogger->_monthdir)
  1632. {
  1633. sprintf(buf, "%04d_%02d/", t.tm_year + 1900, t.tm_mon + 1);
  1634. path += buf;
  1635. }
  1636. if (!isDirectory(path))
  1637. {
  1638. createRecursionDir(path);
  1639. }
  1640. if (LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
  1641. {
  1642. sprintf(buf, "%s_%s_%04d%02d%02d%02d_%s_%03u.log",
  1643. _proName.c_str(), name.c_str(), t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
  1644. t.tm_hour, _pid.c_str(), pLogger->_curFileIndex);
  1645. }
  1646. else
  1647. {
  1648. sprintf(buf, "%s_%s_%04d%02d%02d%02d%02d_%s_%03u.log",
  1649. _proName.c_str(), name.c_str(), t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
  1650. t.tm_hour, t.tm_min, _pid.c_str(), pLogger->_curFileIndex);
  1651. }
  1652. path += buf;
  1653. long curLen = pLogger->_handle.open(path.c_str(), "ab");
  1654. if (!pLogger->_handle.isOpen() || curLen < 0)
  1655. {
  1656. sprintf(buf, "log4z: can not open log file %s. \r\n", path.c_str());
  1657. showColorText("!!!!!!!!!!!!!!!!!!!!!!!!!! \r\n", LOG_LEVEL_FATAL);
  1658. showColorText(buf, LOG_LEVEL_FATAL);
  1659. showColorText("!!!!!!!!!!!!!!!!!!!!!!!!!! \r\n", LOG_LEVEL_FATAL);
  1660. pLogger->_outfile = false;
  1661. return false;
  1662. }
  1663. pLogger->_curWriteLen = (unsigned int)curLen;
  1664. if (pLogger->_logReserveTime > 0 )
  1665. {
  1666. if (pLogger->_historyLogs.size() > LOG4Z_FORCE_RESERVE_FILE_COUNT)
  1667. {
  1668. while (!pLogger->_historyLogs.empty() && pLogger->_historyLogs.front().first < time(NULL) - pLogger->_logReserveTime)
  1669. {
  1670. pLogger->_handle.removeFile(pLogger->_historyLogs.front().second.c_str());
  1671. pLogger->_historyLogs.pop_front();
  1672. }
  1673. }
  1674. if (pLogger->_historyLogs.empty() || pLogger->_historyLogs.back().second != path)
  1675. {
  1676. pLogger->_historyLogs.push_back(std::make_pair(time(NULL), path));
  1677. }
  1678. }
  1679. return true;
  1680. }
  1681. return true;
  1682. }
  1683. bool LogerManager::closeLogger(LoggerId id)
  1684. {
  1685. if (id < 0 || id >_lastId)
  1686. {
  1687. showColorText("log4z: closeLogger can not close, invalide logger id! \r\n", LOG_LEVEL_FATAL);
  1688. return false;
  1689. }
  1690. LoggerInfo * pLogger = &_loggers[id];
  1691. if (pLogger->_handle.isOpen())
  1692. {
  1693. pLogger->_handle.close();
  1694. return true;
  1695. }
  1696. return false;
  1697. }
  1698. bool LogerManager::popLog(LogData *& log)
  1699. {
  1700. if (_logsCache.empty())
  1701. {
  1702. if (!_logs.empty())
  1703. {
  1704. AutoLock l(_logLock);
  1705. if (_logs.empty())
  1706. {
  1707. return false;
  1708. }
  1709. _logsCache.swap(_logs);
  1710. }
  1711. }
  1712. if (!_logsCache.empty())
  1713. {
  1714. log = _logsCache.front();
  1715. _logsCache.pop_front();
  1716. return true;
  1717. }
  1718. return false;
  1719. }
  1720. void LogerManager::run()
  1721. {
  1722. _runing = true;
  1723. LOGA("----------------- log4z thread started! ----------------------------");
  1724. for (int i = 0; i <= _lastId; i++)
  1725. {
  1726. if (_loggers[i]._enable)
  1727. {
  1728. LOGA("logger id=" << i
  1729. << " key=" << _loggers[i]._key
  1730. << " name=" << _loggers[i]._name
  1731. << " path=" << _loggers[i]._path
  1732. << " level=" << _loggers[i]._level
  1733. << " display=" << _loggers[i]._display);
  1734. }
  1735. }
  1736. _semaphore.post();
  1737. LogData * pLog = NULL;
  1738. int needFlush[LOG4Z_LOGGER_MAX] = {0};
  1739. time_t lastCheckUpdate = time(NULL);
  1740. while (true)
  1741. {
  1742. while(popLog(pLog))
  1743. {
  1744. if (pLog->_id <0 || pLog->_id > _lastId)
  1745. {
  1746. freeLogData(pLog);
  1747. continue;
  1748. }
  1749. LoggerInfo & curLogger = _loggers[pLog->_id];
  1750. if (pLog->_type != LDT_GENERAL)
  1751. {
  1752. onHotChange(pLog->_id, (LogDataType)pLog->_type, pLog->_typeval, std::string(pLog->_content, pLog->_contentLen));
  1753. curLogger._handle.close();
  1754. freeLogData(pLog);
  1755. continue;
  1756. }
  1757. //
  1758. _ullStatusTotalPopLog ++;
  1759. //discard
  1760. if (!curLogger._enable || pLog->_level <curLogger._level )
  1761. {
  1762. freeLogData(pLog);
  1763. continue;
  1764. }
  1765. if (curLogger._display)
  1766. {
  1767. showColorText(pLog->_content, pLog->_level);
  1768. }
  1769. if (LOG4Z_ALL_DEBUGOUTPUT_DISPLAY )
  1770. {
  1771. #ifdef WIN32
  1772. OutputDebugStringA(pLog->_content);
  1773. #endif
  1774. }
  1775. if (curLogger._outfile )
  1776. {
  1777. if (!openLogger(pLog))
  1778. {
  1779. freeLogData(pLog);
  1780. continue;
  1781. }
  1782. curLogger._handle.write(pLog->_content, pLog->_contentLen);
  1783. curLogger._curWriteLen += (unsigned int)pLog->_contentLen;
  1784. needFlush[pLog->_id] ++;
  1785. _ullStatusTotalWriteFileCount++;
  1786. _ullStatusTotalWriteFileBytes += pLog->_contentLen;
  1787. }
  1788. else
  1789. {
  1790. _ullStatusTotalWriteFileCount++;
  1791. _ullStatusTotalWriteFileBytes += pLog->_contentLen;
  1792. }
  1793. freeLogData(pLog);
  1794. }
  1795. for (int i=0; i<=_lastId; i++)
  1796. {
  1797. if (_loggers[i]._enable && needFlush[i] > 0)
  1798. {
  1799. _loggers[i]._handle.flush();
  1800. needFlush[i] = 0;
  1801. }
  1802. if(!_loggers[i]._enable && _loggers[i]._handle.isOpen())
  1803. {
  1804. _loggers[i]._handle.close();
  1805. }
  1806. }
  1807. //! delay.
  1808. sleepMillisecond(50);
  1809. //! quit
  1810. if (!_runing && _logs.empty())
  1811. {
  1812. break;
  1813. }
  1814. if (_hotUpdateInterval != 0 && time(NULL) - lastCheckUpdate > _hotUpdateInterval)
  1815. {
  1816. updateConfig();
  1817. lastCheckUpdate = time(NULL);
  1818. }
  1819. }
  1820. for (int i=0; i <= _lastId; i++)
  1821. {
  1822. if (_loggers[i]._enable)
  1823. {
  1824. _loggers[i]._enable = false;
  1825. closeLogger(i);
  1826. }
  1827. }
  1828. }
  1829. //////////////////////////////////////////////////////////////////////////
  1830. //ILog4zManager::getInstance
  1831. //////////////////////////////////////////////////////////////////////////
  1832. ILog4zManager * ILog4zManager::getInstance()
  1833. {
  1834. static LogerManager m;
  1835. return &m;
  1836. }
  1837. _ZSUMMER_LOG4Z_END
  1838. _ZSUMMER_END