jlog.hpp 55 KB

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