11 #ifndef __PCP_CPP_PMDA_HPP__ 12 #define __PCP_CPP_PMDA_HPP__ 30 PCP_CPP_BEGIN_NAMESPACE
59 template <
class Agent>
60 static void init_dso(pmdaInterface *
const interface)
65 }
catch (
const std::exception &ex) {
66 __pmNotifyErr(LOG_ERR,
"%s", ex.what());
90 template <
class Agent>
91 static int run_daemon(
const int argc,
char *
const argv[])
96 }
catch (
const std::exception &ex) {
97 __pmNotifyErr(LOG_ERR,
"%s", ex.what());
128 const int code = PMDA_FETCH_STATIC)
129 : atom(atom), code(code) { }
153 while (!free_on_destruction.empty()) {
154 free(free_on_destruction.top());
155 free_on_destruction.pop();;
186 pmda *
const old_instance = instance;
187 instance = new_instance;
191 #ifndef PCP_CPP_NO_BOOST 204 const std::string sep(1, __pmPathSeparator());
205 return pmGetConfig(
"PCP_PMDAS_DIR") + sep +
get_pmda_name() + sep +
"config";
219 const std::string sep(1, __pmPathSeparator());
220 return pmGetConfig(
"PCP_PMDAS_DIR") + sep +
get_pmda_name() + sep +
"help";
278 return std::string();
304 __pmSetProgname(program_name.c_str());
307 pmdaInterface interface;
311 #if !defined PM_VERSION_CURRENT || PM_VERSION_CURRENT < 0x30B05 // 3.11.5 312 #define PCP_CPP_PMDA_CONST_CHAR(str) const_cast<char *>(str) 314 #define PCP_CPP_PMDA_CONST_CHAR(str) str // Do nothing. 322 #undef PCP_CPP_PMDA_CONST_CHAR 332 pmdaOpenLog(&interface);
338 pmdaConnect(&interface);
341 pmdaMain(&interface);
344 for (
int index = 0; index < interface.version.two.ext->e_nindoms; ++index) {
345 delete [] interface.version.two.ext->e_indoms[index].it_set;
347 delete[] interface.version.two.ext->e_indoms;
348 delete[] interface.version.two.ext->e_metrics;
351 #ifdef PCP_CPP_NO_BOOST 367 pmdaInterface& interface)
369 int c, error_count = 0;
370 while ((c = pmdaGetOpt(argc, const_cast<char **>(argv),
get_supported_options().c_str(), &interface, &error_count)) != EOF) {
371 process_command_line_option(c);
373 if (error_count > 0) {
376 return (error_count == 0);
394 return "d:D:h:i:l:pu:6:";
428 virtual void process_command_line_option(
const int c)
431 ? std::string(
"unrecognised option '-") + (
char)optopt +
"')" 432 : std::string(
"unimplemented option '-") +
char(c) +
"')");
456 pmdaInterface& interface)
458 boost::program_options::variables_map options;
480 pmdaInterface& interface,
481 boost::program_options::variables_map &options)
483 using namespace boost::program_options;
484 const options_description supported_options =
486 store(command_line_parser(argc, argv).options(supported_options)
489 const variable_value &config = options.at(
"config");
490 std::ifstream config_stream(config.as<std::string>().c_str());
492 store(parse_config_file(config_stream, supported_options), options);
493 }
else if (!config.defaulted()) {
494 throw pcp::exception(PM_ERR_GENERIC,
"Failed to open config file: " +
495 config.as<std::string>());
498 #ifdef PCP_CPP_DEBUG_COMMAND_LINE_OPTIONS 499 for (variables_map::const_iterator iter = options.begin(); iter != options.end(); ++iter) {
502 if (iter->second.value().type() ==
typeid(int)) {
503 value = boost::lexical_cast<std::string>(iter->second.as<
int>());
505 value = iter->second.as<std::string>();
507 }
catch (
const boost::bad_any_cast &ex) {
508 value =
"(complex type \"" + std::string(iter->second.value().type().name()) +
"\")";
510 std::cout << iter->first <<
": " << value << std::endl;
515 if (options.count(
"help") > 0) {
521 if (options.count(
"version") > 0) {
527 bool exported =
false;
528 #define PCP_CPP_EXPORT(type, func) \ 529 if (options.count("export-" type) > 0) { \ 530 if (supported_metrics.empty()) { \ 531 supported_metrics = get_supported_metrics(); \ 533 const string_vector &filenames = options.at("export-" type).as<string_vector>(); \ 534 for (string_vector::const_iterator iter = filenames.begin(); iter != filenames.end(); ++iter) { \ 539 PCP_CPP_EXPORT(
"all", export_support_files);
540 PCP_CPP_EXPORT(
"domain", export_domain_header);
541 PCP_CPP_EXPORT(
"help", export_help_text);
542 PCP_CPP_EXPORT(
"pmns", export_pmns_data);
543 PCP_CPP_EXPORT(
"root", export_pmns_root);
544 #undef PCP_CPP_EXPORT 557 if (options.count(
"debug") > 0) {
558 const string_vector &values = options.at(
"debug").as<string_vector>();
559 for (string_vector::const_iterator iter = values.begin(); iter != values.end(); ++iter) {
560 const int result = __pmParseDebug(iter->c_str());
563 "unrecognized debug flag specification '" + *iter +
"'");
568 if (options.count(
"domain") > 0) {
569 interface.domain = options.at(
"domain").as<
int>();
571 if (options.count(
"help-file") > 0) {
572 char *
const help_file = strdup(options.at(
"help-file").as<std::string>().c_str());
573 interface.version.two.ext->e_helptext = help_file;
574 free_on_destruction.push(help_file);
576 if (options.count(
"inet") > 0) {
577 interface.version.two.ext->e_io = pmdaInet;
578 interface.version.two.ext->e_port = options.at(
"inet").as<
int>();
580 if (options.count(
"log-file") > 0) {
581 char *
const log_file = strdup(options.at(
"log-file").as<std::string>().c_str());
582 interface.version.two.ext->e_logfile = log_file;
583 free_on_destruction.push(log_file);
585 if (options.count(
"pipe") > 0) {
586 interface.version.two.ext->e_io = pmdaPipe;
588 if (options.count(
"unix") > 0) {
589 interface.version.two.ext->e_io = pmdaUnix;
590 free_on_destruction.push(interface.version.two.ext->e_sockname =
591 strdup(options.at(
"unix").as<std::string>().c_str()));
593 if (options.count(
"inet6") > 0) {
600 interface.version.two.ext->e_io =
static_cast<pmdaIoType
>(4);
601 interface.version.two.ext->e_port = options.at(
"inet6").as<
int>();
613 using namespace boost::program_options;
614 options_description options(
"Libpcp-pmda options");
615 options.add_options()
616 (
"debug,D", value<string_vector>()
625 "use inet port for pmcd comms; conflicts with -p, -u and -6")
628 (
"pipe,p",
"use stdin/stdout for pmcd comms; conflicts with -i, -u and -6")
630 "use named socket for pmcd comms; conflicts with -i, -p and -6");
631 if (get_pcp_runtime_version<uint_fast32_t>() >= 0x30801) {
632 options.add_options()
634 "use IPv6 port for pmcd comms; conflicts with -i, -p and -u");
653 using namespace boost::program_options;
654 options_description options(
"Extra options");
655 options.add_options()
658 (
"export-all", value<string_vector>()
661 (
"export-domain", value<string_vector>()
664 (
"export-help", value<string_vector>()
667 (
"export-pmns", value<string_vector>()
670 (
"export-root", value<string_vector>()
673 (
"help",
"display this message then exit")
674 (
"version",
"display version info then exit");
696 return boost::program_options::options_description();
710 return boost::program_options::positional_options_description();
727 const std::string &option1,
const std::string &option2)
730 if ((options_map.count(option1)>0) && (!options_map[option1].defaulted()) &&
731 (options_map.count(option2)>0) && (!options_map[option2].defaulted())) {
732 throw boost::program_options::error(
733 "conflicting options '" + option1 +
"' and '" + option2 +
"'.");
750 << std::endl <<
"Usage: " <<
get_usage(program_name) << std::endl
768 const std::ostream::fmtflags cout_format_flags(std::cout.flags());
772 if (!pmda_version.empty()) {
773 std::cout <<
" version " << pmda_version;
775 std::cout << std::endl <<
"PMDA interface version " 777 << std::endl <<
"PCP version " 778 << get_pcp_runtime_version<char *>() <<
" (" 779 << std::hex << get_pcp_runtime_version<uint_fast32_t>()
780 <<
')' << std::endl << std::endl;
782 std::cout.flags(cout_format_flags);
804 virtual std::string
get_usage(
const std::string &program_name)
const 806 return program_name +
" [options]";
822 (help_text_pathname.empty()) ? NULL : const_cast<char *>(help_text_pathname.c_str()));
826 std::ostringstream message;
828 <<
" but the caller only understands " << interface.comm.pmda_interface
832 if (interface.status < 0) {
833 throw pcp::exception(interface.status,
"Failed to initialize DSO via pmdaDSO");
851 const std::pair<size_t,size_t> counts = count_metrics(supported_metrics);
852 const size_t indom_count = counts.second;
853 const size_t metric_count = counts.first;
854 pmdaIndom * indom_table = (indom_count == 0) ? NULL :
new pmdaIndom [indom_count];
855 pmdaMetric * metric_table =
new pmdaMetric [metric_count];
857 std::map<const instance_domain *, pmInDom> instance_domain_ids;
858 std::vector<instance_domain *> instance_domains;
859 instance_domains.reserve(indom_count);
860 size_t metric_index = 0;
861 for (metrics_description::const_iterator metrics_iter = supported_metrics.begin();
862 metrics_iter != supported_metrics.end(); ++metrics_iter)
865 for (metric_cluster::const_iterator cluster_iter = cluster.begin();
866 cluster_iter != cluster.end(); ++cluster_iter)
869 assert(metric_index < metric_count);
870 metric_table[metric_index].m_desc = description;
871 metric_table[metric_index].m_desc.pmid =
873 if (description.
domain != NULL) {
874 const std::pair<std::map<const instance_domain *, pmInDom>::const_iterator,
bool>
875 insert_result = instance_domain_ids.insert(
876 std::make_pair(cluster_iter->second.domain, instance_domain_ids.size()));
877 const pmInDom indom = insert_result.first->second;
878 assert(indom < indom_count);
879 if (insert_result.second) {
880 indom_table[indom] = allocate_pmda_indom(*cluster_iter->second.domain);
881 instance_domains.push_back(cluster_iter->second.domain);
882 assert(instance_domain_ids.size() == instance_domains.size());
884 metric_table[metric_index].m_desc.indom = indom;
886 metric_table[metric_index].m_desc.indom = PM_INDOM_NULL;
888 metric_table[metric_index].m_user = description.
opaque;
892 assert(instance_domain_ids.size() == indom_count);
893 assert(instance_domains.size() == indom_count);
894 assert(metric_index == metric_count);
900 pmdaInit(&interface, indom_table, indom_count, metric_table, metric_count);
903 for (
size_t indom_index = 0; indom_index < indom_count; ++indom_index) {
906 this->instance_domains.insert(std::make_pair(domain->
get_domain_id(), domain));
1000 const pmValueBlock *
const value)
1010 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 6 1015 virtual int on_attribute(
int ctx,
int attr,
const char *value,
1016 int length, pmdaExt *
pmda)
1018 return pmdaAttribute(ctx, attr, value, length, pmda);
1022 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 4 1028 virtual int on_children(
const char *name,
int traverse,
char ***kids,
1029 int **sts, pmdaExt *pmda)
1031 return pmdaChildren(name, traverse, kids, sts, pmda);
1036 virtual int on_desc(pmID pmid, pmDesc *desc, pmdaExt *pmda)
1038 return pmdaDesc(pmid, desc, pmda);
1043 virtual int on_fetch(
int numpmid, pmID *pmidlist, pmResult **resp,
1049 __pmNotifyErr(LOG_ERR,
"%s", ex.
what());
1052 return pmdaFetch(numpmid, pmidlist, resp, pmda);
1062 id.
cluster = pmid_cluster(mdesc->m_desc.pmid);
1064 id.item = pmid_item(mdesc->m_desc.pmid);
1065 id.opaque = mdesc->m_user;
1067 #ifdef PCP_CPP_NO_ID_VALIDITY_CHECKS 1068 id.type = PM_TYPE_UNKNOWN;
1071 supported_metrics.at(
id.cluster).at(
id.item);
1072 id.type = description.
type;
1073 validate_instance(description, inst);
1079 #if PCP_CPP_PMDA_INTERFACE_VERSION <= 2 1081 #elif PCP_CPP_PMDA_INTERFACE_VERSION < 4 1083 #else // PCP_CPP_PMDA_INTERFACE_VERSION >= 5 1087 if (ex.
error_code() != PMDA_FETCH_NOVALUES) {
1088 __pmNotifyErr(LOG_ERR,
"%s", ex.
what());
1091 }
catch (
const std::out_of_range &ex) {
1092 __pmNotifyErr(LOG_DEBUG,
"%s:%d:%s %s", __FILE__, __LINE__, __FUNCTION__, ex.what());
1094 }
catch (
const std::exception &ex) {
1095 __pmNotifyErr(LOG_ERR,
"%s", ex.what());
1096 return PM_ERR_GENERIC;
1098 __pmNotifyErr(LOG_ERR,
"unknown exception in on_fetch_callback");
1099 return PM_ERR_GENERIC;
1105 __pmInResult **result, pmdaExt *pmda)
1107 return pmdaInstance(indom, inst, name, result, pmda);
1110 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 4 1113 virtual int on_name(pmID pmid,
char ***nameset, pmdaExt *pmda)
1115 return pmdaName(pmid, nameset, pmda);
1120 virtual int on_pmid(
const char *name, pmID *pmid, pmdaExt *pmda)
1122 return pmdaPMID(name, pmid, pmda);
1129 return pmdaProfile(prof, pmda);
1135 __pmNotifyErr(LOG_INFO,
"on store");
1137 bool any_stored =
false;
1138 for (
int value_set_index = 0; value_set_index < result->numpmid; ++value_set_index) {
1139 pmValueSet *
const value_set = result->vset[value_set_index];
1143 id.
cluster = pmid_cluster(value_set->pmid);
1144 id.item = pmid_item(value_set->pmid);
1146 id.type = PM_TYPE_UNKNOWN;
1148 for (
int instance_index = 0; instance_index < value_set->numval; ++instance_index) {
1149 id.instance = value_set->vlist[instance_index].inst;
1150 #ifndef PCP_CPP_NO_ID_VALIDITY_CHECKS 1152 supported_metrics.at(
id.cluster).at(
id.item);
1153 id.type = description.
type;
1155 validate_instance(description,
id.instance);
1162 if (value_set->valfmt == PM_VAL_INSITU) {
1163 store_value(
id, value_set->vlist[instance_index].value.lval);
1165 store_value(
id, value_set->vlist[instance_index].value.pval);
1174 if (ex.
error_code() != PMDA_FETCH_NOVALUES) {
1175 __pmNotifyErr(LOG_ERR,
"%s", ex.
what());
1178 }
catch (
const std::out_of_range &ex) {
1179 __pmNotifyErr(LOG_DEBUG,
"%s:%d:%s %s", __FILE__, __LINE__, __FUNCTION__, ex.what());
1181 }
catch (
const std::exception &ex) {
1182 __pmNotifyErr(LOG_ERR,
"%s", ex.what());
1183 return PM_ERR_GENERIC;
1185 __pmNotifyErr(LOG_ERR,
"unknown exception in on_fetch_callback");
1186 return PM_ERR_GENERIC;
1188 return pmdaStore(result, pmda);
1192 virtual int on_text(
int ident,
int type,
char **buffer, pmdaExt *pmda)
1195 const bool get_one_line = ((type & PM_TEXT_ONELINE) == PM_TEXT_ONELINE);
1196 if ((type & PM_TEXT_PMID) == PM_TEXT_PMID) {
1198 supported_metrics.at(pmid_cluster(ident)).at(pmid_item(ident));
1199 const std::string &text = get_one_line
1209 *buffer = strdup(text.c_str());
1211 }
else if ((type & PM_TEXT_INDOM) == PM_TEXT_INDOM) {
1213 instance_domains.at(pmInDom_domain(ident))->at(pmInDom_serial(ident));
1214 const std::string &text = get_one_line
1224 *buffer = strdup(text.c_str());
1227 __pmNotifyErr(LOG_NOTICE,
"unknown text type 0x%x", type);
1231 __pmNotifyErr(LOG_NOTICE,
"%s", ex.
what());
1233 __pmNotifyErr(LOG_DEBUG,
"%s:%d:%s %s", __FILE__, __LINE__, __FUNCTION__, ex.
what());
1235 }
catch (
const std::out_of_range &ex) {
1236 __pmNotifyErr(LOG_DEBUG,
"%s:%d:%s %s", __FILE__, __LINE__, __FUNCTION__, ex.what());
1237 }
catch (
const std::exception &ex) {
1238 __pmNotifyErr(LOG_NOTICE,
"%s", ex.what());
1240 __pmNotifyErr(LOG_ERR,
"unknown exception in on_text");
1241 return PM_ERR_GENERIC;
1243 return pmdaText(ident, type, buffer, pmda);
1257 interface.version.two.profile = &callback_profile;
1258 interface.version.two.fetch = &callback_fetch;
1259 interface.version.two.desc = &callback_desc;
1260 interface.version.two.instance = &callback_instance;
1261 interface.version.two.text = &callback_text;
1262 interface.version.two.store = &callback_store;
1263 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 4 1264 interface.version.four.pmid = &callback_pmid;
1265 interface.version.four.name = &callback_name;
1266 interface.version.four.children = &callback_children;
1268 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 6 1269 interface.version.six.attribute = &callback_attribute;
1273 pmdaSetFetchCallBack(&interface, &callback_fetch_callback);
1280 static pmda * instance;
1281 std::stack<void *> free_on_destruction;
1282 std::map<pmInDom, instance_domain *> instance_domains;
1284 void export_domain_header(
const std::string &filename)
const 1287 std::ofstream file_stream;
1288 if (filename !=
"-") {
1289 file_stream.open(filename.c_str());
1290 if (!file_stream.is_open()) {
1291 throw pcp::exception(PM_ERR_GENERIC,
"failed to open file for writing: " + filename);
1294 std::ostream &stream = (filename ==
"-") ? std::cout : file_stream;
1298 std::transform(upper_name.begin(), upper_name.end(), upper_name.begin(), ::toupper);
1300 <<
"/* The " <<
get_pmda_name() <<
" PMDA's domain number. */" << std::endl
1304 void export_help_text(
const std::string &filename)
const 1307 std::map<std::string, metric_description> metrics;
1308 std::map<domain_id_type, const instance_domain *> instances;
1310 for (metrics_description::const_iterator metrics_iter = supported_metrics.begin();
1311 metrics_iter != supported_metrics.end(); ++metrics_iter)
1315 for (metric_cluster::const_iterator cluster_iter = cluster.begin();
1316 cluster_iter != cluster.end(); ++cluster_iter)
1319 std::string metric_name = pmda_name;
1320 if (!cluster_name.empty()) {
1321 metric_name +=
'.' + cluster_name;
1324 metrics.insert(std::make_pair(metric_name, metric));
1325 if (metric.
domain != NULL) {
1332 std::ofstream file_stream;
1333 if (filename !=
"-") {
1334 file_stream.open(filename.c_str());
1335 if (!file_stream.is_open()) {
1336 throw pcp::exception(PM_ERR_GENERIC,
"failed to open file for writing: " + filename);
1339 std::ostream &stream = (filename ==
"-") ? std::cout : file_stream;
1342 stream << std::endl;
1343 for (std::map<std::string, metric_description>::const_iterator metric = metrics.begin();
1344 metric != metrics.end(); ++metric)
1346 stream <<
"@ " << metric->first <<
' ' << metric->second.short_description << std::endl;
1347 if (!metric->second.verbose_description.empty()) {
1348 stream << metric->second.verbose_description << std::endl;
1350 stream << std::endl;
1352 for (std::map<domain_id_type, const instance_domain *>::const_iterator indom = instances.begin();
1353 indom != instances.end(); ++indom)
1355 for (instance_domain::const_iterator instance = indom->second->begin();
1356 instance != indom->second->end(); ++instance)
1358 stream <<
"@ " << indom->first <<
'.' << instance->first
1359 <<
' ' << instance->second.short_description << std::endl;
1360 if (!instance->second.verbose_description.empty()) {
1361 stream << instance->second.verbose_description << std::endl;
1363 stream << std::endl;
1368 void export_pmns_data(
const std::string &filename)
const 1373 std::transform(upper_name.begin(), upper_name.end(), upper_name.begin(), ::toupper);
1376 std::ofstream file_stream;
1377 if (filename !=
"-") {
1378 file_stream.open(filename.c_str());
1379 if (!file_stream.is_open()) {
1380 throw pcp::exception(PM_ERR_GENERIC,
"failed to open file for writing: " + filename);
1383 std::ostream &stream = (filename ==
"-") ? std::cout : file_stream;
1388 <<
"#ifndef " << upper_name << std::endl
1390 <<
"#endif" << std::endl;
1393 std::string::size_type max_metric_name_size = 0;
1394 for (metrics_description::const_iterator metrics_iter = supported_metrics.begin();
1395 metrics_iter != supported_metrics.end(); ++metrics_iter)
1398 for (metric_cluster::const_iterator cluster_iter = cluster.begin();
1399 cluster_iter != cluster.end(); ++cluster_iter)
1401 if (cluster_iter->second.metric_name.size() > max_metric_name_size) {
1402 max_metric_name_size = cluster_iter->second.metric_name.size();
1408 stream << std::endl << pmda_name <<
" {" << std::endl;
1409 for (metrics_description::const_iterator metrics_iter = supported_metrics.begin();
1410 metrics_iter != supported_metrics.end(); ++metrics_iter)
1414 if (cluster_name.empty()) {
1415 for (metric_cluster::const_iterator cluster_iter = cluster.begin();
1416 cluster_iter != cluster.end(); ++cluster_iter)
1418 stream <<
" " << cluster_iter->second.metric_name
1419 << std::string(max_metric_name_size - cluster_iter->second.metric_name.size() + 4,
' ')
1421 << cluster_iter->first << std::endl;
1424 static std::string previous_cluster_name;
1425 if (cluster_name != previous_cluster_name) {
1426 stream <<
" " << cluster_name << std::endl;
1427 previous_cluster_name = cluster_name;
1431 stream <<
'}' << std::endl;
1434 std::string previous_cluster_name;
1435 for (metrics_description::const_iterator metrics_iter = supported_metrics.begin();
1436 metrics_iter != supported_metrics.end(); ++metrics_iter)
1440 if (!cluster_name.empty()) {
1441 if (cluster_name != previous_cluster_name) {
1442 if (!previous_cluster_name.empty()) {
1443 stream <<
"}" << std::endl;
1445 stream << std::endl << pmda_name <<
'.' << cluster_name <<
" {" << std::endl;
1447 for (metric_cluster::const_iterator cluster_iter = cluster.begin();
1448 cluster_iter != cluster.end(); ++cluster_iter)
1450 stream <<
" " << cluster_iter->second.metric_name
1451 << std::string(max_metric_name_size - cluster_iter->second.metric_name.size() + 4,
' ')
1453 << cluster_iter->first << std::endl;
1455 previous_cluster_name = cluster_name;
1458 if (!previous_cluster_name.empty()) {
1459 stream <<
"}" << std::endl;
1461 stream << std::endl;
1464 void export_pmns_root(
const std::string &filename)
const 1467 std::ofstream file_stream;
1468 if (filename !=
"-") {
1469 file_stream.open(filename.c_str());
1470 if (!file_stream.is_open()) {
1471 throw pcp::exception(PM_ERR_GENERIC,
"failed to open file for writing: " + filename);
1474 std::ostream &stream = (filename ==
"-") ? std::cout : file_stream;
1477 <<
"root { " <<
get_pmda_name() <<
" }" << std::endl << std::endl
1478 <<
"#include \"pmns\"" << std::endl << std::endl;
1481 void export_support_files(
const std::string &directory_name)
const 1483 const std::string sep(1, __pmPathSeparator());
1484 export_domain_header(directory_name + sep +
"domain.h");
1485 export_help_text(directory_name + sep +
"help");
1486 export_pmns_data(directory_name + sep +
"pmns");
1487 export_pmns_root(directory_name + sep +
"root");
1492 std::set<const instance_domain *> instance_domains;
1493 size_t metric_count = 0;
1494 for (metrics_description::const_iterator metrics_iter = metrics.begin();
1495 metrics_iter != metrics.end(); ++metrics_iter)
1498 for (metric_cluster::const_iterator cluster_iter = cluster.begin();
1499 cluster_iter != cluster.end(); ++cluster_iter)
1501 if (cluster_iter->second.domain != NULL) {
1502 instance_domains.insert(cluster_iter->second.domain);
1507 return std::pair<size_t, size_t>(metric_count, instance_domains.size());
1510 static inline pmdaIndom allocate_pmda_indom(
const instance_domain &domain)
1514 indom.it_numinst = domain.size();
1515 indom.it_set =
new pmdaInstid [domain.size()];
1517 for (instance_domain::const_iterator iter = domain.begin(); iter != domain.end(); ++iter, ++index) {
1518 indom.it_set[index].i_inst = iter->first;
1519 indom.it_set[index].i_name =
const_cast<char *
>(iter->second.instance_name.c_str());
1525 const unsigned int instance)
1527 #ifndef PCP_CPP_NO_ID_VALIDITY_CHECKS 1528 if (instance != PM_INDOM_NULL) {
1529 if (description.
domain == NULL) {
1533 if (description.
domain->count(instance) <= 0) {
1537 }
else if (description.
domain != NULL) {
1549 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 6 1550 static int callback_attribute(
int ctx,
int attr,
const char *value,
int length, pmdaExt *pmda)
1552 return get_instance()->on_attribute(ctx, attr, value, length, pmda);
1556 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 4 1557 static int callback_children(
const char *name,
int traverse,
char ***kids,
int **sts, pmdaExt *pmda)
1559 return get_instance()->on_children(name, traverse, kids, sts, pmda);
1563 static int callback_desc(pmID pmid, pmDesc *desc, pmdaExt *pmda)
1568 static int callback_fetch(
int numpmid, pmID *pmidlist, pmResult **resp, pmdaExt *pmda)
1573 static int callback_fetch_callback(pmdaMetric *mdesc,
unsigned int inst, pmAtomValue *avp)
1578 static int callback_instance(pmInDom indom,
int inst,
char *name, __pmInResult **result, pmdaExt *pmda)
1583 #if PCP_CPP_PMDA_INTERFACE_VERSION >= 4 1584 static int callback_name(pmID pmid,
char ***nameset, pmdaExt *pmda)
1589 static int callback_pmid(
const char *name, pmID *pmid, pmdaExt *pmda)
1595 static int callback_profile(__pmProfile *prof, pmdaExt *pmda)
1600 static int callback_store(pmResult *result, pmdaExt *pmda)
1605 static int callback_text(
int ident,
int type,
char **buffer, pmdaExt *pmda)
1614 #ifndef PCP_CPP_SKIP_PCP_PMDA_INSTANCE_DEFINITION 1618 PCP_CPP_END_NAMESPACE
unsigned int instance_id_type
https://github.com/pcolby/pcp-pmda-cpp/issues/11
cluster_id_type get_cluster_id() const
Get this cluster's ID.
virtual bool parse_command_line(const int argc, const char *const argv[], pmdaInterface &interface)
Parse command line options.
virtual std::string get_pmda_version() const
Get this PMDA's version string.
virtual void run_daemon(const int argc, char *const argv[])
Run this daemon.
Indentifies a metric to be fetched.
static void check_conflicting_options(const boost::program_options::variables_map &options_map, const std::string &option1, const std::string &option2)
Check for conflicting command line options.
virtual boost::program_options::positional_options_description get_supported_positional_options()
Get a list of supported positional options.
Basic instance domain information.
virtual int on_instance(pmInDom indom, int inst, char *name, __pmInResult **result, pmdaExt *pmda)
Return description of instances and instance domains.
int code
PMDA fetch code describing atom's memory allocation.
std::string get_cluster_name() const
Get this cluster's name.
std::string metric_name
This metric's name.
item_id_type item
Item ID.
virtual ~pmda()
Destructor.
#define PCP_CPP_UNUSED(name)
Let the compiler know that a parameter is unsed.
static int run_daemon(const int argc, char *const argv[])
Run a PMDA in PCP's daemon mode.
virtual std::string get_help_text_pathname() const
Get the default path to this PMDA's optional help texts file.
Defines the pcp::instance_domain class.
virtual void store_value(const metric_id &metric, const int &value)
Store an in situ value.
virtual void display_help(const std::string &program_name) const
Display a help message.
pmAtomValue atom
Atom value.
#define PCP_CPP_BOOST_PO_VALUE_NAME(name)
Sets a command line option's value name, if supported by the version of Boost.Program_Options being b...
virtual void store_value(const metric_id &metric, const pmValueBlock *const value)
Store an ex situ value.
virtual bool parse_command_line(const int argc, const char *const argv[], pmdaInterface &interface, boost::program_options::variables_map &options)
Parse command line options.
A cluster of metric descriptions.
pmInDom get_pm_instance_domain() const
Get this instance domain's PCP-modifed ID.
Individual metric description.
metric_flags flags
Optional flags for this metric.
virtual int get_default_pmda_domain_number() const =0
Get this PMDA's default performance metrics domain number.
uint_fast8_t atom_type_type
PM_TYPE_* (0 - 9)
void *const opaque
Opaque value to track with this metric.
fetch_value_result(const pmAtomValue &atom, const int code=PMDA_FETCH_STATIC)
Constructor.
#define PCP_CPP_BOOST_PO_IMPLICIT_VALUE(...)
Sets a command line option's implicit value, if supported by the version of Boost.Program_Options being built against.
Sets up common PMDA++ library macros.
atom_type_type type
Expected atom type.
virtual void set_callbacks(pmdaInterface &interface)
Set static callbacks on a PMDA interface.
virtual fetch_value_result fetch_value(const metric_id &metric)=0
Fetch an individual metric value.
void * opaque
Opaque pointer.
virtual int on_text(int ident, int type, char **buffer, pmdaExt *pmda)
Return the help text for the metric.
virtual int on_desc(pmID pmid, pmDesc *desc, pmdaExt *pmda)
Return the metric desciption.
virtual boost::program_options::options_description pcp_builtin_options() const
Get a list of command line options built into the PCP libraries.
std::string verbose_description
This metric's verbose description.
Base class for all PMDA++ exceptions.
Metric supports pmstore operations.
#define PCP_CPP_PMDA_CONST_CHAR(str)
virtual int on_profile(__pmProfile *prof, pmdaExt *pmda)
Store the instance profile away for the next fetch.
instance_domain * domain
Optional instance domain for this metric.
metrics_description supported_metrics
virtual void begin_fetch_values()
Begin fetching values.
virtual boost::program_options::options_description get_supported_hidden_options() const
Get a list of hidden supported command line options.
instance_id_type instance
Instance ID.
atom_type_type type
This metric's atom type.
virtual std::string get_config_file_pathname() const
Get the default path to this PMDA's optional configuration file.
Performance metric instance domain.
virtual void initialize_dso(pmdaInterface &interface)
Initialise a DSO interface with this PMDA.
void set_pm_instance_domain(const pmInDom domain)
Set this instance domain's PCP-modified ID.
std::vector< std::string > string_vector
A simple vector of strings.
virtual int error_code() const
Get this exception's error code.
static pmda * get_instance()
Get the single PMDA instance.
uint_fast16_t item_id_type
__pmID_int::item (10-bits)
std::string verbose_description
Instance domain verbose description.
std::string short_description
This metric's short description.
virtual std::string get_usage(const std::string &program_name) const
Get a usage syntax string.
Defines the pcp::exception class.
Struct returned by the fetch_value function.
static void init_dso(pmdaInterface *const interface)
Initialize PCP's DSO interface for a PMDA.
virtual int on_fetch(int numpmid, pmID *pmidlist, pmResult **resp, pmdaExt *pmda)
Resize the pmResult and call e_callback in the pmdaExt structure for each metric instance required by...
virtual pcp::metrics_description get_supported_metrics()=0
Get descriptions of all of the metrics supported by this PMDA.
cluster_id_type cluster
Cluster ID.
std::string short_description
Instance domain short description.
virtual int on_store(pmResult *result, pmdaExt *pmda)
Store a value into a metric.
virtual int on_fetch_callback(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *avp)
Fetch the value of a single metric instance.
Collection of clusters of metric descriptions.
Abstract base class for implementing PCP PMDAs.
virtual std::string get_log_file_pathname() const
Get the default path to this PMDA's log file.
atom_type_type type()
Get the PM_TYPE_* constant for a given C++ type.
virtual void display_version() const
Display a version message.
virtual boost::program_options::options_description get_supported_options() const
Get a list of command line options supported by this PMDA.
#define PCP_CPP_PMDA_INTERFACE_VERSION
PMDA interface version to use; defaults to "latest".
virtual void initialize_pmda(pmdaInterface &interface)
Initialise this PMDA.
domain_id_type get_domain_id() const
Get this instance domain's user-defined ID.
virtual std::string get_pmda_name() const =0
Get this PMDA's name.
virtual const char * what() const
Get this exception's error message.
instance_id_type store(const pmInDom indom, const std::string &name, const int flags=PMDA_CACHE_ADD, void *const opaque=NULL)
Add a item to the cache.
Defines various metric-description related classes.
uint_fast16_t cluster_id_type
__pmID_int::cluster (12-bits)
static pmda * set_instance(pmda *const new_instance)
Set the single PMDA instance.