1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00
Add support for getting events via mgmapi
removed all traces of stat port


BitKeeper/deleted/.del-NodeLogLevel.cpp~324045b93af7123b:
  Delete: ndb/src/mgmsrv/NodeLogLevel.cpp
BitKeeper/deleted/.del-NodeLogLevel.hpp~4f4ab0fe52fb497c:
  Delete: ndb/src/mgmsrv/NodeLogLevel.hpp
BitKeeper/deleted/.del-NodeLogLevelList.cpp~97dc9c909e3e92bf:
  Delete: ndb/src/mgmsrv/NodeLogLevelList.cpp
BitKeeper/deleted/.del-NodeLogLevelList.hpp~ef567dd850abddc7:
  Delete: ndb/src/mgmsrv/NodeLogLevelList.hpp
ndb/include/debugger/EventLogger.hpp:
  Split EventLogger into two classes
ndb/include/kernel/LogLevel.hpp:
  Add some nice to have methods + use uint8 for storage
ndb/include/kernel/signaldata/EventSubscribeReq.hpp:
  operator=
ndb/include/kernel/signaldata/SetLogLevelOrd.hpp:
  operator=
ndb/include/mgmapi/mgmapi.h:
  remove deprecated vars
ndb/src/common/debugger/EventLogger.cpp:
  Split into 2
ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp:
  Remove hardcoded mgm stuff
ndb/src/mgmsrv/CommandInterpreter.cpp:
  #if 0
  some deprecated code
ndb/src/mgmsrv/Makefile.am:
  remove NodeLogLevel*
ndb/src/mgmsrv/MgmtSrvr.cpp:
  Remove dead code
  Handle multiple event listeners in mgmapi
ndb/src/mgmsrv/MgmtSrvr.hpp:
  Remove dead code
  Handle multiple event listeners in mgmapi
ndb/src/mgmsrv/Services.cpp:
  listen event method in mgmapi
ndb/src/mgmsrv/Services.hpp:
  listen event method in mgmapi
ndb/src/mgmsrv/main.cpp:
  remove stat port
This commit is contained in:
unknown
2004-09-16 18:02:41 +02:00
parent 3e78c89ed4
commit 2468e5ba46
18 changed files with 688 additions and 1308 deletions

View File

