jlog.hpp 57 KB

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