summaryrefslogtreecommitdiff
path: root/ndb/src/mgmsrv/Services.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/mgmsrv/Services.cpp')
-rw-r--r--ndb/src/mgmsrv/Services.cpp256
1 files changed, 190 insertions, 66 deletions
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 7bf408583de..5b552836955 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -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
@@ -413,11 +419,15 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
NodeId tmp= nodeid;
if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
+ BaseString error_string;
if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
- &addr, &addrlen)){
+ &addr, &addrlen, error_string)){
+ const char *alias;
+ const char *str;
+ alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)
+ nodetype, &str);
m_output->println(cmd);
- m_output->println("result: no free nodeid %d for nodetype %d",
- nodeid, nodetype);
+ m_output->println("result: %s", error_string.c_str());
m_output->println("");
return;
}
@@ -551,7 +561,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("");
}
@@ -753,13 +763,12 @@ MgmApiSession::bye(Parser<MgmApiSession>::Context &,
void
MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
Properties const &args) {
- Uint32 node, level;
- BaseString categoryName, errorString;
+ Uint32 node, level, category;
+ BaseString errorString;
SetLogLevelOrd logLevel;
int result;
- logLevel.clear();
args.get("node", &node);
- args.get("category", categoryName);
+ args.get("category", &category);
args.get("level", &level);
/* XXX should use constants for this value */
@@ -768,25 +777,17 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
goto error;
}
- categoryName.ndb_toupper();
-
- LogLevel::EventCategory category;
- if(!EventLogger::matchEventCategory(categoryName.c_str(), &category)) {
- errorString.assign("Unknown category");
- goto error;
- }
-
- logLevel.setLogLevel(category, level);
- result = m_mgmsrv.setEventReportingLevel(node, logLevel);
-
+ EventSubscribeReq req;
+ req.blockRef = 0;
+ req.noOfEntries = 1;
+ req.theData[0] = (category << 16) | 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:
+error:
m_output->println("set cluster loglevel reply");
m_output->println("result: %s", errorString.c_str());
m_output->println("");
@@ -795,13 +796,13 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
void
MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
Properties const &args) {
- Uint32 node = 0, level = 0;
- BaseString categoryName, errorString;
+ Uint32 node = 0, level = 0, category;
+ BaseString errorString;
SetLogLevelOrd logLevel;
int result;
logLevel.clear();
args.get("node", &node);
- args.get("category", categoryName);
+ args.get("category", &category);
args.get("level", &level);
/* XXX should use constants for this value */
@@ -810,23 +811,14 @@ MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
goto error;
}
- categoryName.ndb_toupper();
-
- LogLevel::EventCategory category;
- if(!EventLogger::matchEventCategory(categoryName.c_str(), &category)) {
- errorString.assign("Unknown category");
- goto error;
- }
-
- logLevel.setLogLevel(category, level);
-
- result = m_mgmsrv.setNodeLogLevel(node, logLevel);
-
+ EventSubscribeReq req;
+ req.blockRef = node;
+ req.noOfEntries = 1;
+ req.theData[0] = (category << 16) | 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:
@@ -943,6 +935,7 @@ printNodeStatus(OutputStream *output,
output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
output->println("node.%d.node_group: %d", nodeId, nodeGroup);
output->println("node.%d.connect_count: %d", nodeId, connectCount);
+ output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId));
}
}
@@ -1015,8 +1008,9 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
}
int stop_self= 0;
+ size_t i;
- for(size_t i=0; i < nodes.size(); i++) {
+ for(i=0; i < nodes.size(); i++) {
if (nodes[i] == m_mgmsrv.getOwnNodeId()) {
stop_self= 1;
if (i != nodes.size()-1) {
@@ -1030,13 +1024,13 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
int stopped = 0, result = 0;
- for(size_t i=0; i < nodes.size(); i++)
+ for(i=0; i < nodes.size(); i++)
if (nodes[i] != m_mgmsrv.getOwnNodeId()) {
if((result = m_mgmsrv.stopNode(nodes[i], abort != 0)) == 0)
stopped++;
} else
stopped++;
-
+
m_output->println("stop reply");
if(result != 0)
m_output->println("result: %s", m_mgmsrv.getErrorText(result));
@@ -1129,7 +1123,7 @@ MgmApiSession::logSignals(Parser<MgmApiSession>::Context &,
args.get("blocks", blockList);
// fast fix - pekka
char buf[200];
- snprintf(buf, 200, "%s", blockList.c_str());
+ BaseString::snprintf(buf, 200, "%s", blockList.c_str());
Vector<BaseString> blocks;
blockName=strtok(buf,"|");
@@ -1244,33 +1238,94 @@ 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();
+static NdbOut&
+operator<<(NdbOut& out, const LogLevel & ll)
+{
+ out << "[LogLevel: ";
+ for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
+ out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
+ out << "]";
+ return out;
+}
+
+void
+MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){
+
+ Uint32 threshold = 0;
+ LogLevel::EventCategory cat= LogLevel::llInvalid;
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);
+
+ for(i = 0; (unsigned)i<EventLogger::matrixSize; i++){
+ if(EventLogger::matrix[i].eventType == eventType){
+ cat = EventLogger::matrix[i].eventCategory;
+ threshold = EventLogger::matrix[i].threshold;
+ break;
+ }
+ }
+ if (cat == LogLevel::llInvalid)
+ return;
+
+ char m_text[256];
+ EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId);
+
+ 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 >= 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);
+ }
}
}
- m_sockets.unlock();
+ m_clients.unlock();
- for(i = copy.size() - 1; i >= 0; i--){
+ for(i = 0; (unsigned)i < copy.size(); i++){
NDB_CLOSE_SOCKET(copy[i]);
- copy.erase(i);
}
- if(m_sockets.size() == 0 || false){
- m_mgmsrv->startStatisticEventReporting(0);
+
+ if(copy.size()){
+ LogLevel tmp; tmp.clear();
+ m_clients.lock();
+ for(i = 0; (unsigned)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);
+ }
}
}
@@ -1294,6 +1349,75 @@ 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().ndb_toupper();
+ int category = ndb_mgm_match_event_category(spec[0].c_str());
+ if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){
+ category = atoi(spec[0].c_str());
+ if(category < NDB_MGM_MIN_EVENT_CATEGORY ||
+ category > NDB_MGM_MAX_EVENT_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;
+ }
+ category -= CFG_MIN_LOGLEVEL;
+ le.m_logLevel.setLogLevel((LogLevel::EventCategory)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());
+ m_output->println("");
+}
+
template class MutexVector<int>;
template class Vector<ParserRow<MgmApiSession> const*>;
template class Vector<unsigned short>;