jlog.hpp 48 KB

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