@ -24,128 +24,15 @@
#include <kernel/LogLevel.hpp>
#include <signaldata/EventReport.hpp>
/**
* The EventLogger is primarily used for logging NDB events
* in the Management Server. It inherits all logging functionality of Logger.
*
* HOW TO USE
*
* 1) Create an EventLogger
*
* EventLogger myEventLogger = new EventLogger();
*
* 2) Log NDB events and other log messages.
*
* myEventLogger->info("Changing log levels.");
*
* EventReport* report = (EventReport*)&theSignalData[0];
* myEventLogger->log(eventReport->getEventType(), theSignalData, aNodeId);
*
*
* The following NDB event categories and log levels are enabled as default:
*
* EVENT-CATEGORY LOG-LEVEL
*
* Startup 4
* Shutdown 1
* Statistic 2
* Checkpoint 5
* NodeRestart 8
* Connection 2
* Error 15
* Info 10
*
* @see Logger
* @version #@ $Id: EventLogger.hpp,v 1.3 2003/09/01 10:15:52 innpeno Exp $
*/
class EventLogger : public Logger
{
class EventLoggerBase {
public:
/**
* Default constructor. Enables default log levels and
* sets the log category to 'EventLogger'.
*/
EventLogger();
virtual ~EventLoggerBase();
/**
* Destructor.
* LogLevel settings
*/
~EventLogger();
/**
* Opens/creates the eventlog with the specified filename.
*
* @param aFileName the eventlog filename.
* @param maxNoFiles the maximum no of archived eventlog files.
* @param maxFileSize the maximum eventlog file size.
* @param maxLogEntries the maximum number of log entries before
* checking time to archive.
* @return true if successful.
*/
bool open(const char* logFileName,
int maxNoFiles = FileLogHandler::MAX_NO_FILES,
long int maxFileSize = FileLogHandler::MAX_FILE_SIZE,
unsigned int maxLogEntries = FileLogHandler::MAX_LOG_ENTRIES);
/**
* Closes the eventlog.
*/
void close();
/**
* Logs the NDB event.
*
* @param nodeId the node id of event origin.
* @param eventType the type of event.
* @param theData the event data.
* @deprecated use log(int eventType, const Uint32* theData, NodeId nodeId)
*/
void log(NodeId nodeId, int eventType, const Uint32* theData);
/**
* Logs the NDB event.
*
* @param eventType the type of event.
* @param theData the event data.
* @param nodeId the node id of event origin.
*/
void log(int eventType, const Uint32* theData, NodeId nodeId = 0);
/**
* Returns the current log levels.
* Enable, disable log levels to filter the events that are sent to the
* eventlog.
*
* @return the log level.
*/
LogLevel& getLoglevel();
LogLevel m_logLevel;
/**
* Returns the log level that is used to filter an event. The event will not
* be logged unless its event category's log level is <= levelFilter.
*
* @return the log level filter that is used for all event categories.
*/
int getFilterLevel() const;
/**
* Sets log level filter. The event will be logged if
* the event category's log level is <= 'filterLevel'.
*
* @param level the log level to filter.
*/
void setFilterLevel(int filterLevel);
/**
* Returns the event text for the specified event report type.
*
* @param type the event type.
* @param theData the event data.
* @param nodeId a node id.
* @return the event report text.
*/
static const char* getText(int type,
const Uint32* theData, NodeId nodeId = 0);
/**
* Find a category matching the string
*
@ -193,22 +80,113 @@ public:
};
static const EventRepLogLevelMatrix matrix[];
static const Uint32 matrixSize;
};
/**
* The EventLogger is primarily used for logging NDB events
* in the Management Server. It inherits all logging functionality of Logger.
*
* HOW TO USE
*
* 1) Create an EventLogger
*
* EventLogger myEventLogger = new EventLogger();
*
* 2) Log NDB events and other log messages.
*
* myEventLogger->info("Changing log levels.");
*
* EventReport* report = (EventReport*)&theSignalData[0];
* myEventLogger->log(eventReport->getEventType(), theSignalData, aNodeId);
*
*
* The following NDB event categories and log levels are enabled as default:
*
* EVENT-CATEGORY LOG-LEVEL
*
* Startup 4
* Shutdown 1
* Statistic 2
* Checkpoint 5
* NodeRestart 8
* Connection 2
* Error 15
* Info 10
*
* @see Logger
* @version #@ $Id: EventLogger.hpp,v 1.3 2003/09/01 10:15:52 innpeno Exp $
*/
class EventLogger : public EventLoggerBase, public Logger
{
public:
/**
* Default constructor. Enables default log levels and
* sets the log category to 'EventLogger'.
*/
EventLogger();
/**
* Default log levels for management nodes.
*
* threshold - is in range [0-15]
* Destructor.
*/
struct EventLogMatrix {
LogLevel::EventCategory eventCategory;
Uint32 threshold;
};
virtual ~EventLogger();
static const EventLogMatrix defEventLogMatrix[];
/**
* Opens/creates the eventlog with the specified filename.
*
* @param aFileName the eventlog filename.
* @param maxNoFiles the maximum no of archived eventlog files.
* @param maxFileSize the maximum eventlog file size.
* @param maxLogEntries the maximum number of log entries before
* checking time to archive.
* @return true if successful.
*/
bool open(const char* logFileName,
int maxNoFiles = FileLogHandler::MAX_NO_FILES,
long int maxFileSize = FileLogHandler::MAX_FILE_SIZE,
unsigned int maxLogEntries = FileLogHandler::MAX_LOG_ENTRIES);
/**
* Closes the eventlog.
*/
void close();
/**
* Logs the NDB event.
*
* @param eventType the type of event.
* @param theData the event data.
* @param nodeId the node id of event origin.
*/
virtual void log(int eventType, const Uint32* theData, NodeId nodeId = 0);
/**
* Returns the event text for the specified event report type.
*
* @param type the event type.
* @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,
const Uint32* theData, NodeId nodeId = 0);
static const Uint32 matrixSize;
static const Uint32 defEventLogMatrixSize;
/**
* Returns the log level that is used to filter an event. The event will not
* be logged unless its event category's log level is <= levelFilter.
*
* @return the log level filter that is used for all event categories.
*/
int getFilterLevel() const;
/**
* Sets log level filter. The event will be logged if
* the event category's log level is <= 'filterLevel'.
*
* @param level the log level to filter.
*/
void setFilterLevel(int filterLevel);
private:
/** Prohibit */
@ -216,11 +194,10 @@ private:
EventLogger operator = (const EventLogger&);
bool operator == (const EventLogger&);
LogLevel m_logLevel;
Uint32 m_filterLevel;
STATIC_CONST(MAX_TEXT_LENGTH = 256);
static char m_text[MAX_TEXT_LENGTH];
char m_text[MAX_TEXT_LENGTH];
};

View File

@ -130,18 +130,25 @@ public:
*/
Uint32 getLogLevel(EventCategory ec) const;
/**
* Set this= max(this, ll) per category
*/
LogLevel& set_max(const LogLevel& ll);
bool operator==(const LogLevel& l) const {
return memcmp(this, &l, sizeof(* this)) == 0;
}
private:
/**
* The actual data
*/
Uint32 logLevelData[LOGLEVEL_CATEGORIES];
LogLevel(const LogLevel &);
Uint8 logLevelData[LOGLEVEL_CATEGORIES];
};
inline
LogLevel::LogLevel(){
clear();
clear();
}
inline
@ -176,5 +183,14 @@ LogLevel::getLogLevel(EventCategory ec) const{
return logLevelData[ec];
}
inline
LogLevel &
LogLevel::set_max(const LogLevel & org){
for(Uint32 i = 0; i<LOGLEVEL_CATEGORIES; i++){
if(logLevelData[i] < org.logLevelData[i])
logLevelData[i] = org.logLevelData[i];
}
return * this;
}
#endif

View File

@ -27,7 +27,7 @@
* RECIVER: SimBlockCMCtrBlck
*/
class EventSubscribeReq {
struct EventSubscribeReq {
/**
* Receiver(s)
*/
@ -38,9 +38,8 @@ class EventSubscribeReq {
*/
friend class MgmtSrvr;
public:
STATIC_CONST( SignalLength = 22 );
private:
/**
* Note: If you use the same blockRef as you have used earlier,
* you update your ongoing subscription
@ -55,6 +54,15 @@ private:
Uint32 theCategories[10];
Uint32 theLevels[10];
EventSubscribeReq& operator= (const LogLevel& ll){
noOfEntries = _LOGLEVEL_CATEGORIES;
for(size_t i = 0; i<noOfEntries; i++){
theCategories[i] = i;
theLevels[i] = ll.getLogLevel((LogLevel::EventCategory)i);
}
return * this;
}
};
#endif

View File

@ -18,6 +18,7 @@
#define SET_LOGLEVEL_ORD_HPP
#include <LogLevel.hpp>
#include "EventSubscribeReq.hpp"
#include "SignalData.hpp"
/**
@ -51,6 +52,24 @@ private:
* Note level is valid as 0-15
*/
void setLogLevel(LogLevel::EventCategory ec, int level = 7);
SetLogLevelOrd& operator= (const LogLevel& ll){
noOfEntries = _LOGLEVEL_CATEGORIES;
for(size_t i = 0; i<noOfEntries; i++){
theCategories[i] = i;
theLevels[i] = ll.getLogLevel((LogLevel::EventCategory)i);
}
return * this;
}
SetLogLevelOrd& operator= (const EventSubscribeReq& ll){
noOfEntries = ll.noOfEntries;
for(size_t i = 0; i<noOfEntries; i++){
theCategories[i] = ll.theCategories[i];
theLevels[i] = ll.theLevels[i];
}
return * this;
}
};
inline

View File

@ -55,24 +55,6 @@
extern "C" {
#endif
/**
* Format of statistical information from the NDB Cluster.
* STATISTIC_LINE is sent on the statistical port from the Management server,
* each line is timestamped with STATISTIC_DATE.
*/
#define STATISTIC_LINE "date=%s epochsecs=%d nodeid=%u trans=%u commit=%u " \
"read=%u insert=%u attrinfo=%u cops=%u abort=%u"
/**
* Format of statistical information from the NDB Cluster.
* STATISTIC_LINE is sent on the statistical port from the Management server,
* each line is timestamped with STATISTIC_DATE.
*/
#define STATISTIC_DATE "%d-%.2d-%.2d/%.2d:%.2d:%.2d"
/**
* Format of statistical information from the NDB Cluster.
*/
#define OP_STATISTIC_LINE "date=%s epochsecs=%d nodeid=%d operations=%u"
/**
* The NdbMgmHandle.
*/

File diff suppressed because it is too large Load Diff

View File

@ -250,17 +250,7 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
sendSignal(subReq->blockRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB);
return;
}
/**
* If it's a new subscription, clear the loglevel
*
* Clear only if noOfEntries is 0, this is needed beacuse we set
* the default loglevels for the MGMT nodes during the inital connect phase.
* See reportConnected().
*/
if (subReq->noOfEntries == 0){
ptr.p->logLevel.clear();
}
ptr.p->logLevel.clear();
ptr.p->blockRef = subReq->blockRef;
}
@ -384,11 +374,6 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal)
globalTransporterRegistry.setIOState(i, HaltIO);
globalTransporterRegistry.do_disconnect(i);
/**
* Cancel possible event subscription
*/
cancelSubscription(i);
}
}
if (failNo != 0) {
@ -494,6 +479,8 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal)
globalTransporterRegistry.do_connect(hostId);
}
cancelSubscription(hostId);
signal->theData[0] = EventReport::Disconnected;
signal->theData[1] = hostId;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
@ -539,20 +526,6 @@ void Cmvmi::execCONNECT_REP(Signal *signal){
if(type == NodeInfo::MGM){
jam();
globalTransporterRegistry.setIOState(hostId, NoHalt);
EventSubscribeReq* dst = (EventSubscribeReq *)&signal->theData[0];
for (Uint32 i = 0; i < EventLogger::defEventLogMatrixSize; i++) {
dst->theCategories[i] = EventLogger::defEventLogMatrix[i].eventCategory;
dst->theLevels[i] = EventLogger::defEventLogMatrix[i].threshold;
}
dst->noOfEntries = EventLogger::defEventLogMatrixSize;
/* The BlockNumber is hardcoded as 1 in MgmtSrvr */
dst->blockRef = numberToRef(MIN_API_BLOCK_NO, hostId);
execEVENT_SUBSCRIBE_REQ(signal);
}
//------------------------------------------

View File

@ -389,9 +389,9 @@ void CommandInterpreter::executeHelp(char* parameters) {
<< endl;
ndbout << "<category> = ";
for(i = 0; i<EventLogger::noOfEventCategoryNames; i++){
ndbout << EventLogger::eventCategoryNames[i].name;
if (i < EventLogger::noOfEventCategoryNames - 1) {
for(i = 0; i<EventLoggerBase::noOfEventCategoryNames; i++){
ndbout << EventLoggerBase::eventCategoryNames[i].name;
if (i < EventLoggerBase::noOfEventCategoryNames - 1) {
ndbout << " | ";
}
}
@ -831,12 +831,13 @@ void CommandInterpreter::executeStatus(int processId,
//*****************************************************************************
void CommandInterpreter::executeLogLevel(int processId,
const char* parameters, bool all) {
#if 0
(void)all; // Don't want compiler warning
SetLogLevelOrd logLevel; logLevel.clear();
if (emptyString(parameters) || (strcmp(parameters, "ALL") == 0)) {
for(Uint32 i = 0; i<EventLogger::noOfEventCategoryNames; i++)
logLevel.setLogLevel(EventLogger::eventCategoryNames[i].category, 7);
for(Uint32 i = 0; i<EventLoggerBase::noOfEventCategoryNames; i++)
logLevel.setLogLevel(EventLoggerBase::eventCategoryNames[i].category, 7);
} else {
char * tmpString = strdup(parameters);
@ -852,7 +853,7 @@ void CommandInterpreter::executeLogLevel(int processId,
return;
}
LogLevel::EventCategory cat;
if(!EventLogger::matchEventCategory(categoryTxt,
if(!EventLoggerBase::matchEventCategory(categoryTxt,
&cat)){
ndbout << "Invalid loglevel specification, unknown category: "
<< categoryTxt << endl;
@ -875,6 +876,7 @@ void CommandInterpreter::executeLogLevel(int processId,
if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl;
}
#endif
}
@ -1080,12 +1082,13 @@ void CommandInterpreter::executeTestOff(int processId,
void CommandInterpreter::executeEventReporting(int processId,
const char* parameters,
bool all) {
#if 0
(void)all; // Don't want compiler warning
SetLogLevelOrd logLevel; logLevel.clear();
if (emptyString(parameters) || (strcmp(parameters, "ALL") == 0)) {
for(Uint32 i = 0; i<EventLogger::noOfEventCategoryNames; i++)
logLevel.setLogLevel(EventLogger::eventCategoryNames[i].category, 7);
for(Uint32 i = 0; i<EventLoggerBase::noOfEventCategoryNames; i++)
logLevel.setLogLevel(EventLoggerBase::eventCategoryNames[i].category, 7);
} else {
char * tmpString = strdup(parameters);
@ -1101,7 +1104,7 @@ void CommandInterpreter::executeEventReporting(int processId,
return;
}
LogLevel::EventCategory cat;
if(!EventLogger::matchEventCategory(categoryTxt,
if(!EventLoggerBase::matchEventCategory(categoryTxt,
&cat)){
ndbout << "Invalid loglevel specification, unknown category: "
<< categoryTxt << endl;
@ -1124,6 +1127,7 @@ void CommandInterpreter::executeEventReporting(int processId,
if (result != 0) {
ndbout << _mgmtSrvr.getErrorText(result) << endl;
}
#endif
}
void

View File

@ -12,8 +12,6 @@ ndb_mgmd_SOURCES = \
main.cpp \
Services.cpp \
convertStrToInt.cpp \
NodeLogLevel.cpp \
NodeLogLevelList.cpp \
SignalQueue.cpp \
MgmtSrvrConfig.cpp \
ConfigInfo.cpp \

View File

@ -45,7 +45,6 @@
#include <ndb_version.h>
#include <SocketServer.hpp>
#include "NodeLogLevel.hpp"
#include <NdbConfig.h>
#include <NdbAutoPtr.hpp>
@ -191,41 +190,49 @@ EventLogger g_EventLogger;
void
MgmtSrvr::logLevelThreadRun()
{
NdbMutex* threadMutex = NdbMutex_Create();
while (!_isStopThread) {
if (_startedNodeId != 0) {
NdbMutex_Lock(threadMutex);
/**
* Handle started nodes
*/
EventSubscribeReq req;
req = m_statisticsListner.m_clients[0].m_logLevel;
req.blockRef = _ownReference;
// Local node
NodeLogLevel* n = NULL;
while ((n = _nodeLogLevelList->next()) != NULL) {
if (n->getNodeId() == _startedNodeId) {
setNodeLogLevel(_startedNodeId, n->getLogLevelOrd(), true);
}
SetLogLevelOrd ord;
m_started_nodes.lock();
while(m_started_nodes.size() > 0){
Uint32 node = m_started_nodes[0];
m_started_nodes.erase(0, false);
m_started_nodes.unlock();
setEventReportingLevelImpl(node, req);
ord = m_nodeLogLevel[node];
setNodeLogLevelImpl(node, ord);
m_started_nodes.lock();
}
m_started_nodes.unlock();
m_log_level_requests.lock();
while(m_log_level_requests.size() > 0){
req = m_log_level_requests[0];
m_log_level_requests.erase(0, false);
m_log_level_requests.unlock();
if(req.blockRef == 0){
req.blockRef = _ownReference;
setEventReportingLevelImpl(0, req);
} else {
ord = req;
setNodeLogLevelImpl(req.blockRef, ord);
}
// Cluster log
while ((n = _clusterLogLevelList->next()) != NULL) {
if (n->getNodeId() == _startedNodeId) {
setEventReportingLevel(_startedNodeId, n->getLogLevelOrd(), true);
}
}
_startedNodeId = 0;
NdbMutex_Unlock(threadMutex);
} // if (_startedNodeId != 0) {
m_log_level_requests.lock();
}
m_log_level_requests.unlock();
NdbSleep_MilliSleep(_logLevelThreadSleep);
} // while (!_isStopThread)
NdbMutex_Destroy(threadMutex);
}
void
MgmtSrvr::setStatisticsListner(StatisticsListner* listner)
{
m_statisticsListner = listner;
}
}
void
@ -272,7 +279,7 @@ class ErrorItem
{
public:
int _errorCode;
const BaseString _errorText;
const char * _errorText;
};
bool
@ -485,23 +492,6 @@ MgmtSrvr::getPort() const {
return port;
}
int
MgmtSrvr::getStatPort() const {
#if 0
const Properties *mgmProps;
if(!getConfig()->get("Node", _ownNodeId, &mgmProps))
return -1;
int tmp = -1;
if(!mgmProps->get("PortNumberStats", (Uint32 *)&tmp))
return -1;
return tmp;
#else
return -1;
#endif
}
/* Constructor */
MgmtSrvr::MgmtSrvr(NodeId nodeId,
const BaseString &configFilename,
@ -510,22 +500,19 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
_blockNumber(1), // Hard coded block number since it makes it easy to send
// signals to other management servers.
_ownReference(0),
m_allocated_resources(*this),
theSignalIdleList(NULL),
theWaitState(WAIT_SUBSCRIBE_CONF),
theConfCount(0),
m_allocated_resources(*this) {
m_statisticsListner(this){
DBUG_ENTER("MgmtSrvr::MgmtSrvr");
_config = NULL;
_isStatPortActive = false;
_isClusterLogStatActive = false;
_isStopThread = false;
_logLevelThread = NULL;
_logLevelThreadSleep = 500;
m_signalRecvThread = NULL;
_startedNodeId = 0;
theFacade = 0;
@ -583,13 +570,7 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
ndb_mgm_destroy_iterator(iter);
}
m_statisticsListner = NULL;
_nodeLogLevelList = new NodeLogLevelList();
_clusterLogLevelList = new NodeLogLevelList();
_props = NULL;
_ownNodeId= 0;
NodeId tmp= nodeId;
BaseString error_string;
@ -610,6 +591,16 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
}
}
{
MgmStatService::StatListener se;
se.m_socket = -1;
for(size_t t = 0; t<_LOGLEVEL_CATEGORIES; t++)
se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7);
se.m_logLevel.setLogLevel(LogLevel::llError, 15);
m_statisticsListner.m_clients.push_back(se);
m_statisticsListner.m_logLevel = se.m_logLevel;
}
DBUG_VOID_RETURN;
}
@ -671,8 +662,6 @@ MgmtSrvr::start(BaseString &error_string)
// Set the initial confirmation count for subscribe requests confirm
// from NDB nodes in the cluster.
//
theConfCount = getNodeCount(NDB_MGM_NODE_TYPE_NDB);
// Loglevel thread
_logLevelThread = NdbThread_Create(logLevelThread_C,
(void**)this,
@ -713,9 +702,6 @@ MgmtSrvr::~MgmtSrvr()
if(_config != NULL)
delete _config;
delete _nodeLogLevelList;
delete _clusterLogLevelList;
// End set log level thread
void* res = 0;
_isStopThread = true;
@ -736,6 +722,9 @@ MgmtSrvr::~MgmtSrvr()
int MgmtSrvr::okToSendTo(NodeId processId, bool unCond)
{
if(processId == 0)
return 0;
if (getNodeType(processId) != NDB_MGM_NODE_TYPE_NDB)
return WRONG_PROCESS_TYPE;
@ -1540,175 +1529,72 @@ MgmtSrvr::status(int processId,
return -1;
}
//****************************************************************************
//****************************************************************************
int
MgmtSrvr::startStatisticEventReporting(int level)
{
SetLogLevelOrd ll;
NodeId nodeId = 0;
ll.clear();
ll.setLogLevel(LogLevel::llStatistic, level);
if (level > 0) {
_isStatPortActive = true;
} else {
_isStatPortActive = false;
if (_isClusterLogStatActive) {
return 0;
}
}
while (getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
setEventReportingLevelImpl(nodeId, ll);
}
return 0;
}
int
MgmtSrvr::setEventReportingLevel(int processId, const SetLogLevelOrd & ll,
bool isResend)
{
for (Uint32 i = 0; i < ll.noOfEntries; i++) {
if (ll.theCategories[i] == LogLevel::llStatistic) {
if (ll.theLevels[i] > 0) {
_isClusterLogStatActive = true;
break;
} else {
_isClusterLogStatActive = false;
if (_isStatPortActive) {
return 0;
}
break;
}
} // if (ll.theCategories
} // for (int i = 0
return setEventReportingLevelImpl(processId, ll, isResend);
}
int
MgmtSrvr::setEventReportingLevelImpl(int processId,
const SetLogLevelOrd & ll,
bool isResend)
const EventSubscribeReq& ll)
{
Uint32 i;
for(i = 0; i<ll.noOfEntries; i++){
// Save log level for the cluster log
if (!isResend) {
NodeLogLevel* n = NULL;
bool found = false;
while ((n = _clusterLogLevelList->next()) != NULL) {
if (n->getNodeId() == processId &&
n->getCategory() == ll.theCategories[i]) {
n->setLevel(ll.theLevels[i]);
found = true;
}
}
if (!found) {
_clusterLogLevelList->add(new NodeLogLevel(processId, ll));
}
}
}
int result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
NdbApiSignal signal(_ownReference);
EventSubscribeReq * dst =
CAST_PTR(EventSubscribeReq, signal->getDataPtrSend());
for(i = 0; i<ll.noOfEntries; i++){
dst->theCategories[i] = ll.theCategories[i];
dst->theLevels[i] = ll.theLevels[i];
}
dst->noOfEntries = ll.noOfEntries;
dst->blockRef = _ownReference;
CAST_PTR(EventSubscribeReq, signal.getDataPtrSend());
signal->set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
EventSubscribeReq::SignalLength);
* dst = ll;
signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
EventSubscribeReq::SignalLength);
theFacade->lock_mutex();
send(&signal, processId, NODE_TYPE_DB);
theFacade->unlock_mutex();
result = sendSignal(processId, WAIT_SUBSCRIBE_CONF, signal, true);
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
else {
// Increment the conf counter
theConfCount++;
}
return 0;
}
//****************************************************************************
//****************************************************************************
int
MgmtSrvr::setNodeLogLevel(int processId, const SetLogLevelOrd & ll,
bool isResend)
MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll)
{
Uint32 i;
for(i = 0; i<ll.noOfEntries; i++){
// Save log level for the cluster log
if (!isResend) {
NodeLogLevel* n = NULL;
bool found = false;
while ((n = _clusterLogLevelList->next()) != NULL) {
if (n->getNodeId() == processId &&
n->getCategory() == ll.theCategories[i]) {
n->setLevel(ll.theLevels[i]);
found = true;
}
}
if (!found) {
_clusterLogLevelList->add(new NodeLogLevel(processId, ll));
}
}
}
int result = okToSendTo(processId, true);
if (result != 0) {
return result;
}
NdbApiSignal* signal = getSignal();
if (signal == NULL) {
return COULD_NOT_ALLOCATE_MEMORY;
}
SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal->getDataPtrSend());
for(i = 0; i<ll.noOfEntries; i++){
dst->theCategories[i] = ll.theCategories[i];
dst->theLevels[i] = ll.theLevels[i];
}
NdbApiSignal signal(_ownReference);
dst->noOfEntries = ll.noOfEntries;
SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend());
signal->set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
SetLogLevelOrd::SignalLength);
result = sendSignal(processId, NO_WAIT, signal, true);
if (result == -1) {
return SEND_OR_RECEIVE_FAILED;
}
* dst = ll;
signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
SetLogLevelOrd::SignalLength);
theFacade->lock_mutex();
theFacade->sendSignalUnCond(&signal, processId);
theFacade->unlock_mutex();
return 0;
}
int
MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
Uint32 max = (node == 0) ? MAX_NODES : node + 1;
for(; node < max; node++){
while(nodeTypes[node] != node_type && node < max) node++;
if(nodeTypes[node] != node_type)
break;
theFacade->sendSignalUnCond(signal, node);
}
return 0;
}
//****************************************************************************
//****************************************************************************
@ -2003,7 +1889,7 @@ const char* MgmtSrvr::getErrorText(int errorCode)
for (int i = 0; i < noOfErrorCodes; ++i) {
if (errorCode == errorTable[i]._errorCode) {
return errorTable[i]._errorText.c_str();
return errorTable[i]._errorText;
}
}
@ -2011,21 +1897,6 @@ const char* MgmtSrvr::getErrorText(int errorCode)
return text;
}
/*****************************************************************************
* Handle reception of various signals
*****************************************************************************/
int
MgmtSrvr::handleSTATISTICS_CONF(NdbApiSignal* signal)
{
//ndbout << "MgmtSrvr::handleSTATISTICS_CONF" << endl;
int x = signal->readData(1);
//ndbout << "MgmtSrvr::handleSTATISTICS_CONF, x: " << x << endl;
_statistics._test1 = x;
return 0;
}
void
MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
{
@ -2049,51 +1920,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
}
break;
case GSN_STATISTICS_CONF:
if (theWaitState != WAIT_STATISTICS) {
g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected "
"signal received, gsn %d, theWaitState = %d",
gsn, theWaitState);
return;
}
returnCode = handleSTATISTICS_CONF(signal);
if (returnCode != -1) {
theWaitState = NO_WAIT;
}
break;
case GSN_SET_VAR_CONF:
if (theWaitState != WAIT_SET_VAR) {
g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected "
"signal received, gsn %d, theWaitState = %d",
gsn, theWaitState);
return;
}
theWaitState = NO_WAIT;
_setVarReqResult = 0;
break;
case GSN_SET_VAR_REF:
if (theWaitState != WAIT_SET_VAR) {
g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected "
"signal received, gsn %d, theWaitState = %d",
gsn, theWaitState);
return;
}
theWaitState = NO_WAIT;
_setVarReqResult = -1;
break;
case GSN_EVENT_SUBSCRIBE_CONF:
theConfCount--; // OK, we've received a conf message
if (theConfCount < 0) {
g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected "
"signal received, gsn %d, theWaitState = %d",
gsn, theWaitState);
theConfCount = 0;
}
break;
case GSN_EVENT_REP:
@ -2276,20 +2103,19 @@ void
MgmtSrvr::handleStatus(NodeId nodeId, bool alive)
{
if (alive) {
_startedNodeId = nodeId; // Used by logLevelThreadRun()
m_started_nodes.push_back(nodeId);
Uint32 theData[25];
theData[0] = EventReport::Connected;
theData[1] = nodeId;
eventReport(_ownNodeId, theData);
} else {
handleStopReply(nodeId, 0);
theConfCount++; // Increment the event subscr conf count because
Uint32 theData[25];
theData[0] = EventReport::Disconnected;
theData[1] = nodeId;
eventReport(_ownNodeId, theData);
g_EventLogger.info("Lost connection to node %d", nodeId);
}
}
@ -2370,7 +2196,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
continue;
found_matching_id= true;
if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) abort();
if(type_c != type)
if(type_c != (unsigned)type)
continue;
found_matching_type= true;
if (connected_nodes.get(tmp))
@ -2483,77 +2309,18 @@ MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const
return true;
}
#include "Services.hpp"
void
MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
{
const EventReport * const eventReport = (EventReport *)&theData[0];
EventReport::EventType type = eventReport->getEventType();
if (type == EventReport::TransReportCounters ||
type == EventReport::OperationReportCounters) {
if (_isClusterLogStatActive) {
g_EventLogger.log(type, theData, nodeId);
}
if (_isStatPortActive) {
char theTime[128];
struct tm* tm_now;
time_t now;
now = time((time_t*)NULL);
#ifdef NDB_WIN32
tm_now = localtime(&now);
#else
tm_now = gmtime(&now);
#endif
snprintf(theTime, sizeof(theTime),
STATISTIC_DATE,
tm_now->tm_year + 1900,
tm_now->tm_mon,
tm_now->tm_mday,
tm_now->tm_hour,
tm_now->tm_min,
tm_now->tm_sec);
char str[255];
if (type == EventReport::TransReportCounters) {
snprintf(str, sizeof(str),
STATISTIC_LINE,
theTime,
(int)now,
nodeId,
theData[1],
theData[2],
theData[3],
// theData[4], simple reads
theData[5],
theData[6],
theData[7],
theData[8]);
} else if (type == EventReport::OperationReportCounters) {
snprintf(str, sizeof(str),
OP_STATISTIC_LINE,
theTime,
(int)now,
nodeId,
theData[1]);
}
if(m_statisticsListner != 0){
m_statisticsListner->println_statistics(str);
}
}
return;
} // if (type ==
// Log event
g_EventLogger.log(type, theData, nodeId);
m_statisticsListner.log(type, theData, nodeId);
}
/***************************************************************************
@ -2981,3 +2748,7 @@ template class Vector<SigMatch>;
#if __SUNPRO_CC != 0x560
template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch*&, NdbApiSignal*&, unsigned);
#endif
template class MutexVector<unsigned short>;
template class MutexVector<MgmStatService::StatListener>;
template class MutexVector<EventSubscribeReq>;

View File

@ -28,8 +28,8 @@
#include <signaldata/ManagementServer.hpp>
#include "SignalQueue.hpp"
#include <ndb_version.h>
#include "NodeLogLevelList.hpp"
#include <EventLogger.hpp>
#include <signaldata/EventSubscribeReq.hpp>
/**
* @desc Block number for Management server.
@ -43,6 +43,29 @@ class Config;
class SetLogLevelOrd;
class SocketServer;
class MgmStatService : public EventLoggerBase
{
friend class MgmtSrvr;
public:
struct StatListener : public EventLoggerBase {
NDB_SOCKET_TYPE m_socket;
};
private:
class MgmtSrvr * m_mgmsrv;
MutexVector<StatListener> m_clients;
public:
MgmStatService(class MgmtSrvr * m) : m_clients(5) {
m_mgmsrv = m;
}
void add_listener(const StatListener&);
void log(int eventType, const Uint32* theData, NodeId nodeId);
void stopSessions();
};
/**
* @class MgmtSrvr
* @brief Main class for the management server.
@ -63,11 +86,6 @@ class SocketServer;
class MgmtSrvr {
public:
class StatisticsListner {
public:
virtual void println_statistics(const BaseString &s) = 0;
};
// some compilers need all of this
class Allocated_resources;
friend class Allocated_resources;
@ -84,11 +102,6 @@ public:
NodeBitmask m_reserved_nodes;
};
/**
* Set a reference to the socket server.
*/
void setStatisticsListner(StatisticsListner* listner);
/**
* Start/initate the event log.
*/
@ -150,15 +163,6 @@ public:
STATIC_CONST( OPERATION_IN_PROGRESS = 6667 );
STATIC_CONST( NO_CONTACT_WITH_DB_NODES = 5030 );
/**
* This class holds all statistical variables fetched with
* the getStatistics methods.
*/
class Statistics { // TODO, Real statistic data to be added
public:
int _test1;
};
/**
* This enum specifies the different signal loggig modes possible to set
* with the setSignalLoggingMode method.
@ -206,7 +210,7 @@ public:
typedef void (* EnterSingleCallback)(int nodeId, void * anyData,
int errorCode);
typedef void (* ExitSingleCallback)(int nodeId, void * anyData,
int errorCode);
int errorCode);
/**
* Lock configuration
@ -313,13 +317,6 @@ public:
bool abort = false,
int * stopCount = 0, StopCallback = 0, void * anyData = 0);
int setEventReportingLevel(int processId,
const class SetLogLevelOrd & logLevel,
bool isResend = false);
int startStatisticEventReporting(int level = 5);
struct BackupEvent {
enum Event {
BackupStarted = 1,
@ -377,22 +374,8 @@ public:
// INVALID_LEVEL
//**************************************************************************
/**
* Sets the Node's log level, i.e., its local event reporting.
*
* @param processId the DB node id.
* @param logLevel the log level.
* @param isResend Flag to indicate for resending log levels
* during node restart
* @return 0 if successful or NO_CONTACT_WITH_PROCESS,
* SEND_OR_RECEIVE_FAILED,
* COULD_NOT_ALLOCATE_MEMORY
*/
int setNodeLogLevel(int processId,
const class SetLogLevelOrd & logLevel,
bool isResend = false);
int setEventReportingLevelImpl(int processId, const EventSubscribeReq& ll);
int setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll);
/**
* Insert an error in a DB process.
@ -508,11 +491,6 @@ public:
*/
NodeId getPrimaryNode() const;
/**
* Returns the statistics port number.
* @return statistic port number.
*/
int getStatPort() const;
/**
* Returns the port number.
* @return port number.
@ -526,10 +504,7 @@ public:
private:
//**************************************************************************
int setEventReportingLevelImpl(int processId,
const class SetLogLevelOrd & logLevel,
bool isResend = false);
int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32);
/**
* Check if it is possible to send a signal to a (DB) process
@ -563,10 +538,6 @@ private:
Allocated_resources m_allocated_resources;
struct in_addr m_connect_address[MAX_NODES];
int _setVarReqResult; // The result of the SET_VAR_REQ response
Statistics _statistics; // handleSTATISTICS_CONF store the result here,
// and getStatistics reads it.
//**************************************************************************
// Specific signal handling methods
//**************************************************************************
@ -598,14 +569,6 @@ private:
// Returns: -
//**************************************************************************
int handleSTATISTICS_CONF(NdbApiSignal* signal);
//**************************************************************************
// Description: Handle reception of signal STATISTICS_CONF
// Parameters:
// signal: The recieved signal
// Returns: TODO, to be defined
//**************************************************************************
void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal);
void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal);
@ -631,7 +594,6 @@ private:
*/
enum WaitSignalType {
NO_WAIT, // We don't expect to receive any signal
WAIT_STATISTICS, // Accept STATISTICS_CONF
WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF
WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation
WAIT_STOP,
@ -733,14 +695,6 @@ private:
class SignalQueue m_signalRecvQueue;
enum ndb_mgm_node_type nodeTypes[MAX_NODES];
int theConfCount; // The number of expected conf signals
StatisticsListner * m_statisticsListner; // Used for sending statistics info
bool _isStatPortActive;
bool _isClusterLogStatActive;
struct StopRecord {
StopRecord(){ inUse = false; callback = 0; singleUserMode = false;}
bool inUse;
@ -765,10 +719,16 @@ private:
void handleStopReply(NodeId nodeId, Uint32 errCode);
int translateStopRef(Uint32 errCode);
bool _isStopThread;
int _logLevelThreadSleep;
int _startedNodeId;
MutexVector<NodeId> m_started_nodes;
MutexVector<EventSubscribeReq> m_log_level_requests;
LogLevel m_nodeLogLevel[MAX_NODES];
enum ndb_mgm_node_type nodeTypes[MAX_NODES];
friend class MgmApiSession;
friend class MgmStatService;
MgmStatService m_statisticsListner;
/**
* Handles the thread wich upon a 'Node is started' event will
@ -782,15 +742,13 @@ private:
static void *signalRecvThread_C(void *);
void signalRecvThreadRun();
NodeLogLevelList* _nodeLogLevelList;
NodeLogLevelList* _clusterLogLevelList;
void backupCallback(BackupEvent &);
BackupCallback m_backupCallback;
BackupEvent m_lastBackupEvent;
Config *_props;
int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type);
public:
/**
* This method does not exist

View File

@ -1,70 +0,0 @@
/* 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 "NodeLogLevel.hpp"
// TODO_RONM: Clearly getCategory and getLevel is not correctly coded. Must be taken care of.
NodeLogLevel::NodeLogLevel(int nodeId, const SetLogLevelOrd& ll)
{
m_nodeId = nodeId;
m_logLevel = ll;
}
NodeLogLevel::~NodeLogLevel()
{
}
int
NodeLogLevel::getNodeId() const
{
return m_nodeId;
}
Uint32
NodeLogLevel::getCategory() const
{
for (Uint32 i = 0; i < m_logLevel.noOfEntries; i++)
{
return m_logLevel.theCategories[i];
}
return 0;
}
int
NodeLogLevel::getLevel() const
{
for (Uint32 i = 0; i < m_logLevel.noOfEntries; i++)
{
return m_logLevel.theLevels[i];
}
return 0;
}
void
NodeLogLevel::setLevel(int level)
{
for (Uint32 i = 0; i < m_logLevel.noOfEntries; i++)
{
m_logLevel.theLevels[i] = level;
}
}
SetLogLevelOrd
NodeLogLevel::getLogLevelOrd() const
{
return m_logLevel;
}

View File

@ -1,54 +0,0 @@
/* 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 NODELOGLEVEL_H
#define NODELOGLEVEL_H
#include <ndb_global.h>
#include <signaldata/SetLogLevelOrd.hpp>
/**
* Holds a DB node's log level settings for both local and event log levels.
* It only holds one log level setting even though SetLogLevelOrd can handle
* multiple log levels at once, it is not used in that way in the managment
* server.
*
* @version #@ $Id: NodeLogLevel.hpp,v 1.2 2003/07/05 17:40:22 elathal Exp $
*/
class NodeLogLevel
{
public:
NodeLogLevel(int nodeId, const SetLogLevelOrd& ll);
~NodeLogLevel();
int getNodeId() const;
Uint32 getCategory() const;
int getLevel() const;
void setLevel(int level);
SetLogLevelOrd getLogLevelOrd() const;
private:
NodeLogLevel();
NodeLogLevel(const NodeLogLevel&);
bool operator == (const NodeLogLevel&);
NodeLogLevel operator = (const NodeLogLevel&);
int m_nodeId;
SetLogLevelOrd m_logLevel;
};
#endif

View File

@ -1,182 +0,0 @@
/* 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 "NodeLogLevelList.hpp"
#include "NodeLogLevel.hpp"
//
// PUBLIC
//
NodeLogLevelList::NodeLogLevelList() :
m_size(0),
m_pHeadNode(NULL),
m_pTailNode(NULL),
m_pCurrNode(NULL)
{
}
NodeLogLevelList::~NodeLogLevelList()
{
removeAll();
}
void
NodeLogLevelList::add(NodeLogLevel* pNewNode)
{
NodeLogLevelNode* pNode = new NodeLogLevelNode();
if (m_pHeadNode == NULL)
{
m_pHeadNode = pNode;
pNode->pPrev = NULL;
}
else
{
m_pTailNode->pNext = pNode;
pNode->pPrev = m_pTailNode;
}
m_pTailNode = pNode;
pNode->pNext = NULL;
pNode->pHandler = pNewNode;
m_size++;
}
bool
NodeLogLevelList::remove(NodeLogLevel* pRemoveNode)
{
NodeLogLevelNode* pNode = m_pHeadNode;
bool removed = false;
do
{
if (pNode->pHandler == pRemoveNode)
{
removeNode(pNode);
removed = true;
break;
}
} while ( (pNode = next(pNode)) != NULL);
return removed;
}
void
NodeLogLevelList::removeAll()
{
while (m_pHeadNode != NULL)
{
removeNode(m_pHeadNode);
}
}
NodeLogLevel*
NodeLogLevelList::next()
{
NodeLogLevel* pHandler = NULL;
if (m_pCurrNode == NULL)
{
m_pCurrNode = m_pHeadNode;
if (m_pCurrNode != NULL)
{
pHandler = m_pCurrNode->pHandler;
}
}
else
{
m_pCurrNode = next(m_pCurrNode); // Next node
if (m_pCurrNode != NULL)
{
pHandler = m_pCurrNode->pHandler;
}
}
return pHandler;
}
int
NodeLogLevelList::size() const
{
return m_size;
}
//
// PRIVATE
//
NodeLogLevelList::NodeLogLevelNode*
NodeLogLevelList::next(NodeLogLevelNode* pNode)
{
NodeLogLevelNode* pCurr = pNode;
if (pNode->pNext != NULL)
{
pCurr = pNode->pNext;
}
else
{
// Tail
pCurr = NULL;
}
return pCurr;
}
NodeLogLevelList::NodeLogLevelNode*
NodeLogLevelList::prev(NodeLogLevelNode* pNode)
{
NodeLogLevelNode* pCurr = pNode;
if (pNode->pPrev != NULL) // head
{
pCurr = pNode->pPrev;
}
else
{
// Head
pCurr = NULL;
}
return pCurr;
}
void
NodeLogLevelList::removeNode(NodeLogLevelNode* pNode)
{
if (pNode->pPrev == NULL) // If head
{
m_pHeadNode = pNode->pNext;
}
else
{
pNode->pPrev->pNext = pNode->pNext;
}
if (pNode->pNext == NULL) // if tail
{
m_pTailNode = pNode->pPrev;
}
else
{
pNode->pNext->pPrev = pNode->pPrev;
}
pNode->pNext = NULL;
pNode->pPrev = NULL;
delete pNode->pHandler; // Delete log handler
delete pNode;
m_size--;
}

View File

@ -1,93 +0,0 @@
/* 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 NODELOGLEVELLIST_H
#define NODELOGLEVELLIST_H
class NodeLogLevel;
/**
* Provides a simple linked list of NodeLogLevel.
*
* @see NodeLogLevel
* @version #@ $Id: NodeLogLevelList.hpp,v 1.1 2002/08/09 12:53:50 eyualex Exp $
*/
class NodeLogLevelList
{
public:
/**
* Default Constructor.
*/
NodeLogLevelList();
/**
* Destructor.
*/
~NodeLogLevelList();
/**
* Adds a new node.
*
* @param pNewHandler a new NodeLogLevel.
*/
void add(NodeLogLevel* pNewNode);
/**
* Removes a NodeLogLevel from the list and call its destructor.
*
* @param pRemoveHandler the NodeLogLevel to remove
*/
bool remove(NodeLogLevel* pRemoveNode);
/**
* Removes all items.
*/
void removeAll();
/**
* Returns the next node in the list.
* returns a node or NULL.
*/
NodeLogLevel* next();
/**
* Returns the size of the list.
*/
int size() const;
private:
/** List node */
struct NodeLogLevelNode
{
NodeLogLevelNode* pPrev;
NodeLogLevelNode* pNext;
NodeLogLevel* pHandler;
};
NodeLogLevelNode* next(NodeLogLevelNode* pNode);
NodeLogLevelNode* prev(NodeLogLevelNode* pNode);
void removeNode(NodeLogLevelNode* pNode);
int m_size;
NodeLogLevelNode* m_pHeadNode;
NodeLogLevelNode* m_pTailNode;
NodeLogLevelNode* m_pCurrNode;
};
#endif

View File

@ -23,6 +23,7 @@
#include <mgmapi.h>
#include <EventLogger.hpp>
#include <signaldata/SetLogLevelOrd.hpp>
#include <LogLevel.hpp>
#include <BaseString.hpp>
#include <Base64.hpp>
@ -133,7 +134,7 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("public key", String, Mandatory, "Public key"),
MGM_CMD("get version", &MgmApiSession::getVersion, ""),
MGM_CMD("get status", &MgmApiSession::getStatus, ""),
MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""),
@ -236,7 +237,11 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("parameter", String, Mandatory, "Parameter"),
MGM_ARG("value", String, Mandatory, "Value"),
MGM_CMD("listen event", &MgmApiSession::listen_event, ""),
MGM_ARG("node", Int, Optional, "Node"),
MGM_ARG("filter", String, Mandatory, "Event category"),
MGM_END()
};
@ -289,7 +294,8 @@ MgmApiSession::runSession() {
break;
}
}
NDB_CLOSE_SOCKET(m_socket);
if(m_socket >= 0)
NDB_CLOSE_SOCKET(m_socket);
}
#ifdef MGM_GET_CONFIG_BACKWARDS_COMPAT
@ -554,7 +560,7 @@ MgmApiSession::getStatPort(Parser_t::Context &,
const class Properties &) {
m_output->println("get statport reply");
m_output->println("tcpport: %d", m_mgmsrv.getStatPort());
m_output->println("tcpport: %d", 0);
m_output->println("");
}
@ -760,7 +766,6 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
BaseString categoryName, errorString;
SetLogLevelOrd logLevel;
int result;
logLevel.clear();
args.get("node", &node);
args.get("category", categoryName);
args.get("level", &level);
@ -779,14 +784,15 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
goto error;
}
logLevel.setLogLevel(category, level);
result = m_mgmsrv.setEventReportingLevel(node, logLevel);
EventSubscribeReq req;
req.blockRef = 0;
req.noOfEntries = 1;
req.theCategories[0] = category;
req.theLevels[0] = level;
m_mgmsrv.m_log_level_requests.push_back(req);
m_output->println("set cluster loglevel reply");
if(result != 0)
m_output->println("result: %s", m_mgmsrv.getErrorText(result));
else
m_output->println("result: Ok");
m_output->println("result: Ok");
m_output->println("");
return;
error:
@ -821,15 +827,15 @@ MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
goto error;
}
logLevel.setLogLevel(category, level);
result = m_mgmsrv.setNodeLogLevel(node, logLevel);
EventSubscribeReq req;
req.blockRef = node;
req.noOfEntries = 1;
req.theCategories[0] = category;
req.theLevels[0] = level;
m_mgmsrv.m_log_level_requests.push_back(req);
m_output->println("set loglevel reply");
if(result != 0)
m_output->println("result: %s", m_mgmsrv.getErrorText(result));
else
m_output->println("result: Ok");
m_output->println("result: Ok");
m_output->println("");
return;
error:
@ -1248,33 +1254,91 @@ MgmApiSession::configChange(Parser_t::Context &,
m_output->println("");
}
void
MgmStatService::println_statistics(const BaseString &line){
MutexVector<NDB_SOCKET_TYPE> copy(m_sockets.size());
m_sockets.lock();
int i;
for(i = m_sockets.size() - 1; i >= 0; i--){
if(println_socket(m_sockets[i], MAX_WRITE_TIMEOUT, line.c_str()) == -1){
copy.push_back(m_sockets[i]);
m_sockets.erase(i, false);
NdbOut&
operator<<(NdbOut& out, const LogLevel & ll)
{
out << "[LogLevel: ";
for(size_t i = 0; i<_LOGLEVEL_CATEGORIES; i++)
out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
out << "]";
}
void
MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){
Uint32 threshold = 0;
LogLevel::EventCategory cat;
for(unsigned i = 0; i<EventLogger::matrixSize; i++){
if(EventLogger::matrix[i].eventType == eventType){
cat = EventLogger::matrix[i].eventCategory;
threshold = EventLogger::matrix[i].threshold;
break;
}
}
m_sockets.unlock();
for(i = copy.size() - 1; i >= 0; i--){
NDB_CLOSE_SOCKET(copy[i]);
copy.erase(i);
char m_text[256];
EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId);
Vector<NDB_SOCKET_TYPE> copy;
m_clients.lock();
int i;
for(i = m_clients.size() - 1; i >= 0; i--){
if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat)){
if(m_clients[i].m_socket >= 0 &&
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_sockets.size() == 0 || false){
m_mgmsrv->startStatisticEventReporting(0);
m_clients.unlock();
for(i = 0; (unsigned)i<copy.size(); i++){
NDB_CLOSE_SOCKET(copy[i]);
}
if(copy.size()){
LogLevel tmp; tmp.clear();
m_clients.lock();
for(i = 0; i < m_clients.size(); i++){
tmp.set_max(m_clients[i].m_logLevel);
}
m_clients.unlock();
if(!(tmp == m_logLevel)){
m_logLevel = tmp;
EventSubscribeReq req;
req = tmp;
req.blockRef = 0;
m_mgmsrv->m_log_level_requests.push_back(req);
}
}
}
void
MgmStatService::add_listener(const StatListener& client){
m_clients.push_back(client);
LogLevel tmp = m_logLevel;
tmp.set_max(client.m_logLevel);
if(!(tmp == m_logLevel)){
m_logLevel = tmp;
EventSubscribeReq req;
req = tmp;
req.blockRef = 0;
m_mgmsrv->m_log_level_requests.push_back(req);
}
}
void
MgmStatService::stopSessions(){
for(int i = m_sockets.size() - 1; i >= 0; i--){
NDB_CLOSE_SOCKET(m_sockets[i]);
m_sockets.erase(i);
for(int i = m_clients.size() - 1; i >= 0; i--){
if(m_clients[i].m_socket >= 0){
NDB_CLOSE_SOCKET(m_clients[i].m_socket);
m_clients.erase(i);
}
}
}
@ -1298,6 +1362,71 @@ MgmApiSession::setParameter(Parser_t::Context &,
m_output->println("");
}
void
MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx,
Properties const & args) {
BaseString node, param, value;
args.get("node", node);
args.get("filter", param);
int result = 0;
BaseString msg;
MgmStatService::StatListener le;
le.m_socket = m_socket;
Vector<BaseString> list;
param.trim();
param.split(list, " ,");
for(size_t i = 0; i<list.size(); i++){
Vector<BaseString> spec;
list[i].trim();
list[i].split(spec, "=:");
if(spec.size() != 2){
msg.appfmt("Invalid filter specification: >%s< >%s< %d",
param.c_str(), list[i].c_str(), spec.size());
result = -1;
goto done;
}
spec[0].trim();
spec[0].ndb_toupper();
LogLevel::EventCategory category;
if(!EventLogger::matchEventCategory(spec[0].c_str(), &category)) {
msg.appfmt("Unknown category: >%s<", spec[0].c_str());
result = -1;
goto done;
}
int level = atoi(spec[1].c_str());
if(level < 0 || level > 15){
msg.appfmt("Invalid level: >%s<", spec[1].c_str());
result = -1;
goto done;
}
le.m_logLevel.setLogLevel(category, level);
}
if(list.size() == 0){
msg.appfmt("Empty filter specification");
result = -1;
goto done;
}
m_mgmsrv.m_statisticsListner.add_listener(le);
m_stop = true;
m_socket = -1;
done:
m_output->println("listen event");
m_output->println("result: %d", result);
if(result != 0)
m_output->println("msg: %s", msg.c_str());
}
template class MutexVector<int>;
template class Vector<ParserRow<MgmApiSession> const*>;
template class Vector<unsigned short>;

View File

@ -83,7 +83,8 @@ public:
void configChange(Parser_t::Context &ctx, const class Properties &args);
void setParameter(Parser_t::Context &ctx, const class Properties &args);
void listen_event(Parser_t::Context &ctx, const class Properties &args);
void repCommand(Parser_t::Context &ctx, const class Properties &args);
};
@ -103,28 +104,4 @@ public:
}
};
class MgmStatService : public SocketServer::Service,
public MgmtSrvr::StatisticsListner
{
class MgmtSrvr * m_mgmsrv;
MutexVector<NDB_SOCKET_TYPE> m_sockets;
public:
MgmStatService() : m_sockets(5) {
m_mgmsrv = 0;
}
void setMgm(class MgmtSrvr * mgmsrv){
m_mgmsrv = mgmsrv;
}
SocketServer::Session * newSession(NDB_SOCKET_TYPE socket){
m_sockets.push_back(socket);
m_mgmsrv->startStatisticEventReporting(5);
return 0;
}
void stopSessions();
void println_statistics(const BaseString &line);
};
#endif

