Digitalisierte Elektroverteilung zur permanenten Verbraucherüberwachung
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

easylogging++.h 176KB

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