1 /*
2    Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #include <ndb_global.h>
26 
27 #include <EventLogger.hpp>
28 #include <TransporterCallback.hpp>
29 
30 #include <NdbConfig.h>
31 #include <kernel/BlockNumbers.h>
32 #include <signaldata/ArbitSignalData.hpp>
33 #include <signaldata/FailRep.hpp>
34 #include <NodeState.hpp>
35 #include <version.h>
36 #include <ndb_version.h>
37 
38 #include <ndbd_exit_codes.h>
39 
40 #define make_uint64(a,b) (((Uint64)(a)) + (((Uint64)(b)) << 32))
41 
42 //
43 // PUBLIC
44 //
~EventLoggerBase()45 EventLoggerBase::~EventLoggerBase()
46 {
47 
48 }
49 
50 #define QQQQ char *m_text, size_t m_text_len, const Uint32* theData, Uint32 len
51 
getTextConnected(QQQQ)52 void getTextConnected(QQQQ) {
53   BaseString::snprintf(m_text, m_text_len,
54 		       "Node %u Connected",
55 		       theData[1]);
56 }
getTextConnectedApiVersion(QQQQ)57 void getTextConnectedApiVersion(QQQQ) {
58   char tmp[100];
59   Uint32 mysql_version = theData[3];
60   if (theData[2] < NDBD_SPLIT_VERSION)
61   mysql_version = 0;
62   BaseString::snprintf(m_text, m_text_len,
63 		       "Node %u: API %s",
64 		       theData[1],
65 		       ndbGetVersionString(theData[2], mysql_version, 0,
66                                            tmp, sizeof(tmp)));
67 }
68 
getTextDisconnected(QQQQ)69 void getTextDisconnected(QQQQ) {
70   BaseString::snprintf(m_text, m_text_len,
71 		       "Node %u Disconnected",
72 		       theData[1]);
73 }
getTextCommunicationClosed(QQQQ)74 void getTextCommunicationClosed(QQQQ) {
75   //-----------------------------------------------------------------------
76   // REPORT communication to node closed.
77   //-----------------------------------------------------------------------
78   BaseString::snprintf(m_text, m_text_len,
79 		       "Communication to Node %u closed",
80 		       theData[1]);
81 }
getTextCommunicationOpened(QQQQ)82 void getTextCommunicationOpened(QQQQ) {
83   //-----------------------------------------------------------------------
84   // REPORT communication to node opened.
85   //-----------------------------------------------------------------------
86   BaseString::snprintf(m_text, m_text_len,
87 		       "Communication to Node %u opened",
88 		       theData[1]);
89 }
getTextNDBStartStarted(QQQQ)90 void getTextNDBStartStarted(QQQQ) {
91   //-----------------------------------------------------------------------
92   // Start of NDB has been initiated.
93   //-----------------------------------------------------------------------
94 
95   char tmp[100];
96   Uint32 mysql_version = theData[2];
97   if (theData[1] < NDBD_SPLIT_VERSION)
98     mysql_version = 0;
99   BaseString::snprintf(m_text, m_text_len,
100 		       "Start initiated (%s)",
101 		       ndbGetVersionString(theData[1], mysql_version, 0,
102                                            tmp, sizeof(tmp)));
103 }
getTextNDBStopStarted(QQQQ)104 void getTextNDBStopStarted(QQQQ) {
105   BaseString::snprintf(m_text, m_text_len,
106 		       "%s shutdown initiated",
107 		       (theData[1] == 1 ? "Cluster" : "Node"));
108 }
getRestartAction(Uint32 action,BaseString & str)109 void getRestartAction(Uint32 action, BaseString &str)
110 {
111   if (action == 0)
112     return;
113   str.appfmt(", restarting");
114   if (action & 2)
115     str.appfmt(", no start");
116   if (action & 4)
117     str.appfmt(", initial");
118 }
getTextNDBStopCompleted(QQQQ)119 void getTextNDBStopCompleted(QQQQ) {
120   BaseString action_str("");
121   BaseString signum_str("");
122   getRestartAction(theData[1], action_str);
123   if (theData[2])
124     signum_str.appfmt(" Initiated by signal %d.", theData[2]);
125   BaseString::snprintf(m_text, m_text_len,
126 		       "Node shutdown completed%s.%s",
127 		       action_str.c_str(),
128 		       signum_str.c_str());
129 }
getTextNDBStopForced(QQQQ)130 void getTextNDBStopForced(QQQQ) {
131   BaseString action_str("");
132   BaseString reason_str("");
133   BaseString sphase_str("");
134   int signum        = theData[2];
135   int error         = theData[3];
136   int sphase        = theData[4];
137   int extra         = theData[5];
138   if (signum)
139     getRestartAction(theData[1],action_str);
140   if (signum)
141     reason_str.appfmt(" Initiated by signal %d.", signum);
142   if (error)
143   {
144     ndbd_exit_classification cl;
145     ndbd_exit_status st;
146     const char *msg = ndbd_exit_message(error, &cl);
147     const char *cl_msg = ndbd_exit_classification_message(cl, &st);
148     const char *st_msg = ndbd_exit_status_message(st);
149     reason_str.appfmt(" Caused by error %d: \'%s(%s). %s\'.",
150 		      error, msg, cl_msg, st_msg);
151     if (extra != 0)
152       reason_str.appfmt(" (extra info %d)", extra);
153   }
154   if (sphase < 255)
155     sphase_str.appfmt(" Occured during startphase %u.", sphase);
156   BaseString::snprintf(m_text, m_text_len,
157 		       "Forced node shutdown completed%s.%s%s",
158 		       action_str.c_str(), sphase_str.c_str(),
159 		       reason_str.c_str());
160 }
getTextNDBStopAborted(QQQQ)161 void getTextNDBStopAborted(QQQQ) {
162   BaseString::snprintf(m_text, m_text_len,
163 		       "Node shutdown aborted");
164 }
getTextNDBStartCompleted(QQQQ)165 void getTextNDBStartCompleted(QQQQ) {
166   //-----------------------------------------------------------------------
167   // Start of NDB has been completed.
168   //-----------------------------------------------------------------------
169 
170   char tmp[100];
171   Uint32 mysql_version = theData[2];
172   if (theData[1] < NDBD_SPLIT_VERSION)
173     mysql_version = 0;
174   BaseString::snprintf(m_text, m_text_len,
175 		       "Started (%s)",
176 		       ndbGetVersionString(theData[1], mysql_version, 0,
177                                            tmp, sizeof(tmp)));
178 }
179 
getTextSTTORRYRecieved(QQQQ)180 void getTextSTTORRYRecieved(QQQQ) {
181   //-----------------------------------------------------------------------
182   // STTORRY recevied after restart finished.
183   //-----------------------------------------------------------------------
184   BaseString::snprintf(m_text, m_text_len,
185 		       "STTORRY received after restart finished");
186 }
getTextStartPhaseCompleted(QQQQ)187 void getTextStartPhaseCompleted(QQQQ) {
188   //-----------------------------------------------------------------------
189   // REPORT Start phase completed.
190   //-----------------------------------------------------------------------
191   const char *type = "<Unknown>";
192   switch((NodeState::StartType)theData[2]){
193   case NodeState::ST_INITIAL_START:
194     type = "(initial start)";
195     break;
196   case NodeState::ST_SYSTEM_RESTART:
197     type = "(system restart)";
198     break;
199   case NodeState::ST_NODE_RESTART:
200     type = "(node restart)";
201     break;
202   case NodeState::ST_INITIAL_NODE_RESTART:
203     type = "(initial node restart)";
204     break;
205   case NodeState::ST_ILLEGAL_TYPE:
206     type = "";
207     break;
208   default:
209     BaseString::snprintf(m_text, m_text_len,
210 			 "Start phase %u completed (unknown = %d)",
211 			 theData[1],
212 			 theData[2]);
213     return;
214   }
215   BaseString::snprintf(m_text, m_text_len,
216 		       "Start phase %u completed %s",
217 		       theData[1],
218 		       type);
219 }
getTextCM_REGCONF(QQQQ)220 void getTextCM_REGCONF(QQQQ) {
221   BaseString::snprintf(m_text, m_text_len,
222 		       "CM_REGCONF president = %u, own Node = %u, our dynamic id = %u/%u",
223 		       theData[2],
224 		       theData[1],
225 		       (theData[3] >> 16), (theData[3] & 0xFFFF));
226 }
getTextCM_REGREF(QQQQ)227 void getTextCM_REGREF(QQQQ) {
228   const char* line = "";
229   switch (theData[3]) {
230   case 0:
231     line = "Busy";
232     break;
233   case 1:
234     line = "Election with wait = false";
235     break;
236   case 2:
237     line = "Election with wait = false";
238     break;
239   case 3:
240     line = "Not president";
241     break;
242   case 4:
243     line = "Election without selecting new candidate";
244     break;
245   default:
246     line = "No such cause";
247     break;
248   }//switch
249 
250   BaseString::snprintf(m_text, m_text_len,
251 		       "CM_REGREF from Node %u to our Node %u. Cause = %s",
252 		       theData[2],
253 		       theData[1],
254 		       line);
255 }
getTextFIND_NEIGHBOURS(QQQQ)256 void getTextFIND_NEIGHBOURS(QQQQ) {
257   //-----------------------------------------------------------------------
258   // REPORT Node Restart copied a fragment.
259   //-----------------------------------------------------------------------
260   BaseString::snprintf(m_text, m_text_len,
261 		       "We are Node %u with dynamic ID %u, our left neighbour "
262 		       "is Node %u, our right is Node %u",
263 		       theData[1],
264 		       theData[4],
265 		       theData[2],
266 		       theData[3]);
267 }
getTextNodeFailCompleted(QQQQ)268 void getTextNodeFailCompleted(QQQQ) {
269   //-----------------------------------------------------------------------
270   // REPORT Node failure phase completed.
271   //-----------------------------------------------------------------------
272   if (theData[1] == 0)
273   {
274     if (theData[3] != 0) {
275       BaseString::snprintf(m_text, m_text_len,
276 			   "Node %u completed failure of Node %u",
277 			   theData[3],
278 			   theData[2]);
279     } else {
280       BaseString::snprintf(m_text, m_text_len,
281 			   "All nodes completed failure of Node %u",
282 			   theData[2]);
283     }//if
284   } else {
285     const char* line = "";
286     if (theData[1] == DBTC){
287       line = "DBTC";
288     }else if (theData[1] == DBDICT){
289       line = "DBDICT";
290     }else if (theData[1] == DBDIH){
291       line = "DBDIH";
292     }else if (theData[1] == DBLQH){
293       line = "DBLQH";
294     }
295     BaseString::snprintf(m_text, m_text_len,
296 			 "Node failure of %u %s completed",
297 			 theData[2],
298 			 line);
299   }
300 }
getTextNODE_FAILREP(QQQQ)301 void getTextNODE_FAILREP(QQQQ) {
302   BaseString::snprintf(m_text, m_text_len,
303 		       "Node %u has failed. The Node state at failure "
304 		       "was %u",
305 		       theData[1],
306 		       theData[2]);
307 }
getTextArbitState(QQQQ)308 void getTextArbitState(QQQQ) {
309   //-----------------------------------------------------------------------
310   // REPORT arbitrator found or lost.
311   //-----------------------------------------------------------------------
312   {
313     const ArbitSignalData* sd = (ArbitSignalData*)theData;
314     char ticketText[ArbitTicket::TextLength + 1];
315     char errText[ArbitCode::ErrTextLength + 1];
316     const unsigned code = sd->code & 0xFFFF;
317     const unsigned state = sd->code >> 16;
318     switch (code) {
319     case ArbitCode::ThreadStart:
320       BaseString::snprintf(m_text, m_text_len,
321 			   "President restarts arbitration thread [state=%u]",
322 			   state);
323       break;
324     case ArbitCode::PrepPart2:
325       sd->ticket.getText(ticketText, sizeof(ticketText));
326       BaseString::snprintf(m_text, m_text_len,
327 			   "Prepare arbitrator node %u [ticket=%s]",
328 			   sd->node, ticketText);
329       break;
330     case ArbitCode::PrepAtrun:
331       sd->ticket.getText(ticketText, sizeof(ticketText));
332       BaseString::snprintf(m_text, m_text_len,
333 			   "Receive arbitrator node %u [ticket=%s]",
334 			   sd->node, ticketText);
335       break;
336     case ArbitCode::ApiStart:
337       sd->ticket.getText(ticketText, sizeof(ticketText));
338       BaseString::snprintf(m_text, m_text_len,
339 			   "Started arbitrator node %u [ticket=%s]",
340 			   sd->node, ticketText);
341       break;
342     case ArbitCode::ApiFail:
343       BaseString::snprintf(m_text, m_text_len,
344 			   "Lost arbitrator node %u - process failure [state=%u]",
345 			   sd->node, state);
346       break;
347     case ArbitCode::ApiExit:
348       BaseString::snprintf(m_text, m_text_len,
349 			   "Lost arbitrator node %u - process exit [state=%u]",
350 			   sd->node, state);
351       break;
352     default:
353       ArbitCode::getErrText(code, errText, sizeof(errText));
354       BaseString::snprintf(m_text, m_text_len,
355 			   "Lost arbitrator node %u - %s [state=%u]",
356 			   sd->node, errText, state);
357       break;
358     }
359   }
360 }
361 
getTextArbitResult(QQQQ)362 void getTextArbitResult(QQQQ) {
363   //-----------------------------------------------------------------------
364   // REPORT arbitration result (the failures may not reach us).
365   //-----------------------------------------------------------------------
366   {
367     const ArbitSignalData* sd = (ArbitSignalData*)theData;
368     char errText[ArbitCode::ErrTextLength + 1];
369     const unsigned code = sd->code & 0xFFFF;
370     const unsigned state = sd->code >> 16;
371     switch (code) {
372     case ArbitCode::LoseNodes:
373       BaseString::snprintf(m_text, m_text_len,
374 			   "Arbitration check lost - less than 1/2 nodes left");
375       break;
376     case ArbitCode::WinNodes:
377       BaseString::snprintf(m_text, m_text_len,
378 			   "Arbitration check won - all node groups and more than 1/2 nodes left");
379       break;
380     case ArbitCode::WinGroups:
381       BaseString::snprintf(m_text, m_text_len,
382 			   "Arbitration check won - node group majority");
383       break;
384     case ArbitCode::LoseGroups:
385       BaseString::snprintf(m_text, m_text_len,
386 			   "Arbitration check lost - missing node group");
387       break;
388     case ArbitCode::Partitioning:
389       BaseString::snprintf(m_text, m_text_len,
390 			   "Network partitioning - arbitration required");
391       break;
392     case ArbitCode::WinChoose:
393       BaseString::snprintf(m_text, m_text_len,
394 			   "Arbitration won - positive reply from node %u",
395 			   sd->node);
396       break;
397     case ArbitCode::LoseChoose:
398       BaseString::snprintf(m_text, m_text_len,
399 			   "Arbitration lost - negative reply from node %u",
400 			   sd->node);
401       break;
402     case ArbitCode::LoseNorun:
403       BaseString::snprintf(m_text, m_text_len,
404 			   "Network partitioning - no arbitrator available");
405       break;
406     case ArbitCode::LoseNocfg:
407       BaseString::snprintf(m_text, m_text_len,
408 			   "Network partitioning - no arbitrator configured");
409       break;
410     case ArbitCode::WinWaitExternal:{
411       char buf[8*4*2+1];
412       sd->mask.getText(buf);
413       BaseString::snprintf(m_text, m_text_len,
414 			   "Continuing after wait for external arbitration, "
415                            "nodes: %s", buf);
416       break;
417     }
418     default:
419       ArbitCode::getErrText(code, errText, sizeof(errText));
420       BaseString::snprintf(m_text, m_text_len,
421 			   "Arbitration failure - %s [state=%u]",
422 			   errText, state);
423       break;
424     }
425   }
426 }
getTextGlobalCheckpointStarted(QQQQ)427 void getTextGlobalCheckpointStarted(QQQQ) {
428   //-----------------------------------------------------------------------
429   // This event reports that a global checkpoint has been started and this
430   // node is the master of this global checkpoint.
431   //-----------------------------------------------------------------------
432   BaseString::snprintf(m_text, m_text_len,
433 		       "Global checkpoint %u started",
434 		       theData[1]);
435 }
getTextGlobalCheckpointCompleted(QQQQ)436 void getTextGlobalCheckpointCompleted(QQQQ) {
437   //-----------------------------------------------------------------------
438   // This event reports that a global checkpoint has been completed on this
439   // node and the node is the master of this global checkpoint.
440   //-----------------------------------------------------------------------
441   BaseString::snprintf(m_text, m_text_len,
442 		       "Global checkpoint %u completed",
443 		       theData[1]);
444 }
getTextLocalCheckpointStarted(QQQQ)445 void getTextLocalCheckpointStarted(QQQQ) {
446   //-----------------------------------------------------------------------
447   // This event reports that a local checkpoint has been started and this
448   // node is the master of this local checkpoint.
449   //-----------------------------------------------------------------------
450   BaseString::snprintf(m_text, m_text_len,
451 		       "Local checkpoint %u started. "
452 		       "Keep GCI = %u oldest restorable GCI = %u",
453 		       theData[1],
454 		       theData[2],
455 		       theData[3]);
456 }
getTextLocalCheckpointCompleted(QQQQ)457 void getTextLocalCheckpointCompleted(QQQQ) {
458   //-----------------------------------------------------------------------
459   // This event reports that a local checkpoint has been completed on this
460   // node and the node is the master of this local checkpoint.
461   //-----------------------------------------------------------------------
462   BaseString::snprintf(m_text, m_text_len,
463 		       "Local checkpoint %u completed",
464 		       theData[1]);
465 }
getTextTableCreated(QQQQ)466 void getTextTableCreated(QQQQ) {
467   //-----------------------------------------------------------------------
468   // This event reports that a table has been created.
469   //-----------------------------------------------------------------------
470   BaseString::snprintf(m_text, m_text_len,
471 		       "Table with ID =  %u created",
472 		       theData[1]);
473 }
474 /* STRANGE */
getTextLCPStoppedInCalcKeepGci(QQQQ)475 void getTextLCPStoppedInCalcKeepGci(QQQQ) {
476   if (theData[1] == 0)
477     BaseString::snprintf(m_text, m_text_len,
478 			 "Local Checkpoint stopped in CALCULATED_KEEP_GCI");
479 }
getTextNR_CopyDict(QQQQ)480 void getTextNR_CopyDict(QQQQ) {
481   //-----------------------------------------------------------------------
482   // REPORT Node Restart completed copy of dictionary information.
483   //-----------------------------------------------------------------------
484   BaseString::snprintf(m_text, m_text_len,
485 		       "Node restart completed copy of dictionary information");
486 }
getTextNR_CopyDistr(QQQQ)487 void getTextNR_CopyDistr(QQQQ) {
488   //-----------------------------------------------------------------------
489   // REPORT Node Restart completed copy of distribution information.
490   //-----------------------------------------------------------------------
491   BaseString::snprintf(m_text, m_text_len,
492 		       "Node restart completed copy of distribution information");
493 }
getTextNR_CopyFragsStarted(QQQQ)494 void getTextNR_CopyFragsStarted(QQQQ) {
495   //-----------------------------------------------------------------------
496   // REPORT Node Restart is starting to copy the fragments.
497   //-----------------------------------------------------------------------
498   BaseString::snprintf(m_text, m_text_len,
499 		       "Node restart starting to copy the fragments "
500 		       "to Node %u",
501 		       theData[1]);
502 }
getTextNR_CopyFragDone(QQQQ)503 void getTextNR_CopyFragDone(QQQQ) {
504   //-----------------------------------------------------------------------
505   // REPORT Node Restart copied a fragment.
506   //-----------------------------------------------------------------------
507   Uint64 rows = theData[4] + (Uint64(theData[5]) << 32);
508   Uint64 bytes = theData[6] + (Uint64(theData[7]) << 32);
509   BaseString::snprintf(m_text, m_text_len,
510 		       "Table ID = %u, fragment ID = %u have been synced "
511 		       "to Node %u rows: %llu bytes: %llu ",
512 		       theData[2],
513 		       theData[3],
514 		       theData[1],
515                        rows, bytes);
516 }
getTextNR_CopyFragsCompleted(QQQQ)517 void getTextNR_CopyFragsCompleted(QQQQ) {
518   BaseString::snprintf(m_text, m_text_len,
519 		       "Node restart completed copying the fragments "
520 		       "to Node %u",
521 		       theData[1]);
522 }
getTextLCPFragmentCompleted(QQQQ)523 void getTextLCPFragmentCompleted(QQQQ) {
524   BaseString::snprintf(m_text, m_text_len,
525 		       "Table ID = %u, fragment ID = %u has completed LCP "
526 		       "on Node %u maxGciStarted: %d maxGciCompleted: %d",
527 		       theData[2],
528 		       theData[3],
529 		       theData[1],
530 		       theData[4],
531 		       theData[5]);
532 }
getTextTransReportCounters(QQQQ)533 void getTextTransReportCounters(QQQQ) {
534   // -------------------------------------------------------------------
535   // Report information about transaction activity once per 10 seconds.
536   // -------------------------------------------------------------------
537   BaseString::snprintf(m_text, m_text_len,
538 		       "Trans. Count = %u, Commit Count = %u, "
539 		       "Read Count = %u, Simple Read Count = %u, "
540 		       "Write Count = %u, AttrInfo Count = %u, "
541 		       "Concurrent Operations = %u, Abort Count = %u"
542 		       " Scans = %u Range scans = %u",
543 		       theData[1],
544 		       theData[2],
545 		       theData[3],
546 		       theData[4],
547 		       theData[5],
548 		       theData[6],
549 		       theData[7],
550 		       theData[8],
551 		       theData[9],
552 		       theData[10]);
553 }
getTextOperationReportCounters(QQQQ)554 void getTextOperationReportCounters(QQQQ) {
555   BaseString::snprintf(m_text, m_text_len,
556 		       "Operations=%u",
557 		       theData[1]);
558 }
getTextUndoLogBlocked(QQQQ)559 void getTextUndoLogBlocked(QQQQ) {
560   //-----------------------------------------------------------------------
561   // REPORT Undo Logging blocked due to buffer near to overflow.
562   //-----------------------------------------------------------------------
563   BaseString::snprintf(m_text, m_text_len,
564 		       "ACC Blocked %u and TUP Blocked %u times last second",
565 		       theData[1],
566 		       theData[2]);
567 }
568 
getTextTransporterError(QQQQ)569 void getTextTransporterError(QQQQ) {
570   struct myTransporterError{
571     Uint32 errorNum;
572     char   errorString[256];
573   };
574   int i = 0;
575   int lenth = 0;
576   static const struct myTransporterError TransporterErrorString[]=
577   {
578     //TE_NO_ERROR = 0
579     {TE_NO_ERROR,"No error"},
580     //TE_ERROR_CLOSING_SOCKET = 0x1
581     {TE_ERROR_CLOSING_SOCKET,"Error found during closing of socket"},
582     //TE_ERROR_IN_SELECT_BEFORE_ACCEPT = 0x2
583     {TE_ERROR_IN_SELECT_BEFORE_ACCEPT,"Error found before accept. The transporter will retry"},
584     //TE_INVALID_MESSAGE_LENGTH = 0x3 | TE_DO_DISCONNECT
585     {TE_INVALID_MESSAGE_LENGTH,"Error found in message (invalid message length)"},
586     //TE_INVALID_CHECKSUM = 0x4 | TE_DO_DISCONNECT
587     {TE_INVALID_CHECKSUM,"Error found in message (checksum)"},
588     //TE_COULD_NOT_CREATE_SOCKET = 0x5
589     {TE_COULD_NOT_CREATE_SOCKET,"Error found while creating socket(can't create socket)"},
590     //TE_COULD_NOT_BIND_SOCKET = 0x6
591     {TE_COULD_NOT_BIND_SOCKET,"Error found while binding server socket"},
592     //TE_LISTEN_FAILED = 0x7
593     {TE_LISTEN_FAILED,"Error found while listening to server socket"},
594     //TE_ACCEPT_RETURN_ERROR = 0x8
595     {TE_ACCEPT_RETURN_ERROR,"Error found during accept(accept return error)"},
596     //TE_SHM_DISCONNECT = 0xb | TE_DO_DISCONNECT
597     {TE_SHM_DISCONNECT,"The remote node has disconnected"},
598     //TE_SHM_IPC_STAT = 0xc | TE_DO_DISCONNECT
599     {TE_SHM_IPC_STAT,"Unable to check shm segment"},
600     //TE_SHM_UNABLE_TO_CREATE_SEGMENT = 0xd
601     {TE_SHM_UNABLE_TO_CREATE_SEGMENT,"Unable to create shm segment"},
602     //TE_SHM_UNABLE_TO_ATTACH_SEGMENT = 0xe
603     {TE_SHM_UNABLE_TO_ATTACH_SEGMENT,"Unable to attach shm segment"},
604     //TE_SHM_UNABLE_TO_REMOVE_SEGMENT = 0xf
605     {TE_SHM_UNABLE_TO_REMOVE_SEGMENT,"Unable to remove shm segment"},
606     //TE_TOO_SMALL_SIGID = 0x10
607     {TE_TOO_SMALL_SIGID,"Sig ID too small"},
608     //TE_TOO_LARGE_SIGID = 0x11
609     {TE_TOO_LARGE_SIGID,"Sig ID too large"},
610     //TE_WAIT_STACK_FULL = 0x12 | TE_DO_DISCONNECT
611     {TE_WAIT_STACK_FULL,"Wait stack was full"},
612     //TE_RECEIVE_BUFFER_FULL = 0x13 | TE_DO_DISCONNECT
613     {TE_RECEIVE_BUFFER_FULL,"Receive buffer was full"},
614     //TE_SIGNAL_LOST_SEND_BUFFER_FULL = 0x14 | TE_DO_DISCONNECT
615     {TE_SIGNAL_LOST_SEND_BUFFER_FULL,"Send buffer was full,and trying to force send fails"},
616     //TE_SIGNAL_LOST = 0x15
617     {TE_SIGNAL_LOST,"Send failed for unknown reason(signal lost)"},
618     //TE_SEND_BUFFER_FULL = 0x16
619     {TE_SEND_BUFFER_FULL,"The send buffer was full, but sleeping for a while solved"},
620     //TE_SCI_LINK_ERROR = 0x0017
621     {TE_SCI_LINK_ERROR,"There is no link from this node to the switch"},
622     //TE_SCI_UNABLE_TO_START_SEQUENCE = 0x18 | TE_DO_DISCONNECT
623     {TE_SCI_UNABLE_TO_START_SEQUENCE,"Could not start a sequence, because system resources are exumed or no sequence has been created"},
624     //TE_SCI_UNABLE_TO_REMOVE_SEQUENCE = 0x19 | TE_DO_DISCONNECT
625     {TE_SCI_UNABLE_TO_REMOVE_SEQUENCE,"Could not remove a sequence"},
626     //TE_SCI_UNABLE_TO_CREATE_SEQUENCE = 0x1a | TE_DO_DISCONNECT
627     {TE_SCI_UNABLE_TO_CREATE_SEQUENCE,"Could not create a sequence, because system resources are exempted. Must reboot"},
628     //TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR = 0x1b | TE_DO_DISCONNECT
629     {TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR,"Tried to send data on redundant link but failed"},
630     //TE_SCI_CANNOT_INIT_LOCALSEGMENT = 0x1c | TE_DO_DISCONNECT
631     {TE_SCI_CANNOT_INIT_LOCALSEGMENT,"Cannot initialize local segment"},
632     //TE_SCI_CANNOT_MAP_REMOTESEGMENT = 0x1d | TE_DO_DISCONNEC
633     {TE_SCI_CANNOT_MAP_REMOTESEGMENT,"Cannot map remote segment"},
634     //TE_SCI_UNABLE_TO_UNMAP_SEGMENT = 0x1e | TE_DO_DISCONNECT
635     {TE_SCI_UNABLE_TO_UNMAP_SEGMENT,"Cannot free the resources used by this segment (step 1)"},
636     //TE_SCI_UNABLE_TO_REMOVE_SEGMENT = 0x1f  | TE_DO_DISCONNEC
637     {TE_SCI_UNABLE_TO_REMOVE_SEGMENT,"Cannot free the resources used by this segment (step 2)"},
638     //TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT = 0x20 | TE_DO_DISCONNECT
639     {TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT,"Cannot disconnect from a remote segment"},
640     //TE_SHM_IPC_PERMANENT = 0x21
641     {TE_SHM_IPC_PERMANENT,"Shm ipc Permanent error"},
642     //TE_SCI_UNABLE_TO_CLOSE_CHANNEL = 0x22
643     {TE_SCI_UNABLE_TO_CLOSE_CHANNEL,"Unable to close the sci channel and the resources allocated"}
644   };
645 
646   lenth = sizeof(TransporterErrorString)/sizeof(struct myTransporterError);
647   for(i=0; i<lenth; i++)
648   {
649     if(theData[2] == (Uint32) TransporterErrorString[i].errorNum)
650     {
651       BaseString::snprintf(m_text, m_text_len,
652                            "Transporter to node %d reported error 0x%x: %s",
653                            theData[1],
654                            theData[2],
655                            TransporterErrorString[i].errorString);
656       break;
657     }
658   }
659   if(i == lenth)
660     BaseString::snprintf(m_text, m_text_len,
661                          "Transporter to node %d reported error 0x%x: unknown error",
662                          theData[1],
663                          theData[2]);
664 }
getTextTransporterWarning(QQQQ)665 void getTextTransporterWarning(QQQQ) {
666   getTextTransporterError(m_text, m_text_len, theData, len);
667 }
getTextMissedHeartbeat(QQQQ)668 void getTextMissedHeartbeat(QQQQ) {
669   BaseString::snprintf(m_text, m_text_len,
670 		       "Node %d missed heartbeat %d",
671 		       theData[1],
672 		       theData[2]);
673 }
getTextDeadDueToHeartbeat(QQQQ)674 void getTextDeadDueToHeartbeat(QQQQ) {
675   BaseString::snprintf(m_text, m_text_len,
676 		       "Node %d declared dead due to missed heartbeat",
677 		       theData[1]);
678 }
getTextJobStatistic(QQQQ)679 void getTextJobStatistic(QQQQ) {
680   BaseString::snprintf(m_text, m_text_len,
681 		       "Mean loop Counter in doJob last 8192 times = %u",
682 		       theData[1]);
683 }
getTextThreadConfigLoop(QQQQ)684 void getTextThreadConfigLoop(QQQQ) {
685   BaseString::snprintf(m_text, m_text_len,
686   "8192 loops,tot %u usec,exec %u extra:loops = %u,time %u,const %u",
687 		       theData[1], theData[3], theData[4], theData[5],
688                        theData[2]);
689 }
getTextSendBytesStatistic(QQQQ)690 void getTextSendBytesStatistic(QQQQ) {
691   BaseString::snprintf(m_text, m_text_len,
692 		       "Mean send size to Node = %d last 4096 sends = %u bytes",
693 		       theData[1],
694 		       theData[2]);
695 }
getTextReceiveBytesStatistic(QQQQ)696 void getTextReceiveBytesStatistic(QQQQ) {
697   BaseString::snprintf(m_text, m_text_len,
698 		       "Mean receive size to Node = %d last 4096 sends = %u bytes",
699 		       theData[1],
700 		       theData[2]);
701 }
getTextSentHeartbeat(QQQQ)702 void getTextSentHeartbeat(QQQQ) {
703   BaseString::snprintf(m_text, m_text_len,
704 		       "Node Sent Heartbeat to node = %d",
705 		       theData[1]);
706 }
getTextCreateLogBytes(QQQQ)707 void getTextCreateLogBytes(QQQQ) {
708   BaseString::snprintf(m_text, m_text_len,
709 		       "Log part %u, log file %u, MB %u",
710 		       theData[1],
711 		       theData[2],
712 		       theData[3]);
713 }
getTextStartLog(QQQQ)714 void getTextStartLog(QQQQ) {
715   BaseString::snprintf(m_text, m_text_len,
716 		       "Log part %u, start MB %u, stop MB %u, last GCI, log exec %u",
717 		       theData[1],
718 		       theData[2],
719 		       theData[3],
720 		       theData[4]);
721 }
getTextStartREDOLog(QQQQ)722 void getTextStartREDOLog(QQQQ) {
723   BaseString::snprintf(m_text, m_text_len,
724 		       "Node: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]",
725 		       theData[1],
726 		       theData[2],
727 		       theData[3],
728 		       theData[4]);
729 }
getTextRedoStatus(QQQQ)730 void getTextRedoStatus(QQQQ) {
731   Uint64 total = (Uint64(theData[6]) << 32) + theData[7];
732   Uint64 free = (Uint64(theData[8]) << 32) + theData[9];
733 
734   BaseString::snprintf(m_text, m_text_len,
735 		       "Logpart: %u head=[ file: %u mbyte: %u ] tail=[ file: %u mbyte: %u ] total mb: %llu free mb: %llu free%%: %u",
736 		       theData[1],
737 		       theData[2],
738 		       theData[3],
739 		       theData[4],
740 		       theData[5],
741                        total,
742                        free,
743                        Uint32((100 * free) / total));
744 }
getTextUNDORecordsExecuted(QQQQ)745 void getTextUNDORecordsExecuted(QQQQ) {
746   const char* line = "";
747   if (theData[1] == DBTUP){
748     line = "DBTUP";
749   }else if (theData[1] == DBACC){
750     line = "DBACC";
751   }
752 
753   BaseString::snprintf(m_text, m_text_len,
754 		       " UNDO %s %d [%d %d %d %d %d %d %d %d %d]",
755 		       line,
756 		       theData[2],
757 		       theData[3],
758 		       theData[4],
759 		       theData[5],
760 		       theData[6],
761 		       theData[7],
762 		       theData[8],
763 		       theData[9],
764 		       theData[10],
765 		       theData[11]);
766 }
getTextInfoEvent(QQQQ)767 void getTextInfoEvent(QQQQ) {
768   BaseString::snprintf(m_text, m_text_len, "%s", (char *)&theData[1]);
769 }
770 const char bytes_unit[]= "B";
771 const char kbytes_unit[]= "KB";
772 const char mbytes_unit[]= "MB";
convert_unit(unsigned & data,const char * & unit)773 static void convert_unit(unsigned &data, const char *&unit)
774 {
775   if (data < 16*1024)
776   {
777     unit= bytes_unit;
778     return;
779   }
780   if (data < 16*1024*1024)
781   {
782     data= (data+1023)/1024;
783     unit= kbytes_unit;
784     return;
785   }
786   data= (data+1024*1024-1)/(1024*1024);
787   unit= mbytes_unit;
788 }
789 
getTextEventBufferStatus(QQQQ)790 void getTextEventBufferStatus(QQQQ) {
791   unsigned used= theData[1], alloc= theData[2], max_= theData[3];
792   const char *used_unit, *alloc_unit, *max_unit;
793   convert_unit(used, used_unit);
794   convert_unit(alloc, alloc_unit);
795   convert_unit(max_, max_unit);
796   BaseString::snprintf(m_text, m_text_len,
797 		       "Event buffer status: used=%d%s(%d%%) alloc=%d%s(%d%%) "
798 		       "max=%d%s apply_epoch=%u/%u latest_epoch=%u/%u",
799 		       used, used_unit,
800 		       theData[2] ? (Uint32)((((Uint64)theData[1])*100)/theData[2]) : 0,
801 		       alloc, alloc_unit,
802 		       theData[3] ? (Uint32)((((Uint64)theData[2])*100)/theData[3]) : 0,
803 		       max_, max_unit,
804 		       theData[5], theData[4],
805 		       theData[7], theData[6]);
806 }
getTextWarningEvent(QQQQ)807 void getTextWarningEvent(QQQQ) {
808   BaseString::snprintf(m_text, m_text_len, "%s", (char *)&theData[1]);
809 }
getTextGCP_TakeoverStarted(QQQQ)810 void getTextGCP_TakeoverStarted(QQQQ) {
811   BaseString::snprintf(m_text, m_text_len, "GCP Take over started");
812 }
getTextGCP_TakeoverCompleted(QQQQ)813 void getTextGCP_TakeoverCompleted(QQQQ) {
814   BaseString::snprintf(m_text, m_text_len, "GCP Take over completed");
815 }
getTextLCP_TakeoverStarted(QQQQ)816 void getTextLCP_TakeoverStarted(QQQQ) {
817   BaseString::snprintf(m_text, m_text_len, "LCP Take over started");
818 }
getTextLCP_TakeoverCompleted(QQQQ)819 void getTextLCP_TakeoverCompleted(QQQQ) {
820   BaseString::snprintf(m_text, m_text_len,
821 		       "LCP Take over completed (state = %d)",
822 		       theData[1]);
823 }
getTextMemoryUsage(QQQQ)824 void getTextMemoryUsage(QQQQ) {
825   const int gth = theData[1];
826   const int size = theData[2];
827   const int used = theData[3];
828   const int total = theData[4];
829   const int block = theData[5];
830   const int percent = total ? (used*100)/total : 0;
831 
832   BaseString::snprintf(m_text, m_text_len,
833 		       "%s usage %s %d%s(%d %dK pages of total %d)",
834 		       (block==DBACC ? "Index" : (block == DBTUP ?"Data":"<unknown>")),
835 		       (gth == 0 ? "is" : (gth > 0 ? "increased to" : "decreased to")),
836 		       percent, "%",
837 		       used, size/1024, total
838 		       );
839 }
840 
getTextBackupStarted(QQQQ)841 void getTextBackupStarted(QQQQ) {
842   BaseString::snprintf(m_text, m_text_len,
843 		       "Backup %u started from node %d",
844 		       theData[2], refToNode(theData[1]));
845 }
getTextBackupFailedToStart(QQQQ)846 void getTextBackupFailedToStart(QQQQ) {
847   BaseString::snprintf(m_text, m_text_len,
848 		       "Backup request from %d failed to start. Error: %d",
849 		       refToNode(theData[1]), theData[2]);
850 }
getTextBackupCompleted(QQQQ)851 void getTextBackupCompleted(QQQQ) {
852   BaseString::snprintf(m_text, m_text_len,
853 		       "Backup %u started from node %u completed."
854 		       " StartGCP: %u StopGCP: %u"
855 		       " #Records: %u #LogRecords: %u"
856 		       " Data: %u bytes Log: %u bytes",
857 		       theData[2], refToNode(theData[1]),
858 		       theData[3], theData[4], theData[6], theData[8],
859 		       theData[5], theData[7]);
860 }
getTextBackupStatus(QQQQ)861 void getTextBackupStatus(QQQQ) {
862   if (theData[1])
863     BaseString::snprintf(m_text, m_text_len,
864                          "Local backup status: backup %u started from node %u\n"
865                          " #Records: %llu #LogRecords: %llu\n"
866                          " Data: %llu bytes Log: %llu bytes",
867                          theData[2], refToNode(theData[1]),
868                          make_uint64(theData[5], theData[6]),
869                          make_uint64(theData[9], theData[10]),
870                          make_uint64(theData[3], theData[4]),
871                          make_uint64(theData[7], theData[8]));
872   else
873     BaseString::snprintf(m_text, m_text_len,
874                          "Backup not started");
875 }
getTextBackupAborted(QQQQ)876 void getTextBackupAborted(QQQQ) {
877   BaseString::snprintf(m_text, m_text_len,
878 		       "Backup %u started from %d has been aborted. Error: %d",
879 		       theData[2],
880 		       refToNode(theData[1]),
881 		       theData[3]);
882 }
getTextRestoreStarted(QQQQ)883 void getTextRestoreStarted(QQQQ)
884 {
885   BaseString::snprintf(m_text, m_text_len,
886                        "Restore started: backup %u from node %u",
887                        theData[1], theData[2]);
888 }
getTextRestoreMetaData(QQQQ)889 void getTextRestoreMetaData(QQQQ)
890 {
891   BaseString::snprintf(m_text, m_text_len,
892                        "Restore meta data: backup %u from node %u "
893                        "#Tables: %u\n"
894                        " #Tablespaces: %u #Logfilegroups: %u "
895                        "#datafiles: %u #undofiles: %u",
896                        theData[1], theData[2], theData[3],
897                        theData[4], theData[5], theData[6], theData[7]);
898 }
getTextRestoreData(QQQQ)899 void getTextRestoreData(QQQQ)
900 {
901   BaseString::snprintf(m_text, m_text_len,
902                        "Restore data: backup %u from node %u "
903                        "#Records: %llu Data: %llu bytes",
904                        theData[1], theData[2],
905                        make_uint64(theData[3], theData[4]),
906                        make_uint64(theData[5], theData[6]));
907 }
getTextRestoreLog(QQQQ)908 void getTextRestoreLog(QQQQ)
909 {
910   BaseString::snprintf(m_text, m_text_len,
911                        "Restore log: backup %u from node %u "
912                        "#Records: %llu Data: %llu bytes",
913                        theData[1], theData[2],
914                        make_uint64(theData[3], theData[4]),
915                        make_uint64(theData[5], theData[6]));
916 }
getTextRestoreCompleted(QQQQ)917 void getTextRestoreCompleted(QQQQ)
918 {
919   BaseString::snprintf(m_text, m_text_len,
920                        "Restore completed: backup %u from node %u",
921                        theData[1], theData[2]);
922 }
getTextLogFileInitStatus(QQQQ)923 void getTextLogFileInitStatus(QQQQ) {
924   if (theData[2])
925     BaseString::snprintf(m_text, m_text_len,
926                          "Local redo log file initialization status:\n"
927                          "#Total files: %u, Completed: %u\n"
928                          "#Total MBytes: %u, Completed: %u",
929 //                         refToNode(theData[1]),
930                          theData[2], theData[3],
931                          theData[4], theData[5]);
932   else
933     BaseString::snprintf(m_text, m_text_len,
934                          "Node %u: Log file initializtion completed",
935                           refToNode(theData[1]));
936 }
getTextLogFileInitCompStatus(QQQQ)937 void getTextLogFileInitCompStatus(QQQQ) {
938     BaseString::snprintf(m_text, m_text_len,
939                          "Local redo log file initialization completed:\n"
940                          "#Total files: %u, Completed: %u\n"
941                          "#Total MBytes: %u, Completed: %u",
942 //                         refToNode(theData[1]),
943                          theData[2], theData[3],
944                          theData[4], theData[5]);
945 }
getTextSingleUser(QQQQ)946 void getTextSingleUser(QQQQ) {
947   switch (theData[1])
948   {
949   case 0:
950     BaseString::snprintf(m_text, m_text_len, "Entering single user mode");
951     break;
952   case 1:
953     BaseString::snprintf(m_text, m_text_len,
954 			 "Entered single user mode "
955 			 "Node %d has exclusive access", theData[2]);
956     break;
957   case 2:
958     BaseString::snprintf(m_text, m_text_len,"Exiting single user mode");
959     break;
960   default:
961     BaseString::snprintf(m_text, m_text_len,
962 			 "Unknown single user report %d", theData[1]);
963     break;
964   }
965 }
966 
getTextStartReport(QQQQ)967 void getTextStartReport(QQQQ) {
968   Uint32 time = theData[2];
969   Uint32 sz = theData[3];
970   BaseString
971     bstr0 = BaseString::getPrettyText(sz, theData + 4 + (0 * sz)),
972     bstr1 = BaseString::getPrettyText(sz, theData + 4 + (1 * sz)),
973     bstr2 = BaseString::getPrettyText(sz, theData + 4 + (2 * sz)),
974     bstr3 = BaseString::getPrettyText(sz, theData + 4 + (3 * sz)),
975     bstr4 = BaseString::getPrettyText(sz, theData + 4 + (4 * sz));
976 
977   if (len < 4 + 5 * sz)
978   {
979     bstr4.assign("<unknown>");
980   }
981 
982   switch(theData[1]){
983   case 1: // Wait initial
984     BaseString::snprintf
985       (m_text, m_text_len,
986        "Initial start, waiting for %s to connect, "
987        " nodes [ all: %s connected: %s no-wait: %s ]",
988        bstr3.c_str(), bstr0.c_str(), bstr1.c_str(), bstr2.c_str());
989     break;
990   case 2: // Wait partial
991     BaseString::snprintf
992       (m_text, m_text_len,
993        "Waiting until nodes: %s connects, "
994        "nodes [ all: %s connected: %s no-wait: %s ]",
995        bstr3.c_str(), bstr0.c_str(), bstr1.c_str(), bstr2.c_str());
996     break;
997   case 3: // Wait partial timeout
998     BaseString::snprintf
999       (m_text, m_text_len,
1000        "Waiting %u sec for nodes %s to connect, "
1001        "nodes [ all: %s connected: %s no-wait: %s ]",
1002        time, bstr3.c_str(), bstr0.c_str(), bstr1.c_str(), bstr2.c_str());
1003     break;
1004   case 4: // Wait partioned
1005     BaseString::snprintf
1006       (m_text, m_text_len,
1007        "Waiting for non partitioned start, "
1008        "nodes [ all: %s connected: %s missing: %s no-wait: %s ]",
1009        bstr0.c_str(), bstr1.c_str(), bstr3.c_str(), bstr2.c_str());
1010     break;
1011   case 5:
1012     BaseString::snprintf
1013       (m_text, m_text_len,
1014        "Waiting %u sec for non partitioned start, "
1015        "nodes [ all: %s connected: %s missing: %s no-wait: %s ]",
1016        time, bstr0.c_str(), bstr1.c_str(), bstr3.c_str(), bstr2.c_str());
1017     break;
1018   case 6:
1019     BaseString::snprintf
1020       (m_text, m_text_len,
1021        "Initial start, waiting %u for %s to connect, "
1022        "nodes [ all: %s connected: %s missing: %s no-wait: %s no-nodegroup: %s ]",
1023        time, bstr4.c_str(),
1024        bstr0.c_str(), bstr1.c_str(), bstr3.c_str(), bstr2.c_str(),
1025        bstr4.c_str());
1026     break;
1027   case 7: // Wait no-nodes/partial timeout
1028     BaseString::snprintf
1029       (m_text, m_text_len,
1030        "Waiting %u sec for nodes %s to connect, "
1031        "nodes [ all: %s connected: %s no-wait: %s no-nodegroup: %s ]",
1032        time, bstr3.c_str(), bstr0.c_str(), bstr1.c_str(), bstr2.c_str(),
1033        bstr4.c_str());
1034     break;
1035 
1036   case 0x8000: // Do initial
1037     BaseString::snprintf
1038       (m_text, m_text_len,
1039        "Initial start with nodes %s [ missing: %s no-wait: %s ]",
1040        bstr1.c_str(), bstr3.c_str(), bstr2.c_str());
1041     break;
1042   case 0x8001: // Do start
1043     BaseString::snprintf
1044       (m_text, m_text_len,
1045        "Start with all nodes %s",
1046        bstr1.c_str());
1047     break;
1048   case 0x8002: // Do partial
1049     BaseString::snprintf
1050       (m_text, m_text_len,
1051        "Start with nodes %s [ missing: %s no-wait: %s ]",
1052        bstr1.c_str(), bstr3.c_str(), bstr2.c_str());
1053     break;
1054   case 0x8003: // Do partioned
1055     BaseString::snprintf
1056       (m_text, m_text_len,
1057        "Start potentially partitioned with nodes %s "
1058        " [ missing: %s no-wait: %s ]",
1059        bstr1.c_str(), bstr3.c_str(), bstr2.c_str());
1060     break;
1061   default:
1062     BaseString::snprintf
1063       (m_text, m_text_len,
1064        "Unknown startreport: 0x%x [ %s %s %s %s ]",
1065        theData[1],
1066        bstr0.c_str(), bstr1.c_str(), bstr2.c_str(), bstr3.c_str());
1067   }
1068 }
getTextMTSignalStatistics(QQQQ)1069 void getTextMTSignalStatistics(QQQQ) {
1070   BaseString::snprintf(m_text, m_text_len,
1071 		       "Signals delivered from thread %u: "
1072                        "prio A %u (%u bytes) prio B %u (%u bytes)",
1073 		       theData[1],
1074                        theData[2], theData[3], theData[4], theData[5]);
1075 }
1076 
getTextSubscriptionStatus(QQQQ)1077 void getTextSubscriptionStatus(QQQQ)
1078 {
1079   switch(theData[1]) {
1080   case(1): // SubscriptionStatus::DISCONNECTED
1081     BaseString::snprintf(m_text, m_text_len,
1082                          "Disconnecting node %u because it has "
1083                          "exceeded MaxBufferedEpochs (%u > %u), epoch %u/%u",
1084                          theData[2],
1085                          theData[5],
1086                          theData[6],
1087                          theData[4], theData[3]);
1088     break;
1089   case(2): // SubscriptionStatus::INCONSISTENT
1090     BaseString::snprintf(m_text, m_text_len,
1091                          "Nodefailure while out of event buffer: "
1092                          "informing subscribers of possibly missing event data"
1093                          ", epoch %u/%u",
1094                          theData[4], theData[3]);
1095     break;
1096   }
1097 }
1098 
1099 void
getTextStartReadLCP(QQQQ)1100 getTextStartReadLCP(QQQQ)
1101 {
1102   BaseString::snprintf(m_text, m_text_len,
1103                        "Start reading LCP for table %u fragment: %u",
1104                        theData[1],
1105                        theData[2]);
1106 }
1107 
1108 void
getTextReadLCPComplete(QQQQ)1109 getTextReadLCPComplete(QQQQ)
1110 {
1111   BaseString::snprintf(m_text, m_text_len,
1112                        "Restored LCP for table %u fragment: %u rows: %llu",
1113                        theData[1],
1114                        theData[2],
1115                        (Uint64(theData[3]) << 32) + Uint64(theData[4]));
1116 }
1117 
1118 void
getTextRunRedo(QQQQ)1119 getTextRunRedo(QQQQ)
1120 {
1121   const ndb_logevent_RunRedo * ev = (const ndb_logevent_RunRedo*)(theData+1);
1122   if (ev->currgci == ev->startgci)
1123   {
1124     BaseString::snprintf(m_text, m_text_len,
1125                          "Log part: %u phase: %u run redo from "
1126                          " gci: %u (file: %u mb: %u) to "
1127                          " gci: %u (file: %u mb: %u)",
1128                          ev->logpart,
1129                          ev->phase,
1130                          ev->startgci,
1131                          ev->startfile,
1132                          ev->startmb,
1133                          ev->stopgci,
1134                          ev->stopfile,
1135                          ev->stopmb);
1136   }
1137   else if (ev->currgci == ev->stopgci)
1138   {
1139     BaseString::snprintf(m_text, m_text_len,
1140                          "Log part: %u phase: %u found stop "
1141                          " gci: %u (file: %u mb: %u)",
1142                          ev->logpart,
1143                          ev->phase,
1144                          ev->currgci,
1145                          ev->currfile,
1146                          ev->currmb);
1147   }
1148   else
1149   {
1150     BaseString::snprintf(m_text, m_text_len,
1151                          "Log part: %u phase: %u at "
1152                          " gci: %u (file: %u mb: %u)",
1153                          ev->logpart,
1154                          ev->phase,
1155                          ev->currgci,
1156                          ev->currfile,
1157                          ev->currmb);
1158   }
1159 }
1160 
1161 void
getTextRebuildIndex(QQQQ)1162 getTextRebuildIndex(QQQQ)
1163 {
1164   BaseString::snprintf(m_text, m_text_len,
1165                        "instace: %u rebuild index: %u",
1166                        theData[1],
1167                        theData[2]);
1168 }
1169 
1170 const
1171 char*
getObjectTypeName(Uint32 type)1172 getObjectTypeName(Uint32 type)
1173 {
1174   return "object";
1175 }
1176 
1177 void
getTextCreateSchemaObject(QQQQ)1178 getTextCreateSchemaObject(QQQQ)
1179 {
1180   BaseString::snprintf(m_text, m_text_len,
1181                        "create %s id: %u version: %u (from %u)",
1182                        getObjectTypeName(theData[3]),
1183                        theData[1],
1184                        theData[2],
1185                        theData[4]);
1186 }
1187 
1188 void
getTextAlterSchemaObject(QQQQ)1189 getTextAlterSchemaObject(QQQQ)
1190 {
1191   BaseString::snprintf(m_text, m_text_len,
1192                        "alter %s id: %u version: %u (from %u)",
1193                        getObjectTypeName(theData[3]),
1194                        theData[1],
1195                        theData[2],
1196                        theData[4]);
1197 }
1198 
1199 void
getTextDropSchemaObject(QQQQ)1200 getTextDropSchemaObject(QQQQ)
1201 {
1202   BaseString::snprintf(m_text, m_text_len,
1203                        "drop %s id: %u version: %u (from %u)",
1204                        getObjectTypeName(theData[3]),
1205                        theData[1],
1206                        theData[2],
1207                        theData[4]);
1208 }
1209 
getTextSavedEvent(QQQQ)1210 void getTextSavedEvent(QQQQ)
1211 {
1212   abort();
1213 }
1214 
getTextConnectCheckStarted(QQQQ)1215 void getTextConnectCheckStarted(QQQQ)
1216 {
1217   /* EventReport format :
1218    * 1 : other_node_count
1219    * 2 : reason (FailRep causes or 0)
1220    * 3 : causing_node (if from FailRep)
1221    * 4 : bitmask wordsize
1222    * 5 : bitmask[2]
1223    */
1224   Uint32 other_node_count = theData[1];
1225   Uint32 reason = theData[2];
1226   Uint32 causing_node = theData[3];
1227   Uint32 bitmaskSz = theData[4];
1228   char otherNodeMask[100];
1229   char suspectNodeMask[100];
1230   BitmaskImpl::getText(bitmaskSz, theData + 5 + (0 * bitmaskSz), otherNodeMask);
1231   BitmaskImpl::getText(bitmaskSz, theData + 5 + (1 * bitmaskSz), suspectNodeMask);
1232   Uint32 suspectCount = BitmaskImpl::count(bitmaskSz, theData + 5 + (1 * bitmaskSz));
1233 
1234   if (reason)
1235   {
1236     /* Connect check started for specific reason */
1237     const char * reasonText = NULL;
1238     switch (reason)
1239     {
1240     case FailRep::ZHEARTBEAT_FAILURE:
1241       reasonText = "Heartbeat failure";
1242       break;
1243     case FailRep::ZCONNECT_CHECK_FAILURE:
1244       reasonText = "Connectivity check request";
1245       break;
1246     default:
1247       reasonText = "UNKNOWN";
1248       break;
1249     }
1250 
1251     BaseString::snprintf(m_text, m_text_len,
1252                          "Connectivity Check of %u other nodes (%s) started due to %s from node %u.",
1253                          other_node_count,
1254                          otherNodeMask,
1255                          reasonText,
1256                          causing_node);
1257   }
1258   else
1259   {
1260     /* Connect check restarted due to suspect nodes */
1261     BaseString::snprintf(m_text, m_text_len,
1262                          "Connectivity Check of %u nodes (%s) restarting due to %u suspect nodes (%s).",
1263                          other_node_count,
1264                          otherNodeMask,
1265                          suspectCount,
1266                          suspectNodeMask);
1267   }
1268 }
1269 
getTextConnectCheckCompleted(QQQQ)1270 void getTextConnectCheckCompleted(QQQQ)
1271 {
1272   /* EventReport format
1273    * 1 : Nodes checked
1274    * 2 : Suspect nodes
1275    * 3 : Failed nodes
1276    */
1277 
1278   Uint32 nodes_checked = theData[1];
1279   Uint32 suspect_nodes = theData[2];
1280   Uint32 failed_nodes = theData[3];
1281 
1282   if ((failed_nodes + suspect_nodes) == 0)
1283   {
1284     /* All connectivity ok */
1285     BaseString::snprintf(m_text, m_text_len,
1286                          "Connectivity Check completed on %u nodes, connectivity ok",
1287                          nodes_checked);
1288   }
1289   else
1290   {
1291     if (failed_nodes > 0)
1292     {
1293       if (suspect_nodes > 0)
1294       {
1295         BaseString::snprintf(m_text, m_text_len,
1296                              "Connectivity Check completed on %u nodes.  %u nodes failed.  "
1297                              "%u nodes still suspect, repeating check.",
1298                              nodes_checked,
1299                              failed_nodes,
1300                              suspect_nodes);
1301       }
1302       else
1303       {
1304         BaseString::snprintf(m_text, m_text_len,
1305                              "Connectivity Check completed on %u nodes.  %u nodes failed.  "
1306                              "Connectivity now OK",
1307                              nodes_checked,
1308                              failed_nodes);
1309       }
1310     }
1311     else
1312     {
1313       /* Just suspect nodes */
1314       BaseString::snprintf(m_text, m_text_len,
1315                            "Connectivity Check completed on %u nodes.  %u nodes still suspect, "
1316                            "repeating check.",
1317                            nodes_checked,
1318                            suspect_nodes);
1319     }
1320   }
1321 }
1322 
getTextNodeFailRejected(QQQQ)1323 void getTextNodeFailRejected(QQQQ)
1324 {
1325   Uint32 reason = theData[1];
1326   Uint32 failed_node = theData[2];
1327   Uint32 source_node = theData[3];
1328 
1329   const char* reasonText = "Unknown";
1330   switch (reason)
1331   {
1332   case FailRep::ZCONNECT_CHECK_FAILURE:
1333     reasonText = "Connect Check Failure";
1334     break;
1335   case FailRep::ZLINK_FAILURE:
1336     reasonText = "Link Failure";
1337     break;
1338   }
1339 
1340   BaseString::snprintf(m_text, m_text_len,
1341                        "Received FAIL_REP (%s (%u)) for node %u sourced by suspect node %u.  "
1342                        "Rejecting as failure of node %u.",
1343                        reasonText,
1344                        reason,
1345                        failed_node,
1346                        source_node,
1347                        source_node);
1348 }
1349 
1350 #if 0
1351 BaseString::snprintf(m_text,
1352 		     m_text_len,
1353 		     "Unknown event: %d",
1354 		     theData[0]);
1355 #endif
1356 
1357 /**
1358  * This matrix defines which event should be printed when
1359  *
1360  * threshold - is in range [0-15]
1361  * severity  - DEBUG to ALERT (Type of log message)
1362  */
1363 
1364 #define ROW(a,b,c,d) \
1365 { NDB_LE_ ## a, b, c, d, getText ## a}
1366 
1367 const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = {
1368   // CONNECTION
1369   ROW(Connected,               LogLevel::llConnection,  8, Logger::LL_INFO ),
1370   ROW(Disconnected,            LogLevel::llConnection,  8, Logger::LL_ALERT ),
1371   ROW(CommunicationClosed,     LogLevel::llConnection,  8, Logger::LL_INFO ),
1372   ROW(CommunicationOpened,     LogLevel::llConnection,  8, Logger::LL_INFO ),
1373   ROW(ConnectedApiVersion,     LogLevel::llConnection,  8, Logger::LL_INFO ),
1374   // CHECKPOINT
1375   ROW(GlobalCheckpointStarted, LogLevel::llCheckpoint,  9, Logger::LL_INFO ),
1376   ROW(GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO ),
1377   ROW(LocalCheckpointStarted,  LogLevel::llCheckpoint,  7, Logger::LL_INFO ),
1378   ROW(LocalCheckpointCompleted,LogLevel::llCheckpoint,  7, Logger::LL_INFO ),
1379   ROW(LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint,  0, Logger::LL_ALERT ),
1380   ROW(LCPFragmentCompleted,    LogLevel::llCheckpoint, 11, Logger::LL_INFO ),
1381   ROW(UndoLogBlocked,          LogLevel::llCheckpoint,  7, Logger::LL_INFO ),
1382   ROW(RedoStatus,              LogLevel::llCheckpoint,  7, Logger::LL_INFO ),
1383 
1384   // STARTUP
1385   ROW(NDBStartStarted,         LogLevel::llStartUp,     1, Logger::LL_INFO ),
1386   ROW(NDBStartCompleted,       LogLevel::llStartUp,     1, Logger::LL_INFO ),
1387   ROW(STTORRYRecieved,         LogLevel::llStartUp,    15, Logger::LL_INFO ),
1388   ROW(StartPhaseCompleted,     LogLevel::llStartUp,     4, Logger::LL_INFO ),
1389   ROW(CM_REGCONF,              LogLevel::llStartUp,     3, Logger::LL_INFO ),
1390   ROW(CM_REGREF,               LogLevel::llStartUp,     8, Logger::LL_INFO ),
1391   ROW(FIND_NEIGHBOURS,         LogLevel::llStartUp,     8, Logger::LL_INFO ),
1392   ROW(NDBStopStarted,          LogLevel::llStartUp,     1, Logger::LL_INFO ),
1393   ROW(NDBStopCompleted,        LogLevel::llStartUp,     1, Logger::LL_INFO ),
1394   ROW(NDBStopForced,           LogLevel::llStartUp,     1, Logger::LL_ALERT ),
1395   ROW(NDBStopAborted,          LogLevel::llStartUp,     1, Logger::LL_INFO ),
1396   ROW(StartREDOLog,            LogLevel::llStartUp,     4, Logger::LL_INFO ),
1397   ROW(StartLog,                LogLevel::llStartUp,    10, Logger::LL_INFO ),
1398   ROW(UNDORecordsExecuted,     LogLevel::llStartUp,    15, Logger::LL_INFO ),
1399   ROW(StartReport,             LogLevel::llStartUp,     4, Logger::LL_INFO ),
1400   ROW(LogFileInitStatus,       LogLevel::llStartUp,     7, Logger::LL_INFO),
1401   ROW(LogFileInitCompStatus,   LogLevel::llStartUp,     7, Logger::LL_INFO),
1402   ROW(StartReadLCP,            LogLevel::llStartUp,    10, Logger::LL_INFO),
1403   ROW(ReadLCPComplete,         LogLevel::llStartUp,    10, Logger::LL_INFO),
1404   ROW(RunRedo,                 LogLevel::llStartUp,     8, Logger::LL_INFO),
1405   ROW(RebuildIndex,            LogLevel::llStartUp,    10, Logger::LL_INFO),
1406 
1407   // NODERESTART
1408   ROW(NR_CopyDict,             LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1409   ROW(NR_CopyDistr,            LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1410   ROW(NR_CopyFragsStarted,     LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1411   ROW(NR_CopyFragDone,         LogLevel::llNodeRestart,10, Logger::LL_INFO ),
1412   ROW(NR_CopyFragsCompleted,   LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1413 
1414   ROW(NodeFailCompleted,       LogLevel::llNodeRestart, 8, Logger::LL_ALERT),
1415   ROW(NODE_FAILREP,            LogLevel::llNodeRestart, 8, Logger::LL_ALERT),
1416   ROW(ArbitState,		LogLevel::llNodeRestart, 6, Logger::LL_INFO ),
1417   ROW(ArbitResult,	        LogLevel::llNodeRestart, 2, Logger::LL_ALERT),
1418   ROW(GCP_TakeoverStarted,     LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1419   ROW(GCP_TakeoverCompleted,   LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1420   ROW(LCP_TakeoverStarted,     LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1421   ROW(LCP_TakeoverCompleted,   LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
1422 
1423   ROW(ConnectCheckStarted,     LogLevel::llNodeRestart, 6, Logger::LL_INFO ),
1424   ROW(ConnectCheckCompleted,   LogLevel::llNodeRestart, 6, Logger::LL_INFO ),
1425   ROW(NodeFailRejected,        LogLevel::llNodeRestart, 6, Logger::LL_ALERT ),
1426 
1427   // STATISTIC
1428   ROW(TransReportCounters,     LogLevel::llStatistic,   8, Logger::LL_INFO ),
1429   ROW(OperationReportCounters, LogLevel::llStatistic,   8, Logger::LL_INFO ),
1430   ROW(TableCreated,            LogLevel::llStatistic,   7, Logger::LL_INFO ),
1431   ROW(JobStatistic,            LogLevel::llStatistic,   9, Logger::LL_INFO ),
1432   ROW(ThreadConfigLoop,        LogLevel::llStatistic,   9, Logger::LL_INFO ),
1433   ROW(SendBytesStatistic,      LogLevel::llStatistic,   9, Logger::LL_INFO ),
1434   ROW(ReceiveBytesStatistic,   LogLevel::llStatistic,   9, Logger::LL_INFO ),
1435   ROW(MemoryUsage,             LogLevel::llStatistic,   5, Logger::LL_INFO ),
1436   ROW(MTSignalStatistics,      LogLevel::llStatistic,   9, Logger::LL_INFO ),
1437 
1438   // Schema
1439   ROW(CreateSchemaObject,      LogLevel::llSchema,      8, Logger::LL_INFO ),
1440   ROW(AlterSchemaObject,       LogLevel::llSchema,      8, Logger::LL_INFO ),
1441   ROW(DropSchemaObject,        LogLevel::llSchema,      8, Logger::LL_INFO ),
1442 
1443   // ERROR
1444   ROW(TransporterError,        LogLevel::llError,  2, Logger::LL_ERROR   ),
1445   ROW(TransporterWarning,      LogLevel::llError,  8, Logger::LL_WARNING ),
1446   ROW(MissedHeartbeat,         LogLevel::llError,  8, Logger::LL_WARNING ),
1447   ROW(DeadDueToHeartbeat,      LogLevel::llError,  8, Logger::LL_ALERT   ),
1448   ROW(WarningEvent,            LogLevel::llError,  2, Logger::LL_WARNING ),
1449   ROW(SubscriptionStatus,      LogLevel::llError,  4, Logger::LL_WARNING ),
1450   // INFO
1451   ROW(SentHeartbeat,           LogLevel::llInfo,  12, Logger::LL_INFO ),
1452   ROW(CreateLogBytes,          LogLevel::llInfo,  11, Logger::LL_INFO ),
1453   ROW(InfoEvent,               LogLevel::llInfo,   2, Logger::LL_INFO ),
1454   ROW(EventBufferStatus,       LogLevel::llInfo,   7, Logger::LL_INFO ),
1455 
1456   //Single User
1457   ROW(SingleUser,              LogLevel::llInfo,   7, Logger::LL_INFO ),
1458 
1459   // Backup
1460   ROW(BackupStarted,           LogLevel::llBackup, 7, Logger::LL_INFO ),
1461   ROW(BackupStatus,            LogLevel::llBackup, 7, Logger::LL_INFO ),
1462   ROW(BackupCompleted,         LogLevel::llBackup, 7, Logger::LL_INFO ),
1463   ROW(BackupFailedToStart,     LogLevel::llBackup, 7, Logger::LL_ALERT),
1464   ROW(BackupAborted,           LogLevel::llBackup, 7, Logger::LL_ALERT),
1465   ROW(RestoreStarted,          LogLevel::llBackup, 7, Logger::LL_INFO ),
1466   ROW(RestoreMetaData,         LogLevel::llBackup, 7, Logger::LL_INFO ),
1467   ROW(RestoreData,             LogLevel::llBackup, 7, Logger::LL_INFO ),
1468   ROW(RestoreLog,              LogLevel::llBackup, 7, Logger::LL_INFO ),
1469   ROW(RestoreCompleted,        LogLevel::llBackup, 7, Logger::LL_INFO ),
1470 
1471   ROW(SavedEvent,              LogLevel::llInfo,   7, Logger::LL_INFO)
1472 };
1473 
1474 const Uint32 EventLoggerBase::matrixSize=
1475 sizeof(EventLoggerBase::matrix)/sizeof(EventRepLogLevelMatrix);
1476 
EventLogger()1477 EventLogger::EventLogger()
1478 {
1479   setCategory("EventLogger");
1480   enable(Logger::LL_INFO, Logger::LL_ALERT);
1481 }
1482 
~EventLogger()1483 EventLogger::~EventLogger()
1484 {
1485 }
1486 
1487 void
close()1488 EventLogger::close()
1489 {
1490   removeAllHandlers();
1491 }
1492 
1493 #ifdef NOT_USED
1494 
1495 static NdbOut&
operator <<(NdbOut & out,const LogLevel & ll)1496 operator<<(NdbOut& out, const LogLevel & ll)
1497 {
1498   out << "[LogLevel: ";
1499   for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
1500     out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
1501   out << "]";
1502   return out;
1503 }
1504 #endif
1505 
1506 int
event_lookup(int eventType,LogLevel::EventCategory & cat,Uint32 & threshold,Logger::LoggerLevel & severity,EventTextFunction & textF)1507 EventLoggerBase::event_lookup(int eventType,
1508 			      LogLevel::EventCategory &cat,
1509 			      Uint32 &threshold,
1510 			      Logger::LoggerLevel &severity,
1511 			      EventTextFunction &textF)
1512 {
1513   for(unsigned i = 0; i<EventLoggerBase::matrixSize; i++){
1514     if(EventLoggerBase::matrix[i].eventType == eventType){
1515       cat = EventLoggerBase::matrix[i].eventCategory;
1516       threshold = EventLoggerBase::matrix[i].threshold;
1517       severity = EventLoggerBase::matrix[i].severity;
1518       textF= EventLoggerBase::matrix[i].textF;
1519       return 0;
1520     }
1521   }
1522   return 1;
1523 }
1524 
1525 const char*
getText(char * dst,size_t dst_len,EventTextFunction textF,const Uint32 * theData,Uint32 len,NodeId nodeId)1526 EventLogger::getText(char * dst, size_t dst_len,
1527 		     EventTextFunction textF,
1528 		     const Uint32* theData, Uint32 len, NodeId nodeId )
1529 {
1530   int pos= 0;
1531   if (nodeId != 0)
1532   {
1533     BaseString::snprintf(dst, dst_len, "Node %u: ", nodeId);
1534     pos= strlen(dst);
1535   }
1536   if (dst_len-pos > 0)
1537     textF(dst+pos, dst_len-pos, theData, len);
1538   return dst;
1539 }
1540 
1541 void
log(int eventType,const Uint32 * theData,Uint32 len,NodeId nodeId,const LogLevel * ll)1542 EventLogger::log(int eventType, const Uint32* theData, Uint32 len,
1543 		 NodeId nodeId, const LogLevel* ll)
1544 {
1545   Uint32 threshold = 0;
1546   Logger::LoggerLevel severity = Logger::LL_WARNING;
1547   LogLevel::EventCategory cat= LogLevel::llInvalid;
1548   EventTextFunction textF;
1549   char log_text[MAX_TEXT_LENGTH];
1550 
1551   DBUG_ENTER("EventLogger::log");
1552   DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId));
1553 
1554   if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF))
1555     DBUG_VOID_RETURN;
1556 
1557   Uint32 set = ll?ll->getLogLevel(cat) : m_logLevel.getLogLevel(cat);
1558   DBUG_PRINT("info",("threshold=%d, set=%d", threshold, set));
1559   if (ll)
1560     DBUG_PRINT("info",("m_logLevel.getLogLevel=%d", m_logLevel.getLogLevel(cat)));
1561 
1562   if (threshold <= set){
1563     getText(log_text, sizeof(log_text), textF, theData, len, nodeId);
1564 
1565     switch (severity){
1566     case Logger::LL_ALERT:
1567       alert("%s", log_text);
1568       break;
1569     case Logger::LL_CRITICAL:
1570       critical("%s", log_text);
1571       break;
1572     case Logger::LL_WARNING:
1573       warning("%s", log_text);
1574       break;
1575     case Logger::LL_ERROR:
1576       error("%s", log_text);
1577       break;
1578     case Logger::LL_INFO:
1579       info("%s", log_text);
1580       break;
1581     case Logger::LL_DEBUG:
1582       debug("%s", log_text);
1583       break;
1584     default:
1585       info("%s", log_text);
1586       break;
1587     }
1588   } // if (..
1589   DBUG_VOID_RETURN;
1590 }
1591 
1592 EventLogger*
create_event_logger()1593 create_event_logger()
1594 {
1595   return new EventLogger();
1596 }
1597 
1598 void
destroy_event_logger(class EventLogger ** g_eventLogger)1599 destroy_event_logger(class EventLogger ** g_eventLogger)
1600 {
1601   delete *g_eventLogger;
1602   *g_eventLogger = 0;
1603 }
1604