View File

@ -70,7 +70,6 @@ struct MgmGlobals {
bool use_specific_ip;
char * interface_name;
int port;
int port_stats;
/** The configuration of the cluster */
Config * cluster_config;
@ -169,8 +168,6 @@ NDB_MAIN(mgmsrv){
MgmApiService * mapi = new MgmApiService();
MgmStatService * mstat = new MgmStatService();
/****************************
* Read configuration files *
****************************/
@ -230,13 +227,6 @@ NDB_MAIN(mgmsrv){
goto error_end;
}
if(!glob.socketServer->setup(mstat, glob.port_stats, glob.interface_name)){
ndbout_c("Unable to setup statistic port: %d!\nPlease check if the port"
" is already used.", glob.port_stats);
delete mstat;
goto error_end;
}
if(!glob.mgmObject->check_start()){
ndbout_c("Unable to check start management server.");
ndbout_c("Probably caused by illegal initial configuration file.");
@ -267,10 +257,7 @@ NDB_MAIN(mgmsrv){
}
//glob.mgmObject->saveConfig();
mstat->setMgm(glob.mgmObject);
mapi->setMgm(glob.mgmObject);
glob.mgmObject->setStatisticsListner(mstat);
char msg[256];
snprintf(msg, sizeof(msg),
@ -278,8 +265,8 @@ NDB_MAIN(mgmsrv){
ndbout_c(msg);
g_EventLogger.info(msg);
snprintf(msg, 256, "Id: %d, Command port: %d, Statistics port: %d",
glob.localNodeId, glob.port, glob.port_stats);
snprintf(msg, 256, "Id: %d, Command port: %d",
glob.localNodeId, glob.port);
ndbout_c(msg);
g_EventLogger.info(msg);
@ -309,7 +296,6 @@ NDB_MAIN(mgmsrv){
MgmGlobals::MgmGlobals(){
// Default values
port = 0;
port_stats = 0;
config_filename = NULL;
local_config_filename = NULL;
interface_name = 0;