Commit 4a3eb9e0 authored by lu43jih's avatar lu43jih
Browse files

Changing gpfsmon as inband measurement.

parent d7b6e914
...@@ -758,192 +758,6 @@ protected: ...@@ -758,192 +758,6 @@ protected:
return cpus; return cpus;
} }
/**
* Tries to parse the given compressedList as node names. On success, the specified numbers will be inserted
* into the set nodeNames, and true is returned. On failure, false is returned. A set is used to maintain uniqueness
* and an ascending order among the numbers although this is not strictly required.
*
* @param compressedList String which specifies a range of node names (e.g. "a[2-4]b[1-3]c[4-7]")
* @return true if parsed successfully, false otherwise
*/
bool parseCompressedNodeList(const std::string& compressedList, std::set<std::string>& nodeNames){
int count = 0;
std::string token;
std::stringstream iss(compressedList);
std::stringstream tokenBuffer;
while (getline(iss, token, COMMA)) { //put in token contents until a comma "," is found
std::string::size_type pos_sqbr = token.find(OPEN_SQBRKET);
if (pos_sqbr != std::string::npos && tokenBuffer.rdbuf()->in_avail() == 0){ //found a '[' at the first trial
//for every open bracket we should have a closing bracket
size_t openbrackets = std::count(token.begin(), token.end(), OPEN_SQBRKET);
size_t closedbrackets = std::count(token.begin(), token.end(), CLOSE_SQBRKET);
if(openbrackets != closedbrackets){ // (this case token looks like this: "a[2-4" )
//get the next chunk to process in the geline
tokenBuffer << token; //first time no comma needed
} else { //yuhuu token found with compression (this case token looks like this: "a[2-4]b[1-3]c[4-7]" )
if(!parseCompressedToken(token, nodeNames)){
LOG(warning) << " Nodes could not be parsed!";
return false;
}
//http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable
tokenBuffer.str(std::string()); //reset joinToNext we found the entire token.
}
} else if(pos_sqbr != std::string::npos && tokenBuffer.rdbuf()->in_avail() != 0 ){ //'[' found and buffer has something
tokenBuffer << COMMA << token;
token = tokenBuffer.str();
//for every open bracket we should have a closing bracket
size_t openbrackets = std::count(token.begin(), token.end(), OPEN_SQBRKET);
size_t closedbrackets = std::count(token.begin(), token.end(), CLOSE_SQBRKET);
if(openbrackets == closedbrackets){ //yuhuu token found (this case token looks like this: "a[2-4]b[1,3]" )
if(!parseCompressedToken(token, nodeNames)) {
LOG(warning) << " Nodes could not be parsed!";
return false;
}
tokenBuffer.str(std::string()); //reset joinToNext we found the entire token.
} //else get the next chunk to process in the geline (this case looks token like this: "a[2,4]b[1," )
} else if(pos_sqbr == std::string::npos && tokenBuffer.rdbuf()->in_avail() != 0 ){ //no '[' found and buffer has something
std::string::size_type pos_closesqbr = token.find(CLOSE_SQBRKET);
if(pos_closesqbr == std::string::npos){
//(this case looks like this, buffer: "a[2" and token "4" joined to "a[2,4 )
tokenBuffer << COMMA << token;
} else {
tokenBuffer << COMMA << token; //(this case looks like this, buffer: "a[2" and token "4]b1" joined to "a[2,4]b1 )
token = tokenBuffer.str();
if(!parseCompressedToken(token, nodeNames)) return false;
tokenBuffer.str(std::string()); //reset joinToNext we found the entire token.
}
} else { //no squared brackets found and buffer is empty (no compression)
nodeNames.insert(token);
count++;
}
}
return nodeNames;
}
bool parseCompressedToken(std::string token, std::set<std::string>&nodeNames){
std::string::size_type closing_bracket = token.find(CLOSE_SQBRKET);
std::stringstream iss(token);
std::stringstream token_ss;
std::map<int, std::vector<std::string> > levelPartToNodeNameparts;
int levels = 0;
while (getline(iss, token, CLOSE_SQBRKET)) { //put in token contents until a "]" is found
token_ss << token << CLOSE_SQBRKET;
std::vector<std::string> nodename_parts;
std::string token_part= token_ss.str();
if(parseTokenPart(nodename_parts, token_part) ){
levelPartToNodeNameparts[levels] = nodename_parts;
levels++;
}
token_ss.str(std::string());
}
if(levels < 1) return false;
//cross product of all levels
std::vector<std::string> nodes_comb = levelPartToNodeNameparts[0];
for (unsigned int it = 1; it < levels; ++it) {
std::vector<std::string> nodes_parts1 = nodes_comb;
std::vector<std::string> nodes_parts2 = levelPartToNodeNameparts[it];
nodes_comb.clear();
for (int i = 0; i < nodes_parts1.size(); ++i) {
for (int j = 0; j < nodes_parts2.size(); ++j) {
nodes_comb.push_back(nodes_parts1[i] + nodes_parts2[j]);
}
}
}
nodeNames.insert(nodes_comb.begin(), nodes_comb.end());
return true;
}
bool parseTokenPart(std::vector<std::string> &names_parts, std::string &token){
//first get the "stem" and bracketlist from mpp2r03c05s[02,05,07,11-15]
// stem = mpp2r03c05s,
// bracketlists = 02,05,07,11-15
std::string::size_type sqrbrOpen = token.find(OPEN_SQBRKET);
std::string stem = token.substr(0, sqrbrOpen);
std::string bracketlists = token.substr(sqrbrOpen+1);
//get the comma separated tokens mpp2r03c05s[02,05,07,11-15] ==> tokenize to "02","05","07", "11-15"
std::stringstream iss(bracketlists);
std::string subtoken;
std::vector<int> nodeIntParts;
int decimal_positions =0;
while (getline(iss, subtoken, COMMA)) {
//find if it is a simple number or a list
std::string::size_type dash = subtoken.find(DASH);
if(dash != std::string::npos){ //dash found
std::string minStr = subtoken.substr(0,dash);
std::string maxStr = subtoken.substr(dash+1);
int minIntPart;
try {
minIntPart= std::stoi(minStr.c_str());
} catch (std::exception& e) {
LOG(warning) << "\t\tException when parsing {" << minStr << "}";
LOG(warning) << "\t\t" << e.what();
return false;
}
int maxIntPart;
try {
maxIntPart= std::stoi(maxStr.c_str());
} catch (std::exception& e) {
LOG(warning) << "\t\tException when parsing {" << maxStr << "}";
LOG(warning) << "\t\t" << e.what();
return false;
}
std::string::size_type closingbr = maxStr.find(CLOSE_SQBRKET);
if(closingbr != std::string::npos){ //remove closing bracket
maxStr = maxStr.substr(0, closingbr);
}
if(maxStr.length() > decimal_positions){
decimal_positions = maxStr.length();
}
if(maxIntPart > minIntPart){
for (int i = minIntPart; i < maxIntPart+1; ++i) {
nodeIntParts.push_back(i);
}
} else {
return false; //we are parsing such a case: [10-2] error or simply reverse the order?
}
} else { //dash not found
std::string::size_type closingbr = subtoken.find(CLOSE_SQBRKET);
if(closingbr != std::string::npos){ //remove closing bracket
subtoken = subtoken.substr(0, subtoken.size()-1);
}
if(subtoken.length() > decimal_positions){
decimal_positions = subtoken.length();
}
int nodePartInt;
try {
nodePartInt = std::stoi(subtoken.c_str());
} catch (std::exception& e) {
LOG(warning) << "\t\tException when parsing {" << subtoken << "}";
LOG(warning) << "\t\t" << e.what();
return false;
}
nodeIntParts.push_back(nodePartInt);
}
}
for (auto nodeEnd: nodeIntParts) {
if(nodeEnd < 0){
return false;
}
std::stringstream nodeNameBuilder;
nodeNameBuilder << stem;
if(nodeEnd < pow(10, decimal_positions-1)){
int powers = 0;
if(nodeEnd==0){
powers = 1;
} else {
powers = static_cast<int>(log10(nodeEnd)) + 1;
}
for ( int i = 0; i < decimal_positions - powers; ++ i) {
nodeNameBuilder << "0";
}
}
nodeNameBuilder << nodeEnd;
names_parts.push_back(nodeNameBuilder.str());
}
return true;
}
std::string _entityName; std::string _entityName;
std::string _groupName; std::string _groupName;
std::string _baseName; std::string _baseName;
......
...@@ -37,8 +37,6 @@ void GpfsmonConfigurator::sensorBase(GpfsmonSensorBase& s, CFG_VAL config) { ...@@ -37,8 +37,6 @@ void GpfsmonConfigurator::sensorBase(GpfsmonSensorBase& s, CFG_VAL config) {
} else { } else {
LOG(warning) << " metric \"" << val.second.data() << "\" not known."; LOG(warning) << " metric \"" << val.second.data() << "\" not known.";
} }
} else if(boost::iequals(val.first, "nodeName")){ //todo change this to parse a compressed format (mpp2[2,3-4]r[01,03]c[13-90])
s.setNodeName(val.second.data());
} }
} }
} }
......
...@@ -34,10 +34,6 @@ public: ...@@ -34,10 +34,6 @@ public:
} }
virtual ~GpfsmonSensorBase() { virtual ~GpfsmonSensorBase() {
/*
* TODO
* If necessary, deconstruct plugin specific attributes
*/
} }
GPFS_METRIC getMetricType() const { GPFS_METRIC getMetricType() const {
...@@ -48,18 +44,8 @@ public: ...@@ -48,18 +44,8 @@ public:
_metric_type = metricType; _metric_type = metricType;
} }
const std::string& getNodeName() const {
return _node_name;
}
void setNodeName(const std::string& nodeName) {
_node_name = nodeName;
}
protected: protected:
GPFS_METRIC _metric_type; GPFS_METRIC _metric_type;
std::string _node_name;
}; };
#endif /* GPFSMON_GPFSMONSENSORBASE_H_ */ #endif /* GPFSMON_GPFSMONSENSORBASE_H_ */
...@@ -11,21 +11,6 @@ ...@@ -11,21 +11,6 @@
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
/**
* Comparison functor for GpfsmonSensorBase.
*/
struct GPFSSensorCompare {
bool operator()(const Gpfs_SB& lhs, const Gpfs_SB & rhs) const {
return lhs->getNodeName() < rhs->getNodeName();
}
bool operator()(const Gpfs_SB& lhs, const std::string & rhs) const {
return lhs->getNodeName() < rhs;
}
bool operator()(const std::string & lhs, const Gpfs_SB& rhs ) const {
return lhs < rhs->getNodeName();
}
};
GpfsmonSensorGroup::GpfsmonSensorGroup(const std::string& name) : GpfsmonSensorGroup::GpfsmonSensorGroup(const std::string& name) :
SensorGroupTemplate(name) { SensorGroupTemplate(name) {
createTempFile(); createTempFile();
...@@ -54,8 +39,6 @@ void GpfsmonSensorGroup::start() { ...@@ -54,8 +39,6 @@ void GpfsmonSensorGroup::start() {
return; return;
} }
std::sort(_sensors.begin(), _sensors.end(),GPFSSensorCompare());
_keepRunning = 1; _keepRunning = 1;
_pendingTasks++; _pendingTasks++;
_timer->async_wait(std::bind(&GpfsmonSensorGroup::readAsync, this)); _timer->async_wait(std::bind(&GpfsmonSensorGroup::readAsync, this));
...@@ -76,26 +59,21 @@ void GpfsmonSensorGroup::read() { ...@@ -76,26 +59,21 @@ void GpfsmonSensorGroup::read() {
if (pf != nullptr) { if (pf != nullptr) {
char buf[BUFFER_SIZE]; char buf[BUFFER_SIZE];
while (fgets(buf, BUFFER_SIZE, pf) != nullptr) { while (fgets(buf, BUFFER_SIZE, pf) != nullptr) {
if(parseLine(std::string(buf))){
//ToDo parse nodename here for(auto & s: _sensors){
std::string nodename = "blabla"; reading.value = _data[s->getMetricType()];
auto lower = std::lower_bound(_sensors.begin(), _sensors.end(), nodename, GPFSSensorCompare());
if(lower != _sensors.end()){
parseLine(std::string(buf));
auto searchEnd = lower+ GPFS_METRIC::SIZE;
auto upper = std::upper_bound(lower, searchEnd, nodename, GPFSSensorCompare());
for(;lower!=upper; ++lower){
reading.value = _data[(*lower)->getMetricType()];
(*lower)->storeReading(reading);
#ifdef DEBUG #ifdef DEBUG
LOG(debug) << _groupName << "::" << s->getName() << ": \"" << reading.value << "\""; LOG(debug) << _groupName << "::" << s->getName() << ": \"" << reading.value << "\"";
#endif #endif
s->storeReading(reading);
} }
} else {
LOG(error) << "Sensorgroup" << _groupName << " could not parse line" << buf;
} }
} }
} else { //assume there was a problem with the temp file
createTempFile();
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
LOG(error) << "Sensorgroup" << _groupName << " could not read value: " << e.what(); LOG(error) << "Sensorgroup" << _groupName << " could not read value: " << e.what();
} }
...@@ -123,44 +101,44 @@ void GpfsmonSensorGroup::createTempFile(){ ...@@ -123,44 +101,44 @@ void GpfsmonSensorGroup::createTempFile(){
} }
} }
void GpfsmonSensorGroup::parseLine(std::string &&toparse){ bool GpfsmonSensorGroup::parseLine(std::string &&toparse){
std::string::size_type bytereads_pos = toparse.find("_br_ "); std::string::size_type bytereads_pos = toparse.find("_br_ ");
std::string::size_type bytewrite_pos = toparse.find(" _bw_ "); std::string::size_type bytewrite_pos = toparse.find(" _bw_ ");
if( bytereads_pos != std::string::npos && bytewrite_pos != std::string::npos){ if( bytereads_pos != std::string::npos && bytewrite_pos != std::string::npos){
_data[IOBYTESREAD] = std::stoull(toparse.substr(bytereads_pos + 5, bytewrite_pos - bytereads_pos)); _data[IOBYTESREAD] = std::stoull(toparse.substr(bytereads_pos + 5, bytewrite_pos - bytereads_pos));
} else { } else {
//ToDo log error? return false;
return;
} }
std::string::size_type opens_pos = toparse.find(" _oc_ "); std::string::size_type opens_pos = toparse.find(" _oc_ ");
if( opens_pos != std::string::npos ){ if( opens_pos != std::string::npos ){
_data[IOBYTESWRITE] = std::stoull(toparse.substr(bytewrite_pos + 6, opens_pos - bytewrite_pos)); _data[IOBYTESWRITE] = std::stoull(toparse.substr(bytewrite_pos + 6, opens_pos - bytewrite_pos));
} else { } else {
return; return false;
} }
std::string::size_type closes_pos = toparse.find(" _cc_ "); std::string::size_type closes_pos = toparse.find(" _cc_ ");
if( closes_pos != std::string::npos){ if( closes_pos != std::string::npos){
_data[IOOPENS] = std::stoull(toparse.substr(opens_pos + 6, closes_pos - opens_pos)); _data[IOOPENS] = std::stoull(toparse.substr(opens_pos + 6, closes_pos - opens_pos));
} else { } else {
return; return false;
} }
std::string::size_type reads_pos = toparse.find(" _rdc_ "); std::string::size_type reads_pos = toparse.find(" _rdc_ ");
if( reads_pos != std::string::npos ){ if( reads_pos != std::string::npos ){
_data[IOCLOSES] = std::stoull(toparse.substr(closes_pos + 6, reads_pos - closes_pos)); _data[IOCLOSES] = std::stoull(toparse.substr(closes_pos + 6, reads_pos - closes_pos));
} else { } else {
return; return false;
} }
std::string::size_type writes_pos = toparse.find(" _wc_ "); std::string::size_type writes_pos = toparse.find(" _wc_ ");
if( writes_pos != std::string::npos ){ if( writes_pos != std::string::npos ){
_data[IOREADS] = std::stoull(toparse.substr(reads_pos + 7, writes_pos - reads_pos)); _data[IOREADS] = std::stoull(toparse.substr(reads_pos + 7, writes_pos - reads_pos));
} else { } else {
return; return false;
} }
std::string::size_type dir_pos = toparse.find(" _dir_"); std::string::size_type dir_pos = toparse.find(" _dir_");
if( dir_pos != std::string::npos ){ if( dir_pos != std::string::npos ){
_data[IOWRITES] = std::stoull(toparse.substr(writes_pos + 6, dir_pos - writes_pos)); _data[IOWRITES] = std::stoull(toparse.substr(writes_pos + 6, dir_pos - writes_pos));
} else { } else {
return; return false;
} }
return true;
} }
...@@ -31,11 +31,11 @@ private: ...@@ -31,11 +31,11 @@ private:
void readAsync() override; void readAsync() override;
void createTempFile(); void createTempFile();
void parseLine(std::string &&toparse); bool parseLine(std::string &&toparse);
const std::string _cmd_io = "/usr/lpp/mmfs/bin/mmpmon -p -i /tmp/gpfsmon"; //todo change to real command const std::string _cmd_io = "/usr/lpp/mmfs/bin/mmpmon -p -i /tmp/gpfsmon"; //todo change to real command
std::vector<uint64_t> _data; std::vector<uint64_t> _data; //!< temp variable in parseLine defined here for efficiency.
constexpr static int BUFFER_SIZE=255; //!< constant buffer that is used to parse line by line (from popen) constexpr static int BUFFER_SIZE=255; //!< constant buffer that is used to parse line by line (from popen)
}; };
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment