jlog.hpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifndef JLOG_HPP
  15. #define JLOG_HPP
  16. // Control whether a clock is provided
  17. #define JLOG_PROVIDES_CLOCK
  18. // Control whether XML reports have newlines between category/system/job/text sections
  19. #ifdef _DEBUG
  20. #define LOG_MSG_NEWLINE
  21. #endif
  22. #include "stdio.h"
  23. #include "time.h"
  24. #include "jexpdef.hpp"
  25. #include "jiface.hpp"
  26. #include "jlib.hpp"
  27. #include "jexcept.hpp"
  28. #include "jutil.hpp"
  29. #include "jdebug.hpp"
  30. #include "jptree.hpp"
  31. #include "jsocket.hpp"
  32. // ENUMS, TYPEDEFS, CONSTS ETC.
  33. // Enums, typedefs, and consts for LogMsgCategory, plus enum-to-string functions
  34. // When changing this enum, be sure to update (a) the string functions, and (b) NUM value
  35. typedef MessageAudience LogMsgAudience;
  36. #define MSGAUDNUM 8
  37. inline const char * LogMsgAudienceToVarString(LogMsgAudience audience)
  38. {
  39. switch(audience)
  40. {
  41. case MSGAUD_operator:
  42. return("Operator");
  43. case MSGAUD_user:
  44. return("User");
  45. case MSGAUD_monitor:
  46. return("Monitor");
  47. case MSGAUD_performance:
  48. return("Performance");
  49. case MSGAUD_internal:
  50. return("Internal");
  51. case MSGAUD_programmer:
  52. return("Programmer");
  53. case MSGAUD_legacy:
  54. return("Legacy");
  55. case MSGAUD_audit:
  56. return("Audit");
  57. default:
  58. return("UNKNOWN");
  59. }
  60. }
  61. inline const char * LogMsgAudienceToFixString(LogMsgAudience audience)
  62. {
  63. switch(audience)
  64. {
  65. case MSGAUD_operator:
  66. return("Operator ");
  67. case MSGAUD_user:
  68. return("User ");
  69. case MSGAUD_monitor:
  70. return("Monitor ");
  71. case MSGAUD_performance:
  72. return("Perf. ");
  73. case MSGAUD_internal:
  74. return("Internal ");
  75. case MSGAUD_programmer:
  76. return("Prog. ");
  77. case MSGAUD_legacy:
  78. return("Legacy ");
  79. case MSGAUD_audit:
  80. return("Audit ");
  81. default:
  82. return("UNKNOWN ");
  83. }
  84. }
  85. // When changing this enum, be sure to update (a) the string functions, and (b) NUM value
  86. typedef enum
  87. {
  88. MSGCLS_unknown = 0x00,
  89. MSGCLS_disaster = 0x01,
  90. MSGCLS_error = 0x02,
  91. MSGCLS_warning = 0x04,
  92. MSGCLS_information = 0x08,
  93. MSGCLS_progress = 0x10,
  94. MSGCLS_legacy = 0x20,
  95. MSGCLS_event = 0x40,
  96. MSGCLS_all = 0xFF
  97. } LogMsgClass;
  98. #define MSGCLSNUM 7
  99. inline const char * LogMsgClassToVarString(LogMsgClass msgClass)
  100. {
  101. switch(msgClass)
  102. {
  103. case MSGCLS_disaster:
  104. return("Disaster");
  105. case MSGCLS_error:
  106. return("Error");
  107. case MSGCLS_warning:
  108. return("Warning");
  109. case MSGCLS_information:
  110. return("Information");
  111. case MSGCLS_progress:
  112. return("Progress");
  113. case MSGCLS_legacy:
  114. return("Legacy");
  115. case MSGCLS_event:
  116. return("Event");
  117. default:
  118. return("UNKNOWN");
  119. }
  120. }
  121. inline const char * LogMsgClassToFixString(LogMsgClass msgClass)
  122. {
  123. switch(msgClass)
  124. {
  125. case MSGCLS_disaster:
  126. return("Disaster ");
  127. case MSGCLS_error:
  128. return("Error ");
  129. case MSGCLS_warning:
  130. return("Warning ");
  131. case MSGCLS_information:
  132. return("Inform. ");
  133. case MSGCLS_progress:
  134. return("Progress ");
  135. case MSGCLS_legacy:
  136. return("Legacy ");
  137. case MSGCLS_event:
  138. return("Event ");
  139. default:
  140. return("UNKNOWN ");
  141. }
  142. }
  143. typedef unsigned LogMsgDetail;
  144. #define DefaultDetail 100
  145. #define TopDetail (LogMsgDetail)-1
  146. // Typedef for LogMsgSysInfo
  147. typedef unsigned LogMsgId;
  148. // Typedefs and consts for LogMsgJobInfo
  149. typedef unsigned __int64 LogMsgJobId;
  150. typedef unsigned __int64 LogMsgUserId;
  151. typedef unsigned __int64 LogMsgSessionId;
  152. #define UnknownJob (LogMsgJobId)-1
  153. #define UnknownUser (LogMsgUserId)-1
  154. #define UnknownSession (LogMsgSessionId)-1
  155. // Other enums, typedefs, and consts
  156. typedef int LogMsgCode;
  157. #define NoLogMsgCode -1
  158. // When changing this enum, be sure to update (a) the string function, and (b) the abbrev function
  159. typedef enum
  160. {
  161. MSGFIELD_audience = 0x000001,
  162. MSGFIELD_class = 0x000002,
  163. MSGFIELD_detail = 0x000004,
  164. MSGFIELD_allCategory = 0x000007,
  165. MSGFIELD_msgID = 0x000008,
  166. MSGFIELD_time = 0x000010,
  167. MSGFIELD_date = 0x000020,
  168. MSGFIELD_timeDate = 0x000030,
  169. MSGFIELD_process = 0x000040,
  170. MSGFIELD_thread = 0x000080,
  171. MSGFIELD_node = 0x000100,
  172. MSGFIELD_allSysInfo = 0x00F1F8,
  173. MSGFIELD_job = 0x000200,
  174. MSGFIELD_user = 0x000400,
  175. MSGFIELD_session = 0x000800,
  176. MSGFIELD_allJobInfo = 0x000E00,
  177. MSGFIELD_code = 0x001000,
  178. MSGFIELD_milliTime = 0x002000,
  179. MSGFIELD_microTime = 0x004000,
  180. MSGFIELD_nanoTime = 0x008000,
  181. MSGFIELD_component = 0x010000,
  182. MSGFIELD_quote = 0x020000,
  183. MSGFIELD_prefix = 0x040000,
  184. MSGFIELD_last = 0x040000,
  185. MSGFIELD_all = 0xFFFFFF
  186. } LogMsgField;
  187. #define MSGFIELD_STANDARD MSGFIELD_timeDate | MSGFIELD_msgID | MSGFIELD_process | MSGFIELD_thread | MSGFIELD_code | MSGFIELD_quote | MSGFIELD_prefix
  188. inline const char * LogMsgFieldToString(LogMsgField field)
  189. {
  190. switch(field)
  191. {
  192. case MSGFIELD_audience:
  193. return("Audience");
  194. case MSGFIELD_class:
  195. return("Class");
  196. case MSGFIELD_detail:
  197. return("Detail");
  198. case MSGFIELD_msgID:
  199. return("Message ID");
  200. case MSGFIELD_time:
  201. return("Time");
  202. case MSGFIELD_date:
  203. return("Date");
  204. case MSGFIELD_process:
  205. return("Process ID");
  206. case MSGFIELD_thread:
  207. return("Thread ID");
  208. case MSGFIELD_node:
  209. return("Node");
  210. case MSGFIELD_job:
  211. return("Job");
  212. case MSGFIELD_user:
  213. return("User");
  214. case MSGFIELD_session:
  215. return("Session");
  216. case MSGFIELD_code:
  217. return("Code");
  218. case MSGFIELD_milliTime:
  219. return("Timer (milli)");
  220. case MSGFIELD_microTime:
  221. return("Timer (micro)");
  222. case MSGFIELD_nanoTime:
  223. return("Timer (nano)");
  224. case MSGFIELD_component:
  225. return("Component");
  226. case MSGFIELD_quote:
  227. return("Quote");
  228. default:
  229. return("UNKNOWN");
  230. }
  231. }
  232. inline unsigned LogMsgFieldFromAbbrev(char const * abbrev)
  233. {
  234. if(strnicmp(abbrev, "AUD", 3)==0)
  235. return MSGFIELD_audience;
  236. if(strnicmp(abbrev, "CLS", 3)==0)
  237. return MSGFIELD_class;
  238. if(strnicmp(abbrev, "DET", 3)==0)
  239. return MSGFIELD_detail;
  240. if(strnicmp(abbrev, "MID", 3)==0)
  241. return MSGFIELD_msgID;
  242. if(strnicmp(abbrev, "TIM", 3)==0)
  243. return MSGFIELD_time;
  244. if(strnicmp(abbrev, "DAT", 3)==0)
  245. return MSGFIELD_date;
  246. if(strnicmp(abbrev, "PID", 3)==0)
  247. return MSGFIELD_process;
  248. if(strnicmp(abbrev, "TID", 3)==0)
  249. return MSGFIELD_thread;
  250. if(strnicmp(abbrev, "NOD", 3)==0)
  251. return MSGFIELD_node;
  252. if(strnicmp(abbrev, "JOB", 3)==0)
  253. return MSGFIELD_job;
  254. if(strnicmp(abbrev, "USE", 3)==0)
  255. return MSGFIELD_user;
  256. if(strnicmp(abbrev, "SES", 3)==0)
  257. return MSGFIELD_session;
  258. if(strnicmp(abbrev, "COD", 3)==0)
  259. return MSGFIELD_code;
  260. if(strnicmp(abbrev, "MLT", 3)==0)
  261. return MSGFIELD_milliTime;
  262. if(strnicmp(abbrev, "MCT", 3)==0)
  263. return MSGFIELD_microTime;
  264. if(strnicmp(abbrev, "NNT", 3)==0)
  265. return MSGFIELD_nanoTime;
  266. if(strnicmp(abbrev, "COM", 3)==0)
  267. return MSGFIELD_component;
  268. if(strnicmp(abbrev, "QUO", 3)==0)
  269. return MSGFIELD_quote;
  270. if(strnicmp(abbrev, "ALL", 3)==0)
  271. return MSGFIELD_all;
  272. if(strnicmp(abbrev, "STD", 3)==0)
  273. return MSGFIELD_STANDARD;
  274. return 0;
  275. }
  276. // This function parses strings such as "AUD+CLS+DET+COD" and "STD+MIT-PID", and is used for fields attribute in XML handler descriptions
  277. inline unsigned LogMsgFieldsFromAbbrevs(char const * abbrevs)
  278. {
  279. unsigned fields = 0;
  280. bool negate = false;
  281. bool more = true;
  282. while(more)
  283. {
  284. if(strlen(abbrevs)<3) break;
  285. unsigned field = LogMsgFieldFromAbbrev(abbrevs);
  286. if(field)
  287. if(negate)
  288. fields &= ~field;
  289. else
  290. fields |= field;
  291. switch(abbrevs[3])
  292. {
  293. case '+':
  294. negate = false;
  295. abbrevs += 4;
  296. break;
  297. case '-':
  298. negate = true;
  299. abbrevs += 4;
  300. break;
  301. default:
  302. more = false;
  303. }
  304. }
  305. return fields;
  306. }
  307. inline char const * msgPrefix(LogMsgClass msgClass)
  308. {
  309. switch(msgClass)
  310. {
  311. case MSGCLS_error:
  312. return "ERROR: ";
  313. case MSGCLS_warning:
  314. return "WARNING: ";
  315. default:
  316. return "";
  317. }
  318. }
  319. // LOG MESSAGE CLASS AND ITS COMPONENTS
  320. // Info about category of log message, provided by user (this info is static, chosen during coding)
  321. class jlib_decl LogMsgCategory
  322. {
  323. public:
  324. LogMsgCategory(LogMsgAudience _audience = MSGAUD_unknown, LogMsgClass _class = MSGCLS_unknown, LogMsgDetail _detail = DefaultDetail) : audience(_audience), msgClass(_class), detail(_detail) {}
  325. inline LogMsgAudience queryAudience() const { return audience; }
  326. inline LogMsgClass queryClass() const { return msgClass; }
  327. inline LogMsgDetail queryDetail() const { return detail; }
  328. void serialize(MemoryBuffer & out) const { out.append(audience).append(msgClass).append(detail); }
  329. void deserialize(MemoryBuffer & in) { in.read((unsigned &) audience).read((unsigned &) msgClass).read(detail); }
  330. LogMsgCategory const operator ()(unsigned newDetail) const { return LogMsgCategory(audience, msgClass, newDetail); }
  331. private:
  332. LogMsgAudience audience;
  333. LogMsgClass msgClass;
  334. LogMsgDetail detail;
  335. };
  336. // Info about log message determined automatically by system
  337. class jlib_decl LogMsgSysInfo
  338. {
  339. public:
  340. LogMsgSysInfo(LogMsgId _id = (LogMsgId)-1, unsigned port = 0, LogMsgSessionId session = UnknownSession);
  341. inline LogMsgId queryMsgID() const { return id; }
  342. inline time_t queryTime() const { return timeStarted; }
  343. inline unsigned queryProcessID() const { return processID; }
  344. inline unsigned queryThreadID() const { return threadID; }
  345. inline LogMsgSessionId querySessionID() const { return sessionID; }
  346. inline const SocketEndpoint * queryNode() const { return &node; }
  347. #ifdef JLOG_PROVIDES_CLOCK
  348. inline __int64 queryClock() const { return nanoTime; }
  349. #endif
  350. void serialize(MemoryBuffer & out) const;
  351. void deserialize(MemoryBuffer & in);
  352. private:
  353. LogMsgId id;
  354. time_t timeStarted;
  355. unsigned processID;
  356. unsigned threadID;
  357. LogMsgSessionId sessionID;
  358. SocketEndpoint node;
  359. #ifdef JLOG_PROVIDES_CLOCK
  360. __int64 nanoTime;
  361. #endif
  362. };
  363. // Info about job generating log message, provided by user (this info is dynamic, determined at run-time)
  364. class jlib_decl LogMsgJobInfo
  365. {
  366. public:
  367. LogMsgJobInfo(LogMsgJobId _job = UnknownJob, LogMsgUserId _user = UnknownUser) : jobID(_job), userID(_user) {}
  368. inline LogMsgJobId queryJobID() const { return jobID; }
  369. inline LogMsgUserId queryUserID() const { return userID; }
  370. void serialize(MemoryBuffer & out) const { out.append(jobID).append(userID); }
  371. void deserialize(MemoryBuffer & in) { in.read(jobID).read(userID); }
  372. private:
  373. LogMsgJobId jobID;
  374. LogMsgUserId userID;
  375. };
  376. class jlib_decl LogMsg : public CInterface
  377. {
  378. public:
  379. LogMsg() : category(), sysInfo(), jobInfo(), remoteFlag(false) {}
  380. 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); }
  381. LogMsg(const LogMsgCategory & _cat, LogMsgId _id, const LogMsgJobInfo & _jobInfo, LogMsgCode _code, const char * format, va_list args, unsigned _compo, unsigned port, LogMsgSessionId session) : category(_cat), sysInfo(_id, port, session), jobInfo(_jobInfo), msgCode(_code), component(_compo), remoteFlag(false) { text.valist_appendf(format, args); }
  382. LogMsg(MemoryBuffer & in) { deserialize(in, false); }
  383. StringBuffer & toStringPlain(StringBuffer & out, unsigned fields = MSGFIELD_all) const;
  384. StringBuffer & toStringXML(StringBuffer & out, unsigned fields = MSGFIELD_all) const;
  385. StringBuffer & toStringTable(StringBuffer & out, unsigned fields = MSGFIELD_all) const;
  386. static StringBuffer & toStringTableHead(StringBuffer & out, unsigned fields = MSGFIELD_all);
  387. void fprintPlain(FILE * handle, unsigned fields = MSGFIELD_all) const;
  388. void fprintXML(FILE * handle, unsigned fields = MSGFIELD_all) const;
  389. void fprintTable(FILE * handle, unsigned fields = MSGFIELD_all) const;
  390. static void fprintTableHead(FILE * handle, unsigned fields = MSGFIELD_all);
  391. inline const LogMsgCategory queryCategory() const { return category; }
  392. inline const LogMsgSysInfo & querySysInfo() const { return sysInfo; }
  393. inline const LogMsgJobInfo & queryJobInfo() const { return jobInfo; }
  394. inline unsigned queryComponent() const { return component; }
  395. inline LogMsgCode queryCode() const { return msgCode; }
  396. inline const char * queryText() const { return text.str(); }
  397. void serialize(MemoryBuffer & out) const { category.serialize(out); sysInfo.serialize(out); jobInfo.serialize(out); out.append(msgCode); text.serialize(out); }
  398. 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; }
  399. bool queryRemoteFlag() const { return remoteFlag; }
  400. protected:
  401. LogMsgCategory category;
  402. LogMsgSysInfo sysInfo;
  403. LogMsgJobInfo jobInfo;
  404. LogMsgCode msgCode;
  405. unsigned component;
  406. StringBuffer text;
  407. bool remoteFlag;
  408. };
  409. // INTERFACES
  410. // Filter for log messages --- contains method to accept or reject messages
  411. interface jlib_decl ILogMsgFilter : public IInterface
  412. {
  413. public:
  414. virtual bool includeMessage(const LogMsg & msg) const = 0;
  415. virtual bool mayIncludeCategory(const LogMsgCategory & cat) const = 0;
  416. virtual unsigned queryAudienceMask() const = 0;
  417. virtual unsigned queryClassMask() const = 0;
  418. virtual LogMsgDetail queryMaxDetail() const = 0;
  419. virtual bool isCategoryFilter() const { return false; }
  420. virtual void serialize(MemoryBuffer & out, bool preserveLocal) const = 0;
  421. virtual void addToPTree(IPropertyTree * tree) const = 0;
  422. virtual bool queryLocalFlag() const { return false; }
  423. };
  424. // Handler for log messages --- contains method to write or send messages
  425. interface jlib_decl ILogMsgHandler : public IInterface
  426. {
  427. public:
  428. virtual void handleMessage(const LogMsg & msg) const = 0;
  429. virtual bool needsPrep() const = 0;
  430. virtual void prep() = 0;
  431. virtual unsigned queryMessageFields() const = 0;
  432. virtual void setMessageFields(unsigned _fields = MSGFIELD_all) = 0;
  433. virtual void addToPTree(IPropertyTree * parent) const = 0;
  434. virtual int flush() { return 0; }
  435. virtual char const * disable() { return 0; }
  436. virtual void enable() {}
  437. virtual bool getLogName(StringBuffer &name) const = 0;
  438. };
  439. // Class on manager's list of children which sends new filters to children, and holds thread which receives log messages
  440. class jlib_decl ILogMsgLinkToChild : public IInterface
  441. {
  442. public:
  443. virtual void sendFilter(ILogMsgFilter * filter) const = 0;
  444. virtual void sendFilterOwn(ILogMsgFilter * filter) const = 0;
  445. virtual void connect() = 0;
  446. virtual void disconnect() = 0;
  447. virtual bool queryConnected() const = 0;
  448. virtual void markDisconnected() = 0;
  449. };
  450. // Manager to receive log messages, filter, and pass to handlers
  451. interface jlib_decl ILogMsgListener : public IInterface
  452. {
  453. virtual bool addMonitor(ILogMsgHandler * handler, ILogMsgFilter * filter) = 0;
  454. virtual bool addMonitorOwn(ILogMsgHandler * handler, ILogMsgFilter * filter) = 0;
  455. virtual bool removeMonitor(ILogMsgHandler * handler) = 0;
  456. typedef bool HandlerTest(ILogMsgHandler * handler);
  457. virtual unsigned removeMonitorsMatching(HandlerTest & test) = 0;
  458. virtual void removeAllMonitors() = 0;
  459. virtual bool isActiveMonitor(const ILogMsgHandler * handler) const = 0;
  460. virtual ILogMsgFilter * queryMonitorFilter(const ILogMsgHandler * handler) const = 0;
  461. virtual ILogMsgFilter * getMonitorFilter(const ILogMsgHandler * handler) const = 0;
  462. virtual bool changeMonitorFilter(const ILogMsgHandler * handler, ILogMsgFilter * newFilter) = 0;
  463. virtual bool changeMonitorFilterOwn(const ILogMsgHandler * handler, ILogMsgFilter * newFilter) = 0;
  464. virtual void prepAllHandlers() const = 0;
  465. virtual void addChildOwn(ILogMsgLinkToChild * child) = 0;
  466. virtual void removeChild(ILogMsgLinkToChild * child) = 0;
  467. virtual void removeAllChildren() = 0;
  468. virtual ILogMsgFilter * getCompoundFilter(bool locked = false) const = 0;
  469. virtual void suspendChildren() = 0;
  470. virtual void unsuspendChildren() = 0;
  471. virtual bool addMonitorToPTree(const ILogMsgHandler * handler, IPropertyTree * tree) const = 0;
  472. virtual void addAllMonitorsToPTree(IPropertyTree * tree) const = 0;
  473. virtual void setPort(unsigned _port) = 0;
  474. virtual unsigned queryPort() const = 0;
  475. virtual void setSession(LogMsgSessionId _session) = 0;
  476. virtual LogMsgSessionId querySession() const = 0;
  477. };
  478. interface jlib_decl ILogMsgManager : public ILogMsgListener
  479. {
  480. public:
  481. virtual void enterQueueingMode() = 0;
  482. virtual void setQueueBlockingLimit(unsigned lim) = 0;
  483. virtual void setQueueDroppingLimit(unsigned lim, unsigned numToDrop) = 0;
  484. virtual void resetQueueLimit() = 0;
  485. virtual bool flushQueue(unsigned timeout) = 0;
  486. virtual void resetMonitors() = 0;
  487. virtual void report(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 3, 4))) = 0;
  488. virtual void report_va(const LogMsgCategory & cat, const char * format, va_list args) = 0;
  489. virtual void report(const LogMsgCategory & cat, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 4, 5))) = 0;
  490. virtual void report_va(const LogMsgCategory & cat, LogMsgCode code , const char * format, va_list args) = 0;
  491. virtual void report(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL) = 0;
  492. virtual void report(unsigned compo, const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 4, 5))) = 0;
  493. virtual void report_va(unsigned compo, const LogMsgCategory & cat, const char * format, va_list args) = 0;
  494. virtual void report(unsigned compo, const LogMsgCategory & cat, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 5, 6))) = 0;
  495. virtual void report_va(unsigned compo, const LogMsgCategory & cat, LogMsgCode code , const char * format, va_list args) = 0;
  496. virtual void report(unsigned compo, const LogMsgCategory & cat, const IException * e, const char * prefix = NULL) = 0;
  497. virtual void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 4, 5))) = 0;
  498. virtual void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args) = 0;
  499. virtual void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 5, 6))) = 0;
  500. virtual void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, va_list args) = 0;
  501. virtual void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL) = 0;
  502. virtual void report(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 5, 6))) = 0;
  503. virtual void report_va(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args) = 0;
  504. virtual void report(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 6, 7))) = 0;
  505. virtual void report_va(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, va_list args) = 0;
  506. virtual void report(unsigned compo, const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL) = 0;
  507. virtual void report(const LogMsg & msg) const = 0;
  508. virtual LogMsgId getNextID() = 0;
  509. virtual bool rejectsCategory(const LogMsgCategory & cat) const = 0;
  510. };
  511. // CONCRETE CLASSES
  512. // Class which mimics the report methods of a manager, registering an additional component field
  513. class jlib_decl LogMsgComponentReporter
  514. {
  515. public:
  516. LogMsgComponentReporter(unsigned _compo) : component(_compo) {}
  517. void report(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 3, 4)));
  518. void report_va(const LogMsgCategory & cat, const char * format, va_list args);
  519. void report(const LogMsgCategory & cat, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 4, 5)));
  520. void report_va(const LogMsgCategory & cat, LogMsgCode code, const char * format, va_list args);
  521. void report(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL);
  522. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 4, 5)));
  523. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args);
  524. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 5, 6)));
  525. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, va_list args);
  526. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL);
  527. void report(const LogMsg & msg);
  528. private:
  529. unsigned component;
  530. };
  531. // Class which mimics the report methods of a manager, prepending the given file and line (intended only for use in the FLLOG macro, below)
  532. class jlib_decl LogMsgPrepender
  533. {
  534. public:
  535. // N.B. This method locks the critical section...
  536. LogMsgPrepender * setContext(LogMsgComponentReporter * r, char const * f, unsigned l);
  537. // ... and these ones unlock it. So they should be used in pairs.
  538. void report(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 3, 4)));
  539. void report_va(const LogMsgCategory & cat, const char * format, va_list args);
  540. void report(const LogMsgCategory & cat, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 4, 5)));
  541. void report_va(const LogMsgCategory & cat, LogMsgCode code, const char * format, va_list args);
  542. void report(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL);
  543. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 4, 5)));
  544. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args);
  545. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, ...) __attribute__((format(printf, 5, 6)));
  546. void report_va(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code, const char * format, va_list args);
  547. void report(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL);
  548. IException * report(IException * e, const char * prefix = NULL, LogMsgClass cls = MSGCLS_error); // uses MCexception(e, cls), unknownJob, handy for EXCLOG
  549. private:
  550. LogMsgComponentReporter * reporter;
  551. char const * file;
  552. unsigned line;
  553. CriticalSection crit;
  554. };
  555. // FUNCTIONS, DATA, AND MACROS
  556. // Function to get filters and handlers
  557. extern jlib_decl ILogMsgFilter * getDefaultLogMsgFilter();
  558. extern jlib_decl ILogMsgFilter * getPassAllLogMsgFilter();
  559. extern jlib_decl ILogMsgFilter * getLocalLogMsgFilter();
  560. extern jlib_decl ILogMsgFilter * getPassNoneLogMsgFilter();
  561. extern jlib_decl ILogMsgFilter * queryPassAllLogMsgFilter();
  562. extern jlib_decl ILogMsgFilter * queryLocalLogMsgFilter();
  563. extern jlib_decl ILogMsgFilter * queryPassNoneLogMsgFilter();
  564. extern jlib_decl ILogMsgFilter * getCategoryLogMsgFilter(unsigned audiences = MSGAUD_all, unsigned classes = MSGCLS_all, LogMsgDetail maxDetail = TopDetail, bool local = false);
  565. extern jlib_decl ILogMsgFilter * getPIDLogMsgFilter(unsigned pid, bool local = false);
  566. extern jlib_decl ILogMsgFilter * getTIDLogMsgFilter(unsigned tid, bool local = false);
  567. extern jlib_decl ILogMsgFilter * getNodeLogMsgFilter(const char * name, unsigned port = 0, bool local = false);
  568. extern jlib_decl ILogMsgFilter * getNodeLogMsgFilter(const IpAddress & ip, unsigned port = 0, bool local = false);
  569. extern jlib_decl ILogMsgFilter * getNodeLogMsgFilter(unsigned port, bool local = false);
  570. extern jlib_decl ILogMsgFilter * getIpLogMsgFilter(const char * name, bool local = false);
  571. extern jlib_decl ILogMsgFilter * getIpLogMsgFilter(const IpAddress & ip, bool local = false);
  572. extern jlib_decl ILogMsgFilter * getIpLogMsgFilter(bool local = false);
  573. extern jlib_decl ILogMsgFilter * getJobLogMsgFilter(LogMsgJobId job, bool local = false);
  574. extern jlib_decl ILogMsgFilter * getUserLogMsgFilter(LogMsgUserId user, bool local = false);
  575. extern jlib_decl ILogMsgFilter * getSessionLogMsgFilter(LogMsgSessionId session, bool local = false);
  576. extern jlib_decl ILogMsgFilter * getComponentLogMsgFilter(unsigned component, bool local = false);
  577. extern jlib_decl ILogMsgFilter * getRegexLogMsgFilter(const char *regex, bool local = false);
  578. extern jlib_decl ILogMsgFilter * getNotLogMsgFilter(ILogMsgFilter * arg);
  579. extern jlib_decl ILogMsgFilter * getNotLogMsgFilterOwn(ILogMsgFilter * arg);
  580. extern jlib_decl ILogMsgFilter * getAndLogMsgFilter(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  581. extern jlib_decl ILogMsgFilter * getAndLogMsgFilterOwn(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  582. extern jlib_decl ILogMsgFilter * getOrLogMsgFilter(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  583. extern jlib_decl ILogMsgFilter * getOrLogMsgFilterOwn(ILogMsgFilter * arg1, ILogMsgFilter * arg2);
  584. extern jlib_decl ILogMsgFilter * getSwitchLogMsgFilterOwn(ILogMsgFilter * switchFilter, ILogMsgFilter * yesFilter, ILogMsgFilter * noFilter);
  585. extern jlib_decl ILogMsgHandler * getHandleLogMsgHandler(FILE * handle = stderr, unsigned fields = MSGFIELD_all, bool writeXML = false);
  586. 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);
  587. 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);
  588. extern jlib_decl ILogMsgHandler * getBinLogMsgHandler(const char * filename, bool append = false);
  589. // Function to install switch filter into a monitor, switch some messages to new filter whilst leaving rest to previous filter
  590. extern jlib_decl void installLogMsgFilterSwitch(ILogMsgHandler * handler, ILogMsgFilter * switchFilter, ILogMsgFilter * newFilter);
  591. // Functions to make standard handlers and catagory filters and add to manager
  592. 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);
  593. 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);
  594. 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);
  595. // Function to construct filter from serialized and XML forms, and construct handler from XML form, and attach monitor(s) from XML form
  596. extern jlib_decl ILogMsgFilter * getDeserializedLogMsgFilter(MemoryBuffer & in);
  597. extern jlib_decl ILogMsgFilter * getLogMsgFilterFromPTree(IPropertyTree * tree);
  598. extern jlib_decl ILogMsgHandler * getLogMsgHandlerFromPTree(IPropertyTree * tree);
  599. extern jlib_decl ILogMsgHandler * attachLogMsgMonitorFromPTree(IPropertyTree * tree); // Takes tree containing <handler> and <filter> elements
  600. extern jlib_decl void attachManyLogMsgMonitorsFromPTree(IPropertyTree * tree); // Takes tree containing many <monitor> elements
  601. // Extern standard categories and unknown jobInfo
  602. extern jlib_decl const LogMsgCategory MCdisaster;
  603. extern jlib_decl const LogMsgCategory MCuserError;
  604. #define MCerror MCuserError
  605. extern jlib_decl const LogMsgCategory MCoperatorError;
  606. extern jlib_decl const LogMsgCategory MCinternalError;
  607. extern jlib_decl const LogMsgCategory MCuserWarning;
  608. #define MCwarning MCuserWarning
  609. extern jlib_decl const LogMsgCategory MCoperatorWarning;
  610. extern jlib_decl const LogMsgCategory MCinternalWarning;
  611. // MCexception(e, cls) is now a convenient function to get a message category with its audience taken from an exception
  612. inline LogMsgCategory MCexception(IException * e, LogMsgClass cls = MSGCLS_error) { return LogMsgCategory((e)->errorAudience(),cls); }
  613. extern jlib_decl const LogMsgCategory MCuserProgress;
  614. #define MCprogress MCuserProgress
  615. extern jlib_decl const LogMsgCategory MCoperatorProgress;
  616. extern jlib_decl const LogMsgCategory MCdebugProgress;
  617. extern jlib_decl const LogMsgCategory MCdebugInfo;
  618. extern jlib_decl const LogMsgCategory MCstats;
  619. extern jlib_decl const LogMsgCategory MCevent;
  620. extern jlib_decl const LogMsgCategory MClegacy;
  621. extern jlib_decl const LogMsgJobInfo unknownJob;
  622. // Function to return manager, standard handler and the reporters, and the handler's message fields
  623. extern jlib_decl ILogMsgManager * queryLogMsgManager();
  624. extern jlib_decl ILogMsgHandler * queryStderrLogMsgHandler();
  625. extern jlib_decl LogMsgComponentReporter * queryLogMsgComponentReporter(unsigned compo);
  626. extern jlib_decl LogMsgPrepender * queryLogMsgPrepender();
  627. extern jlib_decl ILogMsgManager * createLogMsgManager(); // use with care! (needed by mplog listener facility)
  628. // Macros to make logging as simple as possible
  629. #ifdef LOGMSGCOMPONENT
  630. #define LOGMSGREPORTER queryLogMsgComponentReporter(LOGMSGCOMPONENT)
  631. #define FLLOG queryLogMsgPrepender()->setContext(LOGMSGREPORTER, __FILE__, __LINE__)->report
  632. #else // LOGMSGCOMPONENT
  633. #define LOGMSGREPORTER queryLogMsgManager()
  634. #define FLLOG queryLogMsgPrepender()->setContext(0, __FILE__, __LINE__)->report
  635. #endif // LOGMSGCOMPONENT
  636. #ifdef LOGMSGCOMPONENT
  637. #else // LOGMSGCOMPONENT
  638. #endif // LOGMSGCOMPONENT
  639. #ifdef _PROFILING_WITH_TRUETIME_
  640. //It can't cope with the macro definition..... at least v6.5 can't.
  641. inline void LOG(const LogMsg & msg)
  642. {
  643. LOGMSGREPORTER->report(msg);
  644. }
  645. void LOG(const LogMsgCategory & cat, const char * format, ...) __attribute__((format(printf, 2, 3)));
  646. inline void LOG(const LogMsgCategory & cat, const char * format, ...)
  647. {
  648. va_list args;
  649. va_start(args, format);
  650. LOGMSGREPORTER->report_va(cat, format, args);
  651. va_end(args);
  652. }
  653. void LOG(const LogMsgCategory & cat, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 3, 4)));
  654. inline void LOG(const LogMsgCategory & cat, LogMsgCode code , const char * format, ...)
  655. {
  656. va_list args;
  657. va_start(args, format);
  658. LOGMSGREPORTER->report_va(cat, code , format, args);
  659. va_end(args);
  660. }
  661. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...) __attribute__((format(printf, 3, 4)));
  662. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, ...)
  663. {
  664. va_list args;
  665. va_start(args, format);
  666. LOGMSGREPORTER->report_va(cat, job, format, args);
  667. va_end(args);
  668. }
  669. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...) __attribute__((format(printf, 4, 5)));
  670. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, ...)
  671. {
  672. va_list args;
  673. va_start(args, format);
  674. LOGMSGREPORTER->report_va(cat, job, code , format, args);
  675. va_end(args);
  676. }
  677. inline void LOG(const LogMsgCategory & cat, const IException * e, const char * prefix = NULL)
  678. {
  679. LOGMSGREPORTER->report(cat, e, prefix);
  680. }
  681. inline void LOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const IException * e, const char * prefix = NULL)
  682. {
  683. LOGMSGREPORTER->report(cat, job, e, prefix);
  684. }
  685. inline void VALOG(const LogMsgCategory & cat, const char * format, va_list args)
  686. {
  687. LOGMSGREPORTER->report_va(cat, format, args);
  688. }
  689. inline void VALOG(const LogMsgCategory & cat, LogMsgCode code , const char * format, va_list args)
  690. {
  691. LOGMSGREPORTER->report_va(cat, code , format, args);
  692. }
  693. inline void VALOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, const char * format, va_list args)
  694. {
  695. LOGMSGREPORTER->report_va(cat, job, format, args);
  696. }
  697. inline void VALOG(const LogMsgCategory & cat, const LogMsgJobInfo & job, LogMsgCode code , const char * format, va_list args)
  698. {
  699. LOGMSGREPORTER->report_va(cat, job, code , format, args);
  700. }
  701. #else
  702. #define LOG LOGMSGREPORTER->report
  703. #define VALOG LOGMSGREPORTER->report_va
  704. #endif
  705. #define INTLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=%d", expr)
  706. #define OCTLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=0%o", expr)
  707. #define HEXLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=0x%X", expr)
  708. #define DBLLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=%lg", expr)
  709. #define CHRLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"=%c", expr)
  710. #define STRLOG(category, job, expr) LOGMSGREPORTER->report(category, job, #expr"='%s'", expr)
  711. #define TOSTRLOG(category, job, prefix, func) { if (!REJECTLOG(category)) { StringBuffer buff; func(buff); LOGMSGREPORTER->report(category, job, prefix"'%s'", buff.str()); } }
  712. #define EVENTLOG(code, extra) LOGMSGREPORTER->report(MCevent, unknownJob, code, extra)
  713. inline void DBGLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  714. inline void DBGLOG(char const * format, ...)
  715. {
  716. va_list args;
  717. va_start(args, format);
  718. VALOG(MCdebugInfo, unknownJob, format, args);
  719. va_end(args);
  720. }
  721. inline void DISLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  722. inline void DISLOG(char const * format, ...)
  723. {
  724. va_list args;
  725. va_start(args, format);
  726. VALOG(MCdisaster, unknownJob, format, args);
  727. va_end(args);
  728. }
  729. inline void ERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  730. inline void ERRLOG(char const * format, ...)
  731. {
  732. va_list args;
  733. va_start(args, format);
  734. VALOG(MCuserError, unknownJob, format, args);
  735. va_end(args);
  736. }
  737. inline void OERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  738. inline void OERRLOG(char const * format, ...)
  739. {
  740. va_list args;
  741. va_start(args, format);
  742. VALOG(MCoperatorError, unknownJob, format, args);
  743. va_end(args);
  744. }
  745. inline void IERRLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  746. inline void IERRLOG(char const * format, ...)
  747. {
  748. va_list args;
  749. va_start(args, format);
  750. VALOG(MCinternalError, unknownJob, format, args);
  751. va_end(args);
  752. }
  753. inline void WARNLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  754. inline void WARNLOG(char const * format, ...)
  755. {
  756. va_list args;
  757. va_start(args, format);
  758. VALOG(MCuserWarning, unknownJob, format, args);
  759. va_end(args);
  760. }
  761. inline void PROGLOG(char const * format, ...) __attribute__((format(printf, 1, 2)));
  762. inline void PROGLOG(char const * format, ...)
  763. {
  764. va_list args;
  765. va_start(args, format);
  766. VALOG(MCprogress, unknownJob, format, args);
  767. va_end(args);
  768. }
  769. inline void DBGLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  770. inline void DBGLOG(LogMsgCode code, char const * format, ...)
  771. {
  772. va_list args;
  773. va_start(args, format);
  774. VALOG(MCdebugInfo, unknownJob, code, format, args);
  775. va_end(args);
  776. }
  777. inline void DISLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  778. inline void DISLOG(LogMsgCode code, char const * format, ...)
  779. {
  780. va_list args;
  781. va_start(args, format);
  782. VALOG(MCdisaster, unknownJob, code, format, args);
  783. va_end(args);
  784. }
  785. inline void ERRLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  786. inline void ERRLOG(LogMsgCode code, char const * format, ...)
  787. {
  788. va_list args;
  789. va_start(args, format);
  790. VALOG(MCuserError, unknownJob, code, format, args);
  791. va_end(args);
  792. }
  793. inline void IERRLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  794. inline void IERRLOG(LogMsgCode code, char const * format, ...)
  795. {
  796. va_list args;
  797. va_start(args, format);
  798. VALOG(MCinternalError, unknownJob, code, format, args);
  799. va_end(args);
  800. }
  801. inline void WARNLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  802. inline void WARNLOG(LogMsgCode code, char const * format, ...)
  803. {
  804. va_list args;
  805. va_start(args, format);
  806. VALOG(MCuserWarning, unknownJob, code, format, args);
  807. va_end(args);
  808. }
  809. inline void PROGLOG(LogMsgCode code, char const * format, ...) __attribute__((format(printf, 2, 3)));
  810. inline void PROGLOG(LogMsgCode code, char const * format, ...)
  811. {
  812. va_list args;
  813. va_start(args, format);
  814. VALOG(MCprogress, unknownJob, code, format, args);
  815. va_end(args);
  816. }
  817. inline IException *DBGLOG(IException *except, const char *prefix=NULL)
  818. {
  819. LOG(MCdebugInfo, except, prefix);
  820. return except;
  821. }
  822. inline IException *DISLOG(IException *except, const char *prefix=NULL)
  823. {
  824. LOG(MCdisaster, except, prefix);
  825. return except;
  826. }
  827. #define EXCLOG FLLOG
  828. #define FILELOG attachStandardFileLogMsgMonitor
  829. #define BINLOG attachStandardBinLogMsgMonitor
  830. #define HANDLELOG attachStandardHandleLogMsgMonitor
  831. inline void removeLog() { queryLogMsgManager()->removeAllMonitors(); queryLogMsgManager()->removeAllChildren(); }
  832. inline void resetLog() { queryLogMsgManager()->resetMonitors(); queryLogMsgManager()->removeAllChildren(); }
  833. #define PREPLOG queryLogMsgManager()->prepAllHandlers
  834. #define REJECTLOG queryLogMsgManager()->rejectsCategory
  835. #define AUDIT_TYPES_BEGIN typedef enum {
  836. #define MAKE_AUDIT_TYPE(name, type, categoryid, eventid, level) AUDIT_TYPE_##name,
  837. #define AUDIT_TYPES_END NUM_AUDIT_TYPES } AuditType;
  838. #include "jelogtype.hpp"
  839. #undef AUDIT_TYPES_BEGIN
  840. #undef MAKE_AUDIT_TYPE
  841. #undef AUDIT_TYPES_END
  842. class jlib_decl ISysLogEventLogger : public IInterface
  843. {
  844. public:
  845. virtual bool log(AuditType auditType, char const * msg) = 0;
  846. virtual bool log(AuditType auditType, char const * msg, size32_t datasize, void const * data) = 0;
  847. };
  848. extern jlib_decl ISysLogEventLogger * querySysLogEventLogger();
  849. extern jlib_decl ILogMsgHandler * getSysLogMsgHandler(unsigned fields = MSGFIELD_all);
  850. extern jlib_decl void UseSysLogForOperatorMessages(bool use=true);
  851. #define SYSLOG querySysLogEventLogger()->log
  852. #define AUDIT SYSLOG // bwd compatibility
  853. extern jlib_decl void AuditSystemAccess(const char *userid, bool success, char const * msg,...) __attribute__((format(printf, 3, 4)));
  854. /***************************************************************************/
  855. /* The simplest logging commands are: */
  856. /* DBGLOG(format, ...) [for temporary logs while debugging, MCdebugInfo] */
  857. /* DISLOG(format, ...) [for disasters, MCdisaster] */
  858. /* ERRLOG(format, ...) [for errors reported to user, MCuserError] */
  859. /* OERRLOG(format, ...) [for errors reported to operator] */
  860. /* IERRLOG(format, ...) [for errors reported to internal & programmer] */
  861. /* WARNLOG(format, ...) [for warnings reported to user, MCuserWarning] */
  862. /* PROGLOG(format, ...) [for progress logs to user, MCprogress] */
  863. /* There are equivalent commands which take a LogMsgCode: */
  864. /* DBGLOG(code, format, ...) */
  865. /* DISLOG(code, format, ...) */
  866. /* ERRLOG(code, format, ...) */
  867. /* OERRLOG(code, format, ...) */
  868. /* IERRLOG(code, format, ...) */
  869. /* WARNLOG(code, format, ...) */
  870. /* PROGLOG(code, format, ...) */
  871. /* This takes code, message, & audience from an exception, class is error */
  872. /* EXCLOG(exception, prefix) */
  873. /* The more general logging command has the following forms: */
  874. /* LOG(category, format, ...) */
  875. /* LOG(category, code, format, ...) */
  876. /* LOG(category, job, format, ...) */
  877. /* LOG(category, job, code, format, ...) */
  878. /* In the first and second cases, the common unknownJob is used. */
  879. /* There are also forms to log exceptions: */
  880. /* LOG(category, exception) */
  881. /* LOG(category, exception, prefix) */
  882. /* LOG(category, job, exception) */
  883. /* LOG(category, job, exception, prefix) */
  884. /* The off-the-shelf categories, MCdebugInfo et al, are listed above. */
  885. /* Their detail level can be modified from the default as MCdebugInfo(50). */
  886. /***************************************************************************/
  887. interface IContextLogger : extends IInterface
  888. {
  889. virtual void CTXLOG(const char *format, ...) const __attribute__((format(printf, 2, 3))) = 0;
  890. virtual void CTXLOGva(const char *format, va_list args) const = 0;
  891. virtual void logOperatorException(IException *E, const char *file, unsigned line, const char *format, ...) const __attribute__((format(printf, 5, 6))) = 0;
  892. virtual void logOperatorExceptionVA(IException *E, const char *file, unsigned line, const char *format, va_list args) const = 0;
  893. virtual void noteStatistic(unsigned statCode, unsigned __int64 value, unsigned count) const = 0; // Values for statcode defined in jstats.h
  894. virtual unsigned queryTraceLevel() const = 0;
  895. };
  896. extern jlib_decl const IContextLogger &queryDummyContextLogger();
  897. #endif