easylogging++.h 180 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574
  1. //
  2. // Bismillah ar-Rahmaan ar-Raheem
  3. //
  4. // Easylogging++ v9.96.7
  5. // Single-header only, cross-platform logging library for C++ applications
  6. //
  7. // Copyright (c) 2012-2018 Zuhd Web Services
  8. // Copyright (c) 2012-2018 @abumusamq
  9. //
  10. // This library is released under the MIT Licence.
  11. // https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE
  12. //
  13. // https://zuhd.org
  14. // http://muflihun.com
  15. //
  16. #ifndef EASYLOGGINGPP_H
  17. #define EASYLOGGINGPP_H
  18. #define ELPP_HANDLE_SIGABRT
  19. #define ELPP_UNICODE
  20. #define ELPP_NO_DEFAULT_LOG_FILE
  21. // Compilers and C++0x/C++11 Evaluation
  22. #if __cplusplus >= 201103L
  23. # define ELPP_CXX11 1
  24. #endif // __cplusplus >= 201103L
  25. #if (defined(__GNUC__))
  26. # define ELPP_COMPILER_GCC 1
  27. #else
  28. # define ELPP_COMPILER_GCC 0
  29. #endif
  30. #if ELPP_COMPILER_GCC
  31. # define ELPP_GCC_VERSION (__GNUC__ * 10000 \
  32. + __GNUC_MINOR__ * 100 \
  33. + __GNUC_PATCHLEVEL__)
  34. # if defined(__GXX_EXPERIMENTAL_CXX0X__)
  35. # define ELPP_CXX0X 1
  36. # endif
  37. #endif
  38. // Visual C++
  39. #if defined(_MSC_VER)
  40. # define ELPP_COMPILER_MSVC 1
  41. #else
  42. # define ELPP_COMPILER_MSVC 0
  43. #endif
  44. #define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC
  45. #if ELPP_COMPILER_MSVC
  46. # if (_MSC_VER == 1600)
  47. # define ELPP_CXX0X 1
  48. # elif(_MSC_VER >= 1700)
  49. # define ELPP_CXX11 1
  50. # endif
  51. #endif
  52. // Clang++
  53. #if (defined(__clang__) && (__clang__ == 1))
  54. # define ELPP_COMPILER_CLANG 1
  55. #else
  56. # define ELPP_COMPILER_CLANG 0
  57. #endif
  58. #if ELPP_COMPILER_CLANG
  59. # if __has_include(<thread>)
  60. # include <cstddef> // Make __GLIBCXX__ defined when using libstdc++
  61. # if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426
  62. # define ELPP_CLANG_SUPPORTS_THREAD
  63. # endif // !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426
  64. # endif // __has_include(<thread>)
  65. #endif
  66. #if (defined(__MINGW32__) || defined(__MINGW64__))
  67. # define ELPP_MINGW 1
  68. #else
  69. # define ELPP_MINGW 0
  70. #endif
  71. #if (defined(__CYGWIN__) && (__CYGWIN__ == 1))
  72. # define ELPP_CYGWIN 1
  73. #else
  74. # define ELPP_CYGWIN 0
  75. #endif
  76. #if (defined(__INTEL_COMPILER))
  77. # define ELPP_COMPILER_INTEL 1
  78. #else
  79. # define ELPP_COMPILER_INTEL 0
  80. #endif
  81. // Operating System Evaluation
  82. // Windows
  83. #if (defined(_WIN32) || defined(_WIN64))
  84. # define ELPP_OS_WINDOWS 1
  85. #else
  86. # define ELPP_OS_WINDOWS 0
  87. #endif
  88. // Linux
  89. #if (defined(__linux) || defined(__linux__))
  90. # define ELPP_OS_LINUX 1
  91. #else
  92. # define ELPP_OS_LINUX 0
  93. #endif
  94. #if (defined(__APPLE__))
  95. # define ELPP_OS_MAC 1
  96. #else
  97. # define ELPP_OS_MAC 0
  98. #endif
  99. #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
  100. # define ELPP_OS_FREEBSD 1
  101. #else
  102. # define ELPP_OS_FREEBSD 0
  103. #endif
  104. #if (defined(__sun))
  105. # define ELPP_OS_SOLARIS 1
  106. #else
  107. # define ELPP_OS_SOLARIS 0
  108. #endif
  109. #if (defined(_AIX))
  110. # define ELPP_OS_AIX 1
  111. #else
  112. # define ELPP_OS_AIX 0
  113. #endif
  114. #if (defined(__NetBSD__))
  115. # define ELPP_OS_NETBSD 1
  116. #else
  117. # define ELPP_OS_NETBSD 0
  118. #endif
  119. #if defined(__EMSCRIPTEN__)
  120. # define ELPP_OS_EMSCRIPTEN 1
  121. #else
  122. # define ELPP_OS_EMSCRIPTEN 0
  123. #endif
  124. // Unix
  125. #if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN) && (!ELPP_OS_WINDOWS))
  126. # define ELPP_OS_UNIX 1
  127. #else
  128. # define ELPP_OS_UNIX 0
  129. #endif
  130. #if (defined(__ANDROID__))
  131. # define ELPP_OS_ANDROID 1
  132. #else
  133. # define ELPP_OS_ANDROID 0
  134. #endif
  135. // Evaluating Cygwin as *nix OS
  136. #if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
  137. # undef ELPP_OS_UNIX
  138. # undef ELPP_OS_LINUX
  139. # define ELPP_OS_UNIX 1
  140. # define ELPP_OS_LINUX 1
  141. #endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN
  142. #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO)
  143. # define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout
  144. #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
  145. #if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR)
  146. # define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr
  147. #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
  148. #if !defined(ELPP_INTERNAL_DEBUGGING_ENDL)
  149. # define ELPP_INTERNAL_DEBUGGING_ENDL std::endl
  150. #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
  151. #if !defined(ELPP_INTERNAL_DEBUGGING_MSG)
  152. # define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg
  153. #endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT)
  154. // Internal Assertions and errors
  155. #if !defined(ELPP_DISABLE_ASSERT)
  156. # if (defined(ELPP_DEBUG_ASSERT_FAILURE))
  157. # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
  158. std::stringstream internalInfoStream; internalInfoStream << msg; \
  159. ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
  160. << "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \
  161. << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \
  162. "ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); }
  163. # else
  164. # define ELPP_ASSERT(expr, msg) if (!(expr)) { \
  165. std::stringstream internalInfoStream; internalInfoStream << msg; \
  166. ELPP_INTERNAL_DEBUGGING_OUT_ERROR\
  167. << "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \
  168. << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \
  169. << ELPP_INTERNAL_DEBUGGING_ENDL; }
  170. # endif // (defined(ELPP_DEBUG_ASSERT_FAILURE))
  171. #else
  172. # define ELPP_ASSERT(x, y)
  173. #endif //(!defined(ELPP_DISABLE_ASSERT)
  174. #if ELPP_COMPILER_MSVC
  175. # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
  176. { char buff[256]; strerror_s(buff, 256, errno); \
  177. ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0
  178. #else
  179. # define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \
  180. ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0
  181. #endif // ELPP_COMPILER_MSVC
  182. #if defined(ELPP_DEBUG_ERRORS)
  183. # if !defined(ELPP_INTERNAL_ERROR)
  184. # define ELPP_INTERNAL_ERROR(msg, pe) { \
  185. std::stringstream internalInfoStream; internalInfoStream << "<ERROR> " << msg; \
  186. ELPP_INTERNAL_DEBUGGING_OUT_ERROR \
  187. << "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \
  188. << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \
  189. if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0
  190. # endif
  191. #else
  192. # undef ELPP_INTERNAL_INFO
  193. # define ELPP_INTERNAL_ERROR(msg, pe)
  194. #endif // defined(ELPP_DEBUG_ERRORS)
  195. #if (defined(ELPP_DEBUG_INFO))
  196. # if !(defined(ELPP_INTERNAL_INFO_LEVEL))
  197. # define ELPP_INTERNAL_INFO_LEVEL 9
  198. # endif // !(defined(ELPP_INTERNAL_INFO_LEVEL))
  199. # if !defined(ELPP_INTERNAL_INFO)
  200. # define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \
  201. std::stringstream internalInfoStream; internalInfoStream << "<INFO> " << msg; \
  202. ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \
  203. << ELPP_INTERNAL_DEBUGGING_ENDL; }}
  204. # endif
  205. #else
  206. # undef ELPP_INTERNAL_INFO
  207. # define ELPP_INTERNAL_INFO(lvl, msg)
  208. #endif // (defined(ELPP_DEBUG_INFO))
  209. #if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
  210. # if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN)
  211. # define ELPP_STACKTRACE 1
  212. # else
  213. # if ELPP_COMPILER_MSVC
  214. # pragma message("Stack trace not available for this compiler")
  215. # else
  216. # warning "Stack trace not available for this compiler";
  217. # endif // ELPP_COMPILER_MSVC
  218. # define ELPP_STACKTRACE 0
  219. # endif // ELPP_COMPILER_GCC
  220. #else
  221. # define ELPP_STACKTRACE 0
  222. #endif // (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
  223. // Miscellaneous macros
  224. #define ELPP_UNUSED(x) (void)x
  225. #if ELPP_OS_UNIX
  226. // Log file permissions for unix-based systems
  227. # define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH
  228. #endif // ELPP_OS_UNIX
  229. #if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
  230. # if defined(ELPP_EXPORT_SYMBOLS)
  231. # define ELPP_EXPORT __declspec(dllexport)
  232. # else
  233. # define ELPP_EXPORT __declspec(dllimport)
  234. # endif // defined(ELPP_EXPORT_SYMBOLS)
  235. #else
  236. # define ELPP_EXPORT
  237. #endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC
  238. // Some special functions that are VC++ specific
  239. #undef STRTOK
  240. #undef STRERROR
  241. #undef STRCAT
  242. #undef STRCPY
  243. #if ELPP_CRT_DBG_WARNINGS
  244. # define STRTOK(a, b, c) strtok_s(a, b, c)
  245. # define STRERROR(a, b, c) strerror_s(a, b, c)
  246. # define STRCAT(a, b, len) strcat_s(a, len, b)
  247. # define STRCPY(a, b, len) strcpy_s(a, len, b)
  248. #else
  249. # define STRTOK(a, b, c) strtok(a, b)
  250. # define STRERROR(a, b, c) strerror(c)
  251. # define STRCAT(a, b, len) strcat(a, b)
  252. # define STRCPY(a, b, len) strcpy(a, b)
  253. #endif
  254. // Compiler specific support evaluations
  255. #if (ELPP_MINGW && !defined(ELPP_FORCE_USE_STD_THREAD))
  256. # define ELPP_USE_STD_THREADING 0
  257. #else
  258. # if ((ELPP_COMPILER_CLANG && defined(ELPP_CLANG_SUPPORTS_THREAD)) || \
  259. (!ELPP_COMPILER_CLANG && defined(ELPP_CXX11)) || \
  260. defined(ELPP_FORCE_USE_STD_THREAD))
  261. # define ELPP_USE_STD_THREADING 1
  262. # else
  263. # define ELPP_USE_STD_THREADING 0
  264. # endif
  265. #endif
  266. #undef ELPP_FINAL
  267. #if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
  268. # define ELPP_FINAL
  269. #else
  270. # define ELPP_FINAL final
  271. #endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702)
  272. #if defined(ELPP_EXPERIMENTAL_ASYNC)
  273. # define ELPP_ASYNC_LOGGING 1
  274. #else
  275. # define ELPP_ASYNC_LOGGING 0
  276. #endif // defined(ELPP_EXPERIMENTAL_ASYNC)
  277. #if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
  278. # define ELPP_THREADING_ENABLED 1
  279. #else
  280. # define ELPP_THREADING_ENABLED 0
  281. #endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING
  282. // Function macro ELPP_FUNC
  283. #undef ELPP_FUNC
  284. #if ELPP_COMPILER_MSVC // Visual C++
  285. # define ELPP_FUNC __FUNCSIG__
  286. #elif ELPP_COMPILER_GCC // GCC
  287. # define ELPP_FUNC __PRETTY_FUNCTION__
  288. #elif ELPP_COMPILER_INTEL // Intel C++
  289. # define ELPP_FUNC __PRETTY_FUNCTION__
  290. #elif ELPP_COMPILER_CLANG // Clang++
  291. # define ELPP_FUNC __PRETTY_FUNCTION__
  292. #else
  293. # if defined(__func__)
  294. # define ELPP_FUNC __func__
  295. # else
  296. # define ELPP_FUNC ""
  297. # endif // defined(__func__)
  298. #endif // defined(_MSC_VER)
  299. #undef ELPP_VARIADIC_TEMPLATES_SUPPORTED
  300. // Keep following line commented until features are fixed
  301. #define ELPP_VARIADIC_TEMPLATES_SUPPORTED \
  302. (ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800))
  303. // Logging Enable/Disable macros
  304. #if defined(ELPP_DISABLE_LOGS)
  305. #define ELPP_LOGGING_ENABLED 0
  306. #else
  307. #define ELPP_LOGGING_ENABLED 1
  308. #endif
  309. #if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
  310. # define ELPP_DEBUG_LOG 1
  311. #else
  312. # define ELPP_DEBUG_LOG 0
  313. #endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED))
  314. #if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
  315. # define ELPP_INFO_LOG 1
  316. #else
  317. # define ELPP_INFO_LOG 0
  318. #endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED))
  319. #if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
  320. # define ELPP_WARNING_LOG 1
  321. #else
  322. # define ELPP_WARNING_LOG 0
  323. #endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED))
  324. #if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
  325. # define ELPP_ERROR_LOG 1
  326. #else
  327. # define ELPP_ERROR_LOG 0
  328. #endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED))
  329. #if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
  330. # define ELPP_FATAL_LOG 1
  331. #else
  332. # define ELPP_FATAL_LOG 0
  333. #endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED))
  334. #if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
  335. # define ELPP_TRACE_LOG 1
  336. #else
  337. # define ELPP_TRACE_LOG 0
  338. #endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED))
  339. #if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
  340. # define ELPP_VERBOSE_LOG 1
  341. #else
  342. # define ELPP_VERBOSE_LOG 0
  343. #endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED))
  344. #if (!(ELPP_CXX0X || ELPP_CXX11))
  345. # error "C++0x (or higher) support not detected! (Is `-std=c++11' missing?)"
  346. #endif // (!(ELPP_CXX0X || ELPP_CXX11))
  347. // Headers
  348. #if defined(ELPP_SYSLOG)
  349. # include <syslog.h>
  350. #endif // defined(ELPP_SYSLOG)
  351. #include <ctime>
  352. #include <cstring>
  353. #include <cstdlib>
  354. #include <cctype>
  355. #include <cwchar>
  356. #include <csignal>
  357. #include <cerrno>
  358. #include <cstdarg>
  359. #if defined(ELPP_UNICODE)
  360. # include <locale>
  361. # if ELPP_OS_WINDOWS
  362. # include <codecvt>
  363. # endif // ELPP_OS_WINDOWS
  364. #endif // defined(ELPP_UNICODE)
  365. #if ELPP_STACKTRACE
  366. # include <cxxabi.h>
  367. # include <execinfo.h>
  368. #endif // ELPP_STACKTRACE
  369. #if ELPP_OS_ANDROID
  370. # include <sys/system_properties.h>
  371. #endif // ELPP_OS_ANDROID
  372. #if ELPP_OS_UNIX
  373. # include <sys/stat.h>
  374. # include <sys/time.h>
  375. #elif ELPP_OS_WINDOWS
  376. # include <direct.h>
  377. # include <windows.h>
  378. # if defined(WIN32_LEAN_AND_MEAN)
  379. # if defined(ELPP_WINSOCK2)
  380. # include <winsock2.h>
  381. # else
  382. # include <winsock.h>
  383. # endif // defined(ELPP_WINSOCK2)
  384. # endif // defined(WIN32_LEAN_AND_MEAN)
  385. #endif // ELPP_OS_UNIX
  386. #include <string>
  387. #include <vector>
  388. #include <map>
  389. #include <unordered_map>
  390. #include <utility>
  391. #include <functional>
  392. #include <algorithm>
  393. #include <fstream>
  394. #include <iostream>
  395. #include <sstream>
  396. #include <memory>
  397. #include <type_traits>
  398. #if ELPP_THREADING_ENABLED
  399. # if ELPP_USE_STD_THREADING
  400. # include <mutex>
  401. # include <thread>
  402. # else
  403. # if ELPP_OS_UNIX
  404. # include <pthread.h>
  405. # endif // ELPP_OS_UNIX
  406. # endif // ELPP_USE_STD_THREADING
  407. #endif // ELPP_THREADING_ENABLED
  408. #if ELPP_ASYNC_LOGGING
  409. # if defined(ELPP_NO_SLEEP_FOR)
  410. # include <unistd.h>
  411. # endif // defined(ELPP_NO_SLEEP_FOR)
  412. # include <thread>
  413. # include <queue>
  414. # include <condition_variable>
  415. #endif // ELPP_ASYNC_LOGGING
  416. #if defined(ELPP_STL_LOGGING)
  417. // For logging STL based templates
  418. # include <list>
  419. # include <queue>
  420. # include <deque>
  421. # include <set>
  422. # include <bitset>
  423. # include <stack>
  424. # if defined(ELPP_LOG_STD_ARRAY)
  425. # include <array>
  426. # endif // defined(ELPP_LOG_STD_ARRAY)
  427. # if defined(ELPP_LOG_UNORDERED_SET)
  428. # include <unordered_set>
  429. # endif // defined(ELPP_UNORDERED_SET)
  430. #endif // defined(ELPP_STL_LOGGING)
  431. #if defined(ELPP_QT_LOGGING)
  432. // For logging Qt based classes & templates
  433. # include <QString>
  434. # include <QByteArray>
  435. # include <QVector>
  436. # include <QList>
  437. # include <QPair>
  438. # include <QMap>
  439. # include <QQueue>
  440. # include <QSet>
  441. # include <QLinkedList>
  442. # include <QHash>
  443. # include <QMultiHash>
  444. # include <QStack>
  445. #endif // defined(ELPP_QT_LOGGING)
  446. #if defined(ELPP_BOOST_LOGGING)
  447. // For logging boost based classes & templates
  448. # include <boost/container/vector.hpp>
  449. # include <boost/container/stable_vector.hpp>
  450. # include <boost/container/list.hpp>
  451. # include <boost/container/deque.hpp>
  452. # include <boost/container/map.hpp>
  453. # include <boost/container/flat_map.hpp>
  454. # include <boost/container/set.hpp>
  455. # include <boost/container/flat_set.hpp>
  456. #endif // defined(ELPP_BOOST_LOGGING)
  457. #if defined(ELPP_WXWIDGETS_LOGGING)
  458. // For logging wxWidgets based classes & templates
  459. # include <wx/vector.h>
  460. #endif // defined(ELPP_WXWIDGETS_LOGGING)
  461. #if defined(ELPP_UTC_DATETIME)
  462. # define elpptime_r gmtime_r
  463. # define elpptime_s gmtime_s
  464. # define elpptime gmtime
  465. #else
  466. # define elpptime_r localtime_r
  467. # define elpptime_s localtime_s
  468. # define elpptime localtime
  469. #endif // defined(ELPP_UTC_DATETIME)
  470. // Forward declarations
  471. namespace el {
  472. class Logger;
  473. class LogMessage;
  474. class PerformanceTrackingData;
  475. class Loggers;
  476. class Helpers;
  477. template <typename T> class Callback;
  478. class LogDispatchCallback;
  479. class PerformanceTrackingCallback;
  480. class LoggerRegistrationCallback;
  481. class LogDispatchData;
  482. namespace base {
  483. class Storage;
  484. class RegisteredLoggers;
  485. class PerformanceTracker;
  486. class MessageBuilder;
  487. class Writer;
  488. class PErrorWriter;
  489. class LogDispatcher;
  490. class DefaultLogBuilder;
  491. class DefaultLogDispatchCallback;
  492. #if ELPP_ASYNC_LOGGING
  493. class AsyncLogDispatchCallback;
  494. class AsyncDispatchWorker;
  495. #endif // ELPP_ASYNC_LOGGING
  496. class DefaultPerformanceTrackingCallback;
  497. } // namespace base
  498. } // namespace el
  499. /// @brief Easylogging++ entry namespace
  500. namespace el {
  501. /// @brief Namespace containing base/internal functionality used by Easylogging++
  502. namespace base {
  503. /// @brief Data types used by Easylogging++
  504. namespace type {
  505. #undef ELPP_LITERAL
  506. #undef ELPP_STRLEN
  507. #undef ELPP_COUT
  508. #if defined(ELPP_UNICODE)
  509. # define ELPP_LITERAL(txt) L##txt
  510. # define ELPP_STRLEN wcslen
  511. # if defined ELPP_CUSTOM_COUT
  512. # define ELPP_COUT ELPP_CUSTOM_COUT
  513. # else
  514. # define ELPP_COUT std::wcout
  515. # endif // defined ELPP_CUSTOM_COUT
  516. typedef wchar_t char_t;
  517. typedef std::wstring string_t;
  518. typedef std::wstringstream stringstream_t;
  519. typedef std::wfstream fstream_t;
  520. typedef std::wostream ostream_t;
  521. #else
  522. # define ELPP_LITERAL(txt) txt
  523. # define ELPP_STRLEN strlen
  524. # if defined ELPP_CUSTOM_COUT
  525. # define ELPP_COUT ELPP_CUSTOM_COUT
  526. # else
  527. # define ELPP_COUT std::cout
  528. # endif // defined ELPP_CUSTOM_COUT
  529. typedef char char_t;
  530. typedef std::string string_t;
  531. typedef std::stringstream stringstream_t;
  532. typedef std::fstream fstream_t;
  533. typedef std::ostream ostream_t;
  534. #endif // defined(ELPP_UNICODE)
  535. #if defined(ELPP_CUSTOM_COUT_LINE)
  536. # define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine)
  537. #else
  538. # define ELPP_COUT_LINE(logLine) logLine << std::flush
  539. #endif // defined(ELPP_CUSTOM_COUT_LINE)
  540. typedef unsigned int EnumType;
  541. typedef unsigned short VerboseLevel;
  542. typedef unsigned long int LineNumber;
  543. typedef std::shared_ptr<base::Storage> StoragePointer;
  544. typedef std::shared_ptr<LogDispatchCallback> LogDispatchCallbackPtr;
  545. typedef std::shared_ptr<PerformanceTrackingCallback> PerformanceTrackingCallbackPtr;
  546. typedef std::shared_ptr<LoggerRegistrationCallback> LoggerRegistrationCallbackPtr;
  547. typedef std::unique_ptr<el::base::PerformanceTracker> PerformanceTrackerPtr;
  548. } // namespace type
  549. /// @brief Internal helper class that prevent copy constructor for class
  550. ///
  551. /// @detail When using this class simply inherit it privately
  552. class NoCopy {
  553. protected:
  554. NoCopy(void) {}
  555. private:
  556. NoCopy(const NoCopy&);
  557. NoCopy& operator=(const NoCopy&);
  558. };
  559. /// @brief Internal helper class that makes all default constructors private.
  560. ///
  561. /// @detail This prevents initializing class making it static unless an explicit constructor is declared.
  562. /// When using this class simply inherit it privately
  563. class StaticClass {
  564. private:
  565. StaticClass(void);
  566. StaticClass(const StaticClass&);
  567. StaticClass& operator=(const StaticClass&);
  568. };
  569. } // namespace base
  570. /// @brief Represents enumeration for severity level used to determine level of logging
  571. ///
  572. /// @detail With Easylogging++, developers may disable or enable any level regardless of
  573. /// what the severity is. Or they can choose to log using hierarchical logging flag
  574. enum class Level : base::type::EnumType {
  575. /// @brief Generic level that represents all the levels. Useful when setting global configuration for all levels
  576. Global = 1,
  577. /// @brief Information that can be useful to back-trace certain events - mostly useful than debug logs.
  578. Trace = 2,
  579. /// @brief Informational events most useful for developers to debug application
  580. Debug = 4,
  581. /// @brief Severe error information that will presumably abort application
  582. Fatal = 8,
  583. /// @brief Information representing errors in application but application will keep running
  584. Error = 16,
  585. /// @brief Useful when application has potentially harmful situtaions
  586. Warning = 32,
  587. /// @brief Information that can be highly useful and vary with verbose logging level.
  588. Verbose = 64,
  589. /// @brief Mainly useful to represent current progress of application
  590. Info = 128,
  591. /// @brief Represents unknown level
  592. Unknown = 1010
  593. };
  594. } // namespace el
  595. namespace std {
  596. template<> struct hash<el::Level> {
  597. public:
  598. std::size_t operator()(const el::Level& l) const {
  599. return hash<el::base::type::EnumType> {}(static_cast<el::base::type::EnumType>(l));
  600. }
  601. };
  602. }
  603. namespace el {
  604. /// @brief Static class that contains helper functions for el::Level
  605. class LevelHelper : base::StaticClass {
  606. public:
  607. /// @brief Represents minimum valid level. Useful when iterating through enum.
  608. static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(Level::Trace);
  609. /// @brief Represents maximum valid level. This is used internally and you should not need it.
  610. static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(Level::Info);
  611. /// @brief Casts level to int, useful for iterating through enum.
  612. static base::type::EnumType castToInt(Level level) {
  613. return static_cast<base::type::EnumType>(level);
  614. }
  615. /// @brief Casts int(ushort) to level, useful for iterating through enum.
  616. static Level castFromInt(base::type::EnumType l) {
  617. return static_cast<Level>(l);
  618. }
  619. /// @brief Converts level to associated const char*
  620. /// @return Upper case string based level.
  621. static const char* convertToString(Level level);
  622. /// @brief Converts from levelStr to Level
  623. /// @param levelStr Upper case string based level.
  624. /// Lower case is also valid but providing upper case is recommended.
  625. static Level convertFromString(const char* levelStr);
  626. /// @brief Applies specified function to each level starting from startIndex
  627. /// @param startIndex initial value to start the iteration from. This is passed as pointer and
  628. /// is left-shifted so this can be used inside function (fn) to represent current level.
  629. /// @param fn function to apply with each level. This bool represent whether or not to stop iterating through levels.
  630. static void forEachLevel(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
  631. };
  632. /// @brief Represents enumeration of ConfigurationType used to configure or access certain aspect
  633. /// of logging
  634. enum class ConfigurationType : base::type::EnumType {
  635. /// @brief Determines whether or not corresponding level and logger of logging is enabled
  636. /// You may disable all logs by using el::Level::Global
  637. Enabled = 1,
  638. /// @brief Whether or not to write corresponding log to log file
  639. ToFile = 2,
  640. /// @brief Whether or not to write corresponding level and logger log to standard output.
  641. /// By standard output meaning termnal, command prompt etc
  642. ToStandardOutput = 4,
  643. /// @brief Determines format of logging corresponding level and logger.
  644. Format = 8,
  645. /// @brief Determines log file (full path) to write logs to for correponding level and logger
  646. Filename = 16,
  647. /// @brief Specifies precision of the subsecond part. It should be within range (1-6).
  648. SubsecondPrecision = 32,
  649. /// @brief Alias of SubsecondPrecision (for backward compatibility)
  650. MillisecondsWidth = SubsecondPrecision,
  651. /// @brief Determines whether or not performance tracking is enabled.
  652. ///
  653. /// @detail This does not depend on logger or level. Performance tracking always uses 'performance' logger
  654. PerformanceTracking = 64,
  655. /// @brief Specifies log file max size.
  656. ///
  657. /// @detail If file size of corresponding log file (for corresponding level) is >= specified size, log file will
  658. /// be truncated and re-initiated.
  659. MaxLogFileSize = 128,
  660. /// @brief Specifies number of log entries to hold until we flush pending log data
  661. LogFlushThreshold = 256,
  662. /// @brief Represents unknown configuration
  663. Unknown = 1010
  664. };
  665. /// @brief Static class that contains helper functions for el::ConfigurationType
  666. class ConfigurationTypeHelper : base::StaticClass {
  667. public:
  668. /// @brief Represents minimum valid configuration type. Useful when iterating through enum.
  669. static const base::type::EnumType kMinValid = static_cast<base::type::EnumType>(ConfigurationType::Enabled);
  670. /// @brief Represents maximum valid configuration type. This is used internally and you should not need it.
  671. static const base::type::EnumType kMaxValid = static_cast<base::type::EnumType>(ConfigurationType::MaxLogFileSize);
  672. /// @brief Casts configuration type to int, useful for iterating through enum.
  673. static base::type::EnumType castToInt(ConfigurationType configurationType) {
  674. return static_cast<base::type::EnumType>(configurationType);
  675. }
  676. /// @brief Casts int(ushort) to configurationt type, useful for iterating through enum.
  677. static ConfigurationType castFromInt(base::type::EnumType c) {
  678. return static_cast<ConfigurationType>(c);
  679. }
  680. /// @brief Converts configuration type to associated const char*
  681. /// @returns Upper case string based configuration type.
  682. static const char* convertToString(ConfigurationType configurationType);
  683. /// @brief Converts from configStr to ConfigurationType
  684. /// @param configStr Upper case string based configuration type.
  685. /// Lower case is also valid but providing upper case is recommended.
  686. static ConfigurationType convertFromString(const char* configStr);
  687. /// @brief Applies specified function to each configuration type starting from startIndex
  688. /// @param startIndex initial value to start the iteration from. This is passed by pointer and is left-shifted
  689. /// so this can be used inside function (fn) to represent current configuration type.
  690. /// @param fn function to apply with each configuration type.
  691. /// This bool represent whether or not to stop iterating through configurations.
  692. static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
  693. };
  694. /// @brief Flags used while writing logs. This flags are set by user
  695. enum class LoggingFlag : base::type::EnumType {
  696. /// @brief Makes sure we have new line for each container log entry
  697. NewLineForContainer = 1,
  698. /// @brief Makes sure if -vmodule is used and does not specifies a module, then verbose
  699. /// logging is allowed via that module.
  700. AllowVerboseIfModuleNotSpecified = 2,
  701. /// @brief When handling crashes by default, detailed crash reason will be logged as well
  702. LogDetailedCrashReason = 4,
  703. /// @brief Allows to disable application abortion when logged using FATAL level
  704. DisableApplicationAbortOnFatalLog = 8,
  705. /// @brief Flushes log with every log-entry (performance sensative) - Disabled by default
  706. ImmediateFlush = 16,
  707. /// @brief Enables strict file rolling
  708. StrictLogFileSizeCheck = 32,
  709. /// @brief Make terminal output colorful for supported terminals
  710. ColoredTerminalOutput = 64,
  711. /// @brief Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network")
  712. MultiLoggerSupport = 128,
  713. /// @brief Disables comparing performance tracker's checkpoints
  714. DisablePerformanceTrackingCheckpointComparison = 256,
  715. /// @brief Disable VModules
  716. DisableVModules = 512,
  717. /// @brief Disable VModules extensions
  718. DisableVModulesExtensions = 1024,
  719. /// @brief Enables hierarchical logging
  720. HierarchicalLogging = 2048,
  721. /// @brief Creates logger automatically when not available
  722. CreateLoggerAutomatically = 4096,
  723. /// @brief Adds spaces b/w logs that separated by left-shift operator
  724. AutoSpacing = 8192,
  725. /// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only)
  726. FixedTimeFormat = 16384,
  727. // @brief Ignore SIGINT or crash
  728. IgnoreSigInt = 32768,
  729. };
  730. namespace base {
  731. /// @brief Namespace containing constants used internally.
  732. namespace consts {
  733. static const char kFormatSpecifierCharValue = 'v';
  734. static const char kFormatSpecifierChar = '%';
  735. static const unsigned int kMaxLogPerCounter = 100000;
  736. static const unsigned int kMaxLogPerContainer = 100;
  737. static const unsigned int kDefaultSubsecondPrecision = 3;
  738. #ifdef ELPP_DEFAULT_LOGGER
  739. static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER;
  740. #else
  741. static const char* kDefaultLoggerId = "default";
  742. #endif
  743. #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  744. #ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER
  745. static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER;
  746. #else
  747. static const char* kPerformanceLoggerId = "performance";
  748. #endif // ELPP_DEFAULT_PERFORMANCE_LOGGER
  749. #endif
  750. #if defined(ELPP_SYSLOG)
  751. static const char* kSysLogLoggerId = "syslog";
  752. #endif // defined(ELPP_SYSLOG)
  753. #if ELPP_OS_WINDOWS
  754. static const char* kFilePathSeperator = "\\";
  755. #else
  756. static const char* kFilePathSeperator = "/";
  757. #endif // ELPP_OS_WINDOWS
  758. static const std::size_t kSourceFilenameMaxLength = 100;
  759. static const std::size_t kSourceLineMaxLength = 10;
  760. static const Level kPerformanceTrackerDefaultLevel = Level::Info;
  761. const struct {
  762. double value;
  763. const base::type::char_t* unit;
  764. } kTimeFormats[] = {
  765. { 1000.0f, ELPP_LITERAL("us") },
  766. { 1000.0f, ELPP_LITERAL("ms") },
  767. { 60.0f, ELPP_LITERAL("seconds") },
  768. { 60.0f, ELPP_LITERAL("minutes") },
  769. { 24.0f, ELPP_LITERAL("hours") },
  770. { 7.0f, ELPP_LITERAL("days") }
  771. };
  772. static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]);
  773. const struct {
  774. int numb;
  775. const char* name;
  776. const char* brief;
  777. const char* detail;
  778. } kCrashSignals[] = {
  779. // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..)
  780. {
  781. SIGABRT, "SIGABRT", "Abnormal termination",
  782. "Program was abnormally terminated."
  783. },
  784. {
  785. SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
  786. "Arithemetic operation issue such as division by zero or operation resulting in overflow."
  787. },
  788. {
  789. SIGILL, "SIGILL", "Illegal instruction",
  790. "Generally due to a corruption in the code or to an attempt to execute data."
  791. },
  792. {
  793. SIGSEGV, "SIGSEGV", "Invalid access to memory",
  794. "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory."
  795. },
  796. {
  797. SIGINT, "SIGINT", "Interactive attention signal",
  798. "Interruption generated (generally) by user or operating system."
  799. },
  800. };
  801. static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]);
  802. } // namespace consts
  803. } // namespace base
  804. typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
  805. namespace base {
  806. static inline void defaultPreRollOutCallback(const char*, std::size_t) {}
  807. /// @brief Enum to represent timestamp unit
  808. enum class TimestampUnit : base::type::EnumType {
  809. Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5
  810. };
  811. /// @brief Format flags used to determine specifiers that are active for performance improvements.
  812. enum class FormatFlags : base::type::EnumType {
  813. DateTime = 1 << 1,
  814. LoggerId = 1 << 2,
  815. File = 1 << 3,
  816. Line = 1 << 4,
  817. Location = 1 << 5,
  818. Function = 1 << 6,
  819. User = 1 << 7,
  820. Host = 1 << 8,
  821. LogMessage = 1 << 9,
  822. VerboseLevel = 1 << 10,
  823. AppName = 1 << 11,
  824. ThreadId = 1 << 12,
  825. Level = 1 << 13,
  826. FileBase = 1 << 14,
  827. LevelShort = 1 << 15
  828. };
  829. /// @brief A subsecond precision class containing actual width and offset of the subsecond part
  830. class SubsecondPrecision {
  831. public:
  832. SubsecondPrecision(void) {
  833. init(base::consts::kDefaultSubsecondPrecision);
  834. }
  835. explicit SubsecondPrecision(int width) {
  836. init(width);
  837. }
  838. bool operator==(const SubsecondPrecision& ssPrec) {
  839. return m_width == ssPrec.m_width && m_offset == ssPrec.m_offset;
  840. }
  841. int m_width;
  842. unsigned int m_offset;
  843. private:
  844. void init(int width);
  845. };
  846. /// @brief Type alias of SubsecondPrecision
  847. typedef SubsecondPrecision MillisecondsWidth;
  848. /// @brief Namespace containing utility functions/static classes used internally
  849. namespace utils {
  850. /// @brief Deletes memory safely and points to null
  851. template <typename T>
  852. static
  853. typename std::enable_if<std::is_pointer<T*>::value, void>::type
  854. safeDelete(T*& pointer) {
  855. if (pointer == nullptr)
  856. return;
  857. delete pointer;
  858. pointer = nullptr;
  859. }
  860. /// @brief Bitwise operations for C++11 strong enum class. This casts e into Flag_T and returns value after bitwise operation
  861. /// Use these function as <pre>flag = bitwise::Or<MyEnum>(MyEnum::val1, flag);</pre>
  862. namespace bitwise {
  863. template <typename Enum>
  864. static inline base::type::EnumType And(Enum e, base::type::EnumType flag) {
  865. return static_cast<base::type::EnumType>(flag) & static_cast<base::type::EnumType>(e);
  866. }
  867. template <typename Enum>
  868. static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) {
  869. return static_cast<base::type::EnumType>(flag) & ~(static_cast<base::type::EnumType>(e));
  870. }
  871. template <typename Enum>
  872. static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) {
  873. return static_cast<base::type::EnumType>(flag) | static_cast<base::type::EnumType>(e);
  874. }
  875. } // namespace bitwise
  876. template <typename Enum>
  877. static inline void addFlag(Enum e, base::type::EnumType* flag) {
  878. *flag = base::utils::bitwise::Or<Enum>(e, *flag);
  879. }
  880. template <typename Enum>
  881. static inline void removeFlag(Enum e, base::type::EnumType* flag) {
  882. *flag = base::utils::bitwise::Not<Enum>(e, *flag);
  883. }
  884. template <typename Enum>
  885. static inline bool hasFlag(Enum e, base::type::EnumType flag) {
  886. return base::utils::bitwise::And<Enum>(e, flag) > 0x0;
  887. }
  888. } // namespace utils
  889. namespace threading {
  890. #if ELPP_THREADING_ENABLED
  891. # if !ELPP_USE_STD_THREADING
  892. namespace internal {
  893. /// @brief A mutex wrapper for compiler that dont yet support std::recursive_mutex
  894. class Mutex : base::NoCopy {
  895. public:
  896. Mutex(void) {
  897. # if ELPP_OS_UNIX
  898. pthread_mutexattr_t attr;
  899. pthread_mutexattr_init(&attr);
  900. pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  901. pthread_mutex_init(&m_underlyingMutex, &attr);
  902. pthread_mutexattr_destroy(&attr);
  903. # elif ELPP_OS_WINDOWS
  904. InitializeCriticalSection(&m_underlyingMutex);
  905. # endif // ELPP_OS_UNIX
  906. }
  907. virtual ~Mutex(void) {
  908. # if ELPP_OS_UNIX
  909. pthread_mutex_destroy(&m_underlyingMutex);
  910. # elif ELPP_OS_WINDOWS
  911. DeleteCriticalSection(&m_underlyingMutex);
  912. # endif // ELPP_OS_UNIX
  913. }
  914. inline void lock(void) {
  915. # if ELPP_OS_UNIX
  916. pthread_mutex_lock(&m_underlyingMutex);
  917. # elif ELPP_OS_WINDOWS
  918. EnterCriticalSection(&m_underlyingMutex);
  919. # endif // ELPP_OS_UNIX
  920. }
  921. inline bool try_lock(void) {
  922. # if ELPP_OS_UNIX
  923. return (pthread_mutex_trylock(&m_underlyingMutex) == 0);
  924. # elif ELPP_OS_WINDOWS
  925. return TryEnterCriticalSection(&m_underlyingMutex);
  926. # endif // ELPP_OS_UNIX
  927. }
  928. inline void unlock(void) {
  929. # if ELPP_OS_UNIX
  930. pthread_mutex_unlock(&m_underlyingMutex);
  931. # elif ELPP_OS_WINDOWS
  932. LeaveCriticalSection(&m_underlyingMutex);
  933. # endif // ELPP_OS_UNIX
  934. }
  935. private:
  936. # if ELPP_OS_UNIX
  937. pthread_mutex_t m_underlyingMutex;
  938. # elif ELPP_OS_WINDOWS
  939. CRITICAL_SECTION m_underlyingMutex;
  940. # endif // ELPP_OS_UNIX
  941. };
  942. /// @brief Scoped lock for compiler that dont yet support std::lock_guard
  943. template <typename M>
  944. class ScopedLock : base::NoCopy {
  945. public:
  946. explicit ScopedLock(M& mutex) {
  947. m_mutex = &mutex;
  948. m_mutex->lock();
  949. }
  950. virtual ~ScopedLock(void) {
  951. m_mutex->unlock();
  952. }
  953. private:
  954. M* m_mutex;
  955. ScopedLock(void);
  956. };
  957. } // namespace internal
  958. typedef base::threading::internal::Mutex Mutex;
  959. typedef base::threading::internal::ScopedLock<base::threading::Mutex> ScopedLock;
  960. # else
  961. typedef std::recursive_mutex Mutex;
  962. typedef std::lock_guard<base::threading::Mutex> ScopedLock;
  963. # endif // !ELPP_USE_STD_THREADING
  964. #else
  965. namespace internal {
  966. /// @brief Mutex wrapper used when multi-threading is disabled.
  967. class NoMutex : base::NoCopy {
  968. public:
  969. NoMutex(void) {}
  970. inline void lock(void) {}
  971. inline bool try_lock(void) {
  972. return true;
  973. }
  974. inline void unlock(void) {}
  975. };
  976. /// @brief Lock guard wrapper used when multi-threading is disabled.
  977. template <typename Mutex>
  978. class NoScopedLock : base::NoCopy {
  979. public:
  980. explicit NoScopedLock(Mutex&) {
  981. }
  982. virtual ~NoScopedLock(void) {
  983. }
  984. private:
  985. NoScopedLock(void);
  986. };
  987. } // namespace internal
  988. typedef base::threading::internal::NoMutex Mutex;
  989. typedef base::threading::internal::NoScopedLock<base::threading::Mutex> ScopedLock;
  990. #endif // ELPP_THREADING_ENABLED
  991. /// @brief Base of thread safe class, this class is inheritable-only
  992. class ThreadSafe {
  993. public:
  994. virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); }
  995. virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); }
  996. virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; }
  997. protected:
  998. ThreadSafe(void) {}
  999. virtual ~ThreadSafe(void) {}
  1000. private:
  1001. base::threading::Mutex m_mutex;
  1002. };
  1003. #if ELPP_THREADING_ENABLED
  1004. # if !ELPP_USE_STD_THREADING
  1005. /// @brief Gets ID of currently running threading in windows systems. On unix, nothing is returned.
  1006. static std::string getCurrentThreadId(void) {
  1007. std::stringstream ss;
  1008. # if (ELPP_OS_WINDOWS)
  1009. ss << GetCurrentThreadId();
  1010. # endif // (ELPP_OS_WINDOWS)
  1011. return ss.str();
  1012. }
  1013. # else
  1014. /// @brief Gets ID of currently running threading using std::this_thread::get_id()
  1015. static std::string getCurrentThreadId(void) {
  1016. std::stringstream ss;
  1017. ss << std::this_thread::get_id();
  1018. return ss.str();
  1019. }
  1020. # endif // !ELPP_USE_STD_THREADING
  1021. #else
  1022. static inline std::string getCurrentThreadId(void) {
  1023. return std::string();
  1024. }
  1025. #endif // ELPP_THREADING_ENABLED
  1026. } // namespace threading
  1027. namespace utils {
  1028. class File : base::StaticClass {
  1029. public:
  1030. /// @brief Creates new out file stream for specified filename.
  1031. /// @return Pointer to newly created fstream or nullptr
  1032. static base::type::fstream_t* newFileStream(const std::string& filename);
  1033. /// @brief Gets size of file provided in stream
  1034. static std::size_t getSizeOfFile(base::type::fstream_t* fs);
  1035. /// @brief Determines whether or not provided path exist in current file system
  1036. static bool pathExists(const char* path, bool considerFile = false);
  1037. /// @brief Creates specified path on file system
  1038. /// @param path Path to create.
  1039. static bool createPath(const std::string& path);
  1040. /// @brief Extracts path of filename with leading slash
  1041. static std::string extractPathFromFilename(const std::string& fullPath,
  1042. const char* seperator = base::consts::kFilePathSeperator);
  1043. /// @brief builds stripped filename and puts it in buff
  1044. static void buildStrippedFilename(const char* filename, char buff[],
  1045. std::size_t limit = base::consts::kSourceFilenameMaxLength);
  1046. /// @brief builds base filename and puts it in buff
  1047. static void buildBaseFilename(const std::string& fullPath, char buff[],
  1048. std::size_t limit = base::consts::kSourceFilenameMaxLength,
  1049. const char* seperator = base::consts::kFilePathSeperator);
  1050. };
  1051. /// @brief String utilities helper class used internally. You should not use it.
  1052. class Str : base::StaticClass {
  1053. public:
  1054. /// @brief Checks if character is digit. Dont use libc implementation of it to prevent locale issues.
  1055. static inline bool isDigit(char c) {
  1056. return c >= '0' && c <= '9';
  1057. }
  1058. /// @brief Matches wildcards, '*' and '?' only supported.
  1059. static bool wildCardMatch(const char* str, const char* pattern);
  1060. static std::string& ltrim(std::string& str);
  1061. static std::string& rtrim(std::string& str);
  1062. static std::string& trim(std::string& str);
  1063. /// @brief Determines whether or not str starts with specified string
  1064. /// @param str String to check
  1065. /// @param start String to check against
  1066. /// @return Returns true if starts with specified string, false otherwise
  1067. static bool startsWith(const std::string& str, const std::string& start);
  1068. /// @brief Determines whether or not str ends with specified string
  1069. /// @param str String to check
  1070. /// @param end String to check against
  1071. /// @return Returns true if ends with specified string, false otherwise
  1072. static bool endsWith(const std::string& str, const std::string& end);
  1073. /// @brief Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performance.
  1074. /// @param [in,out] str String to replace from
  1075. /// @param replaceWhat Character to replace
  1076. /// @param replaceWith Character to replace with
  1077. /// @return Modified version of str
  1078. static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith);
  1079. /// @brief Replaces all instances of 'replaceWhat' with 'replaceWith'. (String version) Replaces in place
  1080. /// @param str String to replace from
  1081. /// @param replaceWhat Character to replace
  1082. /// @param replaceWith Character to replace with
  1083. /// @return Modified (original) str
  1084. static std::string& replaceAll(std::string& str, const std::string& replaceWhat,
  1085. const std::string& replaceWith);
  1086. static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
  1087. const base::type::string_t& replaceWith);
  1088. #if defined(ELPP_UNICODE)
  1089. static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
  1090. const std::string& replaceWith);
  1091. #endif // defined(ELPP_UNICODE)
  1092. /// @brief Converts string to uppercase
  1093. /// @param str String to convert
  1094. /// @return Uppercase string
  1095. static std::string& toUpper(std::string& str);
  1096. /// @brief Compares cstring equality - uses strcmp
  1097. static bool cStringEq(const char* s1, const char* s2);
  1098. /// @brief Compares cstring equality (case-insensitive) - uses toupper(char)
  1099. /// Dont use strcasecmp because of CRT (VC++)
  1100. static bool cStringCaseEq(const char* s1, const char* s2);
  1101. /// @brief Returns true if c exist in str
  1102. static bool contains(const char* str, char c);
  1103. static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true);
  1104. static char* addToBuff(const char* str, char* buf, const char* bufLim);
  1105. static char* clearBuff(char buff[], std::size_t lim);
  1106. /// @brief Converst wchar* to char*
  1107. /// NOTE: Need to free return value after use!
  1108. static char* wcharPtrToCharPtr(const wchar_t* line);
  1109. };
  1110. /// @brief Operating System helper static class used internally. You should not use it.
  1111. class OS : base::StaticClass {
  1112. public:
  1113. #if ELPP_OS_WINDOWS
  1114. /// @brief Gets environment variables for Windows based OS.
  1115. /// We are not using <code>getenv(const char*)</code> because of CRT deprecation
  1116. /// @param varname Variable name to get environment variable value for
  1117. /// @return If variable exist the value of it otherwise nullptr
  1118. static const char* getWindowsEnvironmentVariable(const char* varname);
  1119. #endif // ELPP_OS_WINDOWS
  1120. #if ELPP_OS_ANDROID
  1121. /// @brief Reads android property value
  1122. static std::string getProperty(const char* prop);
  1123. /// @brief Reads android device name
  1124. static std::string getDeviceName(void);
  1125. #endif // ELPP_OS_ANDROID
  1126. /// @brief Runs command on terminal and returns the output.
  1127. ///
  1128. /// @detail This is applicable only on unix based systems, for all other OS, an empty string is returned.
  1129. /// @param command Bash command
  1130. /// @return Result of bash output or empty string if no result found.
  1131. static const std::string getBashOutput(const char* command);
  1132. /// @brief Gets environment variable. This is cross-platform and CRT safe (for VC++)
  1133. /// @param variableName Environment variable name
  1134. /// @param defaultVal If no environment variable or value found the value to return by default
  1135. /// @param alternativeBashCommand If environment variable not found what would be alternative bash command
  1136. /// in order to look for value user is looking for. E.g, for 'user' alternative command will 'whoami'
  1137. static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal,
  1138. const char* alternativeBashCommand = nullptr);
  1139. /// @brief Gets current username.
  1140. static std::string currentUser(void);
  1141. /// @brief Gets current host name or computer name.
  1142. ///
  1143. /// @detail For android systems this is device name with its manufacturer and model seperated by hyphen
  1144. static std::string currentHost(void);
  1145. /// @brief Whether or not terminal supports colors
  1146. static bool termSupportsColor(void);
  1147. };
  1148. /// @brief Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str
  1149. class DateTime : base::StaticClass {
  1150. public:
  1151. /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond.
  1152. ///
  1153. /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided
  1154. /// @param [in,out] tv Pointer that gets updated
  1155. static void gettimeofday(struct timeval* tv);
  1156. /// @brief Gets current date and time with a subsecond part.
  1157. /// @param format User provided date/time format
  1158. /// @param ssPrec A pointer to base::SubsecondPrecision from configuration (non-null)
  1159. /// @returns string based date time in specified format.
  1160. static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec);
  1161. /// @brief Converts timeval (struct from ctime) to string using specified format and subsecond precision
  1162. static std::string timevalToString(struct timeval tval, const char* format,
  1163. const el::base::SubsecondPrecision* ssPrec);
  1164. /// @brief Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc
  1165. static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit);
  1166. /// @brief Gets time difference in milli/micro second depending on timestampUnit
  1167. static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime,
  1168. base::TimestampUnit timestampUnit);
  1169. static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo);
  1170. private:
  1171. static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
  1172. std::size_t msec, const base::SubsecondPrecision* ssPrec);
  1173. };
  1174. /// @brief Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGINGPP(..)
  1175. class CommandLineArgs {
  1176. public:
  1177. CommandLineArgs(void) {
  1178. setArgs(0, static_cast<char**>(nullptr));
  1179. }
  1180. CommandLineArgs(int argc, const char** argv) {
  1181. setArgs(argc, argv);
  1182. }
  1183. CommandLineArgs(int argc, char** argv) {
  1184. setArgs(argc, argv);
  1185. }
  1186. virtual ~CommandLineArgs(void) {}
  1187. /// @brief Sets arguments and parses them
  1188. inline void setArgs(int argc, const char** argv) {
  1189. setArgs(argc, const_cast<char**>(argv));
  1190. }
  1191. /// @brief Sets arguments and parses them
  1192. void setArgs(int argc, char** argv);
  1193. /// @brief Returns true if arguments contain paramKey with a value (seperated by '=')
  1194. bool hasParamWithValue(const char* paramKey) const;
  1195. /// @brief Returns value of arguments
  1196. /// @see hasParamWithValue(const char*)
  1197. const char* getParamValue(const char* paramKey) const;
  1198. /// @brief Return true if arguments has a param (not having a value) i,e without '='
  1199. bool hasParam(const char* paramKey) const;
  1200. /// @brief Returns true if no params available. This exclude argv[0]
  1201. bool empty(void) const;
  1202. /// @brief Returns total number of arguments. This exclude argv[0]
  1203. std::size_t size(void) const;
  1204. friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c);
  1205. private:
  1206. int m_argc;
  1207. char** m_argv;
  1208. std::unordered_map<std::string, std::string> m_paramsWithValue;
  1209. std::vector<std::string> m_params;
  1210. };
  1211. /// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type.
  1212. ///
  1213. /// @detail Most of the functions are virtual final methods but anything implementing this abstract class should implement
  1214. /// unregisterAll() and deepCopy(const AbstractRegistry<T_Ptr, Container>&) and write registerNew() method according to container
  1215. /// and few more methods; get() to find element, unregister() to unregister single entry.
  1216. /// Please note that this is thread-unsafe and should also implement thread-safety mechanisms in implementation.
  1217. template <typename T_Ptr, typename Container>
  1218. class AbstractRegistry : public base::threading::ThreadSafe {
  1219. public:
  1220. typedef typename Container::iterator iterator;
  1221. typedef typename Container::const_iterator const_iterator;
  1222. /// @brief Default constructor
  1223. AbstractRegistry(void) {}
  1224. /// @brief Move constructor that is useful for base classes
  1225. AbstractRegistry(AbstractRegistry&& sr) {
  1226. if (this == &sr) {
  1227. return;
  1228. }
  1229. unregisterAll();
  1230. m_list = std::move(sr.m_list);
  1231. }
  1232. bool operator==(const AbstractRegistry<T_Ptr, Container>& other) {
  1233. if (size() != other.size()) {
  1234. return false;
  1235. }
  1236. for (std::size_t i = 0; i < m_list.size(); ++i) {
  1237. if (m_list.at(i) != other.m_list.at(i)) {
  1238. return false;
  1239. }
  1240. }
  1241. return true;
  1242. }
  1243. bool operator!=(const AbstractRegistry<T_Ptr, Container>& other) {
  1244. if (size() != other.size()) {
  1245. return true;
  1246. }
  1247. for (std::size_t i = 0; i < m_list.size(); ++i) {
  1248. if (m_list.at(i) != other.m_list.at(i)) {
  1249. return true;
  1250. }
  1251. }
  1252. return false;
  1253. }
  1254. /// @brief Assignment move operator
  1255. AbstractRegistry& operator=(AbstractRegistry&& sr) {
  1256. if (this == &sr) {
  1257. return *this;
  1258. }
  1259. unregisterAll();
  1260. m_list = std::move(sr.m_list);
  1261. return *this;
  1262. }
  1263. virtual ~AbstractRegistry(void) {
  1264. }
  1265. /// @return Iterator pointer from start of repository
  1266. virtual inline iterator begin(void) ELPP_FINAL {
  1267. return m_list.begin();
  1268. }
  1269. /// @return Iterator pointer from end of repository
  1270. virtual inline iterator end(void) ELPP_FINAL {
  1271. return m_list.end();
  1272. }
  1273. /// @return Constant iterator pointer from start of repository
  1274. virtual inline const_iterator cbegin(void) const ELPP_FINAL {
  1275. return m_list.cbegin();
  1276. }
  1277. /// @return End of repository
  1278. virtual inline const_iterator cend(void) const ELPP_FINAL {
  1279. return m_list.cend();
  1280. }
  1281. /// @return Whether or not repository is empty
  1282. virtual inline bool empty(void) const ELPP_FINAL {
  1283. return m_list.empty();
  1284. }
  1285. /// @return Size of repository
  1286. virtual inline std::size_t size(void) const ELPP_FINAL {
  1287. return m_list.size();
  1288. }
  1289. /// @brief Returns underlying container by reference
  1290. virtual inline Container& list(void) ELPP_FINAL {
  1291. return m_list;
  1292. }
  1293. /// @brief Returns underlying container by constant reference.
  1294. virtual inline const Container& list(void) const ELPP_FINAL {
  1295. return m_list;
  1296. }
  1297. /// @brief Unregisters all the pointers from current repository.
  1298. virtual void unregisterAll(void) = 0;
  1299. protected:
  1300. virtual void deepCopy(const AbstractRegistry<T_Ptr, Container>&) = 0;
  1301. void reinitDeepCopy(const AbstractRegistry<T_Ptr, Container>& sr) {
  1302. unregisterAll();
  1303. deepCopy(sr);
  1304. }
  1305. private:
  1306. Container m_list;
  1307. };
  1308. /// @brief A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate version)
  1309. ///
  1310. /// @detail NOTE: This is thread-unsafe implementation (although it contains lock function, it does not use these functions)
  1311. /// of AbstractRegistry<T_Ptr, Container>. Any implementation of this class should be
  1312. /// explicitly (by using lock functions)
  1313. template <typename T_Ptr, typename T_Key = const char*>
  1314. class Registry : public AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>> {
  1315. public:
  1316. typedef typename Registry<T_Ptr, T_Key>::iterator iterator;
  1317. typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator;
  1318. Registry(void) {}
  1319. /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor.
  1320. Registry(const Registry& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
  1321. if (this == &sr) {
  1322. return;
  1323. }
  1324. this->reinitDeepCopy(sr);
  1325. }
  1326. /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element
  1327. /// @see unregisterAll()
  1328. /// @see deepCopy(const AbstractRegistry&)
  1329. Registry& operator=(const Registry& sr) {
  1330. if (this == &sr) {
  1331. return *this;
  1332. }
  1333. this->reinitDeepCopy(sr);
  1334. return *this;
  1335. }
  1336. virtual ~Registry(void) {
  1337. unregisterAll();
  1338. }
  1339. protected:
  1340. virtual void unregisterAll(void) ELPP_FINAL {
  1341. if (!this->empty()) {
  1342. for (auto&& curr : this->list()) {
  1343. base::utils::safeDelete(curr.second);
  1344. }
  1345. this->list().clear();
  1346. }
  1347. }
  1348. /// @brief Registers new registry to repository.
  1349. virtual void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL {
  1350. unregister(uniqKey);
  1351. this->list().insert(std::make_pair(uniqKey, ptr));
  1352. }
  1353. /// @brief Unregisters single entry mapped to specified unique key
  1354. void unregister(const T_Key& uniqKey) {
  1355. T_Ptr* existing = get(uniqKey);
  1356. if (existing != nullptr) {
  1357. this->list().erase(uniqKey);
  1358. base::utils::safeDelete(existing);
  1359. }
  1360. }
  1361. /// @brief Gets pointer from repository. If none found, nullptr is returned.
  1362. T_Ptr* get(const T_Key& uniqKey) {
  1363. iterator it = this->list().find(uniqKey);
  1364. return it == this->list().end()
  1365. ? nullptr
  1366. : it->second;
  1367. }
  1368. private:
  1369. virtual void deepCopy(const AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
  1370. for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
  1371. registerNew(it->first, new T_Ptr(*it->second));
  1372. }
  1373. }
  1374. };
  1375. /// @brief A pointer registry mechanism to manage memory and provide search functionalities. (predicate version)
  1376. ///
  1377. /// @detail NOTE: This is thread-unsafe implementation of AbstractRegistry<T_Ptr, Container>. Any implementation of this class
  1378. /// should be made thread-safe explicitly
  1379. template <typename T_Ptr, typename Pred>
  1380. class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
  1381. public:
  1382. typedef typename RegistryWithPred<T_Ptr, Pred>::iterator iterator;
  1383. typedef typename RegistryWithPred<T_Ptr, Pred>::const_iterator const_iterator;
  1384. RegistryWithPred(void) {
  1385. }
  1386. virtual ~RegistryWithPred(void) {
  1387. unregisterAll();
  1388. }
  1389. /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor.
  1390. RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>() {
  1391. if (this == &sr) {
  1392. return;
  1393. }
  1394. this->reinitDeepCopy(sr);
  1395. }
  1396. /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element
  1397. /// @see unregisterAll()
  1398. /// @see deepCopy(const AbstractRegistry&)
  1399. RegistryWithPred& operator=(const RegistryWithPred& sr) {
  1400. if (this == &sr) {
  1401. return *this;
  1402. }
  1403. this->reinitDeepCopy(sr);
  1404. return *this;
  1405. }
  1406. friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const RegistryWithPred& sr) {
  1407. for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
  1408. os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n");
  1409. }
  1410. return os;
  1411. }
  1412. protected:
  1413. virtual void unregisterAll(void) ELPP_FINAL {
  1414. if (!this->empty()) {
  1415. for (auto&& curr : this->list()) {
  1416. base::utils::safeDelete(curr);
  1417. }
  1418. this->list().clear();
  1419. }
  1420. }
  1421. virtual void unregister(T_Ptr*& ptr) ELPP_FINAL {
  1422. if (ptr) {
  1423. iterator iter = this->begin();
  1424. for (; iter != this->end(); ++iter) {
  1425. if (ptr == *iter) {
  1426. break;
  1427. }
  1428. }
  1429. if (iter != this->end() && *iter != nullptr) {
  1430. this->list().erase(iter);
  1431. base::utils::safeDelete(*iter);
  1432. }
  1433. }
  1434. }
  1435. virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL {
  1436. this->list().push_back(ptr);
  1437. }
  1438. /// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate
  1439. /// in order to validate pointer.
  1440. template <typename T, typename T2>
  1441. T_Ptr* get(const T& arg1, const T2 arg2) {
  1442. iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2));
  1443. if (iter != this->list().end() && *iter != nullptr) {
  1444. return *iter;
  1445. }
  1446. return nullptr;
  1447. }
  1448. private:
  1449. virtual void deepCopy(const AbstractRegistry<T_Ptr, std::vector<T_Ptr*>>& sr) {
  1450. for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) {
  1451. registerNew(new T_Ptr(**it));
  1452. }
  1453. }
  1454. };
  1455. class Utils {
  1456. public:
  1457. template <typename T, typename TPtr>
  1458. static bool installCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
  1459. if (mapT->find(id) == mapT->end()) {
  1460. mapT->insert(std::make_pair(id, TPtr(new T())));
  1461. return true;
  1462. }
  1463. return false;
  1464. }
  1465. template <typename T, typename TPtr>
  1466. static void uninstallCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
  1467. if (mapT->find(id) != mapT->end()) {
  1468. mapT->erase(id);
  1469. }
  1470. }
  1471. template <typename T, typename TPtr>
  1472. static T* callback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
  1473. typename std::unordered_map<std::string, TPtr>::iterator iter = mapT->find(id);
  1474. if (iter != mapT->end()) {
  1475. return static_cast<T*>(iter->second.get());
  1476. }
  1477. return nullptr;
  1478. }
  1479. };
  1480. } // namespace utils
  1481. } // namespace base
  1482. /// @brief Base of Easylogging++ friendly class
  1483. ///
  1484. /// @detail After inheriting this class publicly, implement pure-virtual function `void log(std::ostream&) const`
  1485. class Loggable {
  1486. public:
  1487. virtual ~Loggable(void) {}
  1488. virtual void log(el::base::type::ostream_t&) const = 0;
  1489. private:
  1490. friend inline el::base::type::ostream_t& operator<<(el::base::type::ostream_t& os, const Loggable& loggable) {
  1491. loggable.log(os);
  1492. return os;
  1493. }
  1494. };
  1495. namespace base {
  1496. /// @brief Represents log format containing flags and date format. This is used internally to start initial log
  1497. class LogFormat : public Loggable {
  1498. public:
  1499. LogFormat(void);
  1500. LogFormat(Level level, const base::type::string_t& format);
  1501. LogFormat(const LogFormat& logFormat);
  1502. LogFormat(LogFormat&& logFormat);
  1503. LogFormat& operator=(const LogFormat& logFormat);
  1504. virtual ~LogFormat(void) {}
  1505. bool operator==(const LogFormat& other);
  1506. /// @brief Updates format to be used while logging.
  1507. /// @param userFormat User provided format
  1508. void parseFromFormat(const base::type::string_t& userFormat);
  1509. inline Level level(void) const {
  1510. return m_level;
  1511. }
  1512. inline const base::type::string_t& userFormat(void) const {
  1513. return m_userFormat;
  1514. }
  1515. inline const base::type::string_t& format(void) const {
  1516. return m_format;
  1517. }
  1518. inline const std::string& dateTimeFormat(void) const {
  1519. return m_dateTimeFormat;
  1520. }
  1521. inline base::type::EnumType flags(void) const {
  1522. return m_flags;
  1523. }
  1524. inline bool hasFlag(base::FormatFlags flag) const {
  1525. return base::utils::hasFlag(flag, m_flags);
  1526. }
  1527. virtual void log(el::base::type::ostream_t& os) const {
  1528. os << m_format;
  1529. }
  1530. protected:
  1531. /// @brief Updates date time format if available in currFormat.
  1532. /// @param index Index where %datetime, %date or %time was found
  1533. /// @param [in,out] currFormat current format that is being used to format
  1534. virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL;
  1535. /// @brief Updates %level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level
  1536. virtual void updateFormatSpec(void) ELPP_FINAL;
  1537. inline void addFlag(base::FormatFlags flag) {
  1538. base::utils::addFlag(flag, &m_flags);
  1539. }
  1540. private:
  1541. Level m_level;
  1542. base::type::string_t m_userFormat;
  1543. base::type::string_t m_format;
  1544. std::string m_dateTimeFormat;
  1545. base::type::EnumType m_flags;
  1546. std::string m_currentUser;
  1547. std::string m_currentHost;
  1548. friend class el::Logger; // To resolve loggerId format specifier easily
  1549. };
  1550. } // namespace base
  1551. /// @brief Resolving function for format specifier
  1552. typedef std::function<std::string(const LogMessage*)> FormatSpecifierValueResolver;
  1553. /// @brief User-provided custom format specifier
  1554. /// @see el::Helpers::installCustomFormatSpecifier
  1555. /// @see FormatSpecifierValueResolver
  1556. class CustomFormatSpecifier {
  1557. public:
  1558. CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) :
  1559. m_formatSpecifier(formatSpecifier), m_resolver(resolver) {}
  1560. inline const char* formatSpecifier(void) const {
  1561. return m_formatSpecifier;
  1562. }
  1563. inline const FormatSpecifierValueResolver& resolver(void) const {
  1564. return m_resolver;
  1565. }
  1566. inline bool operator==(const char* formatSpecifier) {
  1567. return strcmp(m_formatSpecifier, formatSpecifier) == 0;
  1568. }
  1569. private:
  1570. const char* m_formatSpecifier;
  1571. FormatSpecifierValueResolver m_resolver;
  1572. };
  1573. /// @brief Represents single configuration that has representing level, configuration type and a string based value.
  1574. ///
  1575. /// @detail String based value means any value either its boolean, integer or string itself, it will be embedded inside quotes
  1576. /// and will be parsed later.
  1577. ///
  1578. /// Consider some examples below:
  1579. /// * el::Configuration confEnabledInfo(el::Level::Info, el::ConfigurationType::Enabled, "true");
  1580. /// * el::Configuration confMaxLogFileSizeInfo(el::Level::Info, el::ConfigurationType::MaxLogFileSize, "2048");
  1581. /// * el::Configuration confFilenameInfo(el::Level::Info, el::ConfigurationType::Filename, "/var/log/my.log");
  1582. class Configuration : public Loggable {
  1583. public:
  1584. Configuration(const Configuration& c);
  1585. Configuration& operator=(const Configuration& c);
  1586. virtual ~Configuration(void) {
  1587. }
  1588. /// @brief Full constructor used to sets value of configuration
  1589. Configuration(Level level, ConfigurationType configurationType, const std::string& value);
  1590. /// @brief Gets level of current configuration
  1591. inline Level level(void) const {
  1592. return m_level;
  1593. }
  1594. /// @brief Gets configuration type of current configuration
  1595. inline ConfigurationType configurationType(void) const {
  1596. return m_configurationType;
  1597. }
  1598. /// @brief Gets string based configuration value
  1599. inline const std::string& value(void) const {
  1600. return m_value;
  1601. }
  1602. /// @brief Set string based configuration value
  1603. /// @param value Value to set. Values have to be std::string; For boolean values use "true", "false", for any integral values
  1604. /// use them in quotes. They will be parsed when configuring
  1605. inline void setValue(const std::string& value) {
  1606. m_value = value;
  1607. }
  1608. virtual void log(el::base::type::ostream_t& os) const;
  1609. /// @brief Used to find configuration from configuration (pointers) repository. Avoid using it.
  1610. class Predicate {
  1611. public:
  1612. Predicate(Level level, ConfigurationType configurationType);
  1613. bool operator()(const Configuration* conf) const;
  1614. private:
  1615. Level m_level;
  1616. ConfigurationType m_configurationType;
  1617. };
  1618. private:
  1619. Level m_level;
  1620. ConfigurationType m_configurationType;
  1621. std::string m_value;
  1622. };
  1623. /// @brief Thread-safe Configuration repository
  1624. ///
  1625. /// @detail This repository represents configurations for all the levels and configuration type mapped to a value.
  1626. class Configurations : public base::utils::RegistryWithPred<Configuration, Configuration::Predicate> {
  1627. public:
  1628. /// @brief Default constructor with empty repository
  1629. Configurations(void);
  1630. /// @brief Constructor used to set configurations using configuration file.
  1631. /// @param configurationFile Full path to configuration file
  1632. /// @param useDefaultsForRemaining Lets you set the remaining configurations to default.
  1633. /// @param base If provided, this configuration will be based off existing repository that this argument is pointing to.
  1634. /// @see parseFromFile(const std::string&, Configurations* base)
  1635. /// @see setRemainingToDefault()
  1636. Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true,
  1637. Configurations* base = nullptr);
  1638. virtual ~Configurations(void) {
  1639. }
  1640. /// @brief Parses configuration from file.
  1641. /// @param configurationFile Full path to configuration file
  1642. /// @param base Configurations to base new configuration repository off. This value is used when you want to use
  1643. /// existing Configurations to base all the values and then set rest of configuration via configuration file.
  1644. /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you
  1645. /// do not proceed without successful parse.
  1646. bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr);
  1647. /// @brief Parse configurations from configuration string.
  1648. ///
  1649. /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary
  1650. /// new line characters are provided.
  1651. /// @param base Configurations to base new configuration repository off. This value is used when you want to use
  1652. /// existing Configurations to base all the values and then set rest of configuration via configuration text.
  1653. /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you
  1654. /// do not proceed without successful parse.
  1655. bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr);
  1656. /// @brief Sets configuration based-off an existing configurations.
  1657. /// @param base Pointer to existing configurations.
  1658. void setFromBase(Configurations* base);
  1659. /// @brief Determines whether or not specified configuration type exists in the repository.
  1660. ///
  1661. /// @detail Returns as soon as first level is found.
  1662. /// @param configurationType Type of configuration to check existence for.
  1663. bool hasConfiguration(ConfigurationType configurationType);
  1664. /// @brief Determines whether or not specified configuration type exists for specified level
  1665. /// @param level Level to check
  1666. /// @param configurationType Type of configuration to check existence for.
  1667. bool hasConfiguration(Level level, ConfigurationType configurationType);
  1668. /// @brief Sets value of configuration for specified level.
  1669. ///
  1670. /// @detail Any existing configuration for specified level will be replaced. Also note that configuration types
  1671. /// ConfigurationType::SubsecondPrecision and ConfigurationType::PerformanceTracking will be ignored if not set for
  1672. /// Level::Global because these configurations are not dependant on level.
  1673. /// @param level Level to set configuration for (el::Level).
  1674. /// @param configurationType Type of configuration (el::ConfigurationType)
  1675. /// @param value A string based value. Regardless of what the data type of configuration is, it will always be string
  1676. /// from users' point of view. This is then parsed later to be used internally.
  1677. /// @see Configuration::setValue(const std::string& value)
  1678. /// @see el::Level
  1679. /// @see el::ConfigurationType
  1680. void set(Level level, ConfigurationType configurationType, const std::string& value);
  1681. /// @brief Sets single configuration based on other single configuration.
  1682. /// @see set(Level level, ConfigurationType configurationType, const std::string& value)
  1683. void set(Configuration* conf);
  1684. inline Configuration* get(Level level, ConfigurationType configurationType) {
  1685. base::threading::ScopedLock scopedLock(lock());
  1686. return RegistryWithPred<Configuration, Configuration::Predicate>::get(level, configurationType);
  1687. }
  1688. /// @brief Sets configuration for all levels.
  1689. /// @param configurationType Type of configuration
  1690. /// @param value String based value
  1691. /// @see Configurations::set(Level level, ConfigurationType configurationType, const std::string& value)
  1692. inline void setGlobally(ConfigurationType configurationType, const std::string& value) {
  1693. setGlobally(configurationType, value, false);
  1694. }
  1695. /// @brief Clears repository so that all the configurations are unset
  1696. inline void clear(void) {
  1697. base::threading::ScopedLock scopedLock(lock());
  1698. unregisterAll();
  1699. }
  1700. /// @brief Gets configuration file used in parsing this configurations.
  1701. ///
  1702. /// @detail If this repository was set manually or by text this returns empty string.
  1703. inline const std::string& configurationFile(void) const {
  1704. return m_configurationFile;
  1705. }
  1706. /// @brief Sets configurations to "factory based" configurations.
  1707. void setToDefault(void);
  1708. /// @brief Lets you set the remaining configurations to default.
  1709. ///
  1710. /// @detail By remaining, it means that the level/type a configuration does not exist for.
  1711. /// This function is useful when you want to minimize chances of failures, e.g, if you have a configuration file that sets
  1712. /// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is set to default i.e,
  1713. /// true. If you dont do this explicitly (either by calling this function or by using second param in Constructor
  1714. /// and try to access a value, an error is thrown
  1715. void setRemainingToDefault(void);
  1716. /// @brief Parser used internally to parse configurations from file or text.
  1717. ///
  1718. /// @detail This class makes use of base::utils::Str.
  1719. /// You should not need this unless you are working on some tool for Easylogging++
  1720. class Parser : base::StaticClass {
  1721. public:
  1722. /// @brief Parses configuration from file.
  1723. /// @param configurationFile Full path to configuration file
  1724. /// @param sender Sender configurations pointer. Usually 'this' is used from calling class
  1725. /// @param base Configurations to base new configuration repository off. This value is used when you want to use
  1726. /// existing Configurations to base all the values and then set rest of configuration via configuration file.
  1727. /// @return True if successfully parsed, false otherwise. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you
  1728. /// do not proceed without successful parse.
  1729. static bool parseFromFile(const std::string& configurationFile, Configurations* sender,
  1730. Configurations* base = nullptr);
  1731. /// @brief Parse configurations from configuration string.
  1732. ///
  1733. /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary
  1734. /// new line characters are provided. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you
  1735. /// do not proceed without successful parse (This is recommended)
  1736. /// @param configurationsString the configuration in plain text format
  1737. /// @param sender Sender configurations pointer. Usually 'this' is used from calling class
  1738. /// @param base Configurations to base new configuration repository off. This value is used when you want to use
  1739. /// existing Configurations to base all the values and then set rest of configuration via configuration text.
  1740. /// @return True if successfully parsed, false otherwise.
  1741. static bool parseFromText(const std::string& configurationsString, Configurations* sender,
  1742. Configurations* base = nullptr);
  1743. private:
  1744. friend class el::Loggers;
  1745. static void ignoreComments(std::string* line);
  1746. static bool isLevel(const std::string& line);
  1747. static bool isComment(const std::string& line);
  1748. static inline bool isConfig(const std::string& line);
  1749. static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel,
  1750. Configurations* conf);
  1751. };
  1752. private:
  1753. std::string m_configurationFile;
  1754. bool m_isFromFile;
  1755. friend class el::Loggers;
  1756. /// @brief Unsafely sets configuration if does not already exist
  1757. void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value);
  1758. /// @brief Thread unsafe set
  1759. void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value);
  1760. /// @brief Sets configurations for all levels including Level::Global if includeGlobalLevel is true
  1761. /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value)
  1762. void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel);
  1763. /// @brief Sets configurations (Unsafely) for all levels including Level::Global if includeGlobalLevel is true
  1764. /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value)
  1765. void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel);
  1766. };
  1767. namespace base {
  1768. typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
  1769. typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap;
  1770. /// @brief Configurations with data types.
  1771. ///
  1772. /// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations.
  1773. /// This is to perform faster while writing logs using correct configurations.
  1774. ///
  1775. /// This is thread safe and final class containing non-virtual destructor (means nothing should inherit this class)
  1776. class TypedConfigurations : public base::threading::ThreadSafe {
  1777. public:
  1778. /// @brief Constructor to initialize (construct) the object off el::Configurations
  1779. /// @param configurations Configurations pointer/reference to base this typed configurations off.
  1780. /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference()
  1781. TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference);
  1782. TypedConfigurations(const TypedConfigurations& other);
  1783. virtual ~TypedConfigurations(void) {
  1784. }
  1785. const Configurations* configurations(void) const {
  1786. return m_configurations;
  1787. }
  1788. bool enabled(Level level);
  1789. bool toFile(Level level);
  1790. const std::string& filename(Level level);
  1791. bool toStandardOutput(Level level);
  1792. const base::LogFormat& logFormat(Level level);
  1793. const base::SubsecondPrecision& subsecondPrecision(Level level = Level::Global);
  1794. const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global);
  1795. bool performanceTracking(Level level = Level::Global);
  1796. base::type::fstream_t* fileStream(Level level);
  1797. std::size_t maxLogFileSize(Level level);
  1798. std::size_t logFlushThreshold(Level level);
  1799. private:
  1800. Configurations* m_configurations;
  1801. std::unordered_map<Level, bool> m_enabledMap;
  1802. std::unordered_map<Level, bool> m_toFileMap;
  1803. std::unordered_map<Level, std::string> m_filenameMap;
  1804. std::unordered_map<Level, bool> m_toStandardOutputMap;
  1805. std::unordered_map<Level, base::LogFormat> m_logFormatMap;
  1806. std::unordered_map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
  1807. std::unordered_map<Level, bool> m_performanceTrackingMap;
  1808. std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap;
  1809. std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap;
  1810. std::unordered_map<Level, std::size_t> m_logFlushThresholdMap;
  1811. base::LogStreamsReferenceMap* m_logStreamsReference;
  1812. friend class el::Helpers;
  1813. friend class el::base::MessageBuilder;
  1814. friend class el::base::Writer;
  1815. friend class el::base::DefaultLogDispatchCallback;
  1816. friend class el::base::LogDispatcher;
  1817. template <typename Conf_T>
  1818. inline Conf_T getConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
  1819. base::threading::ScopedLock scopedLock(lock());
  1820. return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
  1821. }
  1822. template <typename Conf_T>
  1823. inline Conf_T& getConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
  1824. base::threading::ScopedLock scopedLock(lock());
  1825. return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
  1826. }
  1827. template <typename Conf_T>
  1828. Conf_T unsafeGetConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
  1829. ELPP_UNUSED(confName);
  1830. typename std::unordered_map<Level, Conf_T>::const_iterator it = confMap->find(level);
  1831. if (it == confMap->end()) {
  1832. try {
  1833. return confMap->at(Level::Global);
  1834. } catch (...) {
  1835. ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
  1836. << LevelHelper::convertToString(level) << "]"
  1837. << std::endl << "Please ensure you have properly configured logger.", false);
  1838. return Conf_T();
  1839. }
  1840. }
  1841. return it->second;
  1842. }
  1843. template <typename Conf_T>
  1844. Conf_T& unsafeGetConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
  1845. ELPP_UNUSED(confName);
  1846. typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(level);
  1847. if (it == confMap->end()) {
  1848. try {
  1849. return confMap->at(Level::Global);
  1850. } catch (...) {
  1851. ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
  1852. << LevelHelper::convertToString(level) << "]"
  1853. << std::endl << "Please ensure you have properly configured logger.", false);
  1854. }
  1855. }
  1856. return it->second;
  1857. }
  1858. template <typename Conf_T>
  1859. void setValue(Level level, const Conf_T& value, std::unordered_map<Level, Conf_T>* confMap,
  1860. bool includeGlobalLevel = true) {
  1861. // If map is empty and we are allowed to add into generic level (Level::Global), do it!
  1862. if (confMap->empty() && includeGlobalLevel) {
  1863. confMap->insert(std::make_pair(Level::Global, value));
  1864. return;
  1865. }
  1866. // If same value exist in generic level already, dont add it to explicit level
  1867. typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
  1868. if (it != confMap->end() && it->second == value) {
  1869. return;
  1870. }
  1871. // Now make sure we dont double up values if we really need to add it to explicit level
  1872. it = confMap->find(level);
  1873. if (it == confMap->end()) {
  1874. // Value not found for level, add new
  1875. confMap->insert(std::make_pair(level, value));
  1876. } else {
  1877. // Value found, just update value
  1878. confMap->at(level) = value;
  1879. }
  1880. }
  1881. void build(Configurations* configurations);
  1882. unsigned long getULong(std::string confVal);
  1883. std::string resolveFilename(const std::string& filename);
  1884. void insertFile(Level level, const std::string& fullFilename);
  1885. bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback);
  1886. inline bool validateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) {
  1887. base::threading::ScopedLock scopedLock(lock());
  1888. return unsafeValidateFileRolling(level, preRollOutCallback);
  1889. }
  1890. };
  1891. /// @brief Class that keeps record of current line hit for occasional logging
  1892. class HitCounter {
  1893. public:
  1894. HitCounter(void) :
  1895. m_filename(""),
  1896. m_lineNumber(0),
  1897. m_hitCounts(0) {
  1898. }
  1899. HitCounter(const char* filename, base::type::LineNumber lineNumber) :
  1900. m_filename(filename),
  1901. m_lineNumber(lineNumber),
  1902. m_hitCounts(0) {
  1903. }
  1904. HitCounter(const HitCounter& hitCounter) :
  1905. m_filename(hitCounter.m_filename),
  1906. m_lineNumber(hitCounter.m_lineNumber),
  1907. m_hitCounts(hitCounter.m_hitCounts) {
  1908. }
  1909. HitCounter& operator=(const HitCounter& hitCounter) {
  1910. if (&hitCounter != this) {
  1911. m_filename = hitCounter.m_filename;
  1912. m_lineNumber = hitCounter.m_lineNumber;
  1913. m_hitCounts = hitCounter.m_hitCounts;
  1914. }
  1915. return *this;
  1916. }
  1917. virtual ~HitCounter(void) {
  1918. }
  1919. /// @brief Resets location of current hit counter
  1920. inline void resetLocation(const char* filename, base::type::LineNumber lineNumber) {
  1921. m_filename = filename;
  1922. m_lineNumber = lineNumber;
  1923. }
  1924. /// @brief Validates hit counts and resets it if necessary
  1925. inline void validateHitCounts(std::size_t n) {
  1926. if (m_hitCounts >= base::consts::kMaxLogPerCounter) {
  1927. m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0);
  1928. }
  1929. ++m_hitCounts;
  1930. }
  1931. inline const char* filename(void) const {
  1932. return m_filename;
  1933. }
  1934. inline base::type::LineNumber lineNumber(void) const {
  1935. return m_lineNumber;
  1936. }
  1937. inline std::size_t hitCounts(void) const {
  1938. return m_hitCounts;
  1939. }
  1940. inline void increment(void) {
  1941. ++m_hitCounts;
  1942. }
  1943. class Predicate {
  1944. public:
  1945. Predicate(const char* filename, base::type::LineNumber lineNumber)
  1946. : m_filename(filename),
  1947. m_lineNumber(lineNumber) {
  1948. }
  1949. inline bool operator()(const HitCounter* counter) {
  1950. return ((counter != nullptr) &&
  1951. (strcmp(counter->m_filename, m_filename) == 0) &&
  1952. (counter->m_lineNumber == m_lineNumber));
  1953. }
  1954. private:
  1955. const char* m_filename;
  1956. base::type::LineNumber m_lineNumber;
  1957. };
  1958. private:
  1959. const char* m_filename;
  1960. base::type::LineNumber m_lineNumber;
  1961. std::size_t m_hitCounts;
  1962. };
  1963. /// @brief Repository for hit counters used across the application
  1964. class RegisteredHitCounters : public base::utils::RegistryWithPred<base::HitCounter, base::HitCounter::Predicate> {
  1965. public:
  1966. /// @brief Validates counter for every N, i.e, registers new if does not exist otherwise updates original one
  1967. /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned
  1968. bool validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
  1969. /// @brief Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one
  1970. /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned
  1971. bool validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
  1972. /// @brief Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original one
  1973. /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned
  1974. bool validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n);
  1975. /// @brief Gets hit counter registered at specified position
  1976. inline const base::HitCounter* getCounter(const char* filename, base::type::LineNumber lineNumber) {
  1977. base::threading::ScopedLock scopedLock(lock());
  1978. return get(filename, lineNumber);
  1979. }
  1980. };
  1981. /// @brief Action to be taken for dispatching
  1982. enum class DispatchAction : base::type::EnumType {
  1983. None = 1, NormalLog = 2, SysLog = 4
  1984. };
  1985. } // namespace base
  1986. template <typename T>
  1987. class Callback : protected base::threading::ThreadSafe {
  1988. public:
  1989. Callback(void) : m_enabled(true) {}
  1990. inline bool enabled(void) const {
  1991. return m_enabled;
  1992. }
  1993. inline void setEnabled(bool enabled) {
  1994. base::threading::ScopedLock scopedLock(lock());
  1995. m_enabled = enabled;
  1996. }
  1997. protected:
  1998. virtual void handle(const T* handlePtr) = 0;
  1999. private:
  2000. bool m_enabled;
  2001. };
  2002. class LogDispatchData {
  2003. public:
  2004. LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {}
  2005. inline const LogMessage* logMessage(void) const {
  2006. return m_logMessage;
  2007. }
  2008. inline base::DispatchAction dispatchAction(void) const {
  2009. return m_dispatchAction;
  2010. }
  2011. inline void setLogMessage(LogMessage* logMessage) {
  2012. m_logMessage = logMessage;
  2013. }
  2014. inline void setDispatchAction(base::DispatchAction dispatchAction) {
  2015. m_dispatchAction = dispatchAction;
  2016. }
  2017. private:
  2018. LogMessage* m_logMessage;
  2019. base::DispatchAction m_dispatchAction;
  2020. friend class base::LogDispatcher;
  2021. };
  2022. class LogDispatchCallback : public Callback<LogDispatchData> {
  2023. protected:
  2024. virtual void handle(const LogDispatchData* data);
  2025. base::threading::Mutex& fileHandle(const LogDispatchData* data);
  2026. private:
  2027. friend class base::LogDispatcher;
  2028. std::unordered_map<std::string, std::unique_ptr<base::threading::Mutex>> m_fileLocks;
  2029. base::threading::Mutex m_fileLocksMapLock;
  2030. };
  2031. class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> {
  2032. private:
  2033. friend class base::PerformanceTracker;
  2034. };
  2035. class LoggerRegistrationCallback : public Callback<Logger> {
  2036. private:
  2037. friend class base::RegisteredLoggers;
  2038. };
  2039. class LogBuilder : base::NoCopy {
  2040. public:
  2041. LogBuilder() : m_termSupportsColor(base::utils::OS::termSupportsColor()) {}
  2042. virtual ~LogBuilder(void) {
  2043. ELPP_INTERNAL_INFO(3, "Destroying log builder...")
  2044. }
  2045. virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0;
  2046. void convertToColoredOutput(base::type::string_t* logLine, Level level);
  2047. private:
  2048. bool m_termSupportsColor;
  2049. friend class el::base::DefaultLogDispatchCallback;
  2050. };
  2051. typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
  2052. /// @brief Represents a logger holding ID and configurations we need to write logs
  2053. ///
  2054. /// @detail This class does not write logs itself instead its used by writer to read configuations from.
  2055. class Logger : public base::threading::ThreadSafe, public Loggable {
  2056. public:
  2057. Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference);
  2058. Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference);
  2059. Logger(const Logger& logger);
  2060. Logger& operator=(const Logger& logger);
  2061. virtual ~Logger(void) {
  2062. base::utils::safeDelete(m_typedConfigurations);
  2063. }
  2064. virtual inline void log(el::base::type::ostream_t& os) const {
  2065. os << m_id.c_str();
  2066. }
  2067. /// @brief Configures the logger using specified configurations.
  2068. void configure(const Configurations& configurations);
  2069. /// @brief Reconfigures logger using existing configurations
  2070. void reconfigure(void);
  2071. inline const std::string& id(void) const {
  2072. return m_id;
  2073. }
  2074. inline const std::string& parentApplicationName(void) const {
  2075. return m_parentApplicationName;
  2076. }
  2077. inline void setParentApplicationName(const std::string& parentApplicationName) {
  2078. m_parentApplicationName = parentApplicationName;
  2079. }
  2080. inline Configurations* configurations(void) {
  2081. return &m_configurations;
  2082. }
  2083. inline base::TypedConfigurations* typedConfigurations(void) {
  2084. return m_typedConfigurations;
  2085. }
  2086. static bool isValidId(const std::string& id);
  2087. /// @brief Flushes logger to sync all log files for all levels
  2088. void flush(void);
  2089. void flush(Level level, base::type::fstream_t* fs);
  2090. inline bool isFlushNeeded(Level level) {
  2091. return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level);
  2092. }
  2093. inline LogBuilder* logBuilder(void) const {
  2094. return m_logBuilder.get();
  2095. }
  2096. inline void setLogBuilder(const LogBuilderPtr& logBuilder) {
  2097. m_logBuilder = logBuilder;
  2098. }
  2099. inline bool enabled(Level level) const {
  2100. return m_typedConfigurations->enabled(level);
  2101. }
  2102. #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
  2103. # define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\
  2104. template <typename T, typename... Args>\
  2105. inline void FUNCTION_NAME(const char*, const T&, const Args&...);\
  2106. template <typename T>\
  2107. inline void FUNCTION_NAME(const T&);
  2108. template <typename T, typename... Args>
  2109. inline void verbose(int, const char*, const T&, const Args&...);
  2110. template <typename T>
  2111. inline void verbose(int, const T&);
  2112. LOGGER_LEVEL_WRITERS_SIGNATURES(info)
  2113. LOGGER_LEVEL_WRITERS_SIGNATURES(debug)
  2114. LOGGER_LEVEL_WRITERS_SIGNATURES(warn)
  2115. LOGGER_LEVEL_WRITERS_SIGNATURES(error)
  2116. LOGGER_LEVEL_WRITERS_SIGNATURES(fatal)
  2117. LOGGER_LEVEL_WRITERS_SIGNATURES(trace)
  2118. # undef LOGGER_LEVEL_WRITERS_SIGNATURES
  2119. #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
  2120. private:
  2121. std::string m_id;
  2122. base::TypedConfigurations* m_typedConfigurations;
  2123. base::type::stringstream_t m_stream;
  2124. std::string m_parentApplicationName;
  2125. bool m_isConfigured;
  2126. Configurations m_configurations;
  2127. std::unordered_map<Level, unsigned int> m_unflushedCount;
  2128. base::LogStreamsReferenceMap* m_logStreamsReference;
  2129. LogBuilderPtr m_logBuilder;
  2130. friend class el::LogMessage;
  2131. friend class el::Loggers;
  2132. friend class el::Helpers;
  2133. friend class el::base::RegisteredLoggers;
  2134. friend class el::base::DefaultLogDispatchCallback;
  2135. friend class el::base::MessageBuilder;
  2136. friend class el::base::Writer;
  2137. friend class el::base::PErrorWriter;
  2138. friend class el::base::Storage;
  2139. friend class el::base::PerformanceTracker;
  2140. friend class el::base::LogDispatcher;
  2141. Logger(void);
  2142. #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
  2143. template <typename T, typename... Args>
  2144. void log_(Level, int, const char*, const T&, const Args&...);
  2145. template <typename T>
  2146. inline void log_(Level, int, const T&);
  2147. template <typename T, typename... Args>
  2148. void log(Level, const char*, const T&, const Args&...);
  2149. template <typename T>
  2150. inline void log(Level, const T&);
  2151. #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
  2152. void initUnflushedCount(void);
  2153. inline base::type::stringstream_t& stream(void) {
  2154. return m_stream;
  2155. }
  2156. void resolveLoggerFormatSpec(void) const;
  2157. };
  2158. namespace base {
  2159. /// @brief Loggers repository
  2160. class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
  2161. public:
  2162. explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder);
  2163. virtual ~RegisteredLoggers(void) {
  2164. unsafeFlushAll();
  2165. }
  2166. inline void setDefaultConfigurations(const Configurations& configurations) {
  2167. base::threading::ScopedLock scopedLock(lock());
  2168. m_defaultConfigurations.setFromBase(const_cast<Configurations*>(&configurations));
  2169. }
  2170. inline Configurations* defaultConfigurations(void) {
  2171. return &m_defaultConfigurations;
  2172. }
  2173. Logger* get(const std::string& id, bool forceCreation = true);
  2174. template <typename T>
  2175. inline bool installLoggerRegistrationCallback(const std::string& id) {
  2176. return base::utils::Utils::installCallback<T, base::type::LoggerRegistrationCallbackPtr>(id,
  2177. &m_loggerRegistrationCallbacks);
  2178. }
  2179. template <typename T>
  2180. inline void uninstallLoggerRegistrationCallback(const std::string& id) {
  2181. base::utils::Utils::uninstallCallback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks);
  2182. }
  2183. template <typename T>
  2184. inline T* loggerRegistrationCallback(const std::string& id) {
  2185. return base::utils::Utils::callback<T, base::type::LoggerRegistrationCallbackPtr>(id, &m_loggerRegistrationCallbacks);
  2186. }
  2187. bool remove(const std::string& id);
  2188. inline bool has(const std::string& id) {
  2189. return get(id, false) != nullptr;
  2190. }
  2191. inline void unregister(Logger*& logger) {
  2192. base::threading::ScopedLock scopedLock(lock());
  2193. base::utils::Registry<Logger, std::string>::unregister(logger->id());
  2194. }
  2195. inline base::LogStreamsReferenceMap* logStreamsReference(void) {
  2196. return &m_logStreamsReference;
  2197. }
  2198. inline void flushAll(void) {
  2199. base::threading::ScopedLock scopedLock(lock());
  2200. unsafeFlushAll();
  2201. }
  2202. inline void setDefaultLogBuilder(LogBuilderPtr& logBuilderPtr) {
  2203. base::threading::ScopedLock scopedLock(lock());
  2204. m_defaultLogBuilder = logBuilderPtr;
  2205. }
  2206. private:
  2207. LogBuilderPtr m_defaultLogBuilder;
  2208. Configurations m_defaultConfigurations;
  2209. base::LogStreamsReferenceMap m_logStreamsReference;
  2210. std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
  2211. friend class el::base::Storage;
  2212. void unsafeFlushAll(void);
  2213. };
  2214. /// @brief Represents registries for verbose logging
  2215. class VRegistry : base::NoCopy, public base::threading::ThreadSafe {
  2216. public:
  2217. explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags);
  2218. /// @brief Sets verbose level. Accepted range is 0-9
  2219. void setLevel(base::type::VerboseLevel level);
  2220. inline base::type::VerboseLevel level(void) const {
  2221. return m_level;
  2222. }
  2223. inline void clearModules(void) {
  2224. base::threading::ScopedLock scopedLock(lock());
  2225. m_modules.clear();
  2226. }
  2227. void setModules(const char* modules);
  2228. bool allowed(base::type::VerboseLevel vlevel, const char* file);
  2229. inline const std::unordered_map<std::string, base::type::VerboseLevel>& modules(void) const {
  2230. return m_modules;
  2231. }
  2232. void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs);
  2233. /// @brief Whether or not vModules enabled
  2234. inline bool vModulesEnabled(void) {
  2235. return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags);
  2236. }
  2237. private:
  2238. base::type::VerboseLevel m_level;
  2239. base::type::EnumType* m_pFlags;
  2240. std::unordered_map<std::string, base::type::VerboseLevel> m_modules;
  2241. };
  2242. } // namespace base
  2243. class LogMessage {
  2244. public:
  2245. LogMessage(Level level, const std::string& file, base::type::LineNumber line, const std::string& func,
  2246. base::type::VerboseLevel verboseLevel, Logger* logger) :
  2247. m_level(level), m_file(file), m_line(line), m_func(func),
  2248. m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) {
  2249. }
  2250. inline Level level(void) const {
  2251. return m_level;
  2252. }
  2253. inline const std::string& file(void) const {
  2254. return m_file;
  2255. }
  2256. inline base::type::LineNumber line(void) const {
  2257. return m_line;
  2258. }
  2259. inline const std::string& func(void) const {
  2260. return m_func;
  2261. }
  2262. inline base::type::VerboseLevel verboseLevel(void) const {
  2263. return m_verboseLevel;
  2264. }
  2265. inline Logger* logger(void) const {
  2266. return m_logger;
  2267. }
  2268. inline const base::type::string_t& message(void) const {
  2269. return m_message;
  2270. }
  2271. private:
  2272. Level m_level;
  2273. std::string m_file;
  2274. base::type::LineNumber m_line;
  2275. std::string m_func;
  2276. base::type::VerboseLevel m_verboseLevel;
  2277. Logger* m_logger;
  2278. base::type::string_t m_message;
  2279. };
  2280. namespace base {
  2281. #if ELPP_ASYNC_LOGGING
  2282. class AsyncLogItem {
  2283. public:
  2284. explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine)
  2285. : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {}
  2286. virtual ~AsyncLogItem() {}
  2287. inline LogMessage* logMessage(void) {
  2288. return &m_logMessage;
  2289. }
  2290. inline LogDispatchData* data(void) {
  2291. return &m_dispatchData;
  2292. }
  2293. inline base::type::string_t logLine(void) {
  2294. return m_logLine;
  2295. }
  2296. private:
  2297. LogMessage m_logMessage;
  2298. LogDispatchData m_dispatchData;
  2299. base::type::string_t m_logLine;
  2300. };
  2301. class AsyncLogQueue : public base::threading::ThreadSafe {
  2302. public:
  2303. virtual ~AsyncLogQueue() {
  2304. ELPP_INTERNAL_INFO(6, "~AsyncLogQueue");
  2305. }
  2306. inline AsyncLogItem next(void) {
  2307. base::threading::ScopedLock scopedLock(lock());
  2308. AsyncLogItem result = m_queue.front();
  2309. m_queue.pop();
  2310. return result;
  2311. }
  2312. inline void push(const AsyncLogItem& item) {
  2313. base::threading::ScopedLock scopedLock(lock());
  2314. m_queue.push(item);
  2315. }
  2316. inline void pop(void) {
  2317. base::threading::ScopedLock scopedLock(lock());
  2318. m_queue.pop();
  2319. }
  2320. inline AsyncLogItem front(void) {
  2321. base::threading::ScopedLock scopedLock(lock());
  2322. return m_queue.front();
  2323. }
  2324. inline bool empty(void) {
  2325. base::threading::ScopedLock scopedLock(lock());
  2326. return m_queue.empty();
  2327. }
  2328. private:
  2329. std::queue<AsyncLogItem> m_queue;
  2330. };
  2331. class IWorker {
  2332. public:
  2333. virtual ~IWorker() {}
  2334. virtual void start() = 0;
  2335. };
  2336. #endif // ELPP_ASYNC_LOGGING
  2337. /// @brief Easylogging++ management storage
  2338. class Storage : base::NoCopy, public base::threading::ThreadSafe {
  2339. public:
  2340. #if ELPP_ASYNC_LOGGING
  2341. Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker);
  2342. #else
  2343. explicit Storage(const LogBuilderPtr& defaultLogBuilder);
  2344. #endif // ELPP_ASYNC_LOGGING
  2345. virtual ~Storage(void);
  2346. inline bool validateEveryNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t occasion) {
  2347. return hitCounters()->validateEveryN(filename, lineNumber, occasion);
  2348. }
  2349. inline bool validateAfterNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) {
  2350. return hitCounters()->validateAfterN(filename, lineNumber, n);
  2351. }
  2352. inline bool validateNTimesCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) {
  2353. return hitCounters()->validateNTimes(filename, lineNumber, n);
  2354. }
  2355. inline base::RegisteredHitCounters* hitCounters(void) const {
  2356. return m_registeredHitCounters;
  2357. }
  2358. inline base::RegisteredLoggers* registeredLoggers(void) const {
  2359. return m_registeredLoggers;
  2360. }
  2361. inline base::VRegistry* vRegistry(void) const {
  2362. return m_vRegistry;
  2363. }
  2364. #if ELPP_ASYNC_LOGGING
  2365. inline base::AsyncLogQueue* asyncLogQueue(void) const {
  2366. return m_asyncLogQueue;
  2367. }
  2368. #endif // ELPP_ASYNC_LOGGING
  2369. inline const base::utils::CommandLineArgs* commandLineArgs(void) const {
  2370. return &m_commandLineArgs;
  2371. }
  2372. inline void addFlag(LoggingFlag flag) {
  2373. base::utils::addFlag(flag, &m_flags);
  2374. }
  2375. inline void removeFlag(LoggingFlag flag) {
  2376. base::utils::removeFlag(flag, &m_flags);
  2377. }
  2378. inline bool hasFlag(LoggingFlag flag) const {
  2379. return base::utils::hasFlag(flag, m_flags);
  2380. }
  2381. inline base::type::EnumType flags(void) const {
  2382. return m_flags;
  2383. }
  2384. inline void setFlags(base::type::EnumType flags) {
  2385. m_flags = flags;
  2386. }
  2387. inline void setPreRollOutCallback(const PreRollOutCallback& callback) {
  2388. m_preRollOutCallback = callback;
  2389. }
  2390. inline void unsetPreRollOutCallback(void) {
  2391. m_preRollOutCallback = base::defaultPreRollOutCallback;
  2392. }
  2393. inline PreRollOutCallback& preRollOutCallback(void) {
  2394. return m_preRollOutCallback;
  2395. }
  2396. bool hasCustomFormatSpecifier(const char* formatSpecifier);
  2397. void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier);
  2398. bool uninstallCustomFormatSpecifier(const char* formatSpecifier);
  2399. const std::vector<CustomFormatSpecifier>* customFormatSpecifiers(void) const {
  2400. return &m_customFormatSpecifiers;
  2401. }
  2402. base::threading::Mutex& customFormatSpecifiersLock() {
  2403. return m_customFormatSpecifiersLock;
  2404. }
  2405. inline void setLoggingLevel(Level level) {
  2406. m_loggingLevel = level;
  2407. }
  2408. template <typename T>
  2409. inline bool installLogDispatchCallback(const std::string& id) {
  2410. return base::utils::Utils::installCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
  2411. }
  2412. template <typename T>
  2413. inline void uninstallLogDispatchCallback(const std::string& id) {
  2414. base::utils::Utils::uninstallCallback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
  2415. }
  2416. template <typename T>
  2417. inline T* logDispatchCallback(const std::string& id) {
  2418. return base::utils::Utils::callback<T, base::type::LogDispatchCallbackPtr>(id, &m_logDispatchCallbacks);
  2419. }
  2420. #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  2421. template <typename T>
  2422. inline bool installPerformanceTrackingCallback(const std::string& id) {
  2423. return base::utils::Utils::installCallback<T, base::type::PerformanceTrackingCallbackPtr>(id,
  2424. &m_performanceTrackingCallbacks);
  2425. }
  2426. template <typename T>
  2427. inline void uninstallPerformanceTrackingCallback(const std::string& id) {
  2428. base::utils::Utils::uninstallCallback<T, base::type::PerformanceTrackingCallbackPtr>(id,
  2429. &m_performanceTrackingCallbacks);
  2430. }
  2431. template <typename T>
  2432. inline T* performanceTrackingCallback(const std::string& id) {
  2433. return base::utils::Utils::callback<T, base::type::PerformanceTrackingCallbackPtr>(id, &m_performanceTrackingCallbacks);
  2434. }
  2435. #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  2436. /// @brief Sets thread name for current thread. Requires std::thread
  2437. inline void setThreadName(const std::string& name) {
  2438. if (name.empty()) return;
  2439. base::threading::ScopedLock scopedLock(m_threadNamesLock);
  2440. m_threadNames[base::threading::getCurrentThreadId()] = name;
  2441. }
  2442. inline std::string getThreadName(const std::string& threadId) {
  2443. base::threading::ScopedLock scopedLock(m_threadNamesLock);
  2444. std::unordered_map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
  2445. if (it == m_threadNames.end()) {
  2446. return threadId;
  2447. }
  2448. return it->second;
  2449. }
  2450. private:
  2451. base::RegisteredHitCounters* m_registeredHitCounters;
  2452. base::RegisteredLoggers* m_registeredLoggers;
  2453. base::type::EnumType m_flags;
  2454. base::VRegistry* m_vRegistry;
  2455. #if ELPP_ASYNC_LOGGING
  2456. base::AsyncLogQueue* m_asyncLogQueue;
  2457. base::IWorker* m_asyncDispatchWorker;
  2458. #endif // ELPP_ASYNC_LOGGING
  2459. base::utils::CommandLineArgs m_commandLineArgs;
  2460. PreRollOutCallback m_preRollOutCallback;
  2461. std::unordered_map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
  2462. std::unordered_map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
  2463. std::unordered_map<std::string, std::string> m_threadNames;
  2464. std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
  2465. base::threading::Mutex m_customFormatSpecifiersLock;
  2466. base::threading::Mutex m_threadNamesLock;
  2467. Level m_loggingLevel;
  2468. friend class el::Helpers;
  2469. friend class el::base::DefaultLogDispatchCallback;
  2470. friend class el::LogBuilder;
  2471. friend class el::base::MessageBuilder;
  2472. friend class el::base::Writer;
  2473. friend class el::base::PerformanceTracker;
  2474. friend class el::base::LogDispatcher;
  2475. void setApplicationArguments(int argc, char** argv);
  2476. inline void setApplicationArguments(int argc, const char** argv) {
  2477. setApplicationArguments(argc, const_cast<char**>(argv));
  2478. }
  2479. };
  2480. extern ELPP_EXPORT base::type::StoragePointer elStorage;
  2481. #define ELPP el::base::elStorage
  2482. class DefaultLogDispatchCallback : public LogDispatchCallback {
  2483. protected:
  2484. void handle(const LogDispatchData* data);
  2485. private:
  2486. const LogDispatchData* m_data;
  2487. void dispatch(base::type::string_t&& logLine);
  2488. };
  2489. #if ELPP_ASYNC_LOGGING
  2490. class AsyncLogDispatchCallback : public LogDispatchCallback {
  2491. protected:
  2492. void handle(const LogDispatchData* data);
  2493. };
  2494. class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe {
  2495. public:
  2496. AsyncDispatchWorker();
  2497. virtual ~AsyncDispatchWorker();
  2498. bool clean(void);
  2499. void emptyQueue(void);
  2500. virtual void start(void);
  2501. void handle(AsyncLogItem* logItem);
  2502. void run(void);
  2503. void setContinueRunning(bool value) {
  2504. base::threading::ScopedLock scopedLock(m_continueRunningLock);
  2505. m_continueRunning = value;
  2506. }
  2507. bool continueRunning(void) const {
  2508. return m_continueRunning;
  2509. }
  2510. private:
  2511. std::condition_variable cv;
  2512. bool m_continueRunning;
  2513. base::threading::Mutex m_continueRunningLock;
  2514. };
  2515. #endif // ELPP_ASYNC_LOGGING
  2516. } // namespace base
  2517. namespace base {
  2518. class DefaultLogBuilder : public LogBuilder {
  2519. public:
  2520. base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const;
  2521. };
  2522. /// @brief Dispatches log messages
  2523. class LogDispatcher : base::NoCopy {
  2524. public:
  2525. LogDispatcher(bool proceed, LogMessage* logMessage, base::DispatchAction dispatchAction) :
  2526. m_proceed(proceed),
  2527. m_logMessage(logMessage),
  2528. m_dispatchAction(std::move(dispatchAction)) {
  2529. }
  2530. void dispatch(void);
  2531. private:
  2532. bool m_proceed;
  2533. LogMessage* m_logMessage;
  2534. base::DispatchAction m_dispatchAction;
  2535. };
  2536. #if defined(ELPP_STL_LOGGING)
  2537. /// @brief Workarounds to write some STL logs
  2538. ///
  2539. /// @detail There is workaround needed to loop through some stl containers. In order to do that, we need iterable containers
  2540. /// of same type and provide iterator interface and pass it on to writeIterator().
  2541. /// Remember, this is passed by value in constructor so that we dont change original containers.
  2542. /// This operation is as expensive as Big-O(std::min(class_.size(), base::consts::kMaxLogPerContainer))
  2543. namespace workarounds {
  2544. /// @brief Abstract IterableContainer template that provides interface for iterable classes of type T
  2545. template <typename T, typename Container>
  2546. class IterableContainer {
  2547. public:
  2548. typedef typename Container::iterator iterator;
  2549. typedef typename Container::const_iterator const_iterator;
  2550. IterableContainer(void) {}
  2551. virtual ~IterableContainer(void) {}
  2552. iterator begin(void) {
  2553. return getContainer().begin();
  2554. }
  2555. iterator end(void) {
  2556. return getContainer().end();
  2557. }
  2558. private:
  2559. virtual Container& getContainer(void) = 0;
  2560. };
  2561. /// @brief Implements IterableContainer and provides iterable std::priority_queue class
  2562. template<typename T, typename Container = std::vector<T>, typename Comparator = std::less<typename Container::value_type>>
  2563. class IterablePriorityQueue : public IterableContainer<T, Container>,
  2564. public std::priority_queue<T, Container, Comparator> {
  2565. public:
  2566. IterablePriorityQueue(std::priority_queue<T, Container, Comparator> queue_) {
  2567. std::size_t count_ = 0;
  2568. while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
  2569. this->push(queue_.top());
  2570. queue_.pop();
  2571. }
  2572. }
  2573. private:
  2574. inline Container& getContainer(void) {
  2575. return this->c;
  2576. }
  2577. };
  2578. /// @brief Implements IterableContainer and provides iterable std::queue class
  2579. template<typename T, typename Container = std::deque<T>>
  2580. class IterableQueue : public IterableContainer<T, Container>, public std::queue<T, Container> {
  2581. public:
  2582. IterableQueue(std::queue<T, Container> queue_) {
  2583. std::size_t count_ = 0;
  2584. while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) {
  2585. this->push(queue_.front());
  2586. queue_.pop();
  2587. }
  2588. }
  2589. private:
  2590. inline Container& getContainer(void) {
  2591. return this->c;
  2592. }
  2593. };
  2594. /// @brief Implements IterableContainer and provides iterable std::stack class
  2595. template<typename T, typename Container = std::deque<T>>
  2596. class IterableStack : public IterableContainer<T, Container>, public std::stack<T, Container> {
  2597. public:
  2598. IterableStack(std::stack<T, Container> stack_) {
  2599. std::size_t count_ = 0;
  2600. while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) {
  2601. this->push(stack_.top());
  2602. stack_.pop();
  2603. }
  2604. }
  2605. private:
  2606. inline Container& getContainer(void) {
  2607. return this->c;
  2608. }
  2609. };
  2610. } // namespace workarounds
  2611. #endif // defined(ELPP_STL_LOGGING)
  2612. // Log message builder
  2613. class MessageBuilder {
  2614. public:
  2615. MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {}
  2616. void initialize(Logger* logger);
  2617. # define ELPP_SIMPLE_LOG(LOG_TYPE)\
  2618. MessageBuilder& operator<<(LOG_TYPE msg) {\
  2619. m_logger->stream() << msg;\
  2620. if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\
  2621. m_logger->stream() << " ";\
  2622. }\
  2623. return *this;\
  2624. }
  2625. inline MessageBuilder& operator<<(const std::string& msg) {
  2626. return operator<<(msg.c_str());
  2627. }
  2628. ELPP_SIMPLE_LOG(char)
  2629. ELPP_SIMPLE_LOG(bool)
  2630. ELPP_SIMPLE_LOG(signed short)
  2631. ELPP_SIMPLE_LOG(unsigned short)
  2632. ELPP_SIMPLE_LOG(signed int)
  2633. ELPP_SIMPLE_LOG(unsigned int)
  2634. ELPP_SIMPLE_LOG(signed long)
  2635. ELPP_SIMPLE_LOG(unsigned long)
  2636. ELPP_SIMPLE_LOG(float)
  2637. ELPP_SIMPLE_LOG(double)
  2638. ELPP_SIMPLE_LOG(char*)
  2639. ELPP_SIMPLE_LOG(const char*)
  2640. ELPP_SIMPLE_LOG(const void*)
  2641. ELPP_SIMPLE_LOG(long double)
  2642. inline MessageBuilder& operator<<(const std::wstring& msg) {
  2643. return operator<<(msg.c_str());
  2644. }
  2645. MessageBuilder& operator<<(const wchar_t* msg);
  2646. // ostream manipulators
  2647. inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) {
  2648. m_logger->stream() << OStreamMani;
  2649. return *this;
  2650. }
  2651. #define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \
  2652. template <typename T> \
  2653. inline MessageBuilder& operator<<(const temp<T>& template_inst) { \
  2654. return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
  2655. }
  2656. #define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \
  2657. template <typename T1, typename T2> \
  2658. inline MessageBuilder& operator<<(const temp<T1, T2>& template_inst) { \
  2659. return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
  2660. }
  2661. #define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \
  2662. template <typename T1, typename T2, typename T3> \
  2663. inline MessageBuilder& operator<<(const temp<T1, T2, T3>& template_inst) { \
  2664. return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
  2665. }
  2666. #define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \
  2667. template <typename T1, typename T2, typename T3, typename T4> \
  2668. inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4>& template_inst) { \
  2669. return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
  2670. }
  2671. #define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \
  2672. template <typename T1, typename T2, typename T3, typename T4, typename T5> \
  2673. inline MessageBuilder& operator<<(const temp<T1, T2, T3, T4, T5>& template_inst) { \
  2674. return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \
  2675. }
  2676. #if defined(ELPP_STL_LOGGING)
  2677. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector)
  2678. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list)
  2679. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque)
  2680. ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set)
  2681. ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset)
  2682. ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map)
  2683. ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap)
  2684. template <class T, class Container>
  2685. inline MessageBuilder& operator<<(const std::queue<T, Container>& queue_) {
  2686. base::workarounds::IterableQueue<T, Container> iterableQueue_ =
  2687. static_cast<base::workarounds::IterableQueue<T, Container> >(queue_);
  2688. return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size());
  2689. }
  2690. template <class T, class Container>
  2691. inline MessageBuilder& operator<<(const std::stack<T, Container>& stack_) {
  2692. base::workarounds::IterableStack<T, Container> iterableStack_ =
  2693. static_cast<base::workarounds::IterableStack<T, Container> >(stack_);
  2694. return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size());
  2695. }
  2696. template <class T, class Container, class Comparator>
  2697. inline MessageBuilder& operator<<(const std::priority_queue<T, Container, Comparator>& priorityQueue_) {
  2698. base::workarounds::IterablePriorityQueue<T, Container, Comparator> iterablePriorityQueue_ =
  2699. static_cast<base::workarounds::IterablePriorityQueue<T, Container, Comparator> >(priorityQueue_);
  2700. return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size());
  2701. }
  2702. template <class First, class Second>
  2703. MessageBuilder& operator<<(const std::pair<First, Second>& pair_) {
  2704. m_logger->stream() << ELPP_LITERAL("(");
  2705. operator << (static_cast<First>(pair_.first));
  2706. m_logger->stream() << ELPP_LITERAL(", ");
  2707. operator << (static_cast<Second>(pair_.second));
  2708. m_logger->stream() << ELPP_LITERAL(")");
  2709. return *this;
  2710. }
  2711. template <std::size_t Size>
  2712. MessageBuilder& operator<<(const std::bitset<Size>& bitset_) {
  2713. m_logger->stream() << ELPP_LITERAL("[");
  2714. operator << (bitset_.to_string());
  2715. m_logger->stream() << ELPP_LITERAL("]");
  2716. return *this;
  2717. }
  2718. # if defined(ELPP_LOG_STD_ARRAY)
  2719. template <class T, std::size_t Size>
  2720. inline MessageBuilder& operator<<(const std::array<T, Size>& array) {
  2721. return writeIterator(array.begin(), array.end(), array.size());
  2722. }
  2723. # endif // defined(ELPP_LOG_STD_ARRAY)
  2724. # if defined(ELPP_LOG_UNORDERED_MAP)
  2725. ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map)
  2726. ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap)
  2727. # endif // defined(ELPP_LOG_UNORDERED_MAP)
  2728. # if defined(ELPP_LOG_UNORDERED_SET)
  2729. ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set)
  2730. ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset)
  2731. # endif // defined(ELPP_LOG_UNORDERED_SET)
  2732. #endif // defined(ELPP_STL_LOGGING)
  2733. #if defined(ELPP_QT_LOGGING)
  2734. inline MessageBuilder& operator<<(const QString& msg) {
  2735. # if defined(ELPP_UNICODE)
  2736. m_logger->stream() << msg.toStdWString();
  2737. # else
  2738. m_logger->stream() << msg.toStdString();
  2739. # endif // defined(ELPP_UNICODE)
  2740. return *this;
  2741. }
  2742. inline MessageBuilder& operator<<(const QByteArray& msg) {
  2743. return operator << (QString(msg));
  2744. }
  2745. inline MessageBuilder& operator<<(const QStringRef& msg) {
  2746. return operator<<(msg.toString());
  2747. }
  2748. inline MessageBuilder& operator<<(qint64 msg) {
  2749. # if defined(ELPP_UNICODE)
  2750. m_logger->stream() << QString::number(msg).toStdWString();
  2751. # else
  2752. m_logger->stream() << QString::number(msg).toStdString();
  2753. # endif // defined(ELPP_UNICODE)
  2754. return *this;
  2755. }
  2756. inline MessageBuilder& operator<<(quint64 msg) {
  2757. # if defined(ELPP_UNICODE)
  2758. m_logger->stream() << QString::number(msg).toStdWString();
  2759. # else
  2760. m_logger->stream() << QString::number(msg).toStdString();
  2761. # endif // defined(ELPP_UNICODE)
  2762. return *this;
  2763. }
  2764. inline MessageBuilder& operator<<(QChar msg) {
  2765. m_logger->stream() << msg.toLatin1();
  2766. return *this;
  2767. }
  2768. inline MessageBuilder& operator<<(const QLatin1String& msg) {
  2769. m_logger->stream() << msg.latin1();
  2770. return *this;
  2771. }
  2772. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList)
  2773. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector)
  2774. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue)
  2775. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet)
  2776. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList)
  2777. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack)
  2778. template <typename First, typename Second>
  2779. MessageBuilder& operator<<(const QPair<First, Second>& pair_) {
  2780. m_logger->stream() << ELPP_LITERAL("(");
  2781. operator << (static_cast<First>(pair_.first));
  2782. m_logger->stream() << ELPP_LITERAL(", ");
  2783. operator << (static_cast<Second>(pair_.second));
  2784. m_logger->stream() << ELPP_LITERAL(")");
  2785. return *this;
  2786. }
  2787. template <typename K, typename V>
  2788. MessageBuilder& operator<<(const QMap<K, V>& map_) {
  2789. m_logger->stream() << ELPP_LITERAL("[");
  2790. QList<K> keys = map_.keys();
  2791. typename QList<K>::const_iterator begin = keys.begin();
  2792. typename QList<K>::const_iterator end = keys.end();
  2793. int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // to prevent warning
  2794. for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
  2795. m_logger->stream() << ELPP_LITERAL("(");
  2796. operator << (static_cast<K>(*begin));
  2797. m_logger->stream() << ELPP_LITERAL(", ");
  2798. operator << (static_cast<V>(map_.value(*begin)));
  2799. m_logger->stream() << ELPP_LITERAL(")");
  2800. m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
  2801. }
  2802. if (begin != end) {
  2803. m_logger->stream() << ELPP_LITERAL("...");
  2804. }
  2805. m_logger->stream() << ELPP_LITERAL("]");
  2806. return *this;
  2807. }
  2808. template <typename K, typename V>
  2809. inline MessageBuilder& operator<<(const QMultiMap<K, V>& map_) {
  2810. operator << (static_cast<QMap<K, V>>(map_));
  2811. return *this;
  2812. }
  2813. template <typename K, typename V>
  2814. MessageBuilder& operator<<(const QHash<K, V>& hash_) {
  2815. m_logger->stream() << ELPP_LITERAL("[");
  2816. QList<K> keys = hash_.keys();
  2817. typename QList<K>::const_iterator begin = keys.begin();
  2818. typename QList<K>::const_iterator end = keys.end();
  2819. int max_ = static_cast<int>(base::consts::kMaxLogPerContainer); // prevent type warning
  2820. for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) {
  2821. m_logger->stream() << ELPP_LITERAL("(");
  2822. operator << (static_cast<K>(*begin));
  2823. m_logger->stream() << ELPP_LITERAL(", ");
  2824. operator << (static_cast<V>(hash_.value(*begin)));
  2825. m_logger->stream() << ELPP_LITERAL(")");
  2826. m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
  2827. }
  2828. if (begin != end) {
  2829. m_logger->stream() << ELPP_LITERAL("...");
  2830. }
  2831. m_logger->stream() << ELPP_LITERAL("]");
  2832. return *this;
  2833. }
  2834. template <typename K, typename V>
  2835. inline MessageBuilder& operator<<(const QMultiHash<K, V>& multiHash_) {
  2836. operator << (static_cast<QHash<K, V>>(multiHash_));
  2837. return *this;
  2838. }
  2839. #endif // defined(ELPP_QT_LOGGING)
  2840. #if defined(ELPP_BOOST_LOGGING)
  2841. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector)
  2842. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector)
  2843. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list)
  2844. ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque)
  2845. ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map)
  2846. ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map)
  2847. ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set)
  2848. ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set)
  2849. #endif // defined(ELPP_BOOST_LOGGING)
  2850. /// @brief Macro used internally that can be used externally to make containers easylogging++ friendly
  2851. ///
  2852. /// @detail This macro expands to write an ostream& operator<< for container. This container is expected to
  2853. /// have begin() and end() methods that return respective iterators
  2854. /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets
  2855. /// @param SizeMethod Method used to get size of container.
  2856. /// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro
  2857. /// for an example usage
  2858. #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
  2859. el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
  2860. const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \
  2861. ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\
  2862. ContainerType::const_iterator elem = container.begin();\
  2863. ContainerType::const_iterator endElem = container.end();\
  2864. std::size_t size_ = container.SizeMethod; \
  2865. ss << ELPP_LITERAL("[");\
  2866. for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \
  2867. ss << ElementInstance;\
  2868. ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\
  2869. }\
  2870. if (elem != endElem) {\
  2871. ss << ELPP_LITERAL("...");\
  2872. }\
  2873. ss << ELPP_LITERAL("]");\
  2874. return ss;\
  2875. }
  2876. #if defined(ELPP_WXWIDGETS_LOGGING)
  2877. ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector)
  2878. # define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem))
  2879. # define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem))
  2880. # define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \
  2881. ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")")
  2882. #else
  2883. # define ELPP_WX_PTR_ENABLED(ContainerType)
  2884. # define ELPP_WX_ENABLED(ContainerType)
  2885. # define ELPP_WX_HASH_MAP_ENABLED(ContainerType)
  2886. #endif // defined(ELPP_WXWIDGETS_LOGGING)
  2887. // Other classes
  2888. template <class Class>
  2889. ELPP_SIMPLE_LOG(const Class&)
  2890. #undef ELPP_SIMPLE_LOG
  2891. #undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG
  2892. #undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG
  2893. #undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG
  2894. #undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG
  2895. #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
  2896. private:
  2897. Logger* m_logger;
  2898. const base::type::char_t* m_containerLogSeperator;
  2899. template<class Iterator>
  2900. MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
  2901. m_logger->stream() << ELPP_LITERAL("[");
  2902. for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
  2903. operator << (*begin_);
  2904. m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL(""));
  2905. }
  2906. if (begin_ != end_) {
  2907. m_logger->stream() << ELPP_LITERAL("...");
  2908. }
  2909. m_logger->stream() << ELPP_LITERAL("]");
  2910. if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {
  2911. m_logger->stream() << " ";
  2912. }
  2913. return *this;
  2914. }
  2915. };
  2916. /// @brief Writes nothing - Used when certain log is disabled
  2917. class NullWriter : base::NoCopy {
  2918. public:
  2919. NullWriter(void) {}
  2920. // Null manipulator
  2921. inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) {
  2922. return *this;
  2923. }
  2924. template <typename T>
  2925. inline NullWriter& operator<<(const T&) {
  2926. return *this;
  2927. }
  2928. inline operator bool() {
  2929. return true;
  2930. }
  2931. };
  2932. /// @brief Main entry point of each logging
  2933. class Writer : base::NoCopy {
  2934. public:
  2935. Writer(Level level, const char* file, base::type::LineNumber line,
  2936. const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
  2937. base::type::VerboseLevel verboseLevel = 0) :
  2938. m_msg(nullptr), m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
  2939. m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
  2940. }
  2941. Writer(LogMessage* msg, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog) :
  2942. m_msg(msg), m_level(msg != nullptr ? msg->level() : Level::Unknown),
  2943. m_line(0), m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
  2944. }
  2945. virtual ~Writer(void) {
  2946. processDispatch();
  2947. }
  2948. template <typename T>
  2949. inline Writer& operator<<(const T& log) {
  2950. #if ELPP_LOGGING_ENABLED
  2951. if (m_proceed) {
  2952. m_messageBuilder << log;
  2953. }
  2954. #endif // ELPP_LOGGING_ENABLED
  2955. return *this;
  2956. }
  2957. inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) {
  2958. #if ELPP_LOGGING_ENABLED
  2959. if (m_proceed) {
  2960. m_messageBuilder << log;
  2961. }
  2962. #endif // ELPP_LOGGING_ENABLED
  2963. return *this;
  2964. }
  2965. inline operator bool() {
  2966. return true;
  2967. }
  2968. Writer& construct(Logger* logger, bool needLock = true);
  2969. Writer& construct(int count, const char* loggerIds, ...);
  2970. protected:
  2971. LogMessage* m_msg;
  2972. Level m_level;
  2973. const char* m_file;
  2974. const base::type::LineNumber m_line;
  2975. const char* m_func;
  2976. base::type::VerboseLevel m_verboseLevel;
  2977. Logger* m_logger;
  2978. bool m_proceed;
  2979. base::MessageBuilder m_messageBuilder;
  2980. base::DispatchAction m_dispatchAction;
  2981. std::vector<std::string> m_loggerIds;
  2982. friend class el::Helpers;
  2983. void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true);
  2984. void processDispatch();
  2985. void triggerDispatch(void);
  2986. };
  2987. class PErrorWriter : public base::Writer {
  2988. public:
  2989. PErrorWriter(Level level, const char* file, base::type::LineNumber line,
  2990. const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
  2991. base::type::VerboseLevel verboseLevel = 0) :
  2992. base::Writer(level, file, line, func, dispatchAction, verboseLevel) {
  2993. }
  2994. virtual ~PErrorWriter(void);
  2995. };
  2996. } // namespace base
  2997. // Logging from Logger class. Why this is here? Because we have Storage and Writer class available
  2998. #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
  2999. template <typename T, typename... Args>
  3000. void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) {
  3001. base::MessageBuilder b;
  3002. b.initialize(this);
  3003. while (*s) {
  3004. if (*s == base::consts::kFormatSpecifierChar) {
  3005. if (*(s + 1) == base::consts::kFormatSpecifierChar) {
  3006. ++s;
  3007. } else {
  3008. if (*(s + 1) == base::consts::kFormatSpecifierCharValue) {
  3009. ++s;
  3010. b << value;
  3011. log_(level, vlevel, ++s, args...);
  3012. return;
  3013. }
  3014. }
  3015. }
  3016. b << *s++;
  3017. }
  3018. ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false);
  3019. }
  3020. template <typename T>
  3021. void Logger::log_(Level level, int vlevel, const T& log) {
  3022. if (level == Level::Verbose) {
  3023. if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) {
  3024. base::Writer(Level::Verbose, "FILE", 0, "FUNCTION",
  3025. base::DispatchAction::NormalLog, vlevel).construct(this, false) << log;
  3026. } else {
  3027. stream().str(ELPP_LITERAL(""));
  3028. releaseLock();
  3029. }
  3030. } else {
  3031. base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log;
  3032. }
  3033. }
  3034. template <typename T, typename... Args>
  3035. inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) {
  3036. acquireLock(); // released in Writer!
  3037. log_(level, 0, s, value, args...);
  3038. }
  3039. template <typename T>
  3040. inline void Logger::log(Level level, const T& log) {
  3041. acquireLock(); // released in Writer!
  3042. log_(level, 0, log);
  3043. }
  3044. # if ELPP_VERBOSE_LOG
  3045. template <typename T, typename... Args>
  3046. inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) {
  3047. acquireLock(); // released in Writer!
  3048. log_(el::Level::Verbose, vlevel, s, value, args...);
  3049. }
  3050. template <typename T>
  3051. inline void Logger::verbose(int vlevel, const T& log) {
  3052. acquireLock(); // released in Writer!
  3053. log_(el::Level::Verbose, vlevel, log);
  3054. }
  3055. # else
  3056. template <typename T, typename... Args>
  3057. inline void Logger::verbose(int, const char*, const T&, const Args&...) {
  3058. return;
  3059. }
  3060. template <typename T>
  3061. inline void Logger::verbose(int, const T&) {
  3062. return;
  3063. }
  3064. # endif // ELPP_VERBOSE_LOG
  3065. # define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\
  3066. template <typename T, typename... Args>\
  3067. inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\
  3068. log(LOG_LEVEL, s, value, args...);\
  3069. }\
  3070. template <typename T>\
  3071. inline void Logger::FUNCTION_NAME(const T& value) {\
  3072. log(LOG_LEVEL, value);\
  3073. }
  3074. # define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\
  3075. template <typename T, typename... Args>\
  3076. inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\
  3077. return;\
  3078. }\
  3079. template <typename T>\
  3080. inline void Logger::FUNCTION_NAME(const T&) {\
  3081. return;\
  3082. }
  3083. # if ELPP_INFO_LOG
  3084. LOGGER_LEVEL_WRITERS(info, Level::Info)
  3085. # else
  3086. LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info)
  3087. # endif // ELPP_INFO_LOG
  3088. # if ELPP_DEBUG_LOG
  3089. LOGGER_LEVEL_WRITERS(debug, Level::Debug)
  3090. # else
  3091. LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug)
  3092. # endif // ELPP_DEBUG_LOG
  3093. # if ELPP_WARNING_LOG
  3094. LOGGER_LEVEL_WRITERS(warn, Level::Warning)
  3095. # else
  3096. LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning)
  3097. # endif // ELPP_WARNING_LOG
  3098. # if ELPP_ERROR_LOG
  3099. LOGGER_LEVEL_WRITERS(error, Level::Error)
  3100. # else
  3101. LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error)
  3102. # endif // ELPP_ERROR_LOG
  3103. # if ELPP_FATAL_LOG
  3104. LOGGER_LEVEL_WRITERS(fatal, Level::Fatal)
  3105. # else
  3106. LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal)
  3107. # endif // ELPP_FATAL_LOG
  3108. # if ELPP_TRACE_LOG
  3109. LOGGER_LEVEL_WRITERS(trace, Level::Trace)
  3110. # else
  3111. LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace)
  3112. # endif // ELPP_TRACE_LOG
  3113. # undef LOGGER_LEVEL_WRITERS
  3114. # undef LOGGER_LEVEL_WRITERS_DISABLED
  3115. #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
  3116. #if ELPP_COMPILER_MSVC
  3117. # define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs
  3118. # define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__))
  3119. # define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\
  3120. 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  3121. #else
  3122. # if ELPP_COMPILER_CLANG
  3123. # define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  3124. # else
  3125. # define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  3126. # endif // ELPP_COMPILER_CLANG
  3127. #endif // ELPP_COMPILER_MSVC
  3128. #define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
  3129. #define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \
  3130. writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3131. #define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \
  3132. writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3133. #define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \
  3134. ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion) && \
  3135. writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3136. #define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \
  3137. ELPP->validateAfterNCounter(__FILE__, __LINE__, n) && \
  3138. writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3139. #define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \
  3140. ELPP->validateNTimesCounter(__FILE__, __LINE__, n) && \
  3141. writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3142. #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  3143. class PerformanceTrackingData {
  3144. public:
  3145. enum class DataType : base::type::EnumType {
  3146. Checkpoint = 1, Complete = 2
  3147. };
  3148. // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*)
  3149. explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr),
  3150. m_dataType(dataType), m_firstCheckpoint(false), m_file(""), m_line(0), m_func("") {}
  3151. inline const std::string* blockName(void) const;
  3152. inline const struct timeval* startTime(void) const;
  3153. inline const struct timeval* endTime(void) const;
  3154. inline const struct timeval* lastCheckpointTime(void) const;
  3155. inline const base::PerformanceTracker* performanceTracker(void) const {
  3156. return m_performanceTracker;
  3157. }
  3158. inline PerformanceTrackingData::DataType dataType(void) const {
  3159. return m_dataType;
  3160. }
  3161. inline bool firstCheckpoint(void) const {
  3162. return m_firstCheckpoint;
  3163. }
  3164. inline std::string checkpointId(void) const {
  3165. return m_checkpointId;
  3166. }
  3167. inline const char* file(void) const {
  3168. return m_file;
  3169. }
  3170. inline base::type::LineNumber line(void) const {
  3171. return m_line;
  3172. }
  3173. inline const char* func(void) const {
  3174. return m_func;
  3175. }
  3176. inline const base::type::string_t* formattedTimeTaken() const {
  3177. return &m_formattedTimeTaken;
  3178. }
  3179. inline const std::string& loggerId(void) const;
  3180. private:
  3181. base::PerformanceTracker* m_performanceTracker;
  3182. base::type::string_t m_formattedTimeTaken;
  3183. PerformanceTrackingData::DataType m_dataType;
  3184. bool m_firstCheckpoint;
  3185. std::string m_checkpointId;
  3186. const char* m_file;
  3187. base::type::LineNumber m_line;
  3188. const char* m_func;
  3189. inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) {
  3190. m_performanceTracker = performanceTracker;
  3191. m_firstCheckpoint = firstCheckpoint;
  3192. }
  3193. friend class el::base::PerformanceTracker;
  3194. };
  3195. namespace base {
  3196. /// @brief Represents performanceTracker block of code that conditionally adds performance status to log
  3197. /// either when goes outside the scope of when checkpoint() is called
  3198. class PerformanceTracker : public base::threading::ThreadSafe, public Loggable {
  3199. public:
  3200. PerformanceTracker(const std::string& blockName,
  3201. base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond,
  3202. const std::string& loggerId = std::string(el::base::consts::kPerformanceLoggerId),
  3203. bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel);
  3204. /// @brief Copy constructor
  3205. PerformanceTracker(const PerformanceTracker& t) :
  3206. m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog),
  3207. m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled),
  3208. m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) {
  3209. }
  3210. virtual ~PerformanceTracker(void);
  3211. /// @brief A checkpoint for current performanceTracker block.
  3212. void checkpoint(const std::string& id = std::string(), const char* file = __FILE__,
  3213. base::type::LineNumber line = __LINE__,
  3214. const char* func = "");
  3215. inline Level level(void) const {
  3216. return m_level;
  3217. }
  3218. private:
  3219. std::string m_blockName;
  3220. base::TimestampUnit m_timestampUnit;
  3221. std::string m_loggerId;
  3222. bool m_scopedLog;
  3223. Level m_level;
  3224. bool m_hasChecked;
  3225. std::string m_lastCheckpointId;
  3226. bool m_enabled;
  3227. struct timeval m_startTime, m_endTime, m_lastCheckpointTime;
  3228. PerformanceTracker(void);
  3229. friend class el::PerformanceTrackingData;
  3230. friend class base::DefaultPerformanceTrackingCallback;
  3231. const inline base::type::string_t getFormattedTimeTaken() const {
  3232. return getFormattedTimeTaken(m_startTime);
  3233. }
  3234. const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const;
  3235. virtual inline void log(el::base::type::ostream_t& os) const {
  3236. os << getFormattedTimeTaken();
  3237. }
  3238. };
  3239. class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback {
  3240. protected:
  3241. void handle(const PerformanceTrackingData* data) {
  3242. m_data = data;
  3243. base::type::stringstream_t ss;
  3244. if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) {
  3245. ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") <<
  3246. *m_data->formattedTimeTaken() << ELPP_LITERAL("]");
  3247. } else {
  3248. ss << ELPP_LITERAL("Performance checkpoint");
  3249. if (!m_data->checkpointId().empty()) {
  3250. ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]");
  3251. }
  3252. ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") <<
  3253. *m_data->performanceTracker();
  3254. if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison)
  3255. && m_data->performanceTracker()->m_hasChecked) {
  3256. ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from ");
  3257. if (m_data->performanceTracker()->m_lastCheckpointId.empty()) {
  3258. ss << ELPP_LITERAL("last checkpoint");
  3259. } else {
  3260. ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'");
  3261. }
  3262. ss << ELPP_LITERAL(")]");
  3263. } else {
  3264. ss << ELPP_LITERAL("]");
  3265. }
  3266. }
  3267. el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1,
  3268. m_data->loggerId().c_str()) << ss.str();
  3269. }
  3270. private:
  3271. const PerformanceTrackingData* m_data;
  3272. };
  3273. } // namespace base
  3274. inline const std::string* PerformanceTrackingData::blockName() const {
  3275. return const_cast<const std::string*>(&m_performanceTracker->m_blockName);
  3276. }
  3277. inline const struct timeval* PerformanceTrackingData::startTime() const {
  3278. return const_cast<const struct timeval*>(&m_performanceTracker->m_startTime);
  3279. }
  3280. inline const struct timeval* PerformanceTrackingData::endTime() const {
  3281. return const_cast<const struct timeval*>(&m_performanceTracker->m_endTime);
  3282. }
  3283. inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const {
  3284. return const_cast<const struct timeval*>(&m_performanceTracker->m_lastCheckpointTime);
  3285. }
  3286. inline const std::string& PerformanceTrackingData::loggerId(void) const {
  3287. return m_performanceTracker->m_loggerId;
  3288. }
  3289. #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  3290. namespace base {
  3291. /// @brief Contains some internal debugging tools like crash handler and stack tracer
  3292. namespace debug {
  3293. #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
  3294. class StackTrace : base::NoCopy {
  3295. public:
  3296. static const unsigned int kMaxStack = 64;
  3297. static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew()
  3298. class StackTraceEntry {
  3299. public:
  3300. StackTraceEntry(std::size_t index, const std::string& loc, const std::string& demang, const std::string& hex,
  3301. const std::string& addr);
  3302. StackTraceEntry(std::size_t index, const std::string& loc) :
  3303. m_index(index),
  3304. m_location(loc) {
  3305. }
  3306. std::size_t m_index;
  3307. std::string m_location;
  3308. std::string m_demangled;
  3309. std::string m_hex;
  3310. std::string m_addr;
  3311. friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si);
  3312. private:
  3313. StackTraceEntry(void);
  3314. };
  3315. StackTrace(void) {
  3316. generateNew();
  3317. }
  3318. virtual ~StackTrace(void) {
  3319. }
  3320. inline std::vector<StackTraceEntry>& getLatestStack(void) {
  3321. return m_stack;
  3322. }
  3323. friend std::ostream& operator<<(std::ostream& os, const StackTrace& st);
  3324. private:
  3325. std::vector<StackTraceEntry> m_stack;
  3326. void generateNew(void);
  3327. };
  3328. /// @brief Handles unexpected crashes
  3329. class CrashHandler : base::NoCopy {
  3330. public:
  3331. typedef void (*Handler)(int);
  3332. explicit CrashHandler(bool useDefault);
  3333. explicit CrashHandler(const Handler& cHandler) {
  3334. setHandler(cHandler);
  3335. }
  3336. void setHandler(const Handler& cHandler);
  3337. private:
  3338. Handler m_handler;
  3339. };
  3340. #else
  3341. class CrashHandler {
  3342. public:
  3343. explicit CrashHandler(bool) {}
  3344. };
  3345. #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
  3346. } // namespace debug
  3347. } // namespace base
  3348. extern base::debug::CrashHandler elCrashHandler;
  3349. #define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \
  3350. el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance)
  3351. /// @brief Initializes syslog with process ID, options and facility. calls closelog() on d'tor
  3352. class SysLogInitializer {
  3353. public:
  3354. SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
  3355. #if defined(ELPP_SYSLOG)
  3356. openlog(processIdent, options, facility);
  3357. #else
  3358. ELPP_UNUSED(processIdent);
  3359. ELPP_UNUSED(options);
  3360. ELPP_UNUSED(facility);
  3361. #endif // defined(ELPP_SYSLOG)
  3362. }
  3363. virtual ~SysLogInitializer(void) {
  3364. #if defined(ELPP_SYSLOG)
  3365. closelog();
  3366. #endif // defined(ELPP_SYSLOG)
  3367. }
  3368. };
  3369. #define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac)
  3370. /// @brief Static helpers for developers
  3371. class Helpers : base::StaticClass {
  3372. public:
  3373. /// @brief Shares logging repository (base::Storage)
  3374. static inline void setStorage(base::type::StoragePointer storage) {
  3375. ELPP = storage;
  3376. }
  3377. /// @return Main storage repository
  3378. static inline base::type::StoragePointer storage() {
  3379. return ELPP;
  3380. }
  3381. /// @brief Sets application arguments and figures out whats active for logging and whats not.
  3382. static inline void setArgs(int argc, char** argv) {
  3383. ELPP->setApplicationArguments(argc, argv);
  3384. }
  3385. /// @copydoc setArgs(int argc, char** argv)
  3386. static inline void setArgs(int argc, const char** argv) {
  3387. ELPP->setApplicationArguments(argc, const_cast<char**>(argv));
  3388. }
  3389. /// @brief Sets thread name for current thread. Requires std::thread
  3390. static inline void setThreadName(const std::string& name) {
  3391. ELPP->setThreadName(name);
  3392. }
  3393. static inline std::string getThreadName() {
  3394. return ELPP->getThreadName(base::threading::getCurrentThreadId());
  3395. }
  3396. #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
  3397. /// @brief Overrides default crash handler and installs custom handler.
  3398. /// @param crashHandler A functor with no return type that takes single int argument.
  3399. /// Handler is a typedef with specification: void (*Handler)(int)
  3400. static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) {
  3401. el::elCrashHandler.setHandler(crashHandler);
  3402. }
  3403. /// @brief Abort due to crash with signal in parameter
  3404. /// @param sig Crash signal
  3405. static void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0);
  3406. /// @brief Logs reason of crash as per sig
  3407. /// @param sig Crash signal
  3408. /// @param stackTraceIfAvailable Includes stack trace if available
  3409. /// @param level Logging level
  3410. /// @param logger Logger to use for logging
  3411. static void logCrashReason(int sig, bool stackTraceIfAvailable = false,
  3412. Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId);
  3413. #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG)
  3414. /// @brief Installs pre rollout callback, this callback is triggered when log file is about to be rolled out
  3415. /// (can be useful for backing up)
  3416. static inline void installPreRollOutCallback(const PreRollOutCallback& callback) {
  3417. ELPP->setPreRollOutCallback(callback);
  3418. }
  3419. /// @brief Uninstalls pre rollout callback
  3420. static inline void uninstallPreRollOutCallback(void) {
  3421. ELPP->unsetPreRollOutCallback();
  3422. }
  3423. /// @brief Installs post log dispatch callback, this callback is triggered when log is dispatched
  3424. template <typename T>
  3425. static inline bool installLogDispatchCallback(const std::string& id) {
  3426. return ELPP->installLogDispatchCallback<T>(id);
  3427. }
  3428. /// @brief Uninstalls log dispatch callback
  3429. template <typename T>
  3430. static inline void uninstallLogDispatchCallback(const std::string& id) {
  3431. ELPP->uninstallLogDispatchCallback<T>(id);
  3432. }
  3433. template <typename T>
  3434. static inline T* logDispatchCallback(const std::string& id) {
  3435. return ELPP->logDispatchCallback<T>(id);
  3436. }
  3437. #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  3438. /// @brief Installs post performance tracking callback, this callback is triggered when performance tracking is finished
  3439. template <typename T>
  3440. static inline bool installPerformanceTrackingCallback(const std::string& id) {
  3441. return ELPP->installPerformanceTrackingCallback<T>(id);
  3442. }
  3443. /// @brief Uninstalls post performance tracking handler
  3444. template <typename T>
  3445. static inline void uninstallPerformanceTrackingCallback(const std::string& id) {
  3446. ELPP->uninstallPerformanceTrackingCallback<T>(id);
  3447. }
  3448. template <typename T>
  3449. static inline T* performanceTrackingCallback(const std::string& id) {
  3450. return ELPP->performanceTrackingCallback<T>(id);
  3451. }
  3452. #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
  3453. /// @brief Converts template to std::string - useful for loggable classes to log containers within log(std::ostream&) const
  3454. template <typename T>
  3455. static std::string convertTemplateToStdString(const T& templ) {
  3456. el::Logger* logger =
  3457. ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId);
  3458. if (logger == nullptr) {
  3459. return std::string();
  3460. }
  3461. base::MessageBuilder b;
  3462. b.initialize(logger);
  3463. logger->acquireLock();
  3464. b << templ;
  3465. #if defined(ELPP_UNICODE)
  3466. std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end());
  3467. #else
  3468. std::string s = logger->stream().str();
  3469. #endif // defined(ELPP_UNICODE)
  3470. logger->stream().str(ELPP_LITERAL(""));
  3471. logger->releaseLock();
  3472. return s;
  3473. }
  3474. /// @brief Returns command line arguments (pointer) provided to easylogging++
  3475. static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) {
  3476. return ELPP->commandLineArgs();
  3477. }
  3478. /// @brief Reserve space for custom format specifiers for performance
  3479. /// @see std::vector::reserve
  3480. static inline void reserveCustomFormatSpecifiers(std::size_t size) {
  3481. ELPP->m_customFormatSpecifiers.reserve(size);
  3482. }
  3483. /// @brief Installs user defined format specifier and handler
  3484. static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
  3485. ELPP->installCustomFormatSpecifier(customFormatSpecifier);
  3486. }
  3487. /// @brief Uninstalls user defined format specifier and handler
  3488. static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) {
  3489. return ELPP->uninstallCustomFormatSpecifier(formatSpecifier);
  3490. }
  3491. /// @brief Returns true if custom format specifier is installed
  3492. static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) {
  3493. return ELPP->hasCustomFormatSpecifier(formatSpecifier);
  3494. }
  3495. static inline void validateFileRolling(Logger* logger, Level level) {
  3496. if (ELPP == nullptr || logger == nullptr) return;
  3497. logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
  3498. }
  3499. };
  3500. /// @brief Static helpers to deal with loggers and their configurations
  3501. class Loggers : base::StaticClass {
  3502. public:
  3503. /// @brief Gets existing or registers new logger
  3504. static Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true);
  3505. /// @brief Changes default log builder for future loggers
  3506. static void setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr);
  3507. /// @brief Installs logger registration callback, this callback is triggered when new logger is registered
  3508. template <typename T>
  3509. static inline bool installLoggerRegistrationCallback(const std::string& id) {
  3510. return ELPP->registeredLoggers()->installLoggerRegistrationCallback<T>(id);
  3511. }
  3512. /// @brief Uninstalls log dispatch callback
  3513. template <typename T>
  3514. static inline void uninstallLoggerRegistrationCallback(const std::string& id) {
  3515. ELPP->registeredLoggers()->uninstallLoggerRegistrationCallback<T>(id);
  3516. }
  3517. template <typename T>
  3518. static inline T* loggerRegistrationCallback(const std::string& id) {
  3519. return ELPP->registeredLoggers()->loggerRegistrationCallback<T>(id);
  3520. }
  3521. /// @brief Unregisters logger - use it only when you know what you are doing, you may unregister
  3522. /// loggers initialized / used by third-party libs.
  3523. static bool unregisterLogger(const std::string& identity);
  3524. /// @brief Whether or not logger with id is registered
  3525. static bool hasLogger(const std::string& identity);
  3526. /// @brief Reconfigures specified logger with new configurations
  3527. static Logger* reconfigureLogger(Logger* logger, const Configurations& configurations);
  3528. /// @brief Reconfigures logger with new configurations after looking it up using identity
  3529. static Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations);
  3530. /// @brief Reconfigures logger's single configuration
  3531. static Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType,
  3532. const std::string& value);
  3533. /// @brief Reconfigures all the existing loggers with new configurations
  3534. static void reconfigureAllLoggers(const Configurations& configurations);
  3535. /// @brief Reconfigures single configuration for all the loggers
  3536. static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) {
  3537. reconfigureAllLoggers(Level::Global, configurationType, value);
  3538. }
  3539. /// @brief Reconfigures single configuration for all the loggers for specified level
  3540. static void reconfigureAllLoggers(Level level, ConfigurationType configurationType,
  3541. const std::string& value);
  3542. /// @brief Sets default configurations. This configuration is used for future (and conditionally for existing) loggers
  3543. static void setDefaultConfigurations(const Configurations& configurations,
  3544. bool reconfigureExistingLoggers = false);
  3545. /// @brief Returns current default
  3546. static const Configurations* defaultConfigurations(void);
  3547. /// @brief Returns log stream reference pointer if needed by user
  3548. static const base::LogStreamsReferenceMap* logStreamsReference(void);
  3549. /// @brief Default typed configuration based on existing defaultConf
  3550. static base::TypedConfigurations defaultTypedConfigurations(void);
  3551. /// @brief Populates all logger IDs in current repository.
  3552. /// @param [out] targetList List of fill up.
  3553. static std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList);
  3554. /// @brief Sets configurations from global configuration file.
  3555. static void configureFromGlobal(const char* globalConfigurationFilePath);
  3556. /// @brief Configures loggers using command line arg. Ensure you have already set command line args,
  3557. /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger.
  3558. /// If true is returned that does not mean it has been configured successfully, it only means that it
  3559. /// has attempeted to configure logger using configuration file provided in argument
  3560. static bool configureFromArg(const char* argKey);
  3561. /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered
  3562. static void flushAll(void);
  3563. /// @brief Adds logging flag used internally.
  3564. static inline void addFlag(LoggingFlag flag) {
  3565. ELPP->addFlag(flag);
  3566. }
  3567. /// @brief Removes logging flag used internally.
  3568. static inline void removeFlag(LoggingFlag flag) {
  3569. ELPP->removeFlag(flag);
  3570. }
  3571. /// @brief Determines whether or not certain flag is active
  3572. static inline bool hasFlag(LoggingFlag flag) {
  3573. return ELPP->hasFlag(flag);
  3574. }
  3575. /// @brief Adds flag and removes it when scope goes out
  3576. class ScopedAddFlag {
  3577. public:
  3578. ScopedAddFlag(LoggingFlag flag) : m_flag(flag) {
  3579. Loggers::addFlag(m_flag);
  3580. }
  3581. ~ScopedAddFlag(void) {
  3582. Loggers::removeFlag(m_flag);
  3583. }
  3584. private:
  3585. LoggingFlag m_flag;
  3586. };
  3587. /// @brief Removes flag and add it when scope goes out
  3588. class ScopedRemoveFlag {
  3589. public:
  3590. ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) {
  3591. Loggers::removeFlag(m_flag);
  3592. }
  3593. ~ScopedRemoveFlag(void) {
  3594. Loggers::addFlag(m_flag);
  3595. }
  3596. private:
  3597. LoggingFlag m_flag;
  3598. };
  3599. /// @brief Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging)
  3600. static void setLoggingLevel(Level level) {
  3601. ELPP->setLoggingLevel(level);
  3602. }
  3603. /// @brief Sets verbose level on the fly
  3604. static void setVerboseLevel(base::type::VerboseLevel level);
  3605. /// @brief Gets current verbose level
  3606. static base::type::VerboseLevel verboseLevel(void);
  3607. /// @brief Sets vmodules as specified (on the fly)
  3608. static void setVModules(const char* modules);
  3609. /// @brief Clears vmodules
  3610. static void clearVModules(void);
  3611. };
  3612. class VersionInfo : base::StaticClass {
  3613. public:
  3614. /// @brief Current version number
  3615. static const std::string version(void);
  3616. /// @brief Release date of current version
  3617. static const std::string releaseDate(void);
  3618. };
  3619. } // namespace el
  3620. #undef VLOG_IS_ON
  3621. /// @brief Determines whether verbose logging is on for specified level current file.
  3622. #define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__))
  3623. #undef TIMED_BLOCK
  3624. #undef TIMED_SCOPE
  3625. #undef TIMED_SCOPE_IF
  3626. #undef TIMED_FUNC
  3627. #undef TIMED_FUNC_IF
  3628. #undef ELPP_MIN_UNIT
  3629. #if defined(ELPP_PERFORMANCE_MICROSECONDS)
  3630. # define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond
  3631. #else
  3632. # define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond
  3633. #endif // (defined(ELPP_PERFORMANCE_MICROSECONDS))
  3634. /// @brief Performance tracked scope. Performance gets written when goes out of scope using
  3635. /// 'performance' logger.
  3636. ///
  3637. /// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint();
  3638. /// @see el::base::PerformanceTracker
  3639. /// @see el::base::PerformanceTracker::checkpoint
  3640. // Note: Do not surround this definition with null macro because of obj instance
  3641. #define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? \
  3642. new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr )
  3643. #define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true)
  3644. #define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \
  3645. el::base::type::PerformanceTrackerPtr(new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT)) }; obj.i < 1; ++obj.i)
  3646. /// @brief Performance tracked function. Performance gets written when goes out of scope using
  3647. /// 'performance' logger.
  3648. ///
  3649. /// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint();
  3650. /// @see el::base::PerformanceTracker
  3651. /// @see el::base::PerformanceTracker::checkpoint
  3652. #define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition)
  3653. #define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC)
  3654. #undef PERFORMANCE_CHECKPOINT
  3655. #undef PERFORMANCE_CHECKPOINT_WITH_ID
  3656. #define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC)
  3657. #define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC)
  3658. #undef ELPP_COUNTER
  3659. #undef ELPP_COUNTER_POS
  3660. /// @brief Gets hit counter for file/line
  3661. #define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__))
  3662. /// @brief Gets hit counter position for file/line, -1 if not registered yet
  3663. #define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts())
  3664. // Undef levels to support LOG(LEVEL)
  3665. #undef INFO
  3666. #undef WARNING
  3667. #undef DEBUG
  3668. #undef ERROR
  3669. #undef FATAL
  3670. #undef TRACE
  3671. #undef VERBOSE
  3672. // Undef existing
  3673. #undef CINFO
  3674. #undef CWARNING
  3675. #undef CDEBUG
  3676. #undef CFATAL
  3677. #undef CERROR
  3678. #undef CTRACE
  3679. #undef CVERBOSE
  3680. #undef CINFO_IF
  3681. #undef CWARNING_IF
  3682. #undef CDEBUG_IF
  3683. #undef CERROR_IF
  3684. #undef CFATAL_IF
  3685. #undef CTRACE_IF
  3686. #undef CVERBOSE_IF
  3687. #undef CINFO_EVERY_N
  3688. #undef CWARNING_EVERY_N
  3689. #undef CDEBUG_EVERY_N
  3690. #undef CERROR_EVERY_N
  3691. #undef CFATAL_EVERY_N
  3692. #undef CTRACE_EVERY_N
  3693. #undef CVERBOSE_EVERY_N
  3694. #undef CINFO_AFTER_N
  3695. #undef CWARNING_AFTER_N
  3696. #undef CDEBUG_AFTER_N
  3697. #undef CERROR_AFTER_N
  3698. #undef CFATAL_AFTER_N
  3699. #undef CTRACE_AFTER_N
  3700. #undef CVERBOSE_AFTER_N
  3701. #undef CINFO_N_TIMES
  3702. #undef CWARNING_N_TIMES
  3703. #undef CDEBUG_N_TIMES
  3704. #undef CERROR_N_TIMES
  3705. #undef CFATAL_N_TIMES
  3706. #undef CTRACE_N_TIMES
  3707. #undef CVERBOSE_N_TIMES
  3708. // Normal logs
  3709. #if ELPP_INFO_LOG
  3710. # define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__)
  3711. #else
  3712. # define CINFO(writer, dispatchAction, ...) el::base::NullWriter()
  3713. #endif // ELPP_INFO_LOG
  3714. #if ELPP_WARNING_LOG
  3715. # define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__)
  3716. #else
  3717. # define CWARNING(writer, dispatchAction, ...) el::base::NullWriter()
  3718. #endif // ELPP_WARNING_LOG
  3719. #if ELPP_DEBUG_LOG
  3720. # define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__)
  3721. #else
  3722. # define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter()
  3723. #endif // ELPP_DEBUG_LOG
  3724. #if ELPP_ERROR_LOG
  3725. # define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__)
  3726. #else
  3727. # define CERROR(writer, dispatchAction, ...) el::base::NullWriter()
  3728. #endif // ELPP_ERROR_LOG
  3729. #if ELPP_FATAL_LOG
  3730. # define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__)
  3731. #else
  3732. # define CFATAL(writer, dispatchAction, ...) el::base::NullWriter()
  3733. #endif // ELPP_FATAL_LOG
  3734. #if ELPP_TRACE_LOG
  3735. # define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__)
  3736. #else
  3737. # define CTRACE(writer, dispatchAction, ...) el::base::NullWriter()
  3738. #endif // ELPP_TRACE_LOG
  3739. #if ELPP_VERBOSE_LOG
  3740. # define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\
  3741. el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3742. #else
  3743. # define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter()
  3744. #endif // ELPP_VERBOSE_LOG
  3745. // Conditional logs
  3746. #if ELPP_INFO_LOG
  3747. # define CINFO_IF(writer, condition_, dispatchAction, ...) \
  3748. ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__)
  3749. #else
  3750. # define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
  3751. #endif // ELPP_INFO_LOG
  3752. #if ELPP_WARNING_LOG
  3753. # define CWARNING_IF(writer, condition_, dispatchAction, ...)\
  3754. ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__)
  3755. #else
  3756. # define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
  3757. #endif // ELPP_WARNING_LOG
  3758. #if ELPP_DEBUG_LOG
  3759. # define CDEBUG_IF(writer, condition_, dispatchAction, ...)\
  3760. ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__)
  3761. #else
  3762. # define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
  3763. #endif // ELPP_DEBUG_LOG
  3764. #if ELPP_ERROR_LOG
  3765. # define CERROR_IF(writer, condition_, dispatchAction, ...)\
  3766. ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__)
  3767. #else
  3768. # define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
  3769. #endif // ELPP_ERROR_LOG
  3770. #if ELPP_FATAL_LOG
  3771. # define CFATAL_IF(writer, condition_, dispatchAction, ...)\
  3772. ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__)
  3773. #else
  3774. # define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
  3775. #endif // ELPP_FATAL_LOG
  3776. #if ELPP_TRACE_LOG
  3777. # define CTRACE_IF(writer, condition_, dispatchAction, ...)\
  3778. ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__)
  3779. #else
  3780. # define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter()
  3781. #endif // ELPP_TRACE_LOG
  3782. #if ELPP_VERBOSE_LOG
  3783. # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \
  3784. el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__)
  3785. #else
  3786. # define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter()
  3787. #endif // ELPP_VERBOSE_LOG
  3788. // Occasional logs
  3789. #if ELPP_INFO_LOG
  3790. # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\
  3791. ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__)
  3792. #else
  3793. # define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
  3794. #endif // ELPP_INFO_LOG
  3795. #if ELPP_WARNING_LOG
  3796. # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\
  3797. ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__)
  3798. #else
  3799. # define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
  3800. #endif // ELPP_WARNING_LOG
  3801. #if ELPP_DEBUG_LOG
  3802. # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\
  3803. ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__)
  3804. #else
  3805. # define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
  3806. #endif // ELPP_DEBUG_LOG
  3807. #if ELPP_ERROR_LOG
  3808. # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\
  3809. ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__)
  3810. #else
  3811. # define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
  3812. #endif // ELPP_ERROR_LOG
  3813. #if ELPP_FATAL_LOG
  3814. # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\
  3815. ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__)
  3816. #else
  3817. # define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
  3818. #endif // ELPP_FATAL_LOG
  3819. #if ELPP_TRACE_LOG
  3820. # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\
  3821. ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__)
  3822. #else
  3823. # define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter()
  3824. #endif // ELPP_TRACE_LOG
  3825. #if ELPP_VERBOSE_LOG
  3826. # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\
  3827. CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__)
  3828. #else
  3829. # define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter()
  3830. #endif // ELPP_VERBOSE_LOG
  3831. // After N logs
  3832. #if ELPP_INFO_LOG
  3833. # define CINFO_AFTER_N(writer, n, dispatchAction, ...)\
  3834. ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
  3835. #else
  3836. # define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
  3837. #endif // ELPP_INFO_LOG
  3838. #if ELPP_WARNING_LOG
  3839. # define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\
  3840. ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
  3841. #else
  3842. # define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
  3843. #endif // ELPP_WARNING_LOG
  3844. #if ELPP_DEBUG_LOG
  3845. # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\
  3846. ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
  3847. #else
  3848. # define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
  3849. #endif // ELPP_DEBUG_LOG
  3850. #if ELPP_ERROR_LOG
  3851. # define CERROR_AFTER_N(writer, n, dispatchAction, ...)\
  3852. ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
  3853. #else
  3854. # define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
  3855. #endif // ELPP_ERROR_LOG
  3856. #if ELPP_FATAL_LOG
  3857. # define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\
  3858. ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
  3859. #else
  3860. # define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
  3861. #endif // ELPP_FATAL_LOG
  3862. #if ELPP_TRACE_LOG
  3863. # define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\
  3864. ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
  3865. #else
  3866. # define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter()
  3867. #endif // ELPP_TRACE_LOG
  3868. #if ELPP_VERBOSE_LOG
  3869. # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\
  3870. CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
  3871. #else
  3872. # define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
  3873. #endif // ELPP_VERBOSE_LOG
  3874. // N Times logs
  3875. #if ELPP_INFO_LOG
  3876. # define CINFO_N_TIMES(writer, n, dispatchAction, ...)\
  3877. ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__)
  3878. #else
  3879. # define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
  3880. #endif // ELPP_INFO_LOG
  3881. #if ELPP_WARNING_LOG
  3882. # define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\
  3883. ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__)
  3884. #else
  3885. # define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
  3886. #endif // ELPP_WARNING_LOG
  3887. #if ELPP_DEBUG_LOG
  3888. # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\
  3889. ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__)
  3890. #else
  3891. # define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
  3892. #endif // ELPP_DEBUG_LOG
  3893. #if ELPP_ERROR_LOG
  3894. # define CERROR_N_TIMES(writer, n, dispatchAction, ...)\
  3895. ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__)
  3896. #else
  3897. # define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
  3898. #endif // ELPP_ERROR_LOG
  3899. #if ELPP_FATAL_LOG
  3900. # define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\
  3901. ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__)
  3902. #else
  3903. # define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
  3904. #endif // ELPP_FATAL_LOG
  3905. #if ELPP_TRACE_LOG
  3906. # define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\
  3907. ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__)
  3908. #else
  3909. # define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter()
  3910. #endif // ELPP_TRACE_LOG
  3911. #if ELPP_VERBOSE_LOG
  3912. # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\
  3913. CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__)
  3914. #else
  3915. # define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter()
  3916. #endif // ELPP_VERBOSE_LOG
  3917. //
  3918. // Custom Loggers - Requires (level, dispatchAction, loggerId/s)
  3919. //
  3920. // undef existing
  3921. #undef CLOG
  3922. #undef CLOG_VERBOSE
  3923. #undef CVLOG
  3924. #undef CLOG_IF
  3925. #undef CLOG_VERBOSE_IF
  3926. #undef CVLOG_IF
  3927. #undef CLOG_EVERY_N
  3928. #undef CVLOG_EVERY_N
  3929. #undef CLOG_AFTER_N
  3930. #undef CVLOG_AFTER_N
  3931. #undef CLOG_N_TIMES
  3932. #undef CVLOG_N_TIMES
  3933. // Normal logs
  3934. #define CLOG(LEVEL, ...)\
  3935. C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3936. #define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3937. // Conditional logs
  3938. #define CLOG_IF(condition, LEVEL, ...)\
  3939. C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3940. #define CVLOG_IF(condition, vlevel, ...)\
  3941. CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3942. // Hit counts based logs
  3943. #define CLOG_EVERY_N(n, LEVEL, ...)\
  3944. C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3945. #define CVLOG_EVERY_N(n, vlevel, ...)\
  3946. CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3947. #define CLOG_AFTER_N(n, LEVEL, ...)\
  3948. C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3949. #define CVLOG_AFTER_N(n, vlevel, ...)\
  3950. CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3951. #define CLOG_N_TIMES(n, LEVEL, ...)\
  3952. C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3953. #define CVLOG_N_TIMES(n, vlevel, ...)\
  3954. CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  3955. //
  3956. // Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
  3957. //
  3958. // undef existing
  3959. #undef LOG
  3960. #undef VLOG
  3961. #undef LOG_IF
  3962. #undef VLOG_IF
  3963. #undef LOG_EVERY_N
  3964. #undef VLOG_EVERY_N
  3965. #undef LOG_AFTER_N
  3966. #undef VLOG_AFTER_N
  3967. #undef LOG_N_TIMES
  3968. #undef VLOG_N_TIMES
  3969. #undef ELPP_CURR_FILE_LOGGER_ID
  3970. #if defined(ELPP_DEFAULT_LOGGER)
  3971. # define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER
  3972. #else
  3973. # define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId
  3974. #endif
  3975. #undef ELPP_TRACE
  3976. #define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID)
  3977. // Normal logs
  3978. #define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  3979. #define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
  3980. // Conditional logs
  3981. #define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  3982. #define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  3983. // Hit counts based logs
  3984. #define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  3985. #define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  3986. #define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  3987. #define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  3988. #define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  3989. #define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  3990. // Generic PLOG()
  3991. #undef CPLOG
  3992. #undef CPLOG_IF
  3993. #undef PLOG
  3994. #undef PLOG_IF
  3995. #undef DCPLOG
  3996. #undef DCPLOG_IF
  3997. #undef DPLOG
  3998. #undef DPLOG_IF
  3999. #define CPLOG(LEVEL, ...)\
  4000. C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  4001. #define CPLOG_IF(condition, LEVEL, ...)\
  4002. C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  4003. #define DCPLOG(LEVEL, ...)\
  4004. if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__)
  4005. #define DCPLOG_IF(condition, LEVEL, ...)\
  4006. C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__)
  4007. #define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4008. #define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4009. #define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4010. #define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4011. // Generic SYSLOG()
  4012. #undef CSYSLOG
  4013. #undef CSYSLOG_IF
  4014. #undef CSYSLOG_EVERY_N
  4015. #undef CSYSLOG_AFTER_N
  4016. #undef CSYSLOG_N_TIMES
  4017. #undef SYSLOG
  4018. #undef SYSLOG_IF
  4019. #undef SYSLOG_EVERY_N
  4020. #undef SYSLOG_AFTER_N
  4021. #undef SYSLOG_N_TIMES
  4022. #undef DCSYSLOG
  4023. #undef DCSYSLOG_IF
  4024. #undef DCSYSLOG_EVERY_N
  4025. #undef DCSYSLOG_AFTER_N
  4026. #undef DCSYSLOG_N_TIMES
  4027. #undef DSYSLOG
  4028. #undef DSYSLOG_IF
  4029. #undef DSYSLOG_EVERY_N
  4030. #undef DSYSLOG_AFTER_N
  4031. #undef DSYSLOG_N_TIMES
  4032. #if defined(ELPP_SYSLOG)
  4033. # define CSYSLOG(LEVEL, ...)\
  4034. C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4035. # define CSYSLOG_IF(condition, LEVEL, ...)\
  4036. C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4037. # define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4038. # define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4039. # define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4040. # define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
  4041. # define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
  4042. # define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
  4043. # define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
  4044. # define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
  4045. # define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4046. # define DCSYSLOG_IF(condition, LEVEL, ...)\
  4047. C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__)
  4048. # define DCSYSLOG_EVERY_N(n, LEVEL, ...)\
  4049. if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4050. # define DCSYSLOG_AFTER_N(n, LEVEL, ...)\
  4051. if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4052. # define DCSYSLOG_N_TIMES(n, LEVEL, ...)\
  4053. if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__)
  4054. # define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId)
  4055. # define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId)
  4056. # define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
  4057. # define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId)
  4058. # define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId)
  4059. #else
  4060. # define CSYSLOG(LEVEL, ...) el::base::NullWriter()
  4061. # define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
  4062. # define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
  4063. # define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
  4064. # define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
  4065. # define SYSLOG(LEVEL) el::base::NullWriter()
  4066. # define SYSLOG_IF(condition, LEVEL) el::base::NullWriter()
  4067. # define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
  4068. # define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
  4069. # define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
  4070. # define DCSYSLOG(LEVEL, ...) el::base::NullWriter()
  4071. # define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter()
  4072. # define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter()
  4073. # define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter()
  4074. # define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter()
  4075. # define DSYSLOG(LEVEL) el::base::NullWriter()
  4076. # define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter()
  4077. # define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter()
  4078. # define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter()
  4079. # define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter()
  4080. #endif // defined(ELPP_SYSLOG)
  4081. //
  4082. // Custom Debug Only Loggers - Requires (level, loggerId/s)
  4083. //
  4084. // undef existing
  4085. #undef DCLOG
  4086. #undef DCVLOG
  4087. #undef DCLOG_IF
  4088. #undef DCVLOG_IF
  4089. #undef DCLOG_EVERY_N
  4090. #undef DCVLOG_EVERY_N
  4091. #undef DCLOG_AFTER_N
  4092. #undef DCVLOG_AFTER_N
  4093. #undef DCLOG_N_TIMES
  4094. #undef DCVLOG_N_TIMES
  4095. // Normal logs
  4096. #define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__)
  4097. #define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__)
  4098. #define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__)
  4099. // Conditional logs
  4100. #define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__)
  4101. #define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__)
  4102. // Hit counts based logs
  4103. #define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__)
  4104. #define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__)
  4105. #define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__)
  4106. #define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__)
  4107. #define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__)
  4108. #define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__)
  4109. //
  4110. // Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros
  4111. //
  4112. #if !defined(ELPP_NO_DEBUG_MACROS)
  4113. // undef existing
  4114. #undef DLOG
  4115. #undef DVLOG
  4116. #undef DLOG_IF
  4117. #undef DVLOG_IF
  4118. #undef DLOG_EVERY_N
  4119. #undef DVLOG_EVERY_N
  4120. #undef DLOG_AFTER_N
  4121. #undef DVLOG_AFTER_N
  4122. #undef DLOG_N_TIMES
  4123. #undef DVLOG_N_TIMES
  4124. // Normal logs
  4125. #define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4126. #define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID)
  4127. // Conditional logs
  4128. #define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4129. #define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  4130. // Hit counts based logs
  4131. #define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4132. #define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  4133. #define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4134. #define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  4135. #define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID)
  4136. #define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID)
  4137. #endif // defined(ELPP_NO_DEBUG_MACROS)
  4138. #if !defined(ELPP_NO_CHECK_MACROS)
  4139. // Check macros
  4140. #undef CCHECK
  4141. #undef CPCHECK
  4142. #undef CCHECK_EQ
  4143. #undef CCHECK_NE
  4144. #undef CCHECK_LT
  4145. #undef CCHECK_GT
  4146. #undef CCHECK_LE
  4147. #undef CCHECK_GE
  4148. #undef CCHECK_BOUNDS
  4149. #undef CCHECK_NOTNULL
  4150. #undef CCHECK_STRCASEEQ
  4151. #undef CCHECK_STRCASENE
  4152. #undef CHECK
  4153. #undef PCHECK
  4154. #undef CHECK_EQ
  4155. #undef CHECK_NE
  4156. #undef CHECK_LT
  4157. #undef CHECK_GT
  4158. #undef CHECK_LE
  4159. #undef CHECK_GE
  4160. #undef CHECK_BOUNDS
  4161. #undef CHECK_NOTNULL
  4162. #undef CHECK_STRCASEEQ
  4163. #undef CHECK_STRCASENE
  4164. #define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
  4165. #define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] "
  4166. #define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
  4167. #define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
  4168. #define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__)
  4169. #define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__)
  4170. #define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__)
  4171. #define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__)
  4172. #define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__)
  4173. #define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__)
  4174. #define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__)
  4175. #define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4176. #define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4177. #define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4178. #define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4179. #define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4180. #define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4181. #define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
  4182. #define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__)
  4183. #define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
  4184. << "Check failed: [" << #str1 << " == " << #str2 << "] "
  4185. #define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \
  4186. << "Check failed: [" << #str1 << " != " << #str2 << "] "
  4187. #define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
  4188. << "Check failed: [" << #str1 << " == " << #str2 << "] "
  4189. #define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \
  4190. << "Check failed: [" << #str1 << " != " << #str2 << "] "
  4191. #define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID)
  4192. #define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4193. #define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4194. #define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4195. #define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4196. #undef DCCHECK
  4197. #undef DCCHECK_EQ
  4198. #undef DCCHECK_NE
  4199. #undef DCCHECK_LT
  4200. #undef DCCHECK_GT
  4201. #undef DCCHECK_LE
  4202. #undef DCCHECK_GE
  4203. #undef DCCHECK_BOUNDS
  4204. #undef DCCHECK_NOTNULL
  4205. #undef DCCHECK_STRCASEEQ
  4206. #undef DCCHECK_STRCASENE
  4207. #undef DCPCHECK
  4208. #undef DCHECK
  4209. #undef DCHECK_EQ
  4210. #undef DCHECK_NE
  4211. #undef DCHECK_LT
  4212. #undef DCHECK_GT
  4213. #undef DCHECK_LE
  4214. #undef DCHECK_GE
  4215. #undef DCHECK_BOUNDS_
  4216. #undef DCHECK_NOTNULL
  4217. #undef DCHECK_STRCASEEQ
  4218. #undef DCHECK_STRCASENE
  4219. #undef DPCHECK
  4220. #define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__)
  4221. #define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__)
  4222. #define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__)
  4223. #define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__)
  4224. #define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__)
  4225. #define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__)
  4226. #define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__)
  4227. #define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__)
  4228. #define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__)
  4229. #define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__)
  4230. #define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__)
  4231. #define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__)
  4232. #define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__)
  4233. #define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__)
  4234. #define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
  4235. #define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4236. #define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4237. #define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4238. #define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4239. #define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4240. #define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID)
  4241. #define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID)
  4242. #define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID)
  4243. #define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4244. #define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4245. #define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4246. #define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID)
  4247. #define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID)
  4248. #endif // defined(ELPP_NO_CHECK_MACROS)
  4249. #if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
  4250. # define ELPP_USE_DEF_CRASH_HANDLER false
  4251. #else
  4252. # define ELPP_USE_DEF_CRASH_HANDLER true
  4253. #endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING)
  4254. #define ELPP_CRASH_HANDLER_INIT
  4255. #define ELPP_INIT_EASYLOGGINGPP(val) \
  4256. namespace el { \
  4257. namespace base { \
  4258. el::base::type::StoragePointer elStorage(val); \
  4259. } \
  4260. el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \
  4261. }
  4262. #if ELPP_ASYNC_LOGGING
  4263. # define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\
  4264. new el::base::AsyncDispatchWorker()))
  4265. #else
  4266. # define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder())))
  4267. #endif // ELPP_ASYNC_LOGGING
  4268. #define INITIALIZE_NULL_EASYLOGGINGPP \
  4269. namespace el {\
  4270. namespace base {\
  4271. el::base::type::StoragePointer elStorage;\
  4272. }\
  4273. el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
  4274. }
  4275. #define SHARE_EASYLOGGINGPP(initializedStorage)\
  4276. namespace el {\
  4277. namespace base {\
  4278. el::base::type::StoragePointer elStorage(initializedStorage);\
  4279. }\
  4280. el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
  4281. }
  4282. #if defined(ELPP_UNICODE)
  4283. # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale(""))
  4284. #else
  4285. # define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv)
  4286. #endif // defined(ELPP_UNICODE)
  4287. #endif // EASYLOGGINGPP_H