diff options
author | unknown <tomas@poseidon.ndb.mysql.com> | 2005-01-19 08:14:52 +0100 |
---|---|---|
committer | unknown <tomas@poseidon.ndb.mysql.com> | 2005-01-19 08:14:52 +0100 |
commit | 3f255881357808f348a20edb50b3c033312b6b68 (patch) | |
tree | 43ecce321a36b04de9127334f273f729c3a9199f | |
parent | 0eb1a8107f2b245b6bbcdc78d0a49a78996df3c9 (diff) | |
download | mariadb-git-3f255881357808f348a20edb50b3c033312b6b68.tar.gz |
WL#2299, structured log events
-rw-r--r-- | ndb/docs/doxygen/Doxyfile.mgmapi | 3 | ||||
-rw-r--r-- | ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp | 104 | ||||
-rw-r--r-- | ndb/include/debugger/EventLogger.hpp | 29 | ||||
-rw-r--r-- | ndb/include/kernel/LogLevel.hpp | 2 | ||||
-rw-r--r-- | ndb/include/kernel/signaldata/SignalData.hpp | 4 | ||||
-rw-r--r-- | ndb/include/mgmapi/mgmapi.h | 197 | ||||
-rw-r--r-- | ndb/include/mgmapi/ndb_logevent.h | 468 | ||||
-rw-r--r-- | ndb/src/common/debugger/EventLogger.cpp | 1957 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp | 3 | ||||
-rw-r--r-- | ndb/src/mgmapi/Makefile.am | 2 | ||||
-rw-r--r-- | ndb/src/mgmapi/mgmapi.cpp | 18 | ||||
-rw-r--r-- | ndb/src/mgmapi/mgmapi_configuration.hpp | 16 | ||||
-rw-r--r-- | ndb/src/mgmapi/ndb_logevent.cpp | 477 | ||||
-rw-r--r-- | ndb/src/mgmapi/ndb_logevent.hpp | 34 | ||||
-rw-r--r-- | ndb/src/mgmsrv/MgmtSrvr.hpp | 1 | ||||
-rw-r--r-- | ndb/src/mgmsrv/Services.cpp | 46 |
16 files changed, 1966 insertions, 1395 deletions
diff --git a/ndb/docs/doxygen/Doxyfile.mgmapi b/ndb/docs/doxygen/Doxyfile.mgmapi index db0b31f11ab..1e743dcb60e 100644 --- a/ndb/docs/doxygen/Doxyfile.mgmapi +++ b/ndb/docs/doxygen/Doxyfile.mgmapi @@ -688,7 +688,8 @@ INCLUDE_FILE_PATTERNS = # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. -PREDEFINED = DOXYGEN_SHOULD_SKIP_DEPRECATED \ +PREDEFINED = DOXYGEN_FIX \ + DOXYGEN_SHOULD_SKIP_DEPRECATED \ DOXYGEN_SHOULD_SKIP_INTERNAL \ protected=private diff --git a/ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp b/ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp new file mode 100644 index 00000000000..abd8089a286 --- /dev/null +++ b/ndb/examples/mgmapi_logevent_example/mgmapi_logevent.cpp @@ -0,0 +1,104 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <mysql.h> +#include <ndbapi/NdbApi.hpp> +#include <mgmapi.h> +#include <stdio.h> + +/* + * export LD_LIBRARY_PATH=../../../libmysql_r/.libs:../../../ndb/src/.libs + */ + +#define MGMERROR(h) \ +{ \ + fprintf(stderr, "code: %d msg: %s\n", \ + ndb_mgm_get_latest_error(h), \ + ndb_mgm_get_latest_error_msg(h)); \ + exit(-1); \ +} + +#define LOGEVENTERROR(h) \ +{ \ + fprintf(stderr, "code: %d msg: %s\n", \ + ndb_logevent_get_latest_error(h), \ + ndb_logevent_get_latest_error_msg(h)); \ + exit(-1); \ +} + +int main() +{ + NdbMgmHandle h; + NdbLogEventHandle l; + int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; + struct ndb_logevent event; + + ndb_init(); + + h= ndb_mgm_create_handle(); + if ( h == 0) + { + printf("Unable to create handle\n"); + exit(-1); + } + if (ndb_mgm_connect(h,0,0,0)) MGMERROR(h); + + l= ndb_mgm_create_logevent_handle(h, filter); + if ( l == 0 ) MGMERROR(h); + + while (1) + { + int timeout= 5000; + int r= ndb_logevent_get_next(l,&event,timeout); + if (r == 0) + printf("No event within %d milliseconds\n", timeout); + else if (r < 0) + LOGEVENTERROR(l) + else + { + printf("Event %d from node ID %d\n", + event.type, + event.source_nodeid); + printf("Category %d, severity %d, level %d\n", + event.category, + event.severity, + event.level); + switch (event.type) { + case NDB_LE_BackupStarted: + printf("BackupStartded\n"); + printf("Starting node ID: %d\n", event.BackupStarted.starting_node); + printf("Backup ID: %d\n", event.BackupStarted.backup_id); + break; + case NDB_LE_BackupCompleted: + printf("BackupCompleted\n"); + printf("Backup ID: %d\n", event.BackupStarted.backup_id); + break; + case NDB_LE_BackupAborted: + break; + case NDB_LE_BackupFailedToStart: + break; + default: + printf("Unexpected event\n"); + break; + } + } + } + + ndb_mgm_destroy_logevent_handle(&l); + ndb_mgm_destroy_handle(&h); + ndb_end(0); + return 0; +} diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp index 7c45dbd353d..6308cf25465 100644 --- a/ndb/include/debugger/EventLogger.hpp +++ b/ndb/include/debugger/EventLogger.hpp @@ -17,12 +17,12 @@ #ifndef EVENTLOGGER_H #define EVENTLOGGER_H -#include <Logger.hpp> -#include <FileLogHandler.hpp> -#include <GrepError.hpp> -#include <kernel_types.h> +#include <logger/Logger.hpp> +#include <logger/FileLogHandler.hpp> +#include "GrepError.hpp" +#include <kernel/kernel_types.h> #include <kernel/LogLevel.hpp> -#include <signaldata/EventReport.hpp> +#include <kernel/signaldata/EventReport.hpp> class EventLoggerBase { public: @@ -39,11 +39,14 @@ public: * threshold - is in range [0-15] * severity - DEBUG to ALERT (Type of log message) */ + typedef void (* EventTextFunction)(char *,size_t,const Uint32*); + struct EventRepLogLevelMatrix { - Ndb_logevent_type eventType; - LogLevel::EventCategory eventCategory; - Uint32 threshold; - Logger::LoggerLevel severity; + Ndb_logevent_type eventType; + LogLevel::EventCategory eventCategory; + Uint32 threshold; + Logger::LoggerLevel severity; + EventTextFunction textF; }; static const EventRepLogLevelMatrix matrix[]; @@ -51,7 +54,8 @@ public: static int event_lookup(int eventType, LogLevel::EventCategory &cat, Uint32 &threshold, - Logger::LoggerLevel &severity); + Logger::LoggerLevel &severity, + EventTextFunction &textF); }; /** @@ -130,17 +134,18 @@ public: * @param nodeId the node id of event origin. */ virtual void log(int, const Uint32*, NodeId = 0,const class LogLevel * = 0); + /** * Returns the event text for the specified event report type. * - * @param type the event type. + * @param textF print function for the event * @param theData the event data. * @param nodeId a node id. * @return the event report text. */ static const char* getText(char * dst, size_t dst_len, - int type, + EventTextFunction textF, const Uint32* theData, NodeId nodeId = 0); /** diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 382016ee761..60dcd36ab56 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -147,7 +147,7 @@ LogLevel::set_max(const LogLevel & org){ return * this; } -#include <signaldata/EventSubscribeReq.hpp> +#include "signaldata/EventSubscribeReq.hpp" inline LogLevel& diff --git a/ndb/include/kernel/signaldata/SignalData.hpp b/ndb/include/kernel/signaldata/SignalData.hpp index 2b29ca06ba0..f825b0feb7b 100644 --- a/ndb/include/kernel/signaldata/SignalData.hpp +++ b/ndb/include/kernel/signaldata/SignalData.hpp @@ -18,8 +18,8 @@ #define SIGNAL_DATA_H #include <ndb_global.h> -#include <ndb_limits.h> -#include <kernel_types.h> +#include <kernel/ndb_limits.h> +#include <kernel/kernel_types.h> #include <BaseString.hpp> #define ASSERT_BOOL(flag, message) assert(flag<=1) diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 3f8d29e13c1..de4286bdbfd 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -86,6 +86,53 @@ * int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; * int fd = ndb_mgm_listen_event(handle, filter); * @endcode + * + * + * @section secSLogEvents Structured Log Events + * + * The following steps are involved: + * - Create a NdbEventLogHandle using ndb_mgm_create_logevent_handle() + * - Wait and store log events using ndb_logevent_get_next() + * - The log event data is available in the struct ndb_logevent. The + * data which is specific to a particular event is stored in a union + * between structs so use ndb_logevent::type to decide which struct + * is valid. + * + * Sample code for listening to Backup related events. The availaable log + * events are listed in @ref ndb_logevent.h + * + * @code + * int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; + * NdbEventLogHandle le_handle= ndb_mgm_create_logevent_handle(handle, filter); + * struct ndb_logevent le; + * int r= ndb_logevent_get_next(le_handle,&le,0); + * if (r < 0) error + * else if (r == 0) no event + * + * switch (le.type) + * { + * case NDB_LE_BackupStarted: + * ... le.BackupStarted.starting_node; + * ... le.BackupStarted.backup_id; + * break; + * case NDB_LE_BackupFailedToStart: + * ... le.BackupFailedToStart.error; + * break; + * case NDB_LE_BackupCompleted: + * ... le.BackupCompleted.stop_gci; + * break; + * case NDB_LE_BackupAborted: + * ... le.BackupStarted.backup_id; + * break; + * default: + * break; + * } + * @endcode + */ + +/* + * @page ndb_logevent.h ndb_logevent.h + * @include ndb_logevent.h */ /** @addtogroup MGM_C_API @@ -93,6 +140,7 @@ */ #include <ndb_types.h> +#include "ndb_logevent.h" #include "mgmapi_config_parameters.h" #ifdef __cplusplus @@ -348,97 +396,6 @@ extern "C" { }; #endif - /** - * Log event severities (used to filter the cluster log, - * ndb_mgm_set_clusterlog_severity_filter(), and filter listening to events - * ndb_mgm_listen_event()) - */ - enum ndb_mgm_event_severity { - NDB_MGM_ILLEGAL_EVENT_SEVERITY = -1, - /* Must be a nonnegative integer (used for array indexing) */ - /** Cluster log on */ - NDB_MGM_EVENT_SEVERITY_ON = 0, - /** Used in NDB Cluster developement */ - NDB_MGM_EVENT_SEVERITY_DEBUG = 1, - /** Informational messages*/ - NDB_MGM_EVENT_SEVERITY_INFO = 2, - /** Conditions that are not error condition, but might require handling. - */ - NDB_MGM_EVENT_SEVERITY_WARNING = 3, - /** Conditions that, while not fatal, should be corrected. */ - NDB_MGM_EVENT_SEVERITY_ERROR = 4, - /** Critical conditions, like device errors or out of resources */ - NDB_MGM_EVENT_SEVERITY_CRITICAL = 5, - /** A condition that should be corrected immediately, - * such as a corrupted system - */ - NDB_MGM_EVENT_SEVERITY_ALERT = 6, - /* must be next number, works as bound in loop */ - /** All severities */ - NDB_MGM_EVENT_SEVERITY_ALL = 7 - }; - - /** - * Log event categories, used to set filter level on the log events using - * ndb_mgm_set_clusterlog_loglevel() and ndb_mgm_listen_event() - */ - enum ndb_mgm_event_category { - /** - * Invalid log event category - */ - NDB_MGM_ILLEGAL_EVENT_CATEGORY = -1, - /** - * Log events during all kinds of startups - */ - NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP, - /** - * Log events during shutdown - */ - NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN, - /** - * Statistics log events - */ - NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS, - /** - * Log events related to checkpoints - */ - NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT, - /** - * Log events during node restart - */ - NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART, - /** - * Log events related to connections between cluster nodes - */ - NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION, - /** - * Backup related log events - */ - NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP, - /** - * Congestion related log events - */ - NDB_MGM_EVENT_CATEGORY_CONGESTION = CFG_LOGLEVEL_CONGESTION, -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - /** - * Loglevel debug - */ - NDB_MGM_EVENT_CATEGORY_DEBUG = CFG_LOGLEVEL_DEBUG, -#endif - /** - * Uncategorized log events (severity info) - */ - NDB_MGM_EVENT_CATEGORY_INFO = CFG_LOGLEVEL_INFO, - /** - * Uncategorized log events (severity warning or higher) - */ - NDB_MGM_EVENT_CATEGORY_ERROR = CFG_LOGLEVEL_ERROR, -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_LOGLEVEL, - NDB_MGM_MAX_EVENT_CATEGORY = CFG_MAX_LOGLEVEL -#endif - }; - /***************************************************************************/ /** * @name Functions: Error Handling @@ -871,6 +828,64 @@ extern "C" { struct ndb_mgm_reply* reply); #endif + /** + * The NdbLogEventHandle + */ + typedef struct ndb_logevent_handle * NdbLogEventHandle; + + /** + * Listen to log events. + * + * @param handle NDB management handle. + * @param filter pairs of { level, ndb_mgm_event_category } that will be + * pushed to fd, level=0 ends list. + * + * @return NdbLogEventHandle + */ + NdbLogEventHandle ndb_mgm_create_logevent_handle(NdbMgmHandle, + const int filter[]); + void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle*); + + /** + * Retrieve filedescriptor from NdbLogEventHandle. May be used in + * e.g. an application select() statement. + * + * @note Do not attemt to read from it, it will corrupt the parsing. + * + * @return filedescriptor, -1 on failure. + */ + int ndb_logevent_get_fd(const NdbLogEventHandle); + + /** + * Attempt to retrieve next log event and will fill in the supplied + * struct dst + * + * @param dst Pointer to struct to fill in event information + * @param timeout_in_milliseconds Timeout for waiting for event + * + * @return >0 if event exists, 0 no event (timed out), or -1 on error. + * + * @note Return value <=0 will leave dst untouched + */ + int ndb_logevent_get_next(const NdbLogEventHandle, + struct ndb_logevent *dst, + unsigned timeout_in_milliseconds); + + /** + * Retrieve laterst error code + * + * @return error code + */ + int ndb_logevent_get_latest_error(const NdbLogEventHandle); + + /** + * Retrieve laterst error message + * + * @return error message + */ + const char *ndb_logevent_get_latest_error_msg(const NdbLogEventHandle); + + /** @} *********************************************************************/ /** * @name Functions: Backup diff --git a/ndb/include/mgmapi/ndb_logevent.h b/ndb/include/mgmapi/ndb_logevent.h index ca6f848206f..3ca744bcc2e 100644 --- a/ndb/include/mgmapi/ndb_logevent.h +++ b/ndb/include/mgmapi/ndb_logevent.h @@ -17,90 +17,542 @@ #ifndef NDB_LOGEVENT_H #define NDB_LOGEVENT_H +/** @addtogroup MGM_C_API + * @{ + */ + +#include "mgmapi_config_parameters.h" + #ifdef __cplusplus extern "C" { #endif + /** + * Available log events grouped by @ref ndb_mgm_event_category + */ + enum Ndb_logevent_type { - /* CONNECTION */ + + NDB_LE_ILLEGAL_TYPE = -1, + + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_Connected = 0, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_Disconnected = 1, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_CommunicationClosed = 2, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_CommunicationOpened = 3, + /** NDB_MGM_EVENT_CATEGORY_CONNECTION */ NDB_LE_ConnectedApiVersion = 51, - /* CHECKPOINT */ + + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_GlobalCheckpointStarted = 4, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_GlobalCheckpointCompleted = 5, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LocalCheckpointStarted = 6, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LocalCheckpointCompleted = 7, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LCPStoppedInCalcKeepGci = 8, + /** NDB_MGM_EVENT_CATEGORY_CHECKPOINT */ NDB_LE_LCPFragmentCompleted = 9, - /* STARTUP */ + + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStartStarted = 10, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStartCompleted = 11, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_STTORRYRecieved = 12, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_StartPhaseCompleted = 13, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_CM_REGCONF = 14, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_CM_REGREF = 15, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_FIND_NEIGHBOURS = 16, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStopStarted = 17, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_NDBStopAborted = 18, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_StartREDOLog = 19, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_StartLog = 20, + /** NDB_MGM_EVENT_CATEGORY_STARTUP */ NDB_LE_UNDORecordsExecuted = 21, - /* NODERESTART */ + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyDict = 22, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyDistr = 23, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyFragsStarted = 24, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyFragDone = 25, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NR_CopyFragsCompleted = 26, /* NODEFAIL */ + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NodeFailCompleted = 27, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_NODE_FAILREP = 28, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_ArbitState = 29, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_ArbitResult = 30, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_GCP_TakeoverStarted = 31, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_GCP_TakeoverCompleted = 32, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_LCP_TakeoverStarted = 33, + /** NDB_MGM_EVENT_CATEGORY_NODE_RESTART */ NDB_LE_LCP_TakeoverCompleted = 34, - /* STATISTIC */ + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_TransReportCounters = 35, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_OperationReportCounters = 36, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_TableCreated = 37, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_UndoLogBlocked = 38, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_JobStatistic = 39, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_SendBytesStatistic = 40, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_ReceiveBytesStatistic = 41, + /** NDB_MGM_EVENT_CATEGORY_STATISTIC */ NDB_LE_MemoryUsage = 50, - /* ERROR */ + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_TransporterError = 42, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_TransporterWarning = 43, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_MissedHeartbeat = 44, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_DeadDueToHeartbeat = 45, + /** NDB_MGM_EVENT_CATEGORY_ERROR */ NDB_LE_WarningEvent = 46, - /* INFO */ + /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_SentHeartbeat = 47, + /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_CreateLogBytes = 48, + /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_InfoEvent = 49, /* GREP */ NDB_LE_GrepSubscriptionInfo = 52, NDB_LE_GrepSubscriptionAlert = 53, - /* BACKUP */ + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupStarted = 54, + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupFailedToStart = 55, + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupCompleted = 56, + /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupAborted = 57 }; + /** + * Log event severities (used to filter the cluster log, + * ndb_mgm_set_clusterlog_severity_filter(), and filter listening to events + * ndb_mgm_listen_event()) + */ + enum ndb_mgm_event_severity { + NDB_MGM_ILLEGAL_EVENT_SEVERITY = -1, + /* Must be a nonnegative integer (used for array indexing) */ + /** Cluster log on */ + NDB_MGM_EVENT_SEVERITY_ON = 0, + /** Used in NDB Cluster developement */ + NDB_MGM_EVENT_SEVERITY_DEBUG = 1, + /** Informational messages*/ + NDB_MGM_EVENT_SEVERITY_INFO = 2, + /** Conditions that are not error condition, but might require handling. + */ + NDB_MGM_EVENT_SEVERITY_WARNING = 3, + /** Conditions that, while not fatal, should be corrected. */ + NDB_MGM_EVENT_SEVERITY_ERROR = 4, + /** Critical conditions, like device errors or out of resources */ + NDB_MGM_EVENT_SEVERITY_CRITICAL = 5, + /** A condition that should be corrected immediately, + * such as a corrupted system + */ + NDB_MGM_EVENT_SEVERITY_ALERT = 6, + /* must be next number, works as bound in loop */ + /** All severities */ + NDB_MGM_EVENT_SEVERITY_ALL = 7 + }; + + /** + * Log event categories, used to set filter level on the log events using + * ndb_mgm_set_clusterlog_loglevel() and ndb_mgm_listen_event() + */ + enum ndb_mgm_event_category { + /** + * Invalid log event category + */ + NDB_MGM_ILLEGAL_EVENT_CATEGORY = -1, + /** + * Log events during all kinds of startups + */ + NDB_MGM_EVENT_CATEGORY_STARTUP = CFG_LOGLEVEL_STARTUP, + /** + * Log events during shutdown + */ + NDB_MGM_EVENT_CATEGORY_SHUTDOWN = CFG_LOGLEVEL_SHUTDOWN, + /** + * Statistics log events + */ + NDB_MGM_EVENT_CATEGORY_STATISTIC = CFG_LOGLEVEL_STATISTICS, + /** + * Log events related to checkpoints + */ + NDB_MGM_EVENT_CATEGORY_CHECKPOINT = CFG_LOGLEVEL_CHECKPOINT, + /** + * Log events during node restart + */ + NDB_MGM_EVENT_CATEGORY_NODE_RESTART = CFG_LOGLEVEL_NODERESTART, + /** + * Log events related to connections between cluster nodes + */ + NDB_MGM_EVENT_CATEGORY_CONNECTION = CFG_LOGLEVEL_CONNECTION, + /** + * Backup related log events + */ + NDB_MGM_EVENT_CATEGORY_BACKUP = CFG_LOGLEVEL_BACKUP, + /** + * Congestion related log events + */ + NDB_MGM_EVENT_CATEGORY_CONGESTION = CFG_LOGLEVEL_CONGESTION, +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + /** + * Loglevel debug + */ + NDB_MGM_EVENT_CATEGORY_DEBUG = CFG_LOGLEVEL_DEBUG, +#endif + /** + * Uncategorized log events (severity info) + */ + NDB_MGM_EVENT_CATEGORY_INFO = CFG_LOGLEVEL_INFO, + /** + * Uncategorized log events (severity warning or higher) + */ + NDB_MGM_EVENT_CATEGORY_ERROR = CFG_LOGLEVEL_ERROR, +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + NDB_MGM_MIN_EVENT_CATEGORY = CFG_MIN_LOGLEVEL, + NDB_MGM_MAX_EVENT_CATEGORY = CFG_MAX_LOGLEVEL +#endif + }; + + /** + * Structure to store and retrieve log event information. + * @see @ref secSLogEvents + */ + struct ndb_logevent { + /** NdbLogEventHandle (to be used for comparing only) + * set in ndb_logevent_get_next() + */ + void *handle; + + /** Which event */ + enum Ndb_logevent_type type; + + /** Time when log event was registred at the management server */ + unsigned time; + + /** Category of log event */ + enum ndb_mgm_event_category category; + + /** Severity of log event */ + enum ndb_mgm_event_severity severity; + + /** Level (0-15) of log event */ + unsigned level; + + /** Node ID of the node that reported the log event */ + unsigned source_nodeid; + + /** Union of log event specific data. Use @ref type to decide + * which struct to use + */ + union { + /* CONNECT */ + struct { + unsigned node; + } Connected; + + struct { + unsigned node; + } Disconnected; + + struct { + unsigned node; + } CommunicationClosed; + + struct { + unsigned node; + } CommunicationOpened; + + struct { + unsigned node; + unsigned version; + } ConnectedApiVersion; + + /* CHECKPOINT */ + struct { + unsigned gci; + } GlobalCheckpointStarted; + struct { + unsigned gci; + } GlobalCheckpointCompleted; + struct { + unsigned lci; + unsigned keep_gci; + unsigned restore_gci; + } LocalCheckpointStarted; + struct { + unsigned lci; + } LocalCheckpointCompleted; + struct { + unsigned data; + } LCPStoppedInCalcKeepGci; + struct { + unsigned node; + unsigned table_id; + unsigned fragment_id; + } LCPFragmentCompleted; + struct { + unsigned acc_count; + unsigned tup_count; + } UndoLogBlocked; + + /* STARTUP */ + struct { + unsigned version; + } NDBStartStarted; + struct { + unsigned version; + } NDBStartCompleted; + struct { + } STTORRYRecieved; + struct { + unsigned phase; + unsigned starttype; + } StartPhaseCompleted; + struct { + unsigned own_id; + unsigned president_id; + unsigned dynamic_id; + } CM_REGCONF; + struct { + unsigned own_id; + unsigned other_id; + unsigned cause; + } CM_REGREF; + struct { + unsigned own_id; + unsigned left_id; + unsigned right_id; + unsigned dynamic_id; + } FIND_NEIGHBOURS; + struct { + unsigned stoptype; + } NDBStopStarted; + struct { + } NDBStopAborted; + struct { + unsigned node; + unsigned keep_gci; + unsigned completed_gci; + unsigned restorable_gci; + } StartREDOLog; + struct { + unsigned log_part; + unsigned start_mb; + unsigned stop_mb; + unsigned gci; + } StartLog; + struct { + unsigned block; + unsigned data1; + unsigned data2; + unsigned data3; + unsigned data4; + unsigned data5; + unsigned data6; + unsigned data7; + unsigned data8; + unsigned data9; + unsigned data10; + } UNDORecordsExecuted; + + /* NODERESTART */ + struct { + } NR_CopyDict; + struct { + } NR_CopyDistr; + struct { + unsigned dest_node; + } NR_CopyFragsStarted; + struct { + unsigned dest_node; + unsigned table_id; + unsigned fragment_id; + } NR_CopyFragDone; + struct { + unsigned dest_node; + } NR_CopyFragsCompleted; + + struct { + unsigned block; /* 0 = all */ + unsigned failed_node; + unsigned completing_node; /* 0 = all */ + } NodeFailCompleted; + struct { + unsigned failed_node; + unsigned failure_state; + } NODE_FAILREP; + struct { + /* TODO */ + } ArbitState; + struct { + /* TODO */ + } ArbitResult; + struct { + } GCP_TakeoverStarted; + struct { + } GCP_TakeoverCompleted; + struct { + } LCP_TakeoverStarted; + struct { + unsigned state; + } LCP_TakeoverCompleted; + + /* STATISTIC */ + struct { + unsigned trans_count; + unsigned commit_count; + unsigned read_count; + unsigned simple_read_count; + unsigned write_count; + unsigned attrinfo_count; + unsigned conc_op_count; + unsigned abort_count; + unsigned scan_count; + unsigned range_scan_count; + } TransReportCounters; + struct { + unsigned ops; + } OperationReportCounters; + struct { + unsigned table_id; + } TableCreated; + struct { + unsigned mean_loop_count; + } JobStatistic; + struct { + unsigned to_node; + unsigned mean_sent_bytes; + } SendBytesStatistic; + struct { + unsigned from_node; + unsigned mean_received_bytes; + } ReceiveBytesStatistic; + struct { + int gth; + unsigned page_size_kb; + unsigned pages_used; + unsigned pages_total; + unsigned block; + } MemoryUsage; + + /* ERROR */ + struct { + unsigned to_node; + unsigned code; + } TransporterError; + struct { + unsigned to_node; + unsigned code; + } TransporterWarning; + struct { + unsigned node; + unsigned count; + } MissedHeartbeat; + struct { + unsigned node; + } DeadDueToHeartbeat; + struct { + /* TODO */ + } WarningEvent; + + /* INFO */ + struct { + unsigned node; + } SentHeartbeat; + struct { + unsigned node; + } CreateLogBytes; + struct { + /* TODO */ + } InfoEvent; + + /** Log event data for @ref NDB_LE_BackupStarted */ + struct { + unsigned starting_node; + unsigned backup_id; + } BackupStarted; + /** Log event data @ref NDB_LE_BackupFailedToStart */ + struct { + unsigned starting_node; + unsigned error; + } BackupFailedToStart; + /** Log event data @ref NDB_LE_BackupCompleted */ + struct { + unsigned starting_node; + unsigned backup_id; + unsigned start_gci; + unsigned stop_gci; + unsigned n_records; + unsigned n_log_records; + unsigned n_bytes; + unsigned n_log_bytes; + } BackupCompleted; + /** Log event data @ref NDB_LE_BackupAborted */ + struct { + unsigned starting_node; + unsigned backup_id; + unsigned error; + } BackupAborted; +#ifndef DOXYGEN_FIX + }; +#else + } <union>; +#endif + }; + +enum ndb_logevent_handle_error { + NDB_LEH_NO_ERROR, + NDB_LEH_READ_ERROR, + NDB_LEH_MISSING_EVENT_SPECIFIER, + NDB_LEH_UNKNOWN_EVENT_TYPE, + NDB_LEH_UNKNOWN_EVENT_VARIABLE, + NDB_LEH_INTERNAL_ERROR +}; + #ifdef __cplusplus } #endif +/** @} */ + #endif diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index 7ffcde88ce2..32a170d27a4 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -33,1277 +33,698 @@ EventLoggerBase::~EventLoggerBase() } -/** - * This matrix defines which event should be printed when - * - * threshold - is in range [0-15] - * severity - DEBUG to ALERT (Type of log message) - */ -const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = { - // CONNECTION - { NDB_LE_Connected, LogLevel::llConnection, 8, Logger::LL_INFO }, - { NDB_LE_Disconnected, LogLevel::llConnection, 8, Logger::LL_ALERT }, - { NDB_LE_CommunicationClosed, LogLevel::llConnection, 8, Logger::LL_INFO }, - { NDB_LE_CommunicationOpened, LogLevel::llConnection, 8, Logger::LL_INFO }, - { NDB_LE_ConnectedApiVersion, LogLevel::llConnection, 8, Logger::LL_INFO }, - // CHECKPOINT - { NDB_LE_GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, Logger::LL_INFO }, - { NDB_LE_GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO }, - { NDB_LE_LocalCheckpointStarted, LogLevel::llCheckpoint, 7, Logger::LL_INFO }, - { NDB_LE_LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, Logger::LL_INFO }, - { NDB_LE_LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, Logger::LL_ALERT }, - { NDB_LE_LCPFragmentCompleted, LogLevel::llCheckpoint, 11, Logger::LL_INFO }, - { NDB_LE_UndoLogBlocked, LogLevel::llCheckpoint, 7, Logger::LL_INFO }, - - // STARTUP - { NDB_LE_NDBStartStarted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_NDBStartCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_STTORRYRecieved, LogLevel::llStartUp,15, Logger::LL_INFO }, - { NDB_LE_StartPhaseCompleted, LogLevel::llStartUp, 4, Logger::LL_INFO }, - { NDB_LE_CM_REGCONF, LogLevel::llStartUp, 3, Logger::LL_INFO }, - { NDB_LE_CM_REGREF, LogLevel::llStartUp, 8, Logger::LL_INFO }, - { NDB_LE_FIND_NEIGHBOURS, LogLevel::llStartUp, 8, Logger::LL_INFO }, - { NDB_LE_NDBStopStarted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO }, - { NDB_LE_StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO }, - { NDB_LE_StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO }, - { NDB_LE_UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO }, - - // NODERESTART - { NDB_LE_NR_CopyDict, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { NDB_LE_NR_CopyDistr, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { NDB_LE_NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { NDB_LE_NR_CopyFragDone, LogLevel::llNodeRestart, 10, Logger::LL_INFO }, - { NDB_LE_NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - - { NDB_LE_NodeFailCompleted, LogLevel::llNodeRestart, 8, Logger::LL_ALERT}, - { NDB_LE_NODE_FAILREP, LogLevel::llNodeRestart, 8, Logger::LL_ALERT}, - { NDB_LE_ArbitState, LogLevel::llNodeRestart, 6, Logger::LL_INFO }, - { NDB_LE_ArbitResult, LogLevel::llNodeRestart, 2, Logger::LL_ALERT}, - { NDB_LE_GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - { NDB_LE_GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - { NDB_LE_LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - { NDB_LE_LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, - - // STATISTIC - { NDB_LE_TransReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO }, - { NDB_LE_OperationReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO }, - { NDB_LE_TableCreated, LogLevel::llStatistic, 7, Logger::LL_INFO }, - { NDB_LE_JobStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, - { NDB_LE_SendBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, - { NDB_LE_ReceiveBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, - { NDB_LE_MemoryUsage, LogLevel::llStatistic, 5, Logger::LL_INFO }, - - // ERROR - { NDB_LE_TransporterError, LogLevel::llError, 2, Logger::LL_ERROR }, - { NDB_LE_TransporterWarning, LogLevel::llError, 8, Logger::LL_WARNING }, - { NDB_LE_MissedHeartbeat, LogLevel::llError, 8, Logger::LL_WARNING }, - { NDB_LE_DeadDueToHeartbeat, LogLevel::llError, 8, Logger::LL_ALERT }, - { NDB_LE_WarningEvent, LogLevel::llError, 2, Logger::LL_WARNING }, - // INFO - { NDB_LE_SentHeartbeat, LogLevel::llInfo, 12, Logger::LL_INFO }, - { NDB_LE_CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO }, - { NDB_LE_InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO }, - - // Backup - { NDB_LE_BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO }, - { NDB_LE_BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO }, - { NDB_LE_BackupFailedToStart, LogLevel::llBackup, 7, Logger::LL_ALERT}, - { NDB_LE_BackupAborted, LogLevel::llBackup, 7, Logger::LL_ALERT } -}; - -const Uint32 EventLoggerBase::matrixSize = sizeof(EventLoggerBase::matrix)/ - sizeof(EventRepLogLevelMatrix); - -const char* -EventLogger::getText(char * m_text, size_t m_text_len, - int type, - const Uint32* theData, NodeId nodeId) -{ - // TODO: Change the switch implementation... - char theNodeId[32]; - if (nodeId != 0){ - BaseString::snprintf(theNodeId, 32, "Node %u: ", nodeId); - } else { - theNodeId[0] = 0; - } - - Ndb_logevent_type eventType = (Ndb_logevent_type)type; - switch (eventType){ - case NDB_LE_Connected: - BaseString::snprintf(m_text, m_text_len, - "%sNode %u Connected", - theNodeId, - theData[1]); - break; - case NDB_LE_ConnectedApiVersion: - BaseString::snprintf(m_text, m_text_len, - "%sNode %u: API version %d.%d.%d", - theNodeId, - theData[1], - getMajor(theData[2]), - getMinor(theData[2]), - getBuild(theData[2])); - break; - case NDB_LE_Disconnected: - BaseString::snprintf(m_text, m_text_len, - "%sNode %u Disconnected", - theNodeId, - theData[1]); - break; - case NDB_LE_CommunicationClosed: - //----------------------------------------------------------------------- - // REPORT communication to node closed. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sCommunication to Node %u closed", - theNodeId, - theData[1]); - break; - case NDB_LE_CommunicationOpened: - //----------------------------------------------------------------------- - // REPORT communication to node opened. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sCommunication to Node %u opened", - theNodeId, - theData[1]); - break; - case NDB_LE_NDBStartStarted: - //----------------------------------------------------------------------- - // Start of NDB has been initiated. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sStart initiated (version %d.%d.%d)", - theNodeId , - getMajor(theData[1]), - getMinor(theData[1]), - getBuild(theData[1])); - break; - case NDB_LE_NDBStopStarted: - BaseString::snprintf(m_text, m_text_len, - "%s%s shutdown initiated", - theNodeId, - (theData[1] == 1 ? "Cluster" : "Node")); - break; - case NDB_LE_NDBStopAborted: - BaseString::snprintf(m_text, m_text_len, - "%sNode shutdown aborted", - theNodeId); - break; - case NDB_LE_NDBStartCompleted: - //----------------------------------------------------------------------- - // Start of NDB has been completed. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sStarted (version %d.%d.%d)", - theNodeId , - getMajor(theData[1]), - getMinor(theData[1]), - getBuild(theData[1])); - - break; - case NDB_LE_STTORRYRecieved: - //----------------------------------------------------------------------- - // STTORRY recevied after restart finished. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sSTTORRY received after restart finished", - theNodeId); - break; - case NDB_LE_StartPhaseCompleted:{ - //----------------------------------------------------------------------- - // REPORT Start phase completed. - //----------------------------------------------------------------------- - const char * type = "<Unknown>"; - switch((NodeState::StartType)theData[2]){ - case NodeState::ST_INITIAL_START: - type = "(initial start)"; - break; - case NodeState::ST_SYSTEM_RESTART: - type = "(system restart)"; - break; - case NodeState::ST_NODE_RESTART: - type = "(node restart)"; - break; - case NodeState::ST_INITIAL_NODE_RESTART: - type = "(initial node restart)"; - break; - case NodeState::ST_ILLEGAL_TYPE: - type = ""; - break; - default:{ - BaseString::snprintf(m_text, m_text_len, - "%sStart phase %u completed (unknown = %d)", - theNodeId, - theData[1], - theData[2]); - return m_text; - } - } - BaseString::snprintf(m_text, m_text_len, - "%sStart phase %u completed %s", - theNodeId, - theData[1], - type); - return m_text; - break; - } - case NDB_LE_CM_REGCONF: - BaseString::snprintf(m_text, m_text_len, - "%sCM_REGCONF president = %u, own Node = %u, our dynamic id = %u" - , - theNodeId, - theData[2], - theData[1], - theData[3]); - break; - case NDB_LE_CM_REGREF: - { - const char* line = ""; - switch (theData[3]) { - case 0: - line = "Busy"; - break; - case 1: - line = "Election with wait = false"; - break; - case 2: - line = "Election with wait = false"; - break; - case 3: - line = "Not president"; - break; - case 4: - line = "Election without selecting new candidate"; - break; - default: - line = "No such cause"; - break; - }//switch - BaseString::snprintf(m_text, m_text_len, - "%sCM_REGREF from Node %u to our Node %u. Cause = %s", - theNodeId, - theData[2], - theData[1], - line); - } - break; - case NDB_LE_FIND_NEIGHBOURS: - //----------------------------------------------------------------------- - // REPORT Node Restart copied a fragment. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sWe are Node %u with dynamic ID %u, our left neighbour " - "is Node %u, our right is Node %u", - theNodeId, - theData[1], - theData[4], - theData[2], - theData[3]); - break; - case NDB_LE_NodeFailCompleted: - //----------------------------------------------------------------------- - // REPORT Node failure phase completed. - //----------------------------------------------------------------------- - if (theData[1] == 0) - { - if (theData[3] != 0) { - BaseString::snprintf(m_text, m_text_len, - "%sNode %u completed failure of Node %u", - theNodeId, - theData[3], - theData[2]); - } else { - BaseString::snprintf(m_text, m_text_len, - "%sAll nodes completed failure of Node %u", - theNodeId, - theData[2]); - }//if - } else { - const char* line = ""; - if (theData[1] == DBTC){ - line = "DBTC"; - }else if (theData[1] == DBDICT){ - line = "DBDICT"; - }else if (theData[1] == DBDIH){ - line = "DBDIH"; - }else if (theData[1] == DBLQH){ - line = "DBLQH"; - } - - BaseString::snprintf(m_text, m_text_len, - "%sNode failure of %u %s completed", - theNodeId, - theData[2], - line); - } - break; - case NDB_LE_NODE_FAILREP: - BaseString::snprintf(m_text, - m_text_len, - "%sNode %u has failed. The Node state at failure " - "was %u", - theNodeId, - theData[1], - theData[2]); +#define QQQQ char *m_text, size_t m_text_len, const Uint32* theData - break; - case NDB_LE_ArbitState: - //----------------------------------------------------------------------- - // REPORT arbitrator found or lost. - //----------------------------------------------------------------------- - { const ArbitSignalData* sd = (ArbitSignalData*)theData; - char ticketText[ArbitTicket::TextLength + 1]; - char errText[ArbitCode::ErrTextLength + 1]; - const unsigned code = sd->code & 0xFFFF; - const unsigned state = sd->code >> 16; - switch (code) { - case ArbitCode::ThreadStart: - BaseString::snprintf(m_text, m_text_len, - "%sPresident restarts arbitration thread [state=%u]", - theNodeId, state); - break; - case ArbitCode::PrepPart2: - sd->ticket.getText(ticketText, sizeof(ticketText)); - BaseString::snprintf(m_text, m_text_len, - "%sPrepare arbitrator node %u [ticket=%s]", - theNodeId, sd->node, ticketText); - break; - case ArbitCode::PrepAtrun: - sd->ticket.getText(ticketText, sizeof(ticketText)); - BaseString::snprintf(m_text, m_text_len, - "%sReceive arbitrator node %u [ticket=%s]", - theNodeId, sd->node, ticketText); - break; - case ArbitCode::ApiStart: - sd->ticket.getText(ticketText, sizeof(ticketText)); - BaseString::snprintf(m_text, m_text_len, - "%sStarted arbitrator node %u [ticket=%s]", - theNodeId, sd->node, ticketText); - break; - case ArbitCode::ApiFail: - BaseString::snprintf(m_text, m_text_len, - "%sLost arbitrator node %u - process failure [state=%u]", - theNodeId, sd->node, state); - break; - case ArbitCode::ApiExit: - BaseString::snprintf(m_text, m_text_len, - "%sLost arbitrator node %u - process exit [state=%u]", - theNodeId, sd->node, state); - break; - default: - ArbitCode::getErrText(code, errText, sizeof(errText)); - BaseString::snprintf(m_text, m_text_len, - "%sLost arbitrator node %u - %s [state=%u]", - theNodeId, sd->node, errText, state); - break; - } - } - break; - case NDB_LE_ArbitResult: - //----------------------------------------------------------------------- - // REPORT arbitration result (the failures may not reach us). - //----------------------------------------------------------------------- - { const ArbitSignalData* sd = (ArbitSignalData*)theData; - char errText[ArbitCode::ErrTextLength + 1]; - const unsigned code = sd->code & 0xFFFF; - const unsigned state = sd->code >> 16; - switch (code) { - case ArbitCode::LoseNodes: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check lost - less than 1/2 nodes left", - theNodeId); - break; - case ArbitCode::WinNodes: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check won - all node groups and more than 1/2 nodes left", - theNodeId); - break; - case ArbitCode::WinGroups: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check won - node group majority", - theNodeId); - break; - case ArbitCode::LoseGroups: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration check lost - missing node group", - theNodeId); - break; - case ArbitCode::Partitioning: - BaseString::snprintf(m_text, m_text_len, - "%sNetwork partitioning - arbitration required", - theNodeId); - break; - case ArbitCode::WinChoose: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration won - positive reply from node %u", - theNodeId, sd->node); - break; - case ArbitCode::LoseChoose: - BaseString::snprintf(m_text, m_text_len, - "%sArbitration lost - negative reply from node %u", - theNodeId, sd->node); - break; - case ArbitCode::LoseNorun: - BaseString::snprintf(m_text, m_text_len, - "%sNetwork partitioning - no arbitrator available", - theNodeId); - break; - case ArbitCode::LoseNocfg: - BaseString::snprintf(m_text, m_text_len, - "%sNetwork partitioning - no arbitrator configured", - theNodeId); - break; - default: - ArbitCode::getErrText(code, errText, sizeof(errText)); - BaseString::snprintf(m_text, m_text_len, - "%sArbitration failure - %s [state=%u]", - theNodeId, errText, state); - break; - } - } +void getTextConnected(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u Connected", + theData[1]); +} +void getTextConnectedApiVersion(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u: API version %d.%d.%d", + theData[1], + getMajor(theData[2]), + getMinor(theData[2]), + getBuild(theData[2])); +} +void getTextDisconnected(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u Disconnected", + theData[1]); +} +void getTextCommunicationClosed(QQQQ) { + //----------------------------------------------------------------------- + // REPORT communication to node closed. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Communication to Node %u closed", + theData[1]); +} +void getTextCommunicationOpened(QQQQ) { + //----------------------------------------------------------------------- + // REPORT communication to node opened. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Communication to Node %u opened", + theData[1]); +} +void getTextNDBStartStarted(QQQQ) { + //----------------------------------------------------------------------- + // Start of NDB has been initiated. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Start initiated (version %d.%d.%d)", + getMajor(theData[1]), + getMinor(theData[1]), + getBuild(theData[1])); +} +void getTextNDBStopStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "%s shutdown initiated", + (theData[1] == 1 ? "Cluster" : "Node")); +} +void getTextNDBStopAborted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node shutdown aborted"); +} +void getTextNDBStartCompleted(QQQQ) { + //----------------------------------------------------------------------- + // Start of NDB has been completed. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Started (version %d.%d.%d)", + getMajor(theData[1]), + getMinor(theData[1]), + getBuild(theData[1])); +} +void getTextSTTORRYRecieved(QQQQ) { + //----------------------------------------------------------------------- + // STTORRY recevied after restart finished. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "STTORRY received after restart finished"); +} +void getTextStartPhaseCompleted(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Start phase completed. + //----------------------------------------------------------------------- + const char *type = "<Unknown>"; + switch((NodeState::StartType)theData[2]){ + case NodeState::ST_INITIAL_START: + type = "(initial start)"; break; - case NDB_LE_GlobalCheckpointStarted: - //----------------------------------------------------------------------- - // This event reports that a global checkpoint has been started and this - // node is the master of this global checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sGlobal checkpoint %u started", - theNodeId, - theData[1]); + case NodeState::ST_SYSTEM_RESTART: + type = "(system restart)"; break; - case NDB_LE_GlobalCheckpointCompleted: - //----------------------------------------------------------------------- - // This event reports that a global checkpoint has been completed on this - // node and the node is the master of this global checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, m_text_len, - "%sGlobal checkpoint %u completed", - theNodeId, - theData[1]); + case NodeState::ST_NODE_RESTART: + type = "(node restart)"; break; - case NDB_LE_LocalCheckpointStarted: - //----------------------------------------------------------------------- - // This event reports that a local checkpoint has been started and this - // node is the master of this local checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sLocal checkpoint %u started. " - "Keep GCI = %u oldest restorable GCI = %u", - theNodeId, - theData[1], - theData[2], - theData[3]); + case NodeState::ST_INITIAL_NODE_RESTART: + type = "(initial node restart)"; break; - case NDB_LE_LocalCheckpointCompleted: - //----------------------------------------------------------------------- - // This event reports that a local checkpoint has been completed on this - // node and the node is the master of this local checkpoint. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sLocal checkpoint %u completed", - theNodeId, - theData[1]); + case NodeState::ST_ILLEGAL_TYPE: + type = ""; break; - case NDB_LE_TableCreated: - //----------------------------------------------------------------------- - // This event reports that a table has been created. - //----------------------------------------------------------------------- + default: BaseString::snprintf(m_text, m_text_len, - "%sTable with ID = %u created", - theNodeId, - theData[1]); - break; - case NDB_LE_LCPStoppedInCalcKeepGci: - if (theData[1] == 0) - BaseString::snprintf(m_text, m_text_len, - "%sLocal Checkpoint stopped in CALCULATED_KEEP_GCI", - theNodeId); - break; - case NDB_LE_NR_CopyDict: - //----------------------------------------------------------------------- - // REPORT Node Restart completed copy of dictionary information. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart completed copy of dictionary information", - theNodeId); - break; - case NDB_LE_NR_CopyDistr: - //----------------------------------------------------------------------- - // REPORT Node Restart completed copy of distribution information. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart completed copy of distribution information", - theNodeId); - break; - case NDB_LE_NR_CopyFragsStarted: - //----------------------------------------------------------------------- - // REPORT Node Restart is starting to copy the fragments. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart starting to copy the fragments " - "to Node %u", - theNodeId, - theData[1]); - break; - case NDB_LE_NR_CopyFragDone: - //----------------------------------------------------------------------- - // REPORT Node Restart copied a fragment. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sTable ID = %u, fragment ID = %u have been copied " - "to Node %u", - theNodeId, - theData[2], - theData[3], - theData[1]); - break; - case NDB_LE_NR_CopyFragsCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sNode restart completed copying the fragments " - "to Node %u", - theNodeId, - theData[1]); - break; - case NDB_LE_LCPFragmentCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sTable ID = %u, fragment ID = %u has completed LCP " - "on Node %u", - theNodeId, - theData[2], - theData[3], - theData[1]); + "Start phase %u completed (unknown = %d)", + theData[1], + theData[2]); + return; + } + BaseString::snprintf(m_text, m_text_len, + "Start phase %u completed %s", + theData[1], + type); +} +void getTextCM_REGCONF(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "CM_REGCONF president = %u, own Node = %u, our dynamic id = %u", + theData[2], + theData[1], + theData[3]); +} +void getTextCM_REGREF(QQQQ) { + const char* line = ""; + switch (theData[3]) { + case 0: + line = "Busy"; break; - case NDB_LE_TransReportCounters: - // ------------------------------------------------------------------- - // Report information about transaction activity once per 10 seconds. - // ------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sTrans. Count = %u, Commit Count = %u, " - "Read Count = %u, Simple Read Count = %u,\n" - "Write Count = %u, AttrInfo Count = %u, " - "Concurrent Operations = %u, Abort Count = %u\n" - " Scans: %u Range scans: %u", - theNodeId, - theData[1], - theData[2], - theData[3], - theData[4], - theData[5], - theData[6], - theData[7], - theData[8], - theData[9], - theData[10]); + case 1: + line = "Election with wait = false"; break; - case NDB_LE_OperationReportCounters: - BaseString::snprintf(m_text, m_text_len, - "%sOperations=%u", - theNodeId, - theData[1]); + case 2: + line = "Election with wait = false"; break; - case NDB_LE_UndoLogBlocked: - //----------------------------------------------------------------------- - // REPORT Undo Logging blocked due to buffer near to overflow. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sACC Blocked %u and TUP Blocked %u times last second", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_TransporterError: - case NDB_LE_TransporterWarning: - BaseString::snprintf(m_text, - m_text_len, - "%sTransporter to node %d reported error 0x%x", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_MissedHeartbeat: - //----------------------------------------------------------------------- - // REPORT Undo Logging blocked due to buffer near to overflow. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode %d missed heartbeat %d", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_DeadDueToHeartbeat: - //----------------------------------------------------------------------- - // REPORT Undo Logging blocked due to buffer near to overflow. - //----------------------------------------------------------------------- - BaseString::snprintf(m_text, - m_text_len, - "%sNode %d declared dead due to missed heartbeat", - theNodeId, - theData[1]); - break; - case NDB_LE_JobStatistic: - BaseString::snprintf(m_text, - m_text_len, - "%sMean loop Counter in doJob last 8192 times = %u", - theNodeId, - theData[1]); + case 3: + line = "Not president"; break; - case NDB_LE_SendBytesStatistic: - BaseString::snprintf(m_text, - m_text_len, - "%sMean send size to Node = %d last 4096 sends = %u bytes", - theNodeId, - theData[1], - theData[2]); + case 4: + line = "Election without selecting new candidate"; break; - case NDB_LE_ReceiveBytesStatistic: - BaseString::snprintf(m_text, - m_text_len, - "%sMean receive size to Node = %d last 4096 sends = %u bytes", - theNodeId, - theData[1], - theData[2]); - break; - case NDB_LE_SentHeartbeat: - BaseString::snprintf(m_text, - m_text_len, - "%sNode Sent Heartbeat to node = %d", - theNodeId, - theData[1]); - break; - case NDB_LE_CreateLogBytes: - BaseString::snprintf(m_text, - m_text_len, - "%sLog part %u, log file %u, MB %u", - theNodeId, - theData[1], - theData[2], - theData[3]); - break; - case NDB_LE_StartLog: - BaseString::snprintf(m_text, - m_text_len, - "%sLog part %u, start MB %u, stop MB %u, last GCI, log exec %u", - theNodeId, - theData[1], - theData[2], - theData[3], - theData[4]); - break; - case NDB_LE_StartREDOLog: - BaseString::snprintf(m_text, - m_text_len, - "%sNode: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]", - theNodeId, - theData[1], - theData[2], - theData[3], - theData[4]); - break; - case NDB_LE_UNDORecordsExecuted:{ - const char* line = ""; - if (theData[1] == DBTUP){ - line = "DBTUP"; - }else if (theData[1] == DBACC){ - line = "DBACC"; - } - - BaseString::snprintf(m_text, - m_text_len, - "%s UNDO %s %d [%d %d %d %d %d %d %d %d %d]", - theNodeId, - line, - theData[2], - theData[3], - theData[4], - theData[5], - theData[6], - theData[7], - theData[8], - theData[9], - theData[10], - theData[11]); - } - break; - case NDB_LE_InfoEvent: - BaseString::snprintf(m_text, - m_text_len, - "%s%s", - theNodeId, - (char *)&theData[1]); - break; - case NDB_LE_WarningEvent: - BaseString::snprintf(m_text, - m_text_len, - "%s%s", - theNodeId, - (char *)&theData[1]); - break; - case NDB_LE_GCP_TakeoverStarted: - BaseString::snprintf(m_text, - m_text_len, - "%sGCP Take over started", theNodeId); - break; - case NDB_LE_GCP_TakeoverCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sGCP Take over completed", theNodeId); - break; - case NDB_LE_LCP_TakeoverStarted: - BaseString::snprintf(m_text, - m_text_len, - "%sLCP Take over started", theNodeId); - break; - case NDB_LE_LCP_TakeoverCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sLCP Take over completed (state = %d)", - theNodeId, theData[1]); - break; - case NDB_LE_MemoryUsage:{ - const int gth = theData[1]; - const int size = theData[2]; - const int used = theData[3]; - const int total = theData[4]; - const int block = theData[5]; - const int percent = (used*100)/total; - - BaseString::snprintf(m_text, m_text_len, - "%s%s usage %s %d%s(%d %dK pages of total %d)", - theNodeId, - (block==DBACC ? "Index" : (block == DBTUP ?"Data":"<unknown>")), - (gth == 0 ? "is" : (gth > 0 ? "increased to" : "decreased to")), - percent, "%", - used, size/1024, total - ); + default: + line = "No such cause"; break; - } - case NDB_LE_GrepSubscriptionInfo : - { - GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; - switch(event) { - case GrepEvent::GrepSS_CreateSubIdConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Created subscription id" - " (subId=%d,SubKey=%d)" - " Return code: %d.", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_CreateSubIdConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Created subscription id" - " (subId=%d,SubKey=%d)" - " Return code: %d.", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubCreateConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int nodegrp = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Created subscription using" - " (subId=%d,SubKey=%d)" - " in primary system. Primary system has %d nodegroup(s)." - " Return code: %d", - subId, - subKey, - nodegrp, - err); - break; - } - case GrepEvent::GrepPS_SubCreateConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have created " - "subscriptions" - " using (subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubStartMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging started on meta data changes." - " using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubStartMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started " - "logging meta data" - " changes on the subscription subId=%d,SubKey=%d) " - "(N.I yet)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubStartDataConf: { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging started on table data changes " - " using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubStartDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started logging " - "table data changes on the subscription " - "subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubSyncMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started " - " synchronization on meta data (META SCAN) using " - "(subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubSyncMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization started (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubSyncDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have started " - "synchronization " - " on table data (DATA SCAN) using (subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubSyncDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization started (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d" - " Return code: %d", - subId, - subKey, - gci, - err); - break; - } - case GrepEvent::GrepPS_SubRemoveConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; + }//switch + + BaseString::snprintf(m_text, m_text_len, + "CM_REGREF from Node %u to our Node %u. Cause = %s", + theData[2], + theData[1], + line); +} +void getTextFIND_NEIGHBOURS(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart copied a fragment. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "We are Node %u with dynamic ID %u, our left neighbour " + "is Node %u, our right is Node %u", + theData[1], + theData[4], + theData[2], + theData[3]); +} +void getTextNodeFailCompleted(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node failure phase completed. + //----------------------------------------------------------------------- + if (theData[1] == 0) + { + if (theData[3] != 0) { BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: All participants have removed " - "subscription (subId=%d,SubKey=%d). I have cleaned " - "up resources I've used." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubRemoveConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; + "Node %u completed failure of Node %u", + theData[3], + theData[2]); + } else { BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Removed subscription " - "(subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - default: - BaseString::snprintf(m_text, - m_text_len, - "%sUnknown GrepSubscriptonInfo event: %d", - theNodeId, - theData[1]); + "All nodes completed failure of Node %u", + theData[2]); + }//if + } else { + const char* line = ""; + if (theData[1] == DBTC){ + line = "DBTC"; + }else if (theData[1] == DBDICT){ + line = "DBDICT"; + }else if (theData[1] == DBDIH){ + line = "DBDIH"; + }else if (theData[1] == DBLQH){ + line = "DBLQH"; } - break; + BaseString::snprintf(m_text, m_text_len, + "Node failure of %u %s completed", + theData[2], + line); } - - case NDB_LE_GrepSubscriptionAlert : +} +void getTextNODE_FAILREP(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node %u has failed. The Node state at failure " + "was %u", + theData[1], + theData[2]); +} +void getTextArbitState(QQQQ) { + //----------------------------------------------------------------------- + // REPORT arbitrator found or lost. + //----------------------------------------------------------------------- { - GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; - switch(event) - { - case GrepEvent::GrepSS_CreateSubIdRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord:Error code: %d Error message: %s" - " (subId=%d,SubKey=%d)", - err, - GrepError::getErrorDesc((GrepError::GE_Code)err), - subId, - subKey); - break; - } - case GrepEvent::GrepSS_SubCreateRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: FAILED to Created subscription using" - " (subId=%d,SubKey=%d)in primary system." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubStartMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging failed to start on meta " - "data changes." - " using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubStartDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Logging FAILED to start on table data " - " changes using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubSyncMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization FAILED (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubSyncDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Synchronization FAILED (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d" - " Error code: %d Error Message: %s", - subId, - subKey, - gci, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepSS_SubRemoveRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::SSCoord: Failed to remove subscription " - "(subId=%d,SubKey=%d). " - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err) - ); - break; - } - - case GrepEvent::GrepPS_CreateSubIdRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Error code: %d Error Message: %s" - " (subId=%d,SubKey=%d)", - err, - GrepError::getErrorDesc((GrepError::GE_Code)err), - subId, - subKey); - break; - } - case GrepEvent::GrepPS_SubCreateRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: FAILED to Created subscription using" - " (subId=%d,SubKey=%d)in primary system." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); + const ArbitSignalData* sd = (ArbitSignalData*)theData; + char ticketText[ArbitTicket::TextLength + 1]; + char errText[ArbitCode::ErrTextLength + 1]; + const unsigned code = sd->code & 0xFFFF; + const unsigned state = sd->code >> 16; + switch (code) { + case ArbitCode::ThreadStart: + BaseString::snprintf(m_text, m_text_len, + "President restarts arbitration thread [state=%u]", + state); + break; + case ArbitCode::PrepPart2: + sd->ticket.getText(ticketText, sizeof(ticketText)); + BaseString::snprintf(m_text, m_text_len, + "Prepare arbitrator node %u [ticket=%s]", + sd->node, ticketText); + break; + case ArbitCode::PrepAtrun: + sd->ticket.getText(ticketText, sizeof(ticketText)); + BaseString::snprintf(m_text, m_text_len, + "Receive arbitrator node %u [ticket=%s]", + sd->node, ticketText); + break; + case ArbitCode::ApiStart: + sd->ticket.getText(ticketText, sizeof(ticketText)); + BaseString::snprintf(m_text, m_text_len, + "Started arbitrator node %u [ticket=%s]", + sd->node, ticketText); + break; + case ArbitCode::ApiFail: + BaseString::snprintf(m_text, m_text_len, + "Lost arbitrator node %u - process failure [state=%u]", + sd->node, state); + break; + case ArbitCode::ApiExit: + BaseString::snprintf(m_text, m_text_len, + "Lost arbitrator node %u - process exit [state=%u]", + sd->node, state); break; - } - case GrepEvent::GrepPS_SubStartMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Logging failed to start on meta " - "data changes." - " using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubStartDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Logging FAILED to start on table data " - " changes using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubSyncMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Synchronization FAILED (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::GrepPS_SubSyncDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Synchronization FAILED (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d. " - " Error code: %d Error Message: %s", - subId, - subKey, - gci, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); + default: + ArbitCode::getErrText(code, errText, sizeof(errText)); + BaseString::snprintf(m_text, m_text_len, + "Lost arbitrator node %u - %s [state=%u]", + sd->node, errText, state); break; } - case GrepEvent::GrepPS_SubRemoveRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - BaseString::snprintf(m_text, m_text_len, - "Grep::PSCoord: Failed to remove subscription " - "(subId=%d,SubKey=%d)." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); - break; - } - case GrepEvent::Rep_Disconnect: - { - const int err = theData[4]; - const int nodeId = theData[5]; - BaseString::snprintf(m_text, m_text_len, - "Rep: Node %d." - " Error code: %d Error Message: %s", - nodeId, - err, - GrepError::getErrorDesc((GrepError::GE_Code)err)); + } +} + +void getTextArbitResult(QQQQ) { + //----------------------------------------------------------------------- + // REPORT arbitration result (the failures may not reach us). + //----------------------------------------------------------------------- + { + const ArbitSignalData* sd = (ArbitSignalData*)theData; + char errText[ArbitCode::ErrTextLength + 1]; + const unsigned code = sd->code & 0xFFFF; + const unsigned state = sd->code >> 16; + switch (code) { + case ArbitCode::LoseNodes: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check lost - less than 1/2 nodes left"); + break; + case ArbitCode::WinNodes: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check won - all node groups and more than 1/2 nodes left"); + break; + case ArbitCode::WinGroups: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check won - node group majority"); + break; + case ArbitCode::LoseGroups: + BaseString::snprintf(m_text, m_text_len, + "Arbitration check lost - missing node group"); + break; + case ArbitCode::Partitioning: + BaseString::snprintf(m_text, m_text_len, + "Network partitioning - arbitration required"); + break; + case ArbitCode::WinChoose: + BaseString::snprintf(m_text, m_text_len, + "Arbitration won - positive reply from node %u", + sd->node); + break; + case ArbitCode::LoseChoose: + BaseString::snprintf(m_text, m_text_len, + "Arbitration lost - negative reply from node %u", + sd->node); + break; + case ArbitCode::LoseNorun: + BaseString::snprintf(m_text, m_text_len, + "Network partitioning - no arbitrator available"); + break; + case ArbitCode::LoseNocfg: + BaseString::snprintf(m_text, m_text_len, + "Network partitioning - no arbitrator configured"); break; - } - - default: - BaseString::snprintf(m_text, - m_text_len, - "%sUnknown GrepSubscriptionAlert event: %d", - theNodeId, - theData[1]); - break; + ArbitCode::getErrText(code, errText, sizeof(errText)); + BaseString::snprintf(m_text, m_text_len, + "Arbitration failure - %s [state=%u]", + errText, state); + break; } - break; } - - case NDB_LE_BackupStarted: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup %d started from node %d", - theNodeId, theData[2], refToNode(theData[1])); - break; - case NDB_LE_BackupFailedToStart: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup request from %d failed to start. Error: %d", - theNodeId, refToNode(theData[1]), theData[2]); - break; - case NDB_LE_BackupCompleted: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup %u started from node %u completed\n" - " StartGCP: %u StopGCP: %u\n" - " #Records: %u #LogRecords: %u\n" - " Data: %u bytes Log: %u bytes", - theNodeId, theData[2], refToNode(theData[1]), - theData[3], theData[4], theData[6], theData[8], - theData[5], theData[7]); - break; - case NDB_LE_BackupAborted: - BaseString::snprintf(m_text, - m_text_len, - "%sBackup %d started from %d has been aborted. Error: %d", - theNodeId, - theData[2], - refToNode(theData[1]), - theData[3]); - break; - default: - BaseString::snprintf(m_text, - m_text_len, - "%sUnknown event: %d", - theNodeId, - theData[0]); - +} +void getTextGlobalCheckpointStarted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a global checkpoint has been started and this + // node is the master of this global checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Global checkpoint %u started", + theData[1]); +} +void getTextGlobalCheckpointCompleted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a global checkpoint has been completed on this + // node and the node is the master of this global checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Global checkpoint %u completed", + theData[1]); +} +void getTextLocalCheckpointStarted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a local checkpoint has been started and this + // node is the master of this local checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Local checkpoint %u started. " + "Keep GCI = %u oldest restorable GCI = %u", + theData[1], + theData[2], + theData[3]); +} +void getTextLocalCheckpointCompleted(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a local checkpoint has been completed on this + // node and the node is the master of this local checkpoint. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Local checkpoint %u completed", + theData[1]); +} +void getTextTableCreated(QQQQ) { + //----------------------------------------------------------------------- + // This event reports that a table has been created. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Table with ID = %u created", + theData[1]); +} +/* STRANGE */ +void getTextLCPStoppedInCalcKeepGci(QQQQ) { + if (theData[1] == 0) + BaseString::snprintf(m_text, m_text_len, + "Local Checkpoint stopped in CALCULATED_KEEP_GCI"); +} +void getTextNR_CopyDict(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart completed copy of dictionary information. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node restart completed copy of dictionary information"); +} +void getTextNR_CopyDistr(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart completed copy of distribution information. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node restart completed copy of distribution information"); +} +void getTextNR_CopyFragsStarted(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart is starting to copy the fragments. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node restart starting to copy the fragments " + "to Node %u", + theData[1]); +} +void getTextNR_CopyFragDone(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Node Restart copied a fragment. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Table ID = %u, fragment ID = %u have been copied " + "to Node %u", + theData[2], + theData[3], + theData[1]); +} +void getTextNR_CopyFragsCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node restart completed copying the fragments " + "to Node %u", + theData[1]); +} +void getTextLCPFragmentCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Table ID = %u, fragment ID = %u has completed LCP " + "on Node %u", + theData[2], + theData[3], + theData[1]); +} +void getTextTransReportCounters(QQQQ) { + // ------------------------------------------------------------------- + // Report information about transaction activity once per 10 seconds. + // ------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Trans. Count = %u, Commit Count = %u, " + "Read Count = %u, Simple Read Count = %u,\n" + "Write Count = %u, AttrInfo Count = %u, " + "Concurrent Operations = %u, Abort Count = %u\n" + " Scans: %u Range scans: %u", + theData[1], + theData[2], + theData[3], + theData[4], + theData[5], + theData[6], + theData[7], + theData[8], + theData[9], + theData[10]); +} +void getTextOperationReportCounters(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Operations=%u", + theData[1]); +} +void getTextUndoLogBlocked(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Undo Logging blocked due to buffer near to overflow. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "ACC Blocked %u and TUP Blocked %u times last second", + theData[1], + theData[2]); +} +void getTextTransporterError(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Transporter to node %d reported error 0x%x", + theData[1], + theData[2]); +} +void getTextTransporterWarning(QQQQ) { + getTextTransporterError(m_text, m_text_len, theData); +} +void getTextMissedHeartbeat(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Undo Logging blocked due to buffer near to overflow. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node %d missed heartbeat %d", + theData[1], + theData[2]); +} +void getTextDeadDueToHeartbeat(QQQQ) { + //----------------------------------------------------------------------- + // REPORT Undo Logging blocked due to buffer near to overflow. + //----------------------------------------------------------------------- + BaseString::snprintf(m_text, m_text_len, + "Node %d declared dead due to missed heartbeat", + theData[1]); +} +void getTextJobStatistic(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Mean loop Counter in doJob last 8192 times = %u", + theData[1]); +} +void getTextSendBytesStatistic(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Mean send size to Node = %d last 4096 sends = %u bytes", + theData[1], + theData[2]); +} +void getTextReceiveBytesStatistic(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Mean receive size to Node = %d last 4096 sends = %u bytes", + theData[1], + theData[2]); +} +void getTextSentHeartbeat(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node Sent Heartbeat to node = %d", + theData[1]); +} +void getTextCreateLogBytes(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Log part %u, log file %u, MB %u", + theData[1], + theData[2], + theData[3]); +} +void getTextStartLog(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Log part %u, start MB %u, stop MB %u, last GCI, log exec %u", + theData[1], + theData[2], + theData[3], + theData[4]); +} +void getTextStartREDOLog(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Node: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]", + theData[1], + theData[2], + theData[3], + theData[4]); +} +void getTextUNDORecordsExecuted(QQQQ) { + const char* line = ""; + if (theData[1] == DBTUP){ + line = "DBTUP"; + }else if (theData[1] == DBACC){ + line = "DBACC"; } - return m_text; + + BaseString::snprintf(m_text, m_text_len, + " UNDO %s %d [%d %d %d %d %d %d %d %d %d]", + line, + theData[2], + theData[3], + theData[4], + theData[5], + theData[6], + theData[7], + theData[8], + theData[9], + theData[10], + theData[11]); +} +void getTextInfoEvent(QQQQ) { + BaseString::snprintf(m_text, m_text_len, (char *)&theData[1]); +} +void getTextWarningEvent(QQQQ) { + BaseString::snprintf(m_text, m_text_len, (char *)&theData[1]); +} +void getTextGCP_TakeoverStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, "GCP Take over started"); +} +void getTextGCP_TakeoverCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, "GCP Take over completed"); +} +void getTextLCP_TakeoverStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, "LCP Take over started"); +} +void getTextLCP_TakeoverCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "LCP Take over completed (state = %d)", + theData[1]); +} +void getTextMemoryUsage(QQQQ) { + const int gth = theData[1]; + const int size = theData[2]; + const int used = theData[3]; + const int total = theData[4]; + const int block = theData[5]; + const int percent = (used*100)/total; + + BaseString::snprintf(m_text, m_text_len, + "%s usage %s %d%s(%d %dK pages of total %d)", + (block==DBACC ? "Index" : (block == DBTUP ?"Data":"<unknown>")), + (gth == 0 ? "is" : (gth > 0 ? "increased to" : "decreased to")), + percent, "%", + used, size/1024, total + ); +} + +void getTextBackupStarted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup %d started from node %d", + theData[2], refToNode(theData[1])); +} +void getTextBackupFailedToStart(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup request from %d failed to start. Error: %d", + refToNode(theData[1]), theData[2]); +} +void getTextBackupCompleted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup %u started from node %u completed\n" + " StartGCP: %u StopGCP: %u\n" + " #Records: %u #LogRecords: %u\n" + " Data: %u bytes Log: %u bytes", + theData[2], refToNode(theData[1]), + theData[3], theData[4], theData[6], theData[8], + theData[5], theData[7]); +} +void getTextBackupAborted(QQQQ) { + BaseString::snprintf(m_text, m_text_len, + "Backup %d started from %d has been aborted. Error: %d", + theData[2], + refToNode(theData[1]), + theData[3]); } +#if 0 +BaseString::snprintf(m_text, + m_text_len, + "Unknown event: %d", + theData[0]); +#endif + +/** + * This matrix defines which event should be printed when + * + * threshold - is in range [0-15] + * severity - DEBUG to ALERT (Type of log message) + */ + +#define ROW(a,b,c,d) \ +{ NDB_LE_ ## a, b, c, d, getText ## a} + +const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = { + // CONNECTION + ROW(Connected, LogLevel::llConnection, 8, Logger::LL_INFO ), + ROW(Disconnected, LogLevel::llConnection, 8, Logger::LL_ALERT ), + ROW(CommunicationClosed, LogLevel::llConnection, 8, Logger::LL_INFO ), + ROW(CommunicationOpened, LogLevel::llConnection, 8, Logger::LL_INFO ), + ROW(ConnectedApiVersion, LogLevel::llConnection, 8, Logger::LL_INFO ), + // CHECKPOINT + ROW(GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, Logger::LL_INFO ), + ROW(GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO ), + ROW(LocalCheckpointStarted, LogLevel::llCheckpoint, 7, Logger::LL_INFO ), + ROW(LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, Logger::LL_INFO ), + ROW(LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, Logger::LL_ALERT ), + ROW(LCPFragmentCompleted, LogLevel::llCheckpoint, 11, Logger::LL_INFO ), + ROW(UndoLogBlocked, LogLevel::llCheckpoint, 7, Logger::LL_INFO ), + + // STARTUP + ROW(NDBStartStarted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(NDBStartCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(STTORRYRecieved, LogLevel::llStartUp, 15, Logger::LL_INFO ), + ROW(StartPhaseCompleted, LogLevel::llStartUp, 4, Logger::LL_INFO ), + ROW(CM_REGCONF, LogLevel::llStartUp, 3, Logger::LL_INFO ), + ROW(CM_REGREF, LogLevel::llStartUp, 8, Logger::LL_INFO ), + ROW(FIND_NEIGHBOURS, LogLevel::llStartUp, 8, Logger::LL_INFO ), + ROW(NDBStopStarted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO ), + ROW(StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO ), + ROW(StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO ), + ROW(UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO ), + + // NODERESTART + ROW(NR_CopyDict, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + ROW(NR_CopyDistr, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + ROW(NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + ROW(NR_CopyFragDone, LogLevel::llNodeRestart,10, Logger::LL_INFO ), + ROW(NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, Logger::LL_INFO ), + + ROW(NodeFailCompleted, LogLevel::llNodeRestart, 8, Logger::LL_ALERT), + ROW(NODE_FAILREP, LogLevel::llNodeRestart, 8, Logger::LL_ALERT), + ROW(ArbitState, LogLevel::llNodeRestart, 6, Logger::LL_INFO ), + ROW(ArbitResult, LogLevel::llNodeRestart, 2, Logger::LL_ALERT), + ROW(GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + ROW(GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + ROW(LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + ROW(LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ), + + // STATISTIC + ROW(TransReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO ), + ROW(OperationReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO ), + ROW(TableCreated, LogLevel::llStatistic, 7, Logger::LL_INFO ), + ROW(JobStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ), + ROW(SendBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ), + ROW(ReceiveBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ), + ROW(MemoryUsage, LogLevel::llStatistic, 5, Logger::LL_INFO ), + + // ERROR + ROW(TransporterError, LogLevel::llError, 2, Logger::LL_ERROR ), + ROW(TransporterWarning, LogLevel::llError, 8, Logger::LL_WARNING ), + ROW(MissedHeartbeat, LogLevel::llError, 8, Logger::LL_WARNING ), + ROW(DeadDueToHeartbeat, LogLevel::llError, 8, Logger::LL_ALERT ), + ROW(WarningEvent, LogLevel::llError, 2, Logger::LL_WARNING ), + // INFO + ROW(SentHeartbeat, LogLevel::llInfo, 12, Logger::LL_INFO ), + ROW(CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO ), + ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ), + + // Backup + ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ), + ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ), + ROW(BackupFailedToStart, LogLevel::llBackup, 7, Logger::LL_ALERT), + ROW(BackupAborted, LogLevel::llBackup, 7, Logger::LL_ALERT ) +}; + +const Uint32 EventLoggerBase::matrixSize= +sizeof(EventLoggerBase::matrix)/sizeof(EventRepLogLevelMatrix); + EventLogger::EventLogger() : m_filterLevel(15) { setCategory("EventLogger"); @@ -1342,19 +763,36 @@ int EventLoggerBase::event_lookup(int eventType, LogLevel::EventCategory &cat, Uint32 &threshold, - Logger::LoggerLevel &severity) + Logger::LoggerLevel &severity, + EventTextFunction &textF) { for(unsigned i = 0; i<EventLoggerBase::matrixSize; i++){ if(EventLoggerBase::matrix[i].eventType == eventType){ cat = EventLoggerBase::matrix[i].eventCategory; threshold = EventLoggerBase::matrix[i].threshold; severity = EventLoggerBase::matrix[i].severity; + textF= EventLoggerBase::matrix[i].textF; return 0; } } return 1; } +const char* +EventLogger::getText(char * dst, size_t dst_len, + EventTextFunction textF, + const Uint32* theData, NodeId nodeId ) +{ + int pos= 0; + if (nodeId != 0) + { + BaseString::snprintf(dst, dst_len, "Node %u: ", nodeId); + pos= strlen(dst); + } + textF(dst,dst_len,theData); + return dst; +} + void EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, const LogLevel* ll) @@ -1362,52 +800,43 @@ EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, Uint32 threshold = 0; Logger::LoggerLevel severity = Logger::LL_WARNING; LogLevel::EventCategory cat= LogLevel::llInvalid; + EventTextFunction textF; DBUG_ENTER("EventLogger::log"); DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId)); - if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity)) + if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF)) DBUG_VOID_RETURN; Uint32 set = ll?ll->getLogLevel(cat) : m_logLevel.getLogLevel(cat); DBUG_PRINT("info",("threshold=%d, set=%d", threshold, set)); if (ll) DBUG_PRINT("info",("m_logLevel.getLogLevel=%d", m_logLevel.getLogLevel(cat))); + if (threshold <= set){ + getText(m_text,sizeof(m_text),textF,theData,nodeId); + switch (severity){ case Logger::LL_ALERT: - alert(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + alert(m_text); break; - case Logger::LL_CRITICAL: - critical(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + critical(m_text); break; - case Logger::LL_WARNING: - warning(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + warning(m_text); break; - case Logger::LL_ERROR: - error(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + error(m_text); break; - case Logger::LL_INFO: - info(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + info(m_text); break; - case Logger::LL_DEBUG: - debug(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + debug(m_text); break; - default: - info(EventLogger::getText(m_text, sizeof(m_text), - eventType, theData, nodeId)); + info(m_text); break; } } // if (.. diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index ba7a77fa4a9..a4335e2ec8f 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -198,7 +198,8 @@ void Cmvmi::execEVENT_REP(Signal* signal) Uint32 threshold; LogLevel::EventCategory eventCategory; Logger::LoggerLevel severity; - if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity)) + EventLoggerBase::EventTextFunction textF; + if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity,textF)) return; SubscriberPtr ptr; diff --git a/ndb/src/mgmapi/Makefile.am b/ndb/src/mgmapi/Makefile.am index 2f2fb407e46..db730bf8c89 100644 --- a/ndb/src/mgmapi/Makefile.am +++ b/ndb/src/mgmapi/Makefile.am @@ -1,7 +1,7 @@ noinst_LTLIBRARIES = libmgmapi.la -libmgmapi_la_SOURCES = mgmapi.cpp mgmapi_configuration.cpp LocalConfig.cpp +libmgmapi_la_SOURCES = mgmapi.cpp ndb_logevent.cpp mgmapi_configuration.cpp LocalConfig.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/include/mgmapi diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 9825185f88b..924d034e212 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -22,8 +22,8 @@ #include <NdbSleep.h> #include <NdbTCP.h> -#include "mgmapi.h" -#include "mgmapi_debug.h" +#include <mgmapi.h> +#include <mgmapi_debug.h> #include "mgmapi_configuration.hpp" #include <socket_io.h> @@ -1156,9 +1156,9 @@ ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId, return 0; } -extern "C" int -ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) +ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[], + int structured) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_listen_event"); const ParserRow<ParserDummy> stat_reply[] = { @@ -1180,6 +1180,8 @@ ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) } Properties args; + + args.put("structured", structured); { BaseString tmp; for(int i = 0; filter[i] != 0; i += 2){ @@ -1204,6 +1206,13 @@ ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) } extern "C" +int +ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[]) +{ + return ndb_mgm_listen_event_internal(handle,filter,0); +} + +extern "C" int ndb_mgm_get_stat_port(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/) { @@ -2138,5 +2147,4 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle, DBUG_RETURN(res); } - template class Vector<const ParserRow<ParserDummy>*>; diff --git a/ndb/src/mgmapi/mgmapi_configuration.hpp b/ndb/src/mgmapi/mgmapi_configuration.hpp index 9e94b3311bf..7d60a4842a1 100644 --- a/ndb/src/mgmapi/mgmapi_configuration.hpp +++ b/ndb/src/mgmapi/mgmapi_configuration.hpp @@ -1,3 +1,19 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef MGMAPI_CONFIGURATION_HPP #define MGMAPI_CONFIGURATION_HPP diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp new file mode 100644 index 00000000000..6d4f1980f0f --- /dev/null +++ b/ndb/src/mgmapi/ndb_logevent.cpp @@ -0,0 +1,477 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <ndb_global.h> +#include <my_sys.h> +#include <mgmapi.h> + +#include <NdbOut.hpp> +#include <Properties.hpp> +#include <socket_io.h> +#include <InputStream.hpp> + +#include <debugger/EventLogger.hpp> + +#include "ndb_logevent.hpp" + +extern +int ndb_mgm_listen_event_internal(NdbMgmHandle, const int filter[], int); + +struct ndb_logevent_error_msg { + enum ndb_logevent_handle_error code; + const char *msg; +}; + +struct ndb_logevent_error_msg ndb_logevent_error_messages[]= { + { NDB_LEH_READ_ERROR, "Read error" }, + { NDB_LEH_MISSING_EVENT_SPECIFIER, "Missing event specifier" }, + { NDB_LEH_UNKNOWN_EVENT_VARIABLE, "Unknown event variable" }, + { NDB_LEH_UNKNOWN_EVENT_TYPE, "Unknown event type" }, + { NDB_LEH_INTERNAL_ERROR, "Unknown internal error" }, + { NDB_LEH_NO_ERROR,0} +}; + +struct ndb_logevent_handle { + NDB_SOCKET_TYPE socket; + enum ndb_logevent_handle_error m_error; +}; + +extern "C" +NdbLogEventHandle +ndb_mgm_create_logevent_handle(NdbMgmHandle mh, + const int filter[]) +{ + int fd= ndb_mgm_listen_event_internal(mh, filter, 1); + + if (fd == -1) + return 0; + + NdbLogEventHandle h= + (NdbLogEventHandle)my_malloc(sizeof(ndb_logevent_handle),MYF(MY_WME)); + + h->socket= fd; + + return h; +} + +extern "C" +void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle * h) +{ + if( !h ) + return; + + if ( *h ) + close((*h)->socket); + + my_free((char*)* h,MYF(MY_ALLOW_ZERO_PTR)); + * h = 0; +} + +#define ROW(a,b,c,d) \ +{ NDB_LE_ ## a, b, c, 0, offsetof(struct ndb_logevent, a.d), \ + sizeof(((struct ndb_logevent *)0)->a.d) } + +#define ROW_FN(a,b,c,d,e) \ +{ NDB_LE_ ## a, b, c, e, offsetof(struct ndb_logevent, a.d), \ + sizeof(((struct ndb_logevent *)0)->a.d) } + +static int ref_to_node(int ref){ + return ref & 0xFFFF; +} + +struct Ndb_logevent_body_row ndb_logevent_body[]= { + + // Connection + ROW( Connected, "node", 1, node), + + ROW( Disconnected, "node", 1, node), + + ROW( CommunicationClosed, "node", 1, node), + + ROW( CommunicationOpened, "node", 1, node), + + ROW( ConnectedApiVersion, "node", 1, node), + ROW( ConnectedApiVersion, "version", 2, version), + + /* CHECKPOINT */ + + ROW( GlobalCheckpointStarted, "gci", 1, gci), + + ROW( GlobalCheckpointCompleted, "gci", 1, gci), + + ROW( LocalCheckpointStarted, "lci", 1, lci), + ROW( LocalCheckpointStarted, "keep_gci", 2, keep_gci), + ROW( LocalCheckpointStarted, "restore_gci", 3, restore_gci), + + ROW( LocalCheckpointCompleted, "lci", 1, lci), + + ROW( LCPStoppedInCalcKeepGci, "data", 1, data), + + ROW( LCPFragmentCompleted, "node", 1, node), + ROW( LCPFragmentCompleted, "table_id", 2, table_id), + ROW( LCPFragmentCompleted, "fragment_id", 3, fragment_id), + + ROW( UndoLogBlocked, "acc_count", 1, acc_count), + ROW( UndoLogBlocked, "tup_count", 2, tup_count), + + /* STARTUP */ + ROW( NDBStartStarted, "version", 1, version), + + ROW( NDBStartCompleted, "version", 1, version), + +// ROW( STTORRYRecieved), + + ROW( StartPhaseCompleted, "phase", 1, phase), + ROW( StartPhaseCompleted, "starttype", 2, starttype), + + ROW( CM_REGCONF, "own_id", 1, own_id), + ROW( CM_REGCONF, "president_id", 2, president_id), + ROW( CM_REGCONF, "dynamic_id", 3, dynamic_id), + + ROW( CM_REGREF, "own_id", 1, own_id), + ROW( CM_REGREF, "other_id", 2, other_id), + ROW( CM_REGREF, "cause", 3, cause), + + ROW( FIND_NEIGHBOURS, "own_id", 1, own_id), + ROW( FIND_NEIGHBOURS, "left_id", 3, left_id), + ROW( FIND_NEIGHBOURS, "right_id", 3, right_id), + ROW( FIND_NEIGHBOURS, "dynamic_id", 4, dynamic_id), + + ROW( NDBStopStarted, "stoptype", 1, stoptype), + +// ROW( NDBStopAborted), + + ROW( StartREDOLog, "node", 1, node), + ROW( StartREDOLog, "keep_gci", 2, keep_gci), + ROW( StartREDOLog, "completed_gci", 3, completed_gci), + ROW( StartREDOLog, "restorable_gci", 4, restorable_gci), + + ROW( StartLog, "log_part", 1, log_part), + ROW( StartLog, "start_mb", 2, start_mb), + ROW( StartLog, "stop_mb", 3, stop_mb), + ROW( StartLog, "gci", 4, gci), + + ROW( UNDORecordsExecuted, "block", 1, block), + ROW( UNDORecordsExecuted, "data1", 2, data1), + ROW( UNDORecordsExecuted, "data2", 3, data2), + ROW( UNDORecordsExecuted, "data3", 4, data3), + ROW( UNDORecordsExecuted, "data4", 5, data4), + ROW( UNDORecordsExecuted, "data5", 6, data5), + ROW( UNDORecordsExecuted, "data6", 7, data6), + ROW( UNDORecordsExecuted, "data7", 8, data7), + ROW( UNDORecordsExecuted, "data8", 9, data8), + ROW( UNDORecordsExecuted, "data9", 10, data9), + ROW( UNDORecordsExecuted, "data10", 11, data10), + + /* NODERESTART */ +// ROW( NR_CopyDict), + +// ROW( NR_CopyDistr), + + ROW( NR_CopyFragsStarted, "dest_node", 1, dest_node), + + ROW( NR_CopyFragDone, "dest_node", 1, dest_node), + ROW( NR_CopyFragDone, "table_id", 2, table_id), + ROW( NR_CopyFragDone, "fragment_id", 3, fragment_id), + + ROW( NR_CopyFragsCompleted, "dest_node", 1, dest_node), + + ROW( NodeFailCompleted, "block", 1, block), /* 0 = all */ + ROW( NodeFailCompleted, "failed_node", 2, failed_node), + ROW( NodeFailCompleted, "completing_node", 3, completing_node), /* 0 = all */ + + ROW( NODE_FAILREP, "failed_node", 1, failed_node), + ROW( NODE_FAILREP, "failure_state", 2, failure_state), + + /* TODO */ +// ROW( ArbitState), + + /* TODO */ +// ROW( ArbitResult), + +// ROW( GCP_TakeoverStarted), + +// ROW( GCP_TakeoverCompleted), + +// ROW( LCP_TakeoverStarted), + + ROW( LCP_TakeoverCompleted, "state", 1, state), + + /* STATISTIC */ + ROW( TransReportCounters, "trans_count", 1, trans_count), + ROW( TransReportCounters, "commit_count", 2, commit_count), + ROW( TransReportCounters, "read_count", 3, read_count), + ROW( TransReportCounters, "simple_read_count", 4, simple_read_count), + ROW( TransReportCounters, "write_count", 5, write_count), + ROW( TransReportCounters, "attrinfo_count", 6, attrinfo_count), + ROW( TransReportCounters, "conc_op_count", 7, conc_op_count), + ROW( TransReportCounters, "abort_count", 8, abort_count), + ROW( TransReportCounters, "scan_count", 9, scan_count), + ROW( TransReportCounters, "range_scan_count", 10, range_scan_count), + + ROW( OperationReportCounters, "ops", 1, ops), + + ROW( TableCreated, "table_id", 1, table_id), + + ROW( JobStatistic, "mean_loop_count", 1, mean_loop_count), + + ROW( SendBytesStatistic, "to_node", 1, to_node), + ROW( SendBytesStatistic, "mean_sent_bytes", 2, mean_sent_bytes), + + ROW( ReceiveBytesStatistic, "from_node", 1, from_node), + ROW( ReceiveBytesStatistic, "mean_received_bytes", 2, mean_received_bytes), + + ROW( MemoryUsage, "gth", 1, gth), + ROW( MemoryUsage, "page_size_kb", 2, page_size_kb), + ROW( MemoryUsage, "pages_used", 3, pages_used), + ROW( MemoryUsage, "pages_total", 4, pages_total), + ROW( MemoryUsage, "block", 5, block), + + /* ERROR */ + ROW( TransporterError, "to_node", 1, to_node), + ROW( TransporterError, "code", 2, code), + + ROW( TransporterWarning, "to_node", 1, to_node), + ROW( TransporterWarning, "code", 2, code), + + ROW( MissedHeartbeat, "node", 1, node), + ROW( MissedHeartbeat, "count", 2, count), + + ROW( DeadDueToHeartbeat, "node", 1, node), + + /* TODO */ +// ROW( WarningEvent), + + /* INFO */ + ROW( SentHeartbeat, "node", 1, node), + + ROW( CreateLogBytes, "node", 1, node), + + /* TODO */ +// ROW( InfoEvent), + + // Backup + ROW_FN( BackupStarted, "starting_node", 1, starting_node, ref_to_node), + ROW( BackupStarted, "backup_id", 2, backup_id), + + ROW_FN(BackupFailedToStart,"starting_node",1, starting_node, ref_to_node), + ROW( BackupFailedToStart, "error", 2, error), + + ROW_FN( BackupCompleted, "starting_node", 1, starting_node, ref_to_node), + ROW( BackupCompleted, "backup_id", 2, backup_id), + ROW( BackupCompleted, "start_gci", 3, start_gci), + ROW( BackupCompleted, "stop_gci", 4, stop_gci), + ROW( BackupCompleted, "n_bytes", 5, n_bytes), + ROW( BackupCompleted, "n_records", 6, n_records), + ROW( BackupCompleted, "n_log_bytes", 7, n_log_bytes), + ROW( BackupCompleted, "n_log_records", 8, n_log_records), + + ROW_FN( BackupAborted, "starting_node", 1, starting_node, ref_to_node), + ROW( BackupAborted, "backup_id", 2, backup_id), + ROW( BackupAborted, "error", 3, error), + + { NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0} +}; + +struct Ndb_logevent_header_row { + const char *token; // token to use for text transfer + int offset; // offset into struct ndb_logevent + int size; +}; + +#define ROW2(a,b) \ +{ a, offsetof(struct ndb_logevent, b), \ + sizeof(((struct ndb_logevent *)0)->b) } + +struct Ndb_logevent_header_row ndb_logevent_header[]= { + ROW2( "type", type), + ROW2( "time", time), + ROW2( "source_nodeid", source_nodeid), + { 0, 0, 0 } +}; + +static int +insert_row(const char * pair, Properties & p){ + BaseString tmp(pair); + + tmp.trim(" \t\n\r"); + Vector<BaseString> split; + tmp.split(split, ":=", 2); + if(split.size() != 2) + return -1; + p.put(split[0].trim().c_str(), split[1].trim().c_str()); + + return 0; +} + +static +int memcpy_atoi(void *dst, const char *str, int sz) +{ + switch (sz) + { + case 1: + { + Int8 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + case 2: + { + Int16 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + case 4: + { + Int32 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + case 8: + { + Int64 val= atoi(str); + memcpy(dst,&val,sz); + return 0; + } + default: + { + return -1; + } + } +} + +extern "C" +int ndb_logevent_get_next(const NdbLogEventHandle h, + struct ndb_logevent *dst, + unsigned timeout_in_milliseconds) +{ + SocketInputStream in(h->socket, timeout_in_milliseconds); + + Properties p; + char buf[256]; + + /* header */ + while (1) { + if (in.gets(buf,sizeof(buf)) == 0) + { + h->m_error= NDB_LEH_READ_ERROR; + return -1; + } + if ( buf[0] == 0 ) + { + // timed out + return 0; + } + if ( strcmp("log event reply\n", buf) == 0 ) + break; + ndbout_c("skipped: %s", buf); + } + + /* read name-value pairs into properties object */ + while (1) + { + if (in.gets(buf,sizeof(buf)) == 0) + { + h->m_error= NDB_LEH_READ_ERROR; + return -1; + } + if ( buf[0] == 0 ) + { + // timed out + return 0; + } + if ( buf[0] == '\n' ) + { + break; + } + if (insert_row(buf,p)) + { + h->m_error= NDB_LEH_READ_ERROR; + return -1; + } + } + + int i; + const char *val; + + dst->type= (enum Ndb_logevent_type)-1; + /* fill in header info from p*/ + for (i= 0; ndb_logevent_header[i].token; i++) + { + if ( p.get(ndb_logevent_header[i].token, &val) == 0 ) + { + ndbout_c("missing: %s\n", ndb_logevent_header[i].token); + h->m_error= NDB_LEH_MISSING_EVENT_SPECIFIER; + return -1; + } + if ( memcpy_atoi((char *)dst+ndb_logevent_header[i].offset, val, + ndb_logevent_header[i].size) ) + { + h->m_error= NDB_LEH_INTERNAL_ERROR; + return -1; + } + } + + Uint32 level; + LogLevel::EventCategory category; + Logger::LoggerLevel severity; + EventLoggerBase::EventTextFunction text_fn; + + /* fill in rest of header info event_lookup */ + if (EventLoggerBase::event_lookup(dst->type,category,level,severity,text_fn)) + { + ndbout_c("unknown type: %d\n", dst->type); + h->m_error= NDB_LEH_UNKNOWN_EVENT_TYPE; + return -1; + } + dst->category= (enum ndb_mgm_event_category)category; + dst->severity= (enum ndb_mgm_event_severity)severity; + dst->level= level; + + /* fill in header info from p */ + for (i= 0; ndb_logevent_body[i].token; i++) + { + if ( ndb_logevent_body[i].type != dst->type ) + continue; + if ( p.get(ndb_logevent_body[i].token, &val) == 0 ) + { + h->m_error= NDB_LEH_UNKNOWN_EVENT_VARIABLE; + return -1; + } + if ( memcpy_atoi((char *)dst+ndb_logevent_body[i].offset, val, + ndb_logevent_body[i].size) ) + { + h->m_error= NDB_LEH_INTERNAL_ERROR; + return -1; + } + } + return 1; +} + +extern "C" +int ndb_logevent_get_latest_error(const NdbLogEventHandle h) +{ + return h->m_error; +} + +extern "C" +const char *ndb_logevent_get_latest_error_msg(const NdbLogEventHandle h) +{ + for (int i= 0; ndb_logevent_error_messages[i].msg; i++) + if (ndb_logevent_error_messages[i].code == h->m_error) + return ndb_logevent_error_messages[i].msg; + return "<unknown error msg>"; +} diff --git a/ndb/src/mgmapi/ndb_logevent.hpp b/ndb/src/mgmapi/ndb_logevent.hpp new file mode 100644 index 00000000000..cb1a0e388e5 --- /dev/null +++ b/ndb/src/mgmapi/ndb_logevent.hpp @@ -0,0 +1,34 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef NDB_LOGEVENT_HPP +#define NDB_LOGEVENT_HPP + +#include <ndb_logevent.h> + +struct Ndb_logevent_body_row { + enum Ndb_logevent_type type; // type + const char *token; // token to use for text transfer + int index; // index into theData array + int (*index_fn)(int); // conversion function on the data array[index] + int offset; // offset into struct ndb_logevent + int size; // offset into struct ndb_logevent +}; + +extern +struct Ndb_logevent_body_row ndb_logevent_body[]; + +#endif diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index 4742d5f6426..03e99fb0770 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -49,6 +49,7 @@ class Ndb_mgmd_event_service : public EventLoggerBase public: struct Event_listener : public EventLoggerBase { NDB_SOCKET_TYPE m_socket; + Uint32 m_parsable; }; private: diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 447bc8bdc2b..8a387f88a96 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -31,6 +31,7 @@ #include <mgmapi_configuration.hpp> #include <Vector.hpp> #include "Services.hpp" +#include "../mgmapi/ndb_logevent.hpp" extern bool g_StopServer; @@ -256,6 +257,7 @@ ParserRow<MgmApiSession> commands[] = { MGM_CMD("listen event", &MgmApiSession::listen_event, ""), MGM_ARG("node", Int, Optional, "Node"), + MGM_ARG("parsable", Int, Optional, "Parsable"), MGM_ARG("filter", String, Mandatory, "Event category"), MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""), @@ -1249,25 +1251,49 @@ Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId) Uint32 threshold; LogLevel::EventCategory cat; Logger::LoggerLevel severity; + EventLoggerBase::EventTextFunction textF; int i; DBUG_ENTER("Ndb_mgmd_event_service::log"); DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId)); - if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity)) + if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF)) DBUG_VOID_RETURN; char m_text[256]; - EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId); + EventLogger::getText(m_text, sizeof(m_text), + textF, theData, nodeId); + + BaseString str("log event reply\n"); + str.appfmt("type=%d\n", eventType); + str.appfmt("time=%d\n", 0); + str.appfmt("source_nodeid=%d\n", nodeId); + for (i= 0; ndb_logevent_body[i].token; i++) + { + if ( ndb_logevent_body[i].type != eventType) + continue; + int val= theData[ndb_logevent_body[i].index]; + if (ndb_logevent_body[i].index_fn) + val= (*(ndb_logevent_body[i].index_fn))(val); + str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val); + } - Vector<NDB_SOCKET_TYPE> copy; + Vector<NDB_SOCKET_TYPE> copy; m_clients.lock(); for(i = m_clients.size() - 1; i >= 0; i--){ if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat)){ - if(m_clients[i].m_socket != NDB_INVALID_SOCKET && - println_socket(m_clients[i].m_socket, - MAX_WRITE_TIMEOUT, m_text) == -1){ - copy.push_back(m_clients[i].m_socket); - m_clients.erase(i, false); + if(m_clients[i].m_socket != NDB_INVALID_SOCKET) + { + int r; + if (m_clients[i].m_parsable) + r= println_socket(m_clients[i].m_socket, + MAX_WRITE_TIMEOUT, str.c_str()); + else + r= println_socket(m_clients[i].m_socket, + MAX_WRITE_TIMEOUT, m_text); + if (r == -1) { + copy.push_back(m_clients[i].m_socket); + m_clients.erase(i, false); + } } } } @@ -1395,15 +1421,17 @@ MgmApiSession::getConnectionParameter(Parser_t::Context &ctx, void MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx, Properties const & args) { - + Uint32 parsable= 0; BaseString node, param, value; args.get("node", node); args.get("filter", param); + args.get("parsable", &parsable); int result = 0; BaseString msg; Ndb_mgmd_event_service::Event_listener le; + le.m_parsable = parsable; le.m_socket = m_socket; Vector<BaseString> list; |