123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034 |
- /*
- * Log4z License
- * -----------
- *
- * Log4z is licensed under the terms of the MIT license reproduced below.
- * This means that Log4z is free software and can be used for both academic
- * and commercial purposes at absolutely no cost.
- *
- *
- * ===============================================================================
- *
- * Copyright (C) 2010-2017 YaweiZhang <yawei.zhang@foxmail.com>.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * ===============================================================================
- *
- * (end of COPYRIGHT)
- */
- #include "stdafx.h"
- #include "log4z.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <time.h>
- #include <string.h>
- #include <math.h>
- #include <string>
- #include <vector>
- #include <map>
- #include <list>
- #include <algorithm>
- #include <iostream>
- #ifdef WIN32
- #include <io.h>
- #include <shlwapi.h>
- #include <process.h>
- #pragma comment(lib, "shlwapi")
- #pragma comment(lib, "User32.lib")
- #pragma warning(disable:4996)
- #else
- #include <unistd.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include<pthread.h>
- #include <sys/time.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include <semaphore.h>
- #include <sys/syscall.h>
- #endif
- #ifdef __APPLE__
- #include "TargetConditionals.h"
- #include <dispatch/dispatch.h>
- #if !TARGET_OS_IPHONE
- #define LOG4Z_HAVE_LIBPROC
- #include <libproc.h>
- #endif
- #endif
- _ZSUMMER_BEGIN
- _ZSUMMER_LOG4Z_BEGIN
- static const char *const LOG_STRING[]=
- {
- "LOG_TRACE",
- "LOG_DEBUG",
- "LOG_INFO ",
- "LOG_WARN ",
- "LOG_ERROR",
- "LOG_ALARM",
- "LOG_FATAL",
- };
- static const size_t LOG_STRING_LEN[] =
- {
- sizeof("LOG_TRACE") - 1,
- sizeof("LOG_DEBUG") - 1,
- sizeof("LOG_INFO") - 1,
- sizeof("LOG_WARN") - 1,
- sizeof("LOG_ERROR") - 1,
- sizeof("LOG_ALARM") - 1,
- sizeof("LOG_FATAL") - 1,
- };
- #ifdef WIN32
- const static WORD LOG_COLOR[LOG_LEVEL_FATAL + 1] = {
- 0,
- 0,
- FOREGROUND_BLUE | FOREGROUND_GREEN,
- FOREGROUND_GREEN | FOREGROUND_RED,
- FOREGROUND_RED,
- FOREGROUND_GREEN,
- FOREGROUND_RED | FOREGROUND_BLUE };
- #else
- const static char LOG_COLOR[LOG_LEVEL_FATAL + 1][50] = {
- "\e[0m",
- "\e[0m",
- "\e[34m\e[1m",//hight blue
- "\e[33m", //yellow
- "\e[31m", //red
- "\e[32m", //green
- "\e[35m" };
- #endif
- //////////////////////////////////////////////////////////////////////////
- //! Log4zFileHandler
- //////////////////////////////////////////////////////////////////////////
- class Log4zFileHandler
- {
- public:
- Log4zFileHandler(){ _file = NULL; }
- ~Log4zFileHandler(){ close(); }
- inline bool isOpen(){ return _file != NULL; }
- inline long open(const char *path, const char * mod)
- {
- if (_file != NULL){fclose(_file);_file = NULL;}
- _file = fopen(path, mod);
- if (_file)
- {
- long tel = 0;
- long cur = ftell(_file);
- fseek(_file, 0L, SEEK_END);
- tel = ftell(_file);
- fseek(_file, cur, SEEK_SET);
- return tel;
- }
- return -1;
- }
- inline void clean(int index, int len)
- {
- #if !defined(__APPLE__) && !defined(WIN32)
- if (_file != NULL)
- {
- int fd = fileno(_file);
- fsync(fd);
- posix_fadvise(fd, index, len, POSIX_FADV_DONTNEED);
- fsync(fd);
- }
- #endif
- }
- inline void close()
- {
- if (_file != NULL){clean(0, 0); fclose(_file);_file = NULL;}
- }
- inline void write(const char * data, size_t len)
- {
- if (_file && len > 0)
- {
- if (fwrite(data, 1, len, _file) != len)
- {
- close();
- }
- }
- }
- inline void flush(){ if (_file) fflush(_file); }
- inline std::string readLine()
- {
- char buf[500] = { 0 };
- if (_file && fgets(buf, 500, _file) != NULL)
- {
- return std::string(buf);
- }
- return std::string();
- }
- inline const std::string readContent();
- inline bool removeFile(const std::string & path) { return ::remove(path.c_str()) == 0; }
- public:
- FILE *_file;
- };
- //////////////////////////////////////////////////////////////////////////
- //! UTILITY
- //////////////////////////////////////////////////////////////////////////
- static void fixPath(std::string &path);
- static void trimLogConfig(std::string &str, std::string extIgnore = std::string());
- static std::pair<std::string, std::string> splitPairString(const std::string & str, const std::string & delimiter);
- static bool isDirectory(std::string path);
- static bool createRecursionDir(std::string path);
- static std::string getProcessID();
- static std::string getProcessName();
- //////////////////////////////////////////////////////////////////////////
- //! SemHelper
- //////////////////////////////////////////////////////////////////////////
- class SemHelper
- {
- public:
- SemHelper();
- virtual ~SemHelper();
- public:
- bool create(int initcount);
- bool wait(int timeout = 0);
- bool post();
- private:
- #ifdef WIN32
- HANDLE _hSem;
- #elif defined(__APPLE__)
- dispatch_semaphore_t _semid;
- #else
- sem_t _semid;
- bool _isCreate;
- #endif
- };
- //////////////////////////////////////////////////////////////////////////
- //! ThreadHelper
- //////////////////////////////////////////////////////////////////////////
- #ifdef WIN32
- static unsigned int WINAPI threadProc(LPVOID lpParam);
- #else
- static void * threadProc(void * pParam);
- #endif
- class ThreadHelper
- {
- public:
- ThreadHelper(){_hThreadID = 0;}
- virtual ~ThreadHelper(){}
- public:
- bool start();
- bool wait();
- virtual void run() = 0;
- private:
- unsigned long long _hThreadID;
- #ifndef WIN32
- pthread_t _phtreadID;
- #endif
- };
- #ifdef WIN32
- unsigned int WINAPI threadProc(LPVOID lpParam)
- {
- ThreadHelper * p = (ThreadHelper *) lpParam;
- p->run();
- return 0;
- }
- #else
- void * threadProc(void * pParam)
- {
- ThreadHelper * p = (ThreadHelper *) pParam;
- p->run();
- return NULL;
- }
- #endif
- //////////////////////////////////////////////////////////////////////////
- //! LogData
- //////////////////////////////////////////////////////////////////////////
- enum LogDataType
- {
- LDT_GENERAL,
- LDT_ENABLE_LOGGER,
- LDT_SET_LOGGER_NAME,
- LDT_SET_LOGGER_PATH,
- LDT_SET_LOGGER_LEVEL,
- LDT_SET_LOGGER_FILELINE,
- LDT_SET_LOGGER_DISPLAY,
- LDT_SET_LOGGER_OUTFILE,
- LDT_SET_LOGGER_LIMITSIZE,
- LDT_SET_LOGGER_MONTHDIR,
- LDT_SET_LOGGER_RESERVETIME,
- // LDT_SET_LOGGER_,
- };
- //////////////////////////////////////////////////////////////////////////
- //! LoggerInfo
- //////////////////////////////////////////////////////////////////////////
- struct LoggerInfo
- {
- //! attribute
- std::string _key; //logger key
- std::string _name; // one logger one name.
- std::string _path; //path for log file.
- int _level; //filter level
- bool _display; //display to screen
- bool _outfile; //output to file
- bool _monthdir; //create directory per month
- unsigned int _limitsize; //limit file's size, unit Million byte.
- bool _enable; //logger is enable
- bool _fileLine; //enable/disable the log's suffix.(file name:line number)
- time_t _logReserveTime; //log file reserve time. unit is time second.
- //! runtime info
- time_t _curFileCreateTime; //file create time
- time_t _curFileCreateDay; //file create day time
- unsigned int _curFileIndex; //rolling file index
- unsigned int _curWriteLen; //current file length
- Log4zFileHandler _handle; //file handle.
- //!history
- std::list<std::pair<time_t, std::string> > _historyLogs;
-
- LoggerInfo()
- {
- _enable = false;
- _path = LOG4Z_DEFAULT_PATH;
- _level = LOG4Z_DEFAULT_LEVEL;
- _display = LOG4Z_DEFAULT_DISPLAY;
- _outfile = LOG4Z_DEFAULT_OUTFILE;
- _monthdir = LOG4Z_DEFAULT_MONTHDIR;
- _limitsize = LOG4Z_DEFAULT_LIMITSIZE;
- _fileLine = LOG4Z_DEFAULT_SHOWSUFFIX;
- _curFileCreateTime = 0;
- _curFileCreateDay = 0;
- _curFileIndex = 0;
- _curWriteLen = 0;
- _logReserveTime = 0;
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //! LogerManager
- //////////////////////////////////////////////////////////////////////////
- class LogerManager : public ThreadHelper, public ILog4zManager
- {
- public:
- LogerManager();
- virtual ~LogerManager();
-
- bool configFromStringImpl(std::string content, bool isUpdate);
- //! 读取配置文件并覆写
- virtual bool config(const char* configPath);
- virtual bool configFromString(const char* configContent);
- //! 覆写式创建
- virtual LoggerId createLogger(const char* key);
- virtual bool start();
- virtual bool stop();
- virtual bool prePushLog(LoggerId id, int level);
- virtual bool pushLog(LogData * pLog, const char * file, int line);
- //! 查找ID
- virtual LoggerId findLogger(const char* key);
- bool hotChange(LoggerId id, LogDataType ldt, int num, const std::string & text);
- virtual bool enableLogger(LoggerId id, bool enable);
- virtual bool setLoggerName(LoggerId id, const char * name);
- virtual bool setLoggerPath(LoggerId id, const char * path);
- virtual bool setLoggerLevel(LoggerId id, int nLevel);
- virtual bool setLoggerFileLine(LoggerId id, bool enable);
- virtual bool setLoggerDisplay(LoggerId id, bool enable);
- virtual bool setLoggerOutFile(LoggerId id, bool enable);
- virtual bool setLoggerLimitsize(LoggerId id, unsigned int limitsize);
- virtual bool setLoggerMonthdir(LoggerId id, bool enable);
- virtual bool setLoggerReserveTime(LoggerId id, time_t sec);
- virtual bool setAutoUpdate(int interval);
- virtual bool updateConfig();
- virtual bool isLoggerEnable(LoggerId id);
- virtual unsigned long long getStatusTotalWriteCount(){return _ullStatusTotalWriteFileCount;}
- virtual unsigned long long getStatusTotalWriteBytes() { return _ullStatusTotalWriteFileBytes; }
- virtual unsigned long long getStatusTotalPushQueue() { return _ullStatusTotalPushLog; }
- virtual unsigned long long getStatusTotalPopQueue() { return _ullStatusTotalPopLog; }
- virtual unsigned int getStatusActiveLoggers();
- protected:
- virtual LogData * makeLogData(LoggerId id, int level);
- virtual void freeLogData(LogData * log);
- void showColorText(const char *text, int level = LOG_LEVEL_DEBUG);
- bool onHotChange(LoggerId id, LogDataType ldt, int num, const std::string & text);
- bool openLogger(LogData * log);
- bool closeLogger(LoggerId id);
- bool popLog(LogData *& log);
- virtual void run();
- private:
- //! thread status.
- bool _runing;
- //! wait thread started.
- SemHelper _semaphore;
- //! hot change name or path for one logger
- int _hotUpdateInterval;
- unsigned int _checksum;
- //! the process info.
- std::string _pid;
- std::string _proName;
- //! config file name
- std::string _configFile;
- //! logger id manager, [logger name]:[logger id].
- std::map<std::string, LoggerId> _ids;
- // the last used id of _loggers
- LoggerId _lastId;
- LoggerInfo _loggers[LOG4Z_LOGGER_MAX];
-
- //! log queue
- char _chunk1[256];
- LockHelper _logLock;
- std::deque<LogData *> _logs;
- unsigned long long _ullStatusTotalPushLog;
- char _chunk2[256];
- LockHelper _freeLock;
- std::vector<LogData*> _freeLogDatas;
- char _chunk3[256];
- //show color lock
- LockHelper _scLock;
- //status statistics
- //write file
- char _chunk4[256];
- std::deque<LogData *> _logsCache;
- unsigned long long _ullStatusTotalPopLog;
- unsigned long long _ullStatusTotalWriteFileCount;
- unsigned long long _ullStatusTotalWriteFileBytes;
- };
- //////////////////////////////////////////////////////////////////////////
- //! Log4zFileHandler
- //////////////////////////////////////////////////////////////////////////
- const std::string Log4zFileHandler::readContent()
- {
- std::string content;
- if (!_file)
- {
- return content;
- }
- char buf[BUFSIZ];
- size_t ret = 0;
- do
- {
- ret = fread(buf, sizeof(char), BUFSIZ, _file);
- content.append(buf, ret);
- }
- while (ret == BUFSIZ);
- return content;
- }
- //////////////////////////////////////////////////////////////////////////
- //! utility
- //////////////////////////////////////////////////////////////////////////
- static inline void sleepMillisecond(unsigned int ms)
- {
- #ifdef WIN32
- ::Sleep(ms);
- #else
- usleep(1000*ms);
- #endif
- }
- static inline struct tm timeToTm(time_t t)
- {
- #ifdef WIN32
- #if _MSC_VER < 1400 //VS2003
- return * localtime(&t);
- #else //vs2005->vs2013->
- struct tm tt = { 0 };
- localtime_s(&tt, &t);
- return tt;
- #endif
- #else //linux
- struct tm tt = { 0 };
- localtime_r(&t, &tt);
- return tt;
- #endif
- }
- static void fixPath(std::string &path)
- {
- if (path.empty()){return;}
- for (std::string::iterator iter = path.begin(); iter != path.end(); ++iter)
- {
- if (*iter == '\\'){*iter = '/';}
- }
- if (path.at(path.length()-1) != '/'){path.append("/");}
- }
- static void trimLogConfig(std::string &str, std::string extIgnore)
- {
- if (str.empty()){return;}
- extIgnore += "\r\n\t ";
- int length = (int)str.length();
- int posBegin = 0;
- int posEnd = 0;
- //trim utf8 file bom
- if (str.length() >= 3
- && (unsigned char)str[0] == 0xef
- && (unsigned char)str[1] == 0xbb
- && (unsigned char)str[2] == 0xbf)
- {
- posBegin = 3;
- }
- //trim character
- for (int i = posBegin; i<length; i++)
- {
- bool bCheck = false;
- for (int j = 0; j < (int)extIgnore.length(); j++)
- {
- if (str[i] == extIgnore[j])
- {
- bCheck = true;
- }
- }
- if (bCheck)
- {
- if (i == posBegin)
- {
- posBegin++;
- }
- }
- else
- {
- posEnd = i + 1;
- }
- }
- if (posBegin < posEnd)
- {
- str = str.substr(posBegin, posEnd-posBegin);
- }
- else
- {
- str.clear();
- }
- }
- //split
- static std::pair<std::string, std::string> splitPairString(const std::string & str, const std::string & delimiter)
- {
- std::string::size_type pos = str.find(delimiter.c_str());
- if (pos == std::string::npos)
- {
- return std::make_pair(str, "");
- }
- return std::make_pair(str.substr(0, pos), str.substr(pos+delimiter.length()));
- }
- static bool parseConfigLine(const std::string& line, int curLineNum, std::string & key, std::map<std::string, LoggerInfo> & outInfo)
- {
- std::pair<std::string, std::string> kv = splitPairString(line, "=");
- if (kv.first.empty())
- {
- return false;
- }
- trimLogConfig(kv.first);
- trimLogConfig(kv.second);
- if (kv.first.empty() || kv.first.at(0) == '#')
- {
- return true;
- }
- if (kv.first.at(0) == '[')
- {
- trimLogConfig(kv.first, "[]");
- key = kv.first;
- {
- std::string tmpstr = kv.first;
- std::transform(tmpstr.begin(), tmpstr.end(), tmpstr.begin(), ::tolower);
- if (tmpstr == "main")
- {
- key = "Main";
- }
- }
- std::map<std::string, LoggerInfo>::iterator iter = outInfo.find(key);
- if (iter == outInfo.end())
- {
- LoggerInfo li;
- li._enable = true;
- li._key = key;
- li._name = key;
- outInfo.insert(std::make_pair(li._key, li));
- }
- else
- {
- printf("log4z configure warning: duplicate logger key:[%s] at line: %d \r\n", key.c_str(), curLineNum);
- }
- return true;
- }
- trimLogConfig(kv.first);
- trimLogConfig(kv.second);
- std::map<std::string, LoggerInfo>::iterator iter = outInfo.find(key);
- if (iter == outInfo.end())
- {
- printf("log4z configure warning: not found current logger name:[%s] at line:%d, key=%s, value=%s \r\n",
- key.c_str(), curLineNum, kv.first.c_str(), kv.second.c_str());
- return true;
- }
- std::transform(kv.first.begin(), kv.first.end(), kv.first.begin(), ::tolower);
- //! path
- if (kv.first == "path")
- {
- iter->second._path = kv.second;
- return true;
- }
- else if (kv.first == "name")
- {
- iter->second._name = kv.second;
- return true;
- }
- std::transform(kv.second.begin(), kv.second.end(), kv.second.begin(), ::tolower);
- //! level
- if (kv.first == "level")
- {
- if (kv.second == "trace" || kv.second == "all")
- {
- iter->second._level = LOG_LEVEL_TRACE;
- }
- else if (kv.second == "debug")
- {
- iter->second._level = LOG_LEVEL_DEBUG;
- }
- else if (kv.second == "info")
- {
- iter->second._level = LOG_LEVEL_INFO;
- }
- else if (kv.second == "warn" || kv.second == "warning")
- {
- iter->second._level = LOG_LEVEL_WARN;
- }
- else if (kv.second == "error")
- {
- iter->second._level = LOG_LEVEL_ERROR;
- }
- else if (kv.second == "alarm")
- {
- iter->second._level = LOG_LEVEL_ALARM;
- }
- else if (kv.second == "fatal")
- {
- iter->second._level = LOG_LEVEL_FATAL;
- }
- }
- //! display
- else if (kv.first == "display")
- {
- if (kv.second == "false" || kv.second == "0")
- {
- iter->second._display = false;
- }
- else
- {
- iter->second._display = true;
- }
- }
- //! output to file
- else if (kv.first == "outfile")
- {
- if (kv.second == "false" || kv.second == "0")
- {
- iter->second._outfile = false;
- }
- else
- {
- iter->second._outfile = true;
- }
- }
- //! monthdir
- else if (kv.first == "monthdir")
- {
- if (kv.second == "false" || kv.second == "0")
- {
- iter->second._monthdir = false;
- }
- else
- {
- iter->second._monthdir = true;
- }
- }
- //! limit file size
- else if (kv.first == "limitsize")
- {
- iter->second._limitsize = atoi(kv.second.c_str());
- }
- //! display log in file line
- else if (kv.first == "fileline")
- {
- if (kv.second == "false" || kv.second == "0")
- {
- iter->second._fileLine = false;
- }
- else
- {
- iter->second._fileLine = true;
- }
- }
- //! enable/disable one logger
- else if (kv.first == "enable")
- {
- if (kv.second == "false" || kv.second == "0")
- {
- iter->second._enable = false;
- }
- else
- {
- iter->second._enable = true;
- }
- }
- //! set reserve time
- else if (kv.first == "reserve")
- {
- iter->second._logReserveTime = atoi(kv.second.c_str());
- }
- return true;
- }
- static bool parseConfigFromString(std::string content, std::map<std::string, LoggerInfo> & outInfo)
- {
- std::string key;
- int curLine = 1;
- std::string line;
- std::string::size_type curPos = 0;
- if (content.empty())
- {
- return true;
- }
- do
- {
- std::string::size_type pos = std::string::npos;
- for (std::string::size_type i = curPos; i < content.length(); ++i)
- {
- //support linux/unix/windows LRCF
- if (content[i] == '\r' || content[i] == '\n')
- {
- pos = i;
- break;
- }
- }
- line = content.substr(curPos, pos - curPos);
- parseConfigLine(line, curLine, key, outInfo);
- curLine++;
- if (pos == std::string::npos)
- {
- break;
- }
- else
- {
- curPos = pos+1;
- }
- } while (1);
- return true;
- }
- bool isDirectory(std::string path)
- {
- #ifdef WIN32
- return PathIsDirectoryA(path.c_str()) ? true : false;
- #else
- DIR * pdir = opendir(path.c_str());
- if (pdir == NULL)
- {
- return false;
- }
- else
- {
- closedir(pdir);
- pdir = NULL;
- return true;
- }
- #endif
- }
- bool createRecursionDir(std::string path)
- {
- if (path.length() == 0) return true;
- std::string sub;
- fixPath(path);
- std::string::size_type pos = path.find('/');
- while (pos != std::string::npos)
- {
- std::string cur = path.substr(0, pos-0);
- if (cur.length() > 0 && !isDirectory(cur))
- {
- bool ret = false;
- #ifdef WIN32
- ret = CreateDirectoryA(cur.c_str(), NULL) ? true : false;
- #else
- ret = (mkdir(cur.c_str(), S_IRWXU|S_IRWXG|S_IRWXO) == 0);
- #endif
- if (!ret)
- {
- return false;
- }
- }
- pos = path.find('/', pos+1);
- }
- return true;
- }
- std::string getProcessID()
- {
- std::string pid = "0";
- char buf[260] = {0};
- #ifdef WIN32
- DWORD winPID = GetCurrentProcessId();
- sprintf(buf, "%06u", winPID);
- pid = buf;
- #else
- sprintf(buf, "%06d", getpid());
- pid = buf;
- #endif
- return pid;
- }
- std::string getProcessName()
- {
- std::string name = "process";
- char buf[260] = {0};
- #ifdef WIN32
- if (GetModuleFileNameA(NULL, buf, 259) > 0)
- {
- name = buf;
- }
- std::string::size_type pos = name.rfind("\\");
- if (pos != std::string::npos)
- {
- name = name.substr(pos+1, std::string::npos);
- }
- pos = name.rfind(".");
- if (pos != std::string::npos)
- {
- name = name.substr(0, pos-0);
- }
- #elif defined(LOG4Z_HAVE_LIBPROC)
- proc_name(getpid(), buf, 260);
- name = buf;
- return name;;
- #else
- sprintf(buf, "/proc/%d/cmdline", (int)getpid());
- Log4zFileHandler i;
- i.open(buf, "rb");
- if (!i.isOpen())
- {
- return name;
- }
- name = i.readLine();
- i.close();
- std::string::size_type pos = name.rfind("/");
- if (pos != std::string::npos)
- {
- name = name.substr(pos+1, std::string::npos);
- }
- #endif
- return name;
- }
- //////////////////////////////////////////////////////////////////////////
- // LockHelper
- //////////////////////////////////////////////////////////////////////////
- LockHelper::LockHelper()
- {
- #ifdef WIN32
- InitializeCriticalSection(&_crit);
- #else
- //_crit = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP);
- //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&_crit, &attr);
- pthread_mutexattr_destroy(&attr);
- #endif
- }
- LockHelper::~LockHelper()
- {
- #ifdef WIN32
- DeleteCriticalSection(&_crit);
- #else
- pthread_mutex_destroy(&_crit);
- #endif
- }
- void LockHelper::lock()
- {
- #ifdef WIN32
- EnterCriticalSection(&_crit);
- #else
- pthread_mutex_lock(&_crit);
- #endif
- }
- void LockHelper::unLock()
- {
- #ifdef WIN32
- LeaveCriticalSection(&_crit);
- #else
- pthread_mutex_unlock(&_crit);
- #endif
- }
- //////////////////////////////////////////////////////////////////////////
- // SemHelper
- //////////////////////////////////////////////////////////////////////////
- SemHelper::SemHelper()
- {
- #ifdef WIN32
- _hSem = NULL;
- #elif defined(__APPLE__)
- _semid = NULL;
- #else
- _isCreate = false;
- #endif
- }
- SemHelper::~SemHelper()
- {
- #ifdef WIN32
- if (_hSem != NULL)
- {
- CloseHandle(_hSem);
- _hSem = NULL;
- }
- #elif defined(__APPLE__)
- if (_semid)
- {
- dispatch_release(_semid);
- _semid = NULL;
- }
- #else
- if (_isCreate)
- {
- _isCreate = false;
- sem_destroy(&_semid);
- }
- #endif
- }
- bool SemHelper::create(int initcount)
- {
- if (initcount < 0)
- {
- initcount = 0;
- }
- #ifdef WIN32
- if (initcount > 64)
- {
- return false;
- }
- _hSem = CreateSemaphore(NULL, initcount, 64, NULL);
- if (_hSem == NULL)
- {
- return false;
- }
- #elif defined(__APPLE__)
- _semid = dispatch_semaphore_create(initcount);
- if (!_semid)
- {
- return false;
- }
- #else
- if (sem_init(&_semid, 0, initcount) != 0)
- {
- return false;
- }
- _isCreate = true;
- #endif
- return true;
- }
- bool SemHelper::wait(int timeout)
- {
- #ifdef WIN32
- if (timeout <= 0)
- {
- timeout = INFINITE;
- }
- if (WaitForSingleObject(_hSem, timeout) != WAIT_OBJECT_0)
- {
- return false;
- }
- #elif defined(__APPLE__)
- if (dispatch_semaphore_wait(_semid, dispatch_time(DISPATCH_TIME_NOW, timeout*1000)) != 0)
- {
- return false;
- }
- #else
- if (timeout <= 0)
- {
- return (sem_wait(&_semid) == 0);
- }
- else
- {
- struct timeval tm;
- gettimeofday(&tm, NULL);
- long long endtime = tm.tv_sec *1000 + tm.tv_usec/1000 + timeout;
- do
- {
- sleepMillisecond(50);
- int ret = sem_trywait(&_semid);
- if (ret == 0)
- {
- return true;
- }
- struct timeval tv_cur;
- gettimeofday(&tv_cur, NULL);
- if (tv_cur.tv_sec*1000 + tv_cur.tv_usec/1000 > endtime)
- {
- return false;
- }
- if (ret == -1 && errno == EAGAIN)
- {
- continue;
- }
- else
- {
- return false;
- }
- } while (true);
- return false;
- }
- #endif
- return true;
- }
- bool SemHelper::post()
- {
- #ifdef WIN32
- return ReleaseSemaphore(_hSem, 1, NULL) ? true : false;
- #elif defined(__APPLE__)
- return dispatch_semaphore_signal(_semid) == 0;
- #else
- return (sem_post(&_semid) == 0);
- #endif
- }
- //////////////////////////////////////////////////////////////////////////
- //! ThreadHelper
- //////////////////////////////////////////////////////////////////////////
- bool ThreadHelper::start()
- {
- #ifdef WIN32
- unsigned long long ret = _beginthreadex(NULL, 0, threadProc, (void *) this, 0, NULL);
- if (ret == -1 || ret == 0)
- {
- printf("log4z: create log4z thread error! \r\n");
- return false;
- }
- _hThreadID = ret;
- #else
- int ret = pthread_create(&_phtreadID, NULL, threadProc, (void*)this);
- if (ret != 0)
- {
- printf("log4z: create log4z thread error! \r\n");
- return false;
- }
- #endif
- return true;
- }
- bool ThreadHelper::wait()
- {
- #ifdef WIN32
- if (WaitForSingleObject((HANDLE)_hThreadID, INFINITE) != WAIT_OBJECT_0)
- {
- return false;
- }
- #else
- if (pthread_join(_phtreadID, NULL) != 0)
- {
- return false;
- }
- #endif
- return true;
- }
- //////////////////////////////////////////////////////////////////////////
- //! LogerManager
- //////////////////////////////////////////////////////////////////////////
- LogerManager::LogerManager()
- {
- _runing = false;
- _lastId = LOG4Z_MAIN_LOGGER_ID;
- _hotUpdateInterval = 0;
- _ullStatusTotalPushLog = 0;
- _ullStatusTotalPopLog = 0;
- _ullStatusTotalWriteFileCount = 0;
- _ullStatusTotalWriteFileBytes = 0;
-
- _pid = getProcessID();
- _proName = getProcessName();
- _loggers[LOG4Z_MAIN_LOGGER_ID]._enable = true;
- _ids[LOG4Z_MAIN_LOGGER_KEY] = LOG4Z_MAIN_LOGGER_ID;
- _loggers[LOG4Z_MAIN_LOGGER_ID]._key = LOG4Z_MAIN_LOGGER_KEY;
- _loggers[LOG4Z_MAIN_LOGGER_ID]._name = LOG4Z_MAIN_LOGGER_KEY;
- _chunk1[0] = '\0';
- _chunk2[1] = '\0';
- _chunk3[2] = '\0';
- _chunk4[3] = '\0';
- }
- LogerManager::~LogerManager()
- {
- stop();
- }
- LogData * LogerManager::makeLogData(LoggerId id, int level)
- {
- LogData * pLog = NULL;
- if (true)
- {
- if (!_freeLogDatas.empty())
- {
- AutoLock l(_freeLock);
- if (!_freeLogDatas.empty())
- {
- pLog = _freeLogDatas.back();
- _freeLogDatas.pop_back();
- }
- }
- if (pLog == NULL)
- {
- pLog = new(malloc(sizeof(LogData) + LOG4Z_LOG_BUF_SIZE-1))LogData();
- }
- }
- //append precise time to log
- if (true)
- {
- pLog->_id = id;
- pLog->_level = level;
- pLog->_type = LDT_GENERAL;
- pLog->_typeval = 0;
- pLog->_threadID = 0;
- pLog->_contentLen = 0;
- #ifdef WIN32
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- unsigned long long now = ft.dwHighDateTime;
- now <<= 32;
- now |= ft.dwLowDateTime;
- now /= 10;
- now -= 11644473600000000ULL;
- now /= 1000;
- pLog->_time = now / 1000;
- pLog->_precise = (unsigned int)(now % 1000);
- #else
- struct timeval tm;
- gettimeofday(&tm, NULL);
- pLog->_time = tm.tv_sec;
- pLog->_precise = tm.tv_usec / 1000;
- #endif
- #ifdef WIN32
- pLog->_threadID = GetCurrentThreadId();
- #elif defined(__APPLE__)
- unsigned long long tid = 0;
- pthread_threadid_np(NULL, &tid);
- pLog->_threadID = (unsigned int) tid;
- #else
- pLog->_threadID = (unsigned int)syscall(SYS_gettid);
- #endif
- }
- //format log
- if (true)
- {
- #ifdef WIN32
- static __declspec(thread) tm g_tt = { 0 };
- static __declspec(thread) time_t g_curDayTime = 0 ;
- #else
- static __thread tm g_tt = { 0 };
- static __thread time_t g_curDayTime = 0;
- #endif // WIN32
- if (pLog->_time < g_curDayTime || pLog->_time >= g_curDayTime + 24*3600)
- {
- g_tt = timeToTm(pLog->_time);
- g_tt.tm_hour = 0;
- g_tt.tm_min = 0;
- g_tt.tm_sec = 0;
- g_curDayTime = mktime(&g_tt);
- }
- time_t sec = pLog->_time - g_curDayTime;
- Log4zStream ls(pLog->_content, LOG4Z_LOG_BUF_SIZE);
- ls.writeULongLong(g_tt.tm_year + 1900, 4);
- ls.writeChar('-');
- ls.writeULongLong(g_tt.tm_mon + 1, 2);
- ls.writeChar('-');
- ls.writeULongLong(g_tt.tm_mday, 2);
- ls.writeChar(' ');
- ls.writeULongLong(sec/3600, 2);
- ls.writeChar(':');
- ls.writeULongLong((sec % 3600)/60 , 2);
- ls.writeChar(':');
- ls.writeULongLong(sec % 60, 2);
- ls.writeChar('.');
- ls.writeULongLong(pLog->_precise, 3);
- ls.writeChar(' ');
- ls.writeChar('[');
- ls.writeULongLong(pLog->_threadID, 4);
- ls.writeChar(']');
- ls.writeChar(' ');
- ls.writeString(LOG_STRING[pLog->_level], LOG_STRING_LEN[pLog->_level]);
- ls.writeChar(' ');
- pLog->_contentLen = ls.getCurrentLen();
- }
- return pLog;
- }
- void LogerManager::freeLogData(LogData * log)
- {
- if (_freeLogDatas.size() < 200)
- {
- AutoLock l(_freeLock);
- _freeLogDatas.push_back(log);
- }
- else
- {
- log->~LogData();
- free( log);
- }
- }
- void LogerManager::showColorText(const char *text, int level)
- {
- #if defined(WIN32) && defined(LOG4Z_OEM_CONSOLE)
- char oem[LOG4Z_LOG_BUF_SIZE] = { 0 };
- CharToOemBuffA(text, oem, LOG4Z_LOG_BUF_SIZE);
- #endif
- if (level <= LOG_LEVEL_DEBUG || level > LOG_LEVEL_FATAL)
- {
- #if defined(WIN32) && defined(LOG4Z_OEM_CONSOLE)
- printf("%s", oem);
- #else
- printf("%s", text);
- #endif
- return;
- }
- #ifndef WIN32
- printf("%s%s\e[0m", LOG_COLOR[level], text);
- #else
- AutoLock l(_scLock);
- HANDLE hStd = ::GetStdHandle(STD_OUTPUT_HANDLE);
- if (hStd == INVALID_HANDLE_VALUE) return;
- CONSOLE_SCREEN_BUFFER_INFO oldInfo;
- if (!GetConsoleScreenBufferInfo(hStd, &oldInfo))
- {
- return;
- }
- else
- {
- SetConsoleTextAttribute(hStd, LOG_COLOR[level]);
- #ifdef LOG4Z_OEM_CONSOLE
- printf("%s", oem);
- #else
- printf("%s", text);
- #endif
- SetConsoleTextAttribute(hStd, oldInfo.wAttributes);
- }
- #endif
- return;
- }
- bool LogerManager::configFromStringImpl(std::string content, bool isUpdate)
- {
- unsigned int sum = 0;
- for (std::string::iterator iter = content.begin(); iter != content.end(); ++iter)
- {
- sum += (unsigned char)*iter;
- }
- if (sum == _checksum)
- {
- return true;
- }
- _checksum = sum;
-
- std::map<std::string, LoggerInfo> loggerMap;
- if (!parseConfigFromString(content, loggerMap))
- {
- printf(" !!! !!! !!! !!!\r\n");
- printf(" !!! !!! log4z load config file error \r\n");
- printf(" !!! !!! !!! !!!\r\n");
- return false;
- }
- for (std::map<std::string, LoggerInfo>::iterator iter = loggerMap.begin(); iter != loggerMap.end(); ++iter)
- {
- LoggerId id = LOG4Z_INVALID_LOGGER_ID;
- id = findLogger(iter->second._key.c_str());
- if (id == LOG4Z_INVALID_LOGGER_ID)
- {
- if (isUpdate)
- {
- continue;
- }
- else
- {
- id = createLogger(iter->second._key.c_str());
- if (id == LOG4Z_INVALID_LOGGER_ID)
- {
- continue;
- }
- }
- }
- enableLogger(id, iter->second._enable);
- setLoggerName(id, iter->second._name.c_str());
- setLoggerPath(id, iter->second._path.c_str());
- setLoggerLevel(id, iter->second._level);
- setLoggerFileLine(id, iter->second._fileLine);
- setLoggerDisplay(id, iter->second._display);
- setLoggerOutFile(id, iter->second._outfile);
- setLoggerLimitsize(id, iter->second._limitsize);
- setLoggerMonthdir(id, iter->second._monthdir);
- }
- return true;
- }
- //! read configure and create with overwriting
- bool LogerManager::config(const char* configPath)
- {
- if (!_configFile.empty())
- {
- printf(" !!! !!! !!! !!!\r\n");
- printf(" !!! !!! log4z configure error: too many calls to Config. the old config file=%s, the new config file=%s !!! !!! \r\n"
- , _configFile.c_str(), configPath);
- printf(" !!! !!! !!! !!!\r\n");
- return false;
- }
- _configFile = configPath;
- Log4zFileHandler f;
- f.open(_configFile.c_str(), "rb");
- if (!f.isOpen())
- {
- printf(" !!! !!! !!! !!!\r\n");
- printf(" !!! !!! log4z load config file error. filename=%s !!! !!! \r\n", configPath);
- printf(" !!! !!! !!! !!!\r\n");
- return false;
- }
- return configFromStringImpl(f.readContent().c_str(), false);
- }
- //! read configure and create with overwriting
- bool LogerManager::configFromString(const char* configContent)
- {
- return configFromStringImpl(configContent, false);
- }
- //! create with overwriting
- LoggerId LogerManager::createLogger(const char* key)
- {
- if (key == NULL)
- {
- return LOG4Z_INVALID_LOGGER_ID;
- }
-
- std::string copyKey = key;
- trimLogConfig(copyKey);
- LoggerId newID = LOG4Z_INVALID_LOGGER_ID;
- {
- std::map<std::string, LoggerId>::iterator iter = _ids.find(copyKey);
- if (iter != _ids.end())
- {
- newID = iter->second;
- }
- }
- if (newID == LOG4Z_INVALID_LOGGER_ID)
- {
- if (_lastId +1 >= LOG4Z_LOGGER_MAX)
- {
- showColorText("log4z: CreateLogger can not create|writeover, because loggerid need < LOGGER_MAX! \r\n", LOG_LEVEL_FATAL);
- return LOG4Z_INVALID_LOGGER_ID;
- }
- newID = ++ _lastId;
- _ids[copyKey] = newID;
- _loggers[newID]._enable = true;
- _loggers[newID]._key = copyKey;
- _loggers[newID]._name = copyKey;
- }
- return newID;
- }
- bool LogerManager::start()
- {
- if (_runing)
- {
- showColorText("log4z already start \r\n", LOG_LEVEL_FATAL);
- return false;
- }
- _semaphore.create(0);
- bool ret = ThreadHelper::start();
- return ret && _semaphore.wait(3000);
- }
- bool LogerManager::stop()
- {
- if (_runing)
- {
- showColorText("log4z stopping \r\n", LOG_LEVEL_FATAL);
- _runing = false;
- wait();
- while (!_freeLogDatas.empty())
- {
- delete _freeLogDatas.back();
- _freeLogDatas.pop_back();
- }
- return true;
- }
- return false;
- }
- bool LogerManager::prePushLog(LoggerId id, int level)
- {
- if (id < 0 || id > _lastId || !_runing || !_loggers[id]._enable)
- {
- return false;
- }
- if (level < _loggers[id]._level)
- {
- return false;
- }
- size_t count = _logs.size();
- if (count > LOG4Z_LOG_QUEUE_LIMIT_SIZE)
- {
- size_t rate = (count - LOG4Z_LOG_QUEUE_LIMIT_SIZE) * 100 / LOG4Z_LOG_QUEUE_LIMIT_SIZE;
- if (rate > 100)
- {
- rate = 100;
- }
- if ((size_t)rand() % 100 < rate)
- {
- if (rate > 50)
- {
- AutoLock l(_logLock);
- count = _logs.size();
- }
- if (count > LOG4Z_LOG_QUEUE_LIMIT_SIZE)
- {
- sleepMillisecond((unsigned int)(rate));
- }
- }
- }
- return true;
- }
- bool LogerManager::pushLog(LogData * pLog, const char * file, int line)
- {
- // discard log
- if (pLog->_id < 0 || pLog->_id > _lastId || !_runing || !_loggers[pLog->_id]._enable)
- {
- freeLogData(pLog);
- return false;
- }
- //filter log
- if (pLog->_level < _loggers[pLog->_id]._level)
- {
- freeLogData(pLog);
- return false;
- }
- if (_loggers[pLog->_id]._fileLine && file)
- {
- const char * pNameEnd = file + strlen(file);
- const char * pNameBegin = pNameEnd;
- do
- {
- if (*pNameBegin == '\\' || *pNameBegin == '/') { pNameBegin++; break; }
- if (pNameBegin == file) { break; }
- pNameBegin--;
- } while (true);
- zsummer::log4z::Log4zStream ss(pLog->_content + pLog->_contentLen, LOG4Z_LOG_BUF_SIZE - pLog->_contentLen);
- ss.writeChar(' ');
- ss.writeString(pNameBegin, pNameEnd - pNameBegin);
- ss.writeChar(':');
- ss.writeULongLong((unsigned long long)line);
- pLog->_contentLen += ss.getCurrentLen();
- }
- if (pLog->_contentLen +3 > LOG4Z_LOG_BUF_SIZE ) pLog->_contentLen = LOG4Z_LOG_BUF_SIZE - 3;
- pLog->_content[pLog->_contentLen + 0] = '\r';
- pLog->_content[pLog->_contentLen + 1] = '\n';
- pLog->_content[pLog->_contentLen + 2] = '\0';
- pLog->_contentLen += 2;
- if (_loggers[pLog->_id]._display && LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
- {
- showColorText(pLog->_content, pLog->_level);
- }
- if (LOG4Z_ALL_DEBUGOUTPUT_DISPLAY && LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
- {
- #ifdef WIN32
- OutputDebugStringA(pLog->_content);
- #endif
- }
- if (_loggers[pLog->_id]._outfile && LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
- {
- AutoLock l(_logLock);
- if (openLogger(pLog))
- {
- _loggers[pLog->_id]._handle.write(pLog->_content, pLog->_contentLen);
- _loggers[pLog->_id]._curWriteLen += (unsigned int)pLog->_contentLen;
- closeLogger(pLog->_id);
- _ullStatusTotalWriteFileCount++;
- _ullStatusTotalWriteFileBytes += pLog->_contentLen;
- }
- }
- if (LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
- {
- freeLogData(pLog);
- return true;
- }
-
- AutoLock l(_logLock);
- _logs.push_back(pLog);
- _ullStatusTotalPushLog ++;
- return true;
- }
- //! 查找ID
- LoggerId LogerManager::findLogger(const char * key)
- {
- std::map<std::string, LoggerId>::iterator iter;
- iter = _ids.find(key);
- if (iter != _ids.end())
- {
- return iter->second;
- }
- return LOG4Z_INVALID_LOGGER_ID;
- }
- bool LogerManager::hotChange(LoggerId id, LogDataType ldt, int num, const std::string & text)
- {
- if (id <0 || id > _lastId) return false;
- if (text.length() >= LOG4Z_LOG_BUF_SIZE) return false;
- if (!_runing || LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
- {
- return onHotChange(id, ldt, num, text);
- }
- LogData * pLog = makeLogData(id, LOG4Z_DEFAULT_LEVEL);
- pLog->_id = id;
- pLog->_type = ldt;
- pLog->_typeval = num;
- memcpy(pLog->_content, text.c_str(), text.length());
- pLog->_contentLen = (int)text.length();
- AutoLock l(_logLock);
- _logs.push_back(pLog);
- return true;
- }
- bool LogerManager::onHotChange(LoggerId id, LogDataType ldt, int num, const std::string & text)
- {
- if (id < LOG4Z_MAIN_LOGGER_ID || id > _lastId)
- {
- return false;
- }
- LoggerInfo & logger = _loggers[id];
- if (ldt == LDT_ENABLE_LOGGER) logger._enable = num != 0;
- else if (ldt == LDT_SET_LOGGER_NAME) logger._name = text;
- else if (ldt == LDT_SET_LOGGER_PATH) logger._path = text;
- else if (ldt == LDT_SET_LOGGER_LEVEL) logger._level = num;
- else if (ldt == LDT_SET_LOGGER_FILELINE) logger._fileLine = num != 0;
- else if (ldt == LDT_SET_LOGGER_DISPLAY) logger._display = num != 0;
- else if (ldt == LDT_SET_LOGGER_OUTFILE) logger._outfile = num != 0;
- else if (ldt == LDT_SET_LOGGER_LIMITSIZE) logger._limitsize = num;
- else if (ldt == LDT_SET_LOGGER_MONTHDIR) logger._monthdir = num != 0;
- else if (ldt == LDT_SET_LOGGER_RESERVETIME) logger._logReserveTime = num >= 0 ? num : 0;
- return true;
- }
- bool LogerManager::enableLogger(LoggerId id, bool enable)
- {
- if (id < 0 || id > _lastId) return false;
- if (enable)
- {
- _loggers[id]._enable = true;
- return true;
- }
- return hotChange(id, LDT_ENABLE_LOGGER, false, "");
- }
- bool LogerManager::setLoggerLevel(LoggerId id, int level)
- {
- if (id < 0 || id > _lastId) return false;
- if (level <= _loggers[id]._level)
- {
- _loggers[id]._level = level;
- return true;
- }
- return hotChange(id, LDT_SET_LOGGER_LEVEL, level, "");
- }
- bool LogerManager::setLoggerDisplay(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_DISPLAY, enable, ""); }
- bool LogerManager::setLoggerOutFile(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_OUTFILE, enable, ""); }
- bool LogerManager::setLoggerMonthdir(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_MONTHDIR, enable, ""); }
- bool LogerManager::setLoggerFileLine(LoggerId id, bool enable) { return hotChange(id, LDT_SET_LOGGER_FILELINE, enable, ""); }
- bool LogerManager::setLoggerReserveTime(LoggerId id, time_t sec) { return hotChange(id, LDT_SET_LOGGER_RESERVETIME, (int)sec, ""); }
- bool LogerManager::setLoggerLimitsize(LoggerId id, unsigned int limitsize)
- {
- if (limitsize == 0 ) {limitsize = (unsigned int)-1;}
- return hotChange(id, LDT_SET_LOGGER_LIMITSIZE, limitsize, "");
- }
- bool LogerManager::setLoggerName(LoggerId id, const char * name)
- {
- if (id <0 || id > _lastId) return false;
- //the name by main logger is the process name and it's can't change.
- // if (id == LOG4Z_MAIN_LOGGER_ID) return false;
-
- if (name == NULL || strlen(name) == 0)
- {
- return false;
- }
- return hotChange(id, LDT_SET_LOGGER_NAME, 0, name);
- }
- bool LogerManager::setLoggerPath(LoggerId id, const char * path)
- {
- if (id <0 || id > _lastId) return false;
- if (path == NULL || strlen(path) == 0) return false;
- std::string copyPath = path;
- {
- char ch = copyPath.at(copyPath.length() - 1);
- if (ch != '\\' && ch != '/')
- {
- copyPath.append("/");
- }
- }
- return hotChange(id, LDT_SET_LOGGER_PATH, 0, copyPath);
- }
- bool LogerManager::setAutoUpdate(int interval)
- {
- _hotUpdateInterval = interval;
- return true;
- }
- bool LogerManager::updateConfig()
- {
- if (_configFile.empty())
- {
- //LOGW("log4z update config file error. filename is empty.");
- return false;
- }
- Log4zFileHandler f;
- f.open(_configFile.c_str(), "rb");
- if (!f.isOpen())
- {
- printf(" !!! !!! !!! !!!\r\n");
- printf(" !!! !!! log4z load config file error. filename=%s !!! !!! \r\n", _configFile.c_str());
- printf(" !!! !!! !!! !!!\r\n");
- return false;
- }
- return configFromStringImpl(f.readContent().c_str(), true);
- }
- bool LogerManager::isLoggerEnable(LoggerId id)
- {
- if (id <0 || id > _lastId) return false;
- return _loggers[id]._enable;
- }
- unsigned int LogerManager::getStatusActiveLoggers()
- {
- unsigned int actives = 0;
- for (int i=0; i<= _lastId; i++)
- {
- if (_loggers[i]._enable)
- {
- actives ++;
- }
- }
- return actives;
- }
- bool LogerManager::openLogger(LogData * pLog)
- {
- int id = pLog->_id;
- if (id < 0 || id >_lastId)
- {
- showColorText("log4z: openLogger can not open, invalide logger id! \r\n", LOG_LEVEL_FATAL);
- return false;
- }
- LoggerInfo * pLogger = &_loggers[id];
- if (!pLogger->_enable || !pLogger->_outfile || pLog->_level < pLogger->_level)
- {
- return false;
- }
- bool sameday = pLog->_time >= pLogger->_curFileCreateDay && pLog->_time - pLogger->_curFileCreateDay < 24*3600;
- bool needChageFile = pLogger->_curWriteLen > pLogger->_limitsize * 1024 * 1024;
- if (!sameday || needChageFile)
- {
- if (!sameday)
- {
- pLogger->_curFileIndex = 0;
- }
- else
- {
- pLogger->_curFileIndex++;
- }
- if (pLogger->_handle.isOpen())
- {
- pLogger->_handle.close();
- }
- }
- if (!pLogger->_handle.isOpen())
- {
- pLogger->_curFileCreateTime = pLog->_time;
- pLogger->_curWriteLen = 0;
- tm t = timeToTm(pLogger->_curFileCreateTime);
- if (true) //process day time
- {
- tm day = t;
- day.tm_hour = 0;
- day.tm_min = 0;
- day.tm_sec = 0;
- pLogger->_curFileCreateDay = mktime(&day);
- }
-
- std::string name;
- std::string path;
- name = pLogger->_name;
- path = pLogger->_path;
-
- char buf[500] = { 0 };
- if (pLogger->_monthdir)
- {
- sprintf(buf, "%04d_%02d/", t.tm_year + 1900, t.tm_mon + 1);
- path += buf;
- }
- if (!isDirectory(path))
- {
- createRecursionDir(path);
- }
- if (LOG4Z_ALL_SYNCHRONOUS_OUTPUT)
- {
- sprintf(buf, "%s_%s_%04d%02d%02d%02d_%s_%03u.log",
- _proName.c_str(), name.c_str(), t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
- t.tm_hour, _pid.c_str(), pLogger->_curFileIndex);
- }
- else
- {
- sprintf(buf, "%s_%s_%04d%02d%02d%02d%02d_%s_%03u.log",
- _proName.c_str(), name.c_str(), t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
- t.tm_hour, t.tm_min, _pid.c_str(), pLogger->_curFileIndex);
- }
- path += buf;
- long curLen = pLogger->_handle.open(path.c_str(), "ab");
- if (!pLogger->_handle.isOpen() || curLen < 0)
- {
- sprintf(buf, "log4z: can not open log file %s. \r\n", path.c_str());
- showColorText("!!!!!!!!!!!!!!!!!!!!!!!!!! \r\n", LOG_LEVEL_FATAL);
- showColorText(buf, LOG_LEVEL_FATAL);
- showColorText("!!!!!!!!!!!!!!!!!!!!!!!!!! \r\n", LOG_LEVEL_FATAL);
- pLogger->_outfile = false;
- return false;
- }
- pLogger->_curWriteLen = (unsigned int)curLen;
- if (pLogger->_logReserveTime > 0 )
- {
- if (pLogger->_historyLogs.size() > LOG4Z_FORCE_RESERVE_FILE_COUNT)
- {
- while (!pLogger->_historyLogs.empty() && pLogger->_historyLogs.front().first < time(NULL) - pLogger->_logReserveTime)
- {
- pLogger->_handle.removeFile(pLogger->_historyLogs.front().second.c_str());
- pLogger->_historyLogs.pop_front();
- }
- }
- if (pLogger->_historyLogs.empty() || pLogger->_historyLogs.back().second != path)
- {
- pLogger->_historyLogs.push_back(std::make_pair(time(NULL), path));
- }
- }
- return true;
- }
- return true;
- }
- bool LogerManager::closeLogger(LoggerId id)
- {
- if (id < 0 || id >_lastId)
- {
- showColorText("log4z: closeLogger can not close, invalide logger id! \r\n", LOG_LEVEL_FATAL);
- return false;
- }
- LoggerInfo * pLogger = &_loggers[id];
- if (pLogger->_handle.isOpen())
- {
- pLogger->_handle.close();
- return true;
- }
- return false;
- }
- bool LogerManager::popLog(LogData *& log)
- {
- if (_logsCache.empty())
- {
- if (!_logs.empty())
- {
- AutoLock l(_logLock);
- if (_logs.empty())
- {
- return false;
- }
- _logsCache.swap(_logs);
- }
- }
- if (!_logsCache.empty())
- {
- log = _logsCache.front();
- _logsCache.pop_front();
- return true;
- }
- return false;
- }
- void LogerManager::run()
- {
- _runing = true;
- LOGA("----------------- log4z thread started! ----------------------------");
- for (int i = 0; i <= _lastId; i++)
- {
- if (_loggers[i]._enable)
- {
- LOGA("logger id=" << i
- << " key=" << _loggers[i]._key
- << " name=" << _loggers[i]._name
- << " path=" << _loggers[i]._path
- << " level=" << _loggers[i]._level
- << " display=" << _loggers[i]._display);
- }
- }
- _semaphore.post();
- LogData * pLog = NULL;
- int needFlush[LOG4Z_LOGGER_MAX] = {0};
- time_t lastCheckUpdate = time(NULL);
- while (true)
- {
- while(popLog(pLog))
- {
- if (pLog->_id <0 || pLog->_id > _lastId)
- {
- freeLogData(pLog);
- continue;
- }
- LoggerInfo & curLogger = _loggers[pLog->_id];
- if (pLog->_type != LDT_GENERAL)
- {
- onHotChange(pLog->_id, (LogDataType)pLog->_type, pLog->_typeval, std::string(pLog->_content, pLog->_contentLen));
- curLogger._handle.close();
- freeLogData(pLog);
- continue;
- }
-
- //
- _ullStatusTotalPopLog ++;
- //discard
-
- if (!curLogger._enable || pLog->_level <curLogger._level )
- {
- freeLogData(pLog);
- continue;
- }
- if (curLogger._display)
- {
- showColorText(pLog->_content, pLog->_level);
- }
- if (LOG4Z_ALL_DEBUGOUTPUT_DISPLAY )
- {
- #ifdef WIN32
- OutputDebugStringA(pLog->_content);
- #endif
- }
- if (curLogger._outfile )
- {
- if (!openLogger(pLog))
- {
- freeLogData(pLog);
- continue;
- }
- curLogger._handle.write(pLog->_content, pLog->_contentLen);
- curLogger._curWriteLen += (unsigned int)pLog->_contentLen;
- needFlush[pLog->_id] ++;
- _ullStatusTotalWriteFileCount++;
- _ullStatusTotalWriteFileBytes += pLog->_contentLen;
- }
- else
- {
- _ullStatusTotalWriteFileCount++;
- _ullStatusTotalWriteFileBytes += pLog->_contentLen;
- }
- freeLogData(pLog);
- }
- for (int i=0; i<=_lastId; i++)
- {
- if (_loggers[i]._enable && needFlush[i] > 0)
- {
- _loggers[i]._handle.flush();
- needFlush[i] = 0;
- }
- if(!_loggers[i]._enable && _loggers[i]._handle.isOpen())
- {
- _loggers[i]._handle.close();
- }
- }
- //! delay.
- sleepMillisecond(50);
- //! quit
- if (!_runing && _logs.empty())
- {
- break;
- }
-
- if (_hotUpdateInterval != 0 && time(NULL) - lastCheckUpdate > _hotUpdateInterval)
- {
- updateConfig();
- lastCheckUpdate = time(NULL);
- }
-
- }
- for (int i=0; i <= _lastId; i++)
- {
- if (_loggers[i]._enable)
- {
- _loggers[i]._enable = false;
- closeLogger(i);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- //ILog4zManager::getInstance
- //////////////////////////////////////////////////////////////////////////
- ILog4zManager * ILog4zManager::getInstance()
- {
- static LogerManager m;
- return &m;
- }
- _ZSUMMER_LOG4Z_END
- _ZSUMMER_END
|