jlog.hpp 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef JLOG_HPP
  14. #define JLOG_HPP
  15. // Control whether XML reports have newlines between category/system/job/text sections
  16. #ifdef _DEBUG
  17. #define LOG_MSG_NEWLINE
  18. #endif
  19. #include "stdio.h"
  20. #include "time.h"
  21. #include "jiface.hpp"
  22. #include "jlib.hpp"
  23. #include "jexcept.hpp"
  24. #include "jutil.hpp"
  25. #include "jdebug.hpp"
  26. #include "jptree.hpp"
  27. #include "jsocket.hpp"
  28. typedef enum
  29. {
  30. LogMsgAttType_class = 0x01,
  31. LogMsgAttType_Audience = 0x02,
  32. LogMsgAttType_fields = 0x04,
  33. } LogMsgAttType;
  34. /****************************************************************************************/
  35. /* LOG MESSAGE AUDIENCES: *
  36. * MSGAUD_operator - This should be used when the message may be normally monitored by, *
  37. * acted on, or resolved by sys admins. E.g. out of memory alerts, *
  38. * configuration issues, possible hardware/network related issues, *
  39. * MSGAUD_user - Messages targetted at the end-users of HPCC (including ecl coders *
  40. * E.g. ECL code issues, workunit issues, data file related issues, *
  41. * authentication issues *
  42. * MSGAUD_programmer - Messages targetted at platform developers. E.g. debugging *
  43. * and tracing messages, internal errors that would not normally be *
  44. * resolved by sys admins or users, unexpected internal error *
  45. * MSGAUD_audit - Audit messages related to file access and authentication *
  46. * ------------------------------------------------------------------------------------ *
  47. * LOG MESSAGE CLASS: */
  48. typedef enum
  49. {
  50. MSGCLS_disaster = 0x01, // Any unrecoverable or critical system errors
  51. MSGCLS_error = 0x02, // Recoverable/not critical Errors
  52. MSGCLS_warning = 0x04, // Warnings
  53. MSGCLS_information = 0x08, // Config, environmental and internal status info
  54. MSGCLS_progress = 0x10, // Progress of workunits. Status of file operations
  55. MSGCLS_metric = 0x20, // A metric line
  56. MSGCLS_addid = 0x40, // Internal use within log system
  57. MSGCLS_removeid = 0x80, // Internal use within log system
  58. MSGCLS_all = 0xFF // Use as a filter to select all messages
  59. } LogMsgClass;
  60. /* ------------------------------------------------------------------------------------ *
  61. * NOTES: *
  62. * Every message will have an audience and message class. The job number is optional *
  63. * *
  64. * Standard categories of Audience + Message class are defined with LogMsgCategory. *
  65. * *
  66. * The following are common logging functions (for common audience+message class) *
  67. * 1) For temporary logs whilst debugging (may be disabled for releases ): *
  68. * DBGLOG([LogMsgCode,] format,..) - uses MCdebugInfo *
  69. * *
  70. * 2) For fatal errors or unrecoverable errors: *
  71. * DISLOG([LogMsgCode,] format,..) - uses MCdisaster *
  72. * *
  73. * 3) For warning messages: *
  74. * (i) Messages for End-users (including ECL coders) should use: *
  75. * UWARNLOG([LogMsgCode,] format,..) - uses MCuserWarning *
  76. * *
  77. * (ii) Messages for SysAdmins: *
  78. * OWARNLOG([LogMsgCode,] format,..) - uses MCoperatorWarning *
  79. * *
  80. * (iii) Messages for platform developers: *
  81. * IWARNLOG([LogMsgCode,] format,..) - uses MCinternalWarning *
  82. * *
  83. * 4) For error messages: *
  84. * (i) Messages for End-users (including ECL coders) should use: *
  85. * UERRLOG([LogMsgCode,] format,..) - uses MCuserError *
  86. * *
  87. * (ii) Messages for SysAdmins: *
  88. * OERRLOG([LogMsgCode,] format,..) - uses MCoperatorError *
  89. * *
  90. * (iii) Messages for platform developers: *
  91. * IERRLOG([LogMsgCode,] format,..) - uses MCinternalError *
  92. * *
  93. * (iv) Messages for audit: *
  94. * AERRLOG([LogMsgCode,] format,..) - uses MCinternalError *
  95. * *
  96. * *
  97. * 5) For progress messages: *
  98. * PROGLOG([LogMsgCode,] format,..) - uses MCuserProgress *
  99. * *
  100. * More general logging functions include: *
  101. * 1) Full control over the log message: *
  102. * LOG(LogMsgCategory, [job,] [code,] format, ...) *
  103. * 2) Takes code, message, & audience from an exception, class is error *
  104. * EXCLOG(exception, prefix) *
  105. * 3) More control over logging exceptions: *
  106. * LOG(LogMsgCategory, [job,] exception [, prefix]) *
  107. * *
  108. * LogMsgCategory detail level may be modified from the default with a numeric paramter *
  109. * For example as MCdebugInfo(50). *
  110. ****************************************************************************************/
  111. // ENUMS, TYPEDEFS, CONSTS ETC.
  112. // Enums, typedefs, and consts for LogMsgCategory, plus enum-to-string functions
  113. // When changing this enum, be sure to update (a) the string functions, and (b) NUM value
  114. typedef MessageAudience LogMsgAudience;
  115. inline const char * LogMsgAudienceToVarString(LogMsgAudience audience)
  116. {
  117. switch(audience)
  118. {
  119. case MSGAUD_operator:
  120. return("Operator");
  121. case MSGAUD_user:
  122. return("User");
  123. case MSGAUD_programmer:
  124. return("Programmer");
  125. case MSGAUD_audit:
  126. return("Audit");
  127. default:
  128. return("UNKNOWN");
  129. }
  130. }
  131. inline const char * LogMsgAudienceToFixString(LogMsgAudience audience)
  132. {
  133. switch(audience)
  134. {
  135. case MSGAUD_operator:
  136. return("OPR ");
  137. case MSGAUD_user:
  138. return("USR ");
  139. case MSGAUD_programmer:
  140. return("PRG ");
  141. case MSGAUD_audit:
  142. return("AUD ");
  143. default:
  144. return("UNK ");
  145. }
  146. }
  147. inline unsigned LogMsgAudFromAbbrev(char const * abbrev)
  148. {
  149. if(strnicmp(abbrev, "OPR", 3)==0)
  150. return MSGAUD_operator;
  151. if(strnicmp(abbrev, "USR", 3)==0)
  152. return MSGAUD_user;
  153. if(strnicmp(abbrev, "PRO", 3)==0)
  154. return MSGAUD_programmer;
  155. if(strnicmp(abbrev, "ADT", 3)==0)
  156. return MSGAUD_audit;
  157. if(strnicmp(abbrev, "ALL", 3)==0)
  158. return MSGAUD_all;
  159. return 0;
  160. }
  161. inline const char * LogMsgClassToVarString(LogMsgClass msgClass)
  162. {
  163. switch(msgClass)
  164. {
  165. case MSGCLS_disaster:
  166. return("Disaster");
  167. case MSGCLS_error:
  168. return("Error");
  169. case MSGCLS_warning:
  170. return("Warning");
  171. case MSGCLS_information:
  172. return("Information");
  173. case MSGCLS_progress:
  174. return("Progress");
  175. case MSGCLS_metric:
  176. return("Metric");
  177. default:
  178. return("UNKNOWN");
  179. }
  180. }
  181. inline const char * LogMsgClassToFixString(LogMsgClass msgClass)
  182. {
  183. switch(msgClass)
  184. {
  185. case MSGCLS_disaster:
  186. return("DIS ");
  187. case MSGCLS_error:
  188. return("ERR ");
  189. case MSGCLS_warning:
  190. return("WRN ");
  191. case MSGCLS_information:
  192. return("INF ");
  193. case MSGCLS_progress:
  194. return("PRO ");
  195. case MSGCLS_metric:
  196. return("MET ");
  197. default:
  198. return("UNK ");
  199. }
  200. }
  201. inline unsigned LogMsgClassFromAbbrev(char const * abbrev)
  202. {
  203. if(strnicmp(abbrev, "DIS", 3)==0)
  204. return MSGCLS_disaster;
  205. if(strnicmp(abbrev, "ERR", 3)==0)
  206. return MSGCLS_error;
  207. if(strnicmp(abbrev, "WRN", 3)==0)
  208. return MSGCLS_warning;
  209. if(strnicmp(abbrev, "INF", 3)==0)
  210. return MSGCLS_information;
  211. if(strnicmp(abbrev, "PRO", 3)==0)
  212. return MSGCLS_progress;
  213. if(strnicmp(abbrev, "MET", 3)==0)
  214. return MSGCLS_metric;
  215. if(strnicmp(abbrev, "ALL", 3)==0)
  216. return MSGCLS_all;
  217. return 0;
  218. }
  219. typedef unsigned LogMsgDetail;
  220. #define DefaultDetail DebugMsgThreshold
  221. #define TopDetail (LogMsgDetail)-1
  222. /*
  223. * Log message thresholds, assigned to log message category types.
  224. * It represents the lowest logging level (detail) required to output
  225. * messages of the given category.
  226. */
  227. constexpr LogMsgDetail CriticalMsgThreshold = 1; //Use to declare categories reporting critical events (log level => 1)
  228. constexpr LogMsgDetail FatalMsgThreshold = 1; //Use to declare categories reporting Fatal events (log level => 1)
  229. constexpr LogMsgDetail ErrMsgThreshold = 10; //Use to declare categories reporting Err messages (log level => 10)
  230. constexpr LogMsgDetail WarnMsgThreshold = 20; //Use to declare categories reporting Warn messages (log level => 20)
  231. constexpr LogMsgDetail AudMsgThreshold = 30; //Use to declare categories reporting Aud messages (log level => 30)
  232. constexpr LogMsgDetail ProgressMsgThreshold = 50; //Use to declare categories reporting Progress messages (log level => 50)
  233. constexpr LogMsgDetail InfoMsgThreshold = 60; //Use to declare categories reporting Info messages (log level => 60)
  234. constexpr LogMsgDetail DebugMsgThreshold = 80; //Use to declare categories reporting Debug messages (log level => 80)
  235. constexpr LogMsgDetail ExtraneousMsgThreshold = 90; //Use to declare categories reporting Extraneous messages (log level => 90)
  236. // Typedef for LogMsgSysInfo
  237. typedef unsigned LogMsgId;
  238. // Typedefs and consts for LogMsgJobInfo
  239. typedef unsigned __int64 LogMsgJobId;
  240. typedef unsigned __int64 LogMsgUserId;
  241. typedef unsigned __int64 LogMsgSessionId;
  242. #define UnknownJob (LogMsgJobId)-1
  243. #define UnknownUser (LogMsgUserId)-1
  244. #define UnknownSession (LogMsgSessionId)-1
  245. // Other enums, typedefs, and consts
  246. typedef int LogMsgCode;
  247. #define NoLogMsgCode -1
  248. // When changing this enum, be sure to update (a) the string function, and (b) the abbrev function
  249. typedef enum
  250. {
  251. MSGFIELD_audience = 0x000001,
  252. MSGFIELD_class = 0x000002,
  253. MSGFIELD_detail = 0x000004,
  254. MSGFIELD_allCategory = 0x000007,
  255. MSGFIELD_msgID = 0x000008,
  256. MSGFIELD_time = 0x000010,
  257. MSGFIELD_date = 0x000020,
  258. MSGFIELD_timeDate = 0x000030,
  259. MSGFIELD_process = 0x000040,
  260. MSGFIELD_thread = 0x000080,
  261. MSGFIELD_node = 0x000100,
  262. MSGFIELD_allSysInfo = 0x00F1F8,
  263. MSGFIELD_job = 0x000200,
  264. MSGFIELD_user = 0x000400,
  265. MSGFIELD_session = 0x000800,
  266. MSGFIELD_allJobInfo = 0x000E00,
  267. MSGFIELD_code = 0x001000,
  268. MSGFIELD_milliTime = 0x002000,
  269. MSGFIELD_microTime = 0x004000,
  270. MSGFIELD_nanoTime = 0x008000, // Not supported
  271. MSGFIELD_component = 0x010000,
  272. MSGFIELD_quote = 0x020000,
  273. MSGFIELD_prefix = 0x040000,
  274. MSGFIELD_last = 0x040000,
  275. MSGFIELD_all = 0xFFFFFF
  276. } LogMsgField;
  277. #ifdef _WIN32
  278. #define MSGFIELD_STANDARD LogMsgField(MSGFIELD_timeDate | MSGFIELD_msgID | MSGFIELD_process | MSGFIELD_thread | MSGFIELD_code | MSGFIELD_quote | MSGFIELD_prefix | MSGFIELD_audience)
  279. #define MSGFIELD_LEGACY LogMsgField(MSGFIELD_timeDate | MSGFIELD_milliTime | MSGFIELD_msgID | MSGFIELD_process | MSGFIELD_thread | MSGFIELD_code | MSGFIELD_quote | MSGFIELD_prefix)
  280. #else
  281. #ifdef _CONTAINERIZED
  282. #define MSGFIELD_STANDARD LogMsgField(MSGFIELD_job | MSGFIELD_timeDate | MSGFIELD_milliTime | MSGFIELD_msgID | MSGFIELD_process | MSGFIELD_thread | MSGFIELD_code | MSGFIELD_quote | MSGFIELD_class | MSGFIELD_audience)
  283. #else
  284. #define MSGFIELD_STANDARD LogMsgField(MSGFIELD_timeDate | MSGFIELD_milliTime | MSGFIELD_msgID | MSGFIELD_process | MSGFIELD_thread | MSGFIELD_code | MSGFIELD_quote | MSGFIELD_prefix | MSGFIELD_audience)
  285. #endif
  286. #define MSGFIELD_LEGACY LogMsgField(MSGFIELD_timeDate | MSGFIELD_milliTime | MSGFIELD_msgID | MSGFIELD_process | MSGFIELD_thread | MSGFIELD_code | MSGFIELD_quote | MSGFIELD_prefix)
  287. #endif
  288. inline const char * LogMsgFieldToString(LogMsgField field)
  289. {
  290. switch(field)
  291. {
  292. case MSGFIELD_audience:
  293. return("Audience");
  294. case MSGFIELD_class:
  295. return("Class");
  296. case MSGFIELD_detail:
  297. return("Detail");
  298. case MSGFIELD_msgID:
  299. return("Message ID");
  300. case MSGFIELD_time:
  301. return("Time");
  302. case MSGFIELD_date:
  303. return("Date");
  304. case MSGFIELD_process:
  305. return("Process ID");
  306. case MSGFIELD_thread:
  307. return("Thread ID");
  308. case MSGFIELD_node:
  309. return("Node");
  310. case MSGFIELD_job:
  311. return("Job");
  312. case MSGFIELD_user:
  313. return("User");
  314. case MSGFIELD_session:
  315. return("Session");
  316. case MSGFIELD_code:
  317. return("Code");
  318. case MSGFIELD_milliTime:
  319. return("Timer (milli)");
  320. case MSGFIELD_microTime:
  321. return("Timer (micro)");
  322. case MSGFIELD_nanoTime:
  323. return("Timer (nano)");
  324. case MSGFIELD_component:
  325. return("Component");
  326. case MSGFIELD_quote:
  327. return("Quote");
  328. default:
  329. return("UNKNOWN");
  330. }
  331. }
  332. inline unsigned LogMsgFieldFromAbbrev(char const * abbrev)
  333. {
  334. if(strnicmp(abbrev, "AUD", 3)==0)
  335. return MSGFIELD_audience;
  336. if(strnicmp(abbrev, "CLS", 3)==0)
  337. return MSGFIELD_class;
  338. if(strnicmp(abbrev, "DET", 3)==0)
  339. return MSGFIELD_detail;
  340. if(strnicmp(abbrev, "MID", 3)==0)
  341. return MSGFIELD_msgID;
  342. if(strnicmp(abbrev, "TIM", 3)==0)
  343. return MSGFIELD_time;
  344. if(strnicmp(abbrev, "DAT", 3)==0)
  345. return MSGFIELD_date;
  346. if(strnicmp(abbrev, "PID", 3)==0)
  347. return MSGFIELD_process;
  348. if(strnicmp(abbrev, "TID", 3)==0)
  349. return MSGFIELD_thread;
  350. if(strnicmp(abbrev, "NOD", 3)==0)
  351. return MSGFIELD_node;
  352. if(strnicmp(abbrev, "JOB", 3)==0)
  353. return MSGFIELD_job;
  354. if(strnicmp(abbrev, "USE", 3)==0)
  355. return MSGFIELD_user;
  356. if(strnicmp(abbrev, "SES", 3)==0)
  357. return MSGFIELD_session;
  358. if(strnicmp(abbrev, "COD", 3)==0)
  359. return MSGFIELD_code;
  360. if(strnicmp(abbrev, "MLT", 3)==0)
  361. return MSGFIELD_milliTime;
  362. if(strnicmp(abbrev, "MCT", 3)==0)
  363. return MSGFIELD_microTime;
  364. if(strnicmp(abbrev, "NNT", 3)==0)
  365. return MSGFIELD_nanoTime;
  366. if(strnicmp(abbrev, "COM", 3)==0)
  367. return MSGFIELD_component;
  368. if(strnicmp(abbrev, "QUO", 3)==0)
  369. return MSGFIELD_quote;
  370. if(strnicmp(abbrev, "PFX", 3)==0)
  371. return MSGFIELD_prefix;
  372. if(strnicmp(abbrev, "ALL", 3)==0)
  373. return MSGFIELD_all;
  374. if(strnicmp(abbrev, "STD", 3)==0)
  375. return MSGFIELD_STANDARD;
  376. return 0;
  377. }
  378. inline unsigned processAbbrevsString(char const * abbrevs, LogMsgAttType type)
  379. {
  380. unsigned values = 0;
  381. bool negate = false;
  382. bool more = true;
  383. while(more)
  384. {
  385. if(strlen(abbrevs) < 3)
  386. break;
  387. unsigned value = 0;
  388. switch(type)
  389. {
  390. case LogMsgAttType_Audience:
  391. value = LogMsgAudFromAbbrev(abbrevs);
  392. break;
  393. case LogMsgAttType_fields:
  394. value = LogMsgFieldFromAbbrev(abbrevs);
  395. break;
  396. case LogMsgAttType_class:
  397. value = LogMsgClassFromAbbrev(abbrevs);
  398. break;
  399. default:
  400. throwUnexpected();
  401. }
  402. if(value)
  403. {
  404. if(negate)
  405. values &= ~value;
  406. else
  407. values |= value;
  408. }
  409. switch(abbrevs[3])
  410. {
  411. case '+':
  412. negate = false;
  413. abbrevs += 4;
  414. break;
  415. case '-':
  416. negate = true;
  417. abbrevs += 4;
  418. break;
  419. default:
  420. more = false;
  421. }
  422. }
  423. return values;
  424. }
  425. // This function parses strings such as "ADT+PRO+USR" and "ALL+ADT-PRO"
  426. inline unsigned logMsgAudsFromAbbrevs(const char * abbrevs)
  427. {
  428. return processAbbrevsString(abbrevs, LogMsgAttType_Audience);
  429. }
  430. // This function parses strings such as "DIS+ERR+WRN+INF" and "ALL+PRO-INF"
  431. inline unsigned logMsgClassesFromAbbrevs(const char * abbrevs)
  432. {
  433. return processAbbrevsString(abbrevs, LogMsgAttType_class);
  434. }
  435. // This function parses strings such as "AUD+CLS+DET+COD" and "STD+MIT-PID", and is used for fields attribute in XML handler descriptions
  436. inline unsigned logMsgFieldsFromAbbrevs(const char * abbrevs)
  437. {
  438. return processAbbrevsString(abbrevs, LogMsgAttType_fields);
  439. }
  440. inline char const * msgPrefix(LogMsgClass msgClass)
  441. {
  442. switch(msgClass)
  443. {
  444. case MSGCLS_error:
  445. return "ERROR: ";
  446. case MSGCLS_warning:
  447. return "WARNING: ";
  448. default:
  449. return "";
  450. }
  451. }
  452. // LOG MESSAGE CLASS AND ITS COMPONENTS
  453. // Info about category of log message, provided by user (this info is static, chosen during coding)
  454. class jlib_decl LogMsgCategory
  455. {
  456. public:
  457. constexpr LogMsgCategory(LogMsgAudience _audience = MSGAUD_programmer, LogMsgClass _class = MSGCLS_information, LogMsgDetail _detail = DefaultDetail) : audience(_audience), msgClass(_class), detail(_detail) {}
  458. constexpr LogMsgAudience queryAudience() const { return audience; }
  459. constexpr LogMsgClass queryClass() const { return msgClass; }
  460. constexpr LogMsgDetail queryDetail() const { return detail; }
  461. void serialize(MemoryBuffer & out) const { out.append(audience).append(msgClass).append(detail); }
  462. void deserialize(MemoryBuffer & in)
  463. {
  464. unsigned a, c, d; in.read(a).read(c).read(d);
  465. audience = (LogMsgAudience) a;
  466. msgClass = (LogMsgClass) c;
  467. detail = (LogMsgDetail) d;
  468. }
  469. constexpr LogMsgCategory operator ()(unsigned newDetail) const { return LogMsgCategory(audience, msgClass, newDetail); }
  470. private:
  471. LogMsgAudience audience;
  472. LogMsgClass msgClass;
  473. LogMsgDetail detail;
  474. };
  475. // Info about log message determined automatically by system
  476. class jlib_decl LogMsgSysInfo
  477. {
  478. public:
  479. LogMsgSysInfo(LogMsgId _id = (LogMsgId)-1, unsigned port = 0, LogMsgSessionId session = UnknownSession);
  480. inline LogMsgId queryMsgID() const { return id; }
  481. #ifdef _WIN32
  482. inline time_t queryTime() const { return timeStarted; }
  483. inline unsigned queryUSecs() const { return 0; }
  484. #else
  485. inline time_t queryTime() const { return timeStarted.tv_sec; }
  486. inline unsigned queryUSecs() const { return (unsigned)timeStarted.tv_usec; }
  487. #endif
  488. inline unsigned queryProcessID() const { return processID; }
  489. inline unsigned queryThreadID() const { return threadID; }
  490. inline LogMsgSessionId querySessionID() const { return sessionID; }
  491. inline const SocketEndpoint * queryNode() const { return &node; }
  492. void serialize(MemoryBuffer & out) const;
  493. void deserialize(MemoryBuffer & in);
  494. private:
  495. LogMsgId id;
  496. #ifdef _WIN32
  497. time_t timeStarted;
  498. #else
  499. struct timeval timeStarted;
  500. #endif
  501. unsigned processID;
  502. unsigned threadID;
  503. LogMsgSessionId sessionID;
  504. SocketEndpoint node;
  505. };
  506. // Info about job generating log message, provided by user (this info is dynamic, determined at run-time)
  507. class jlib_decl LogMsgJobInfo
  508. {
  509. public:
  510. LogMsgJobInfo(LogMsgJobId _job = UnknownJob, LogMsgUserId _user = UnknownUser) : jobID(_job), userID(_user) {}
  511. ~LogMsgJobInfo();
  512. LogMsgJobId queryJobID() const;
  513. const char * queryJobIDStr() const;
  514. inline LogMsgUserId queryUserID() const { return userID; }
  515. void setJobID(LogMsgUserId id);
  516. void serialize(MemoryBuffer & out) const;
  517. void deserialize(MemoryBuffer & in);
  518. private:
  519. union {
  520. LogMsgJobId jobID;
  521. const char * jobIDStr;
  522. };
  523. LogMsgUserId userID;
  524. bool isDeserialized = false;
  525. };
  526. class jlib_decl LogMsg : public CInterface
  527. {
  528. public:
  529. LogMsg() : category(), sysInfo(), jobInfo(), remoteFlag(false) {}
  530. LogMsg(LogMsgJobId id, const char *job); // Used for tracking job ids
  531. LogMsg(const LogMsgCategory & _cat, LogMsgId _id, const LogMsgJobInfo & _jobInfo, LogMsgCode _code, const char * _text, unsigned _compo, unsigned port, LogMsgSessionId session);
  532. LogMsg(const LogMsgCategory & _cat, LogMsgId _id, const LogMsgJobInfo & _jobInfo, LogMsgCode _code, size32_t sz, const char * _text, unsigned _compo, unsigned port, LogMsgSessionId session);
  533. LogMsg(const LogMsgCategory & _cat, LogMsgId _id, const LogMsgJobInfo & _jobInfo, LogMsgCode _code, const char * format, va_list args,
  534. unsigned _compo, unsigned port, LogMsgSessionId session) __attribute__((format(printf,6, 0)));
  535. StringBuffer & toStringPlain(StringBuffer & out, unsigned fields = MSGFIELD_all) const;
  536. StringBuffer & toStringXML(StringBuffer & out, unsigned fields = MSGFIELD_all) const;
  537. StringBuffer & toStringTable(StringBuffer & out, unsigned fields = MSGFIELD_all) const;
  538. static StringBuffer & toStringTableHead(StringBuffer & out, unsigned fields = MSGFIELD_all);
  539. void fprintPlain(FILE * handle, unsigned fields = MSGFIELD_all) const;
  540. void fprintXML(FILE * handle, unsigned fields = MSGFIELD_all) const;
  541. void fprintTable(FILE * handle, unsigned fields = MSGFIELD_all) const;
  542. static void fprintTableHead(FILE * handle, unsigned fields = MSGFIELD_all);
  543. inline const LogMsgCategory queryCategory() const { return category; }
  544. inline const LogMsgSysInfo & querySysInfo() const { return sysInfo; }
  545. inline const LogMsgJobInfo & queryJobInfo() const { return jobInfo; }
  546. inline unsigned queryComponent() const { return component; }
  547. inline LogMsgCode queryCode() const { return msgCode; }
  548. inline const char * queryText() const { return text.str(); }
  549. void serialize(MemoryBuffer & out) const { category.serialize(out); sysInfo.serialize(out); jobInfo.serialize(out); out.append(msgCode); text.serialize(out); }
  550. void deserialize(MemoryBuffer & in);
  551. bool queryRemoteFlag() const { return remoteFlag; }
  552. protected:
  553. LogMsgCategory category;
  554. LogMsgSysInfo sysInfo;
  555. LogMsgJobInfo jobInfo;
  556. LogMsgCode msgCode = NoLogMsgCode;
  557. unsigned component = 0; // Not sure this is used
  558. StringBuffer text;
  559. bool remoteFlag = false;
  560. };
  561. jlib_decl unsigned getPositionOfField(unsigned logfields, unsigned positionoffield);
  562. jlib_decl unsigned getMessageFieldsFromHeader(const char * line);
  563. jlib_decl unsigned getMessageFieldsFromHeader(FILE *handle);
  564. // INTERFACES
  565. // Filter for log messages --- contains method to accept or reject messages
  566. interface jlib_decl ILogMsgFilter : public IInterface
  567. {
  568. public:
  569. virtual bool includeMessage(const LogMsg & msg) const = 0;
  570. virtual bool mayIncludeCategory(const LogMsgCategory & cat) const = 0;
  571. virtual unsigned queryAudienceMask() const = 0;
  572. virtual unsigned queryClassMask() const = 0;
  573. virtual LogMsgDetail queryMaxDetail() const = 0;
  574. virtual bool isCategoryFilter() const { return false; }
  575. virtual void serialize(MemoryBuffer & out, bool preserveLocal) const = 0;
  576. virtual void addToPTree(IPropertyTree * tree) const = 0;
  577. virtual bool queryLocalFlag() const { return false; }
  578. };
  579. // Handler for log messages --- contains method to write or send messages
  580. interface jlib_decl ILogMsgHandler : public IInterface
  581. {
  582. public:
  583. virtual void handleMessage(const LogMsg & msg) = 0;
  584. virtual bool needsPrep() const = 0;
  585. virtual void prep() = 0;
  586. virtual unsigned queryMessageFields() const = 0;
  587. virtual void setMessageFields(unsigned _fields = MSGFIELD_all) = 0;
  588. virtual void addToPTree(IPropertyTree * parent) const = 0;
  589. virtual int flush() { return 0; }
  590. virtual char const * disable() { return 0; }
  591. virtual void enable() {}
  592. virtual bool getLogName(StringBuffer &name) const = 0;
  593. virtual offset_t getLogPosition(StringBuffer &logFileName) const = 0;
  594. };
  595. // Class on manager's list of children which sends new filters to children, and holds thread which receives log messages
  596. class jlib_decl ILogMsgLinkToChild : public IInterface
  597. {
  598. public:
  599. virtual void sendFilter(ILogMsgFilter * filter) const = 0;
  600. virtual void sendFilterOwn(ILogMsgFilter * filter) const = 0;
  601. virtual void connect() = 0;
  602. virtual void disconnect() = 0;
  603. virtual bool queryConnected() const = 0;
  604. virtual void markDisconnected() = 0;
  605. };
  606. // Manager to receive log messages, filter, and pass to handlers
  607. interface jlib_decl ILogMsgListener : public IInterface
  608. {
  609. virtual bool addMonitor(ILogMsgHandler * handler, ILogMsgFilter * filter) = 0;
  610. virtual bool addMonitorOwn(ILogMsgHandler * handler, ILogMsgFilter * filter) = 0;
  611. virtual bool removeMonitor(ILogMsgHandler * handler) = 0;
  612. typedef bool HandlerTest(ILogMsgHandler * handler);
  613. virtual unsigned removeMonitorsMatching(HandlerTest & test) = 0;
  614. virtual void removeAllMonitors() = 0;
  615. virtual bool isActiveMonitor(const ILogMsgHandler * handler) const = 0;
  616. virtual ILogMsgFilter * queryMonitorFilter(const ILogMsgHandler * handler) const = 0;
  617. virtual ILogMsgFilter * getMonitorFilter(const ILogMsgHandler * handler) const = 0;
  618. virtual bool changeMonitorFilter(const ILogMsgHandler * handler, ILogMsgFilter * newFilter) = 0;
  619. virtual bool changeMonitorFilterOwn(const ILogMsgHandler * handler, ILogMsgFilter * newFilter) = 0;
  620. virtual void prepAllHandlers() const = 0;
  621. virtual void addChildOwn(ILogMsgLinkToChild * child) = 0;
  622. virtual void removeChild(ILogMsgLinkToChild * child) = 0;
  623. virtual void removeAllChildren() = 0;
  624. virtual ILogMsgFilter * getCompoundFilter(bool locked = false) const = 0;
  625. virtual void suspendChildren() = 0;
  626. virtual void unsuspendChildren() = 0;
  627. virtual bool addMonitorToPTree(const ILogMsgHandler * handler, IPropertyTree * tree) const = 0;
  628. virtual void addAllMonitorsToPTree(IPropertyTree * tree) const = 0;
  629. virtual void setPort(unsigned _port) = 0;
  630. virtual unsigned queryPort() const = 0;
  631. virtual void setSession(LogMsgSessionId _session) = 0;
  632. virtual LogMsgSessionId querySession() const = 0;
  633. };
  634. interface jlib_decl ILogMsgManager : public ILogMsgListener
  635. {
  636. public:
  637. virtual void enterQueueingMode() = 0;
  638. virtual void setQueueBlockingLimit(unsigned lim) = 0;
  639. virtual void setQueueDroppingLimit(unsigned lim, unsigned numToDrop) = 0;
  640. virtual void resetQueueLimit() = 0;
  641. virtual bool flushQueue(unsigned timeout) = 0;
  642. virtual void resetMonitors() = 0;
  643. virtual void report(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 3, 4))) = 0;
  644. virtual void report_va(const LogMsgCategory & cat, const char * format, va_list args) = 0;
  645. virtual void report(const LogMsgCategory & cat, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 4, 5))) = 0;
  646. virtual void report_va(const LogMsgCategory & cat, LogMsgCode code , const char * format, va_list args) = 0;
  647. virtual void report(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL) = 0;
  648. virtual void report(unsigned compo, const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 4, 5))) = 0;
  649. virtual void report_va(unsigned compo, const LogMsgCategory & cat, const char * format, va_list args) = 0;
  650. virtual void report(unsigned compo, const LogMsgCategory & cat, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 5, 6))) = 0;
  651. virtual void report_va(unsigned compo, const LogMsgCategory & cat, LogMsgCode code , const char * format, va_list args) = 0;
  652. virtual void report(unsigned compo, const LogMsgCategory & cat, const IException * e, const char * prefix = NULL) = 0;
  653. virtual void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 4, 5))) = 0;
  654. virtual void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args) = 0;
  655. virtual void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 5, 6))) = 0;
  656. virtual void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, va_list args) = 0;
  657. virtual void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL) = 0;
  658. virtual void report(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 5, 6))) = 0;
  659. virtual void report_va(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args) = 0;
  660. virtual void report(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 6, 7))) = 0;
  661. virtual void report_va(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, va_list args) = 0;
  662. virtual void report(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL) = 0;
  663. virtual void mreport_direct(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * msg) = 0;
  664. virtual void mreport_direct(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * msg) = 0;
  665. virtual void mreport_va(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args) = 0;
  666. virtual void mreport_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args) = 0;
  667. virtual void report(const LogMsg & msg) const = 0;
  668. virtual LogMsgId getNextID() = 0;
  669. virtual bool rejectsCategory(const LogMsgCategory & cat) const = 0;
  670. virtual offset_t getLogPosition(StringBuffer &logFileName, const ILogMsgHandler * handler) const = 0;
  671. virtual LogMsgJobId addJobId(const char *job) = 0;
  672. virtual void removeJobId(LogMsgJobId) = 0;
  673. virtual const char * queryJobId(LogMsgJobId id) const = 0;
  674. };
  675. // CONCRETE CLASSES
  676. // Class which mimics the report methods of a manager, registering an additional component field
  677. class jlib_decl LogMsgComponentReporter
  678. {
  679. public:
  680. LogMsgComponentReporter(unsigned _compo) : component(_compo) {}
  681. void report(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 3, 4)));
  682. void report_va(const LogMsgCategory & cat, const char * format, va_list args);
  683. void report(const LogMsgCategory & cat, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 4, 5)));
  684. void report_va(const LogMsgCategory & cat, LogMsgCode code, const char * format, va_list args);
  685. void report(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL);
  686. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 4, 5)));
  687. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args);
  688. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 5, 6)));
  689. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, va_list args);
  690. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL);
  691. void report(const LogMsg & msg);
  692. void mreport_direct(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * msg);
  693. void mreport_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args);
  694. private:
  695. unsigned component;
  696. };
  697. // Class which mimics the report methods of a manager, prepending the given file and line (intended only for use in the FLLOG macro, below)
  698. class jlib_decl LogMsgPrepender
  699. {
  700. public:
  701. LogMsgPrepender(LogMsgComponentReporter * r, char const * f, unsigned l) : reporter(r), file(sanitizeSourceFile(f)), line(l) { }
  702. void report(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 3, 4)));
  703. void report_va(const LogMsgCategory & cat, const char * format, va_list args);
  704. void report(const LogMsgCategory & cat, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 4, 5)));
  705. void report_va(const LogMsgCategory & cat, LogMsgCode code, const char * format, va_list args);
  706. void report(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL);
  707. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 4, 5)));
  708. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args);
  709. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 5, 6)));
  710. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, va_list args);
  711. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL);
  712. IException * report(IException * e, const char * prefix = NULL, LogMsgClass cls = MSGCLS_error); // uses MCexception(e, cls), unknownJob, handy for EXCLOG
  713. private:
  714. LogMsgComponentReporter * reporter;
  715. char const * file;
  716. unsigned line;
  717. };
  718. // FUNCTIONS, DATA, AND MACROS
  719. // Function to get filters and handlers
  720. extern jlib_decl ILogMsgFilter * getDefaultLogMsgFilter();
  721. extern jlib_decl ILogMsgFilter * getPassAllLogMsgFilter();
  722. extern jlib_decl ILogMsgFilter * getLocalLogMsgFilter();
  723. extern jlib_decl ILogMsgFilter * getPassNoneLogMsgFilter();
  724. extern jlib_decl ILogMsgFilter * queryPassAllLogMsgFilter();
  725. extern jlib_decl ILogMsgFilter * queryLocalLogMsgFilter();
  726. extern jlib_decl ILogMsgFilter * queryPassNoneLogMsgFilter();
  727. extern jlib_decl ILogMsgFilter * getCategoryLogMsgFilter(unsigned audiences = MSGAUD_all, unsigned classes = MSGCLS_all, LogMsgDetail maxDetail = TopDetail, bool local = false);
  728. extern jlib_decl ILogMsgFilter * getPIDLogMsgFilter(unsigned pid, bool local = false);
  729. extern jlib_decl ILogMsgFilter * getTIDLogMsgFilter(unsigned tid, bool local = false);
  730. extern jlib_decl ILogMsgFilter * getNodeLogMsgFilter(const char * name, unsigned port = 0, bool local = false);
  731. extern jlib_decl ILogMsgFilter * getNodeLogMsgFilter(const IpAddress & ip, unsigned port = 0, bool local = false);
  732. extern jlib_decl ILogMsgFilter * getNodeLogMsgFilter(unsigned port, bool local = false);
  733. extern jlib_decl ILogMsgFilter * getIpLogMsgFilter(const char * name, bool local = false);
  734. extern jlib_decl ILogMsgFilter * getIpLogMsgFilter(const IpAddress & ip, bool local = false);
  735. extern jlib_decl ILogMsgFilter * getIpLogMsgFilter(bool local = false);
  736. extern jlib_decl ILogMsgFilter * getJobLogMsgFilter(LogMsgJobId job, bool local = false);
  737. extern jlib_decl ILogMsgFilter * getUserLogMsgFilter(LogMsgUserId user, bool local = false);
  738. extern jlib_decl ILogMsgFilter * getSessionLogMsgFilter(LogMsgSessionId session, bool local = false);
  739. extern jlib_decl ILogMsgFilter * getComponentLogMsgFilter(unsigned component, bool local = false);
  740. extern jlib_decl ILogMsgFilter * getRegexLogMsgFilter(const char *regex, bool local = false);
  741. extern jlib_decl ILogMsgFilter * getNotLogMsgFilter(ILogMsgFilter * arg);
  742. extern jlib_decl ILogMsgFilter * getNotLogMsgFilterOwn(ILogMsgFilter * arg);
  743. extern jlib_decl ILogMsgFilter * getAndLogMsgFilter(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  744. extern jlib_decl ILogMsgFilter * getAndLogMsgFilterOwn(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  745. extern jlib_decl ILogMsgFilter * getOrLogMsgFilter(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  746. extern jlib_decl ILogMsgFilter * getOrLogMsgFilterOwn(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  747. extern jlib_decl ILogMsgFilter * getSwitchLogMsgFilterOwn(ILogMsgFilter * switchFilter, ILogMsgFilter * yesFilter, ILogMsgFilter * noFilter);
  748. extern jlib_decl ILogMsgHandler * getHandleLogMsgHandler(FILE * handle = stderr, unsigned fields = MSGFIELD_all, bool writeXML = false);
  749. extern jlib_decl ILogMsgHandler * getFileLogMsgHandler(const char * filename, const char * headertext = 0, unsigned fields = MSGFIELD_all, bool writeXML = true, bool append = false, bool flushes = true);
  750. extern jlib_decl ILogMsgHandler * getRollingFileLogMsgHandler(const char * filebase, const char * fileextn, unsigned fields = MSGFIELD_all, bool append = false, bool flushes = true, const char *initialName = NULL, const char *alias = NULL, bool daily = false, long maxLogSize = 0);
  751. extern jlib_decl ILogMsgHandler * getBinLogMsgHandler(const char * filename, bool append = false);
  752. // Function to install switch filter into a monitor, switch some messages to new filter whilst leaving rest to previous filter
  753. extern jlib_decl void installLogMsgFilterSwitch(ILogMsgHandler * handler, ILogMsgFilter * switchFilter, ILogMsgFilter * newFilter);
  754. // Functions to make standard handlers and catagory filters and add to manager
  755. extern jlib_decl ILogMsgHandler * attachStandardFileLogMsgMonitor(const char * filename, const char * headertext = 0, unsigned fields = MSGFIELD_all, unsigned audiences = MSGAUD_all, unsigned classes = MSGCLS_all, LogMsgDetail detail = TopDetail, bool writeXML = true, bool append = false, bool flushes = true, bool local = false);
  756. extern jlib_decl ILogMsgHandler * attachStandardBinLogMsgMonitor(const char * filename, unsigned audiences = MSGAUD_all, unsigned classes = MSGCLS_all, LogMsgDetail detail = TopDetail, bool append = false, bool local = false);
  757. extern jlib_decl ILogMsgHandler * attachStandardHandleLogMsgMonitor(FILE * handle = stderr, unsigned fields = MSGFIELD_all, unsigned audiences = MSGAUD_all, unsigned classes = MSGCLS_all, LogMsgDetail detail = TopDetail, bool writeXML = false, bool local = false);
  758. // Function to construct filter from serialized and XML forms, and construct handler from XML form, and attach monitor(s) from XML form
  759. extern jlib_decl ILogMsgFilter * getDeserializedLogMsgFilter(MemoryBuffer & in);
  760. extern jlib_decl ILogMsgFilter * getLogMsgFilterFromPTree(IPropertyTree * tree);
  761. extern jlib_decl ILogMsgHandler * getLogMsgHandlerFromPTree(IPropertyTree * tree);
  762. extern jlib_decl ILogMsgHandler * attachLogMsgMonitorFromPTree(IPropertyTree * tree); // Takes tree containing <handler> and <filter> elements
  763. extern jlib_decl void attachManyLogMsgMonitorsFromPTree(IPropertyTree * tree); // Takes tree containing many <monitor> elements
  764. // Standard categories and unknown jobInfo
  765. constexpr LogMsgCategory MCdisaster(MSGAUD_all, MSGCLS_disaster, FatalMsgThreshold);
  766. constexpr LogMsgCategory MCuserError(MSGAUD_user, MSGCLS_error, ErrMsgThreshold);
  767. constexpr LogMsgCategory MCoperatorError(MSGAUD_operator, MSGCLS_error, ErrMsgThreshold);
  768. constexpr LogMsgCategory MCinternalError(MSGAUD_programmer, MSGCLS_error, ErrMsgThreshold);
  769. constexpr LogMsgCategory MCauditError(MSGAUD_audit, MSGCLS_error, ErrMsgThreshold);
  770. constexpr LogMsgCategory MCuserWarning(MSGAUD_user, MSGCLS_warning, WarnMsgThreshold);
  771. constexpr LogMsgCategory MCoperatorWarning(MSGAUD_operator, MSGCLS_warning, WarnMsgThreshold);
  772. constexpr LogMsgCategory MCinternalWarning(MSGAUD_programmer, MSGCLS_warning, WarnMsgThreshold);
  773. constexpr LogMsgCategory MCauditWarning(MSGAUD_audit, MSGCLS_warning, WarnMsgThreshold);
  774. constexpr LogMsgCategory MCuserProgress(MSGAUD_user, MSGCLS_progress, ProgressMsgThreshold);
  775. constexpr LogMsgCategory MCoperatorProgress(MSGAUD_operator, MSGCLS_progress, ProgressMsgThreshold);
  776. constexpr LogMsgCategory MCdebugProgress(MSGAUD_programmer, MSGCLS_progress, DebugMsgThreshold);
  777. constexpr LogMsgCategory MCuserInfo(MSGAUD_user, MSGCLS_information, InfoMsgThreshold);
  778. constexpr LogMsgCategory MCdebugInfo(MSGAUD_programmer, MSGCLS_information, DebugMsgThreshold);
  779. constexpr LogMsgCategory MCauditInfo(MSGAUD_audit, MSGCLS_information, AudMsgThreshold);
  780. constexpr LogMsgCategory MCstats(MSGAUD_operator, MSGCLS_progress, ProgressMsgThreshold);
  781. constexpr LogMsgCategory MCoperatorInfo(MSGAUD_operator, MSGCLS_information, InfoMsgThreshold);
  782. constexpr LogMsgCategory MCmetrics(MSGAUD_operator, MSGCLS_metric, ErrMsgThreshold);
  783. constexpr LogMsgCategory MCExtraneousInfo(MSGAUD_programmer, MSGCLS_information, ExtraneousMsgThreshold);
  784. /*
  785. * Function to determine log level (detail) for exceptions, based on log message class
  786. */
  787. inline LogMsgDetail mapClassToDefaultDetailLevel(LogMsgClass cls)
  788. {
  789. switch (cls)
  790. {
  791. case MSGCLS_disaster:
  792. case MSGCLS_all:
  793. return FatalMsgThreshold;
  794. case MSGCLS_error:
  795. return ErrMsgThreshold;
  796. case MSGCLS_warning:
  797. return WarnMsgThreshold;
  798. case MSGCLS_information:
  799. return InfoMsgThreshold;
  800. case MSGCLS_progress:
  801. return ProgressMsgThreshold;
  802. default:
  803. return DefaultDetail;
  804. }
  805. }
  806. inline LogMsgCategory MCexception(IException * e, LogMsgClass cls = MSGCLS_error)
  807. {
  808. return LogMsgCategory((e)->errorAudience(),cls, mapClassToDefaultDetailLevel(cls));
  809. }
  810. #define MCerror MCuserError
  811. #define MCwarning MCuserWarning
  812. #define MCprogress MCuserProgress
  813. extern jlib_decl const LogMsgJobInfo unknownJob;
  814. // Function to return manager, standard handler and the reporters, and the handler's message fields
  815. extern jlib_decl ILogMsgManager * queryLogMsgManager();
  816. extern jlib_decl ILogMsgHandler * queryStderrLogMsgHandler();
  817. #ifdef _CONTAINERIZED
  818. extern jlib_decl void setupContainerizedLogMsgHandler();
  819. #endif
  820. extern jlib_decl LogMsgComponentReporter * queryLogMsgComponentReporter(unsigned compo);
  821. //extern jlib_decl ILogMsgManager * createLogMsgManager(); // use with care! (needed by mplog listener facility)
  822. extern jlib_decl void setDefaultJobId(const char *id, bool threaded = false);
  823. extern jlib_decl void setDefaultJobId(LogMsgJobId id, bool threaded = false);
  824. // Macros to make logging as simple as possible
  825. #ifdef LOGMSGCOMPONENT
  826. #define LOGMSGREPORTER queryLogMsgComponentReporter(LOGMSGCOMPONENT)
  827. #define FLLOG LogMsgPrepender(LOGMSGREPORTER, __FILE__, __LINE__).report
  828. #else // LOGMSGCOMPONENT
  829. #define LOGMSGREPORTER queryLogMsgManager()
  830. #define FLLOG LogMsgPrepender(NULL, __FILE__, __LINE__).report
  831. #endif // LOGMSGCOMPONENT
  832. #ifdef LOGMSGCOMPONENT
  833. #else // LOGMSGCOMPONENT
  834. #endif // LOGMSGCOMPONENT
  835. #ifdef _PROFILING_WITH_TRUETIME_
  836. //It can't cope with the macro definition..... at least v6.5 can't.
  837. inline void LOG(const LogMsg & msg)
  838. {
  839. LOGMSGREPORTER->report(msg);
  840. }
  841. void LOG(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 2, 3)));
  842. inline void LOG(const LogMsgCategory & cat, const char * format, ...)
  843. {
  844. va_list args;
  845. va_start(args, format);
  846. LOGMSGREPORTER->report_va(cat, format, args);
  847. va_end(args);
  848. }
  849. void LOG(const LogMsgCategory & cat, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 3, 4)));
  850. inline void LOG(const LogMsgCategory & cat, LogMsgCode code , const char * format, ...)
  851. {
  852. va_list args;
  853. va_start(args, format);
  854. LOGMSGREPORTER->report_va(cat, code , format, args);
  855. va_end(args);
  856. }
  857. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 3, 4)));
  858. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...)
  859. {
  860. va_list args;
  861. va_start(args, format);
  862. LOGMSGREPORTER->report_va(cat, job, format, args);
  863. va_end(args);
  864. }
  865. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 4, 5)));
  866. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...)
  867. {
  868. va_list args;
  869. va_start(args, format);
  870. LOGMSGREPORTER->report_va(cat, job, code , format, args);
  871. va_end(args);
  872. }
  873. inline void LOG(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL)
  874. {
  875. LOGMSGREPORTER->report(cat, e, prefix);
  876. }
  877. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL)
  878. {
  879. LOGMSGREPORTER->report(cat, job, e, prefix);
  880. }
  881. inline void VALOG(const LogMsgCategory & cat, const char * format, va_list args)
  882. {
  883. LOGMSGREPORTER->report_va(cat, format, args);
  884. }
  885. inline void VALOG(const LogMsgCategory & cat, LogMsgCode code , const char * format, va_list args)
  886. {
  887. LOGMSGREPORTER->report_va(cat, code , format, args);
  888. }
  889. inline void VALOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args)
  890. {
  891. LOGMSGREPORTER->report_va(cat, job, format, args);
  892. }
  893. inline void VALOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, va_list args)
  894. {
  895. LOGMSGREPORTER->report_va(cat, job, code , format, args);
  896. }
  897. #else
  898. #define LOG LOGMSGREPORTER->report
  899. #define VALOG LOGMSGREPORTER->report_va
  900. #endif
  901. #define INTLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=%d", expr)
  902. #define OCTLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=0%o", expr)
  903. #define HEXLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=0x%X", expr)
  904. #define DBLLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=%lg", expr)
  905. #define CHRLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=%c", expr)
  906. #define STRLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"='%s'", expr)
  907. #define TOSTRLOG(category, job, prefix, func) { if (!REJECTLOG(category)) { StringBuffer buff; func(buff); LOGMSGREPORTER->report(category, job, prefix"'%s'", buff.str()); } }
  908. inline void DBGLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  909. inline void DBGLOG(char const * format, ...)
  910. {
  911. va_list args;
  912. va_start(args, format);
  913. VALOG(MCdebugInfo, unknownJob, format, args);
  914. va_end(args);
  915. }
  916. inline void DISLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  917. inline void DISLOG(char const * format, ...)
  918. {
  919. va_list args;
  920. va_start(args, format);
  921. VALOG(MCdisaster, unknownJob, format, args);
  922. va_end(args);
  923. }
  924. inline void UERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  925. inline void UERRLOG(char const * format, ...)
  926. {
  927. va_list args;
  928. va_start(args, format);
  929. VALOG(MCuserError, unknownJob, format, args);
  930. va_end(args);
  931. }
  932. // TODO: Remove the following #define once all ERRLOG has been removed from code
  933. #define ERRLOG UERRLOG
  934. inline void OERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  935. inline void OERRLOG(char const * format, ...)
  936. {
  937. va_list args;
  938. va_start(args, format);
  939. VALOG(MCoperatorError, unknownJob, format, args);
  940. va_end(args);
  941. }
  942. inline void IERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  943. inline void IERRLOG(char const * format, ...)
  944. {
  945. va_list args;
  946. va_start(args, format);
  947. VALOG(MCinternalError, unknownJob, format, args);
  948. va_end(args);
  949. }
  950. inline void AERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  951. inline void AERRLOG(char const * format, ...)
  952. {
  953. va_list args;
  954. va_start(args, format);
  955. VALOG(MCauditError, unknownJob, format, args);
  956. va_end(args);
  957. }
  958. inline void UWARNLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  959. inline void UWARNLOG(char const * format, ...)
  960. {
  961. va_list args;
  962. va_start(args, format);
  963. VALOG(MCuserWarning, unknownJob, format, args);
  964. va_end(args);
  965. }
  966. // TODO: Remove the following #define once all WARNLOG has been removed from code
  967. #define WARNLOG UWARNLOG
  968. inline void OWARNLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  969. inline void OWARNLOG(char const * format, ...)
  970. {
  971. va_list args;
  972. va_start(args, format);
  973. VALOG(MCoperatorWarning, unknownJob, format, args);
  974. va_end(args);
  975. }
  976. inline void IWARNLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  977. inline void IWARNLOG(char const * format, ...)
  978. {
  979. va_list args;
  980. va_start(args, format);
  981. VALOG(MCinternalWarning, unknownJob, format, args);
  982. va_end(args);
  983. }
  984. inline void PROGLOG(const char * format, ...) __attribute__((format(printf, 1, 2)));
  985. inline void PROGLOG(const char * format, ...)
  986. {
  987. va_list args;
  988. va_start(args, format);
  989. VALOG(MCuserProgress, unknownJob, format, args);
  990. va_end(args);
  991. }
  992. inline void MLOG(const LogMsgCategory & cat, const char * msg)
  993. {
  994. LOGMSGREPORTER->mreport_direct(cat, unknownJob, msg);
  995. }
  996. inline void MLOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...)
  997. {
  998. va_list args;
  999. va_start(args, format);
  1000. LOGMSGREPORTER->mreport_va(cat, job, format, args);
  1001. va_end(args);
  1002. }
  1003. inline void MLOG(const LogMsgCategory & cat, const char * format, ...)
  1004. {
  1005. va_list args;
  1006. va_start(args, format);
  1007. LOGMSGREPORTER->mreport_va(cat, unknownJob, format, args);
  1008. va_end(args);
  1009. }
  1010. inline void MLOG(const char * format, ...) __attribute__((format(printf, 1, 2)));
  1011. inline void MLOG(const char * format, ...)
  1012. {
  1013. va_list args;
  1014. va_start(args, format);
  1015. LOGMSGREPORTER->mreport_va(MCuserProgress, unknownJob, format, args);
  1016. va_end(args);
  1017. }
  1018. inline void DBGLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1019. inline void DBGLOG(LogMsgCode code, char const * format, ...)
  1020. {
  1021. va_list args;
  1022. va_start(args, format);
  1023. VALOG(MCdebugInfo, unknownJob, code, format, args);
  1024. va_end(args);
  1025. }
  1026. inline void DISLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1027. inline void DISLOG(LogMsgCode code, char const * format, ...)
  1028. {
  1029. va_list args;
  1030. va_start(args, format);
  1031. VALOG(MCdisaster, unknownJob, code, format, args);
  1032. va_end(args);
  1033. }
  1034. inline void UWARNLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1035. inline void UWARNLOG(LogMsgCode code, char const * format, ...)
  1036. {
  1037. va_list args;
  1038. va_start(args, format);
  1039. VALOG(MCuserWarning, unknownJob, code, format, args);
  1040. va_end(args);
  1041. }
  1042. inline void OWARNLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1043. inline void OWARNLOG(LogMsgCode code, char const * format, ...)
  1044. {
  1045. va_list args;
  1046. va_start(args, format);
  1047. VALOG(MCoperatorWarning, unknownJob, code, format, args);
  1048. va_end(args);
  1049. }
  1050. inline void IWARNLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1051. inline void IWARNLOG(LogMsgCode code, char const * format, ...)
  1052. {
  1053. va_list args;
  1054. va_start(args, format);
  1055. VALOG(MCinternalWarning, unknownJob, code, format, args);
  1056. va_end(args);
  1057. }
  1058. inline void IWARNLOG(IException *except, const char *prefix=nullptr)
  1059. {
  1060. LOG(MCinternalWarning, except, prefix);
  1061. }
  1062. inline void UWARNLOG(IException *except, const char *prefix=nullptr)
  1063. {
  1064. LOG(MCuserWarning, except, prefix);
  1065. }
  1066. inline void OWARNLOG(IException *except, const char *prefix=nullptr)
  1067. {
  1068. LOG(MCoperatorWarning, except, prefix);
  1069. }
  1070. inline void OERRLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1071. inline void OERRLOG(LogMsgCode code, char const * format, ...)
  1072. {
  1073. va_list args;
  1074. va_start(args, format);
  1075. VALOG(MCoperatorError, unknownJob, code, format, args);
  1076. va_end(args);
  1077. }
  1078. inline void IERRLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1079. inline void IERRLOG(LogMsgCode code, char const * format, ...)
  1080. {
  1081. va_list args;
  1082. va_start(args, format);
  1083. VALOG(MCinternalError, unknownJob, code, format, args);
  1084. va_end(args);
  1085. }
  1086. inline void UERRLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1087. inline void UERRLOG(LogMsgCode code, char const * format, ...)
  1088. {
  1089. va_list args;
  1090. va_start(args, format);
  1091. VALOG(MCuserError, unknownJob, code, format, args);
  1092. va_end(args);
  1093. }
  1094. inline void PROGLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  1095. inline void PROGLOG(LogMsgCode code, char const * format, ...)
  1096. {
  1097. va_list args;
  1098. va_start(args, format);
  1099. VALOG(MCuserProgress, unknownJob, code, format, args);
  1100. va_end(args);
  1101. }
  1102. inline void DBGLOG(IException *except, const char *prefix=NULL)
  1103. {
  1104. LOG(MCdebugInfo, except, prefix);
  1105. }
  1106. inline void IERRLOG(IException *except, const char *prefix=NULL)
  1107. {
  1108. LOG(MCinternalError, except, prefix);
  1109. }
  1110. inline void UERRLOG(IException *except, const char *prefix=NULL)
  1111. {
  1112. LOG(MCuserError, except, prefix);
  1113. }
  1114. inline void OERRLOG(IException *except, const char *prefix=NULL)
  1115. {
  1116. LOG(MCoperatorError, except, prefix);
  1117. }
  1118. inline void DISLOG(IException *except, const char *prefix=NULL)
  1119. {
  1120. LOG(MCdisaster, except, prefix);
  1121. }
  1122. #define EXCLOG FLLOG
  1123. #define FILELOG attachStandardFileLogMsgMonitor
  1124. #define BINLOG attachStandardBinLogMsgMonitor
  1125. #define HANDLELOG attachStandardHandleLogMsgMonitor
  1126. inline void removeLog() { queryLogMsgManager()->removeAllMonitors(); queryLogMsgManager()->removeAllChildren(); }
  1127. inline void resetLog() { queryLogMsgManager()->resetMonitors(); queryLogMsgManager()->removeAllChildren(); }
  1128. #define PREPLOG queryLogMsgManager()->prepAllHandlers
  1129. #define REJECTLOG queryLogMsgManager()->rejectsCategory
  1130. #define AUDIT_TYPES_BEGIN typedef enum {
  1131. #define MAKE_AUDIT_TYPE(name, type, categoryid, eventid, level) AUDIT_TYPE_##name,
  1132. #define AUDIT_TYPES_END NUM_AUDIT_TYPES } AuditType;
  1133. #include "jelogtype.hpp"
  1134. #undef AUDIT_TYPES_BEGIN
  1135. #undef MAKE_AUDIT_TYPE
  1136. #undef AUDIT_TYPES_END
  1137. class jlib_decl ISysLogEventLogger : public IInterface
  1138. {
  1139. public:
  1140. virtual bool log(AuditType auditType, char const * msg) = 0;
  1141. virtual bool log(AuditType auditType, char const * msg, size32_t datasize, void const * data) = 0;
  1142. };
  1143. extern jlib_decl ISysLogEventLogger * querySysLogEventLogger();
  1144. extern jlib_decl ILogMsgHandler * getSysLogMsgHandler(unsigned fields = MSGFIELD_all);
  1145. extern jlib_decl void UseSysLogForOperatorMessages(bool use=true);
  1146. #define SYSLOG querySysLogEventLogger()->log
  1147. #define AUDIT SYSLOG // bwd compatibility
  1148. extern jlib_decl void AuditSystemAccess(const char *userid, bool success, char const * msg,...) __attribute__((format(printf, 3, 4)));
  1149. interface jlib_decl IContextLogger : extends IInterface
  1150. {
  1151. void CTXLOG(const char *format, ...) const __attribute__((format(printf, 2, 3)));
  1152. void mCTXLOG(const char *format, ...) const __attribute__((format(printf, 2, 3)));
  1153. virtual void CTXLOGva(const char *format, va_list args) const __attribute__((format(printf,2,0))) = 0;
  1154. void logOperatorException(IException *E, const char *file, unsigned line, const char *format, ...) const __attribute__((format(printf, 5, 6)));
  1155. virtual void logOperatorExceptionVA(IException *E, const char *file, unsigned line, const char *format, va_list args) const __attribute__((format(printf,5,0))) = 0;
  1156. virtual void noteStatistic(StatisticKind kind, unsigned __int64 value) const = 0;
  1157. virtual void mergeStats(const CRuntimeStatisticCollection &from) const = 0;
  1158. virtual unsigned queryTraceLevel() const = 0;
  1159. virtual void setGlobalId(const char *id, SocketEndpoint &ep, unsigned pid) = 0;
  1160. virtual void setHttpIdHeaders(const char *global, const char *caller) = 0;
  1161. virtual const char *queryGlobalId() const = 0;
  1162. virtual const char *queryLocalId() const = 0;
  1163. virtual const char *queryGlobalIdHttpHeader() const = 0;
  1164. virtual const char *queryCallerIdHttpHeader() const = 0;
  1165. virtual void setCallerId(const char *id) = 0;
  1166. virtual const char *queryCallerId() const = 0;
  1167. };
  1168. extern jlib_decl StringBuffer &appendGloballyUniqueId(StringBuffer &s);
  1169. extern jlib_decl const IContextLogger &queryDummyContextLogger();
  1170. extern jlib_decl IContextLogger &updateDummyContextLogger();
  1171. //---------------------------------------------------------------------------
  1172. interface IComponentLogFileCreator : extends IInterface
  1173. {
  1174. //IComponentLogFileCreator set methods
  1175. virtual void setExtension(const char * _ext) = 0; //log filename extension (eg ".log")
  1176. virtual void setPrefix(const char * _prefix) = 0; //filename prefix (eg "master")
  1177. virtual void setName(const char * _name) = 0; //log filename, overrides default of component name (without extension)
  1178. virtual void setPostfix(const char * _postfix) = 0; //filename postfix (eg "coalesce")
  1179. virtual void setCreateAliasFile(bool _create) = 0; //controls creation of hardlink alias file
  1180. virtual void setAliasName(const char * _aliasName) = 0; //alias file name, overrides default of component name
  1181. virtual void setLogDirSubdir(const char * _subdir) = 0; //subdir be appended to config log dir (eg "server" or "audit")
  1182. virtual void setRolling(const bool _rolls) = 0; //daily rollover to new file
  1183. virtual void setMaxLogFileSize(const long _size) = 0; //maximum log file size (files too large rolled over)
  1184. virtual void setCompleteFilespec(const char * _fs) = 0; //Full filespec (path/fn.ext), overrides everything else
  1185. //ILogMsgHandler fields
  1186. virtual void setAppend(const bool _append) = 0; //append to existing logfile
  1187. virtual void setFlushes(const bool _flushes) = 0; //automatically flush
  1188. virtual void setMsgFields(const unsigned _fields) = 0; //fields/columns to be included in log
  1189. //ILogMsgFilter fields
  1190. virtual void setMsgAudiences(const unsigned _audiences) = 0; //log audience
  1191. virtual void setMsgClasses(const unsigned _classes) = 0; //message class
  1192. virtual void setMaxDetail(const LogMsgDetail _maxDetail) = 0; //message detail
  1193. virtual void setLocal(const bool _local) = 0; //local logging
  1194. //query methods (not valid until logging started)
  1195. virtual const char * queryLogDir() const = 0; //Location of component logfile
  1196. virtual const char * queryLogFileSpec() const = 0; //Full log filespec
  1197. virtual const char * queryAliasFileSpec() const = 0; //Full alias filespec, if created
  1198. virtual ILogMsgHandler * beginLogging() = 0; //begin logging to specified file(s)
  1199. };
  1200. extern jlib_decl IComponentLogFileCreator * createComponentLogFileCreator(IPropertyTree * _properties, const char *_component);
  1201. extern jlib_decl IComponentLogFileCreator * createComponentLogFileCreator(const char *_logDir, const char *_component);
  1202. extern jlib_decl IComponentLogFileCreator * createComponentLogFileCreator(const char *_component);
  1203. #endif