jlog.hpp 49 KB

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