47extern XrdSysError
Log;
65XrdMonitor::RegInfo::RegInfo(
const char* sName,
const char* tName,
66 XrdMonitor::sType sTVal)
67 : typName(strdup(tName)),
68 setName(strdup(sName)),
71 snprintf(buff,
sizeof(buff),
"%s %s.Item[%%d]%%s",tName,sName);
72 eTmplt = strdup(buff);
75XrdMonitor::RegInfo::~RegInfo()
77 if (typName) free(typName);
78 if (setName) free(setName);
79 if (Json_hdr) free(Json_hdr);
80 if (Xml_hdr) free(Xml_hdr);
81 if (eTmplt) free(eTmplt);
92XrdMonitor::RegInfo* XrdMonitor::FindSet(
const char* setName,
int sType)
94 for (
auto it = regVec.begin(); it != regVec.end(); it++)
95 if ((*it)->setType & sType && !std::strcmp((*it)->setName, setName))
108 if (item < 0 || item >= (
int)regVec.size())
return 0;
112 while((regVec[item]->setType &
opts) == 0)
114 if (item >= (
int)regVec.size())
return 0;
119 if (
opts &
F_JSON) bsize = FormJSON(*regVec[item], buff, bsize);
120 else bsize = FormXML (*regVec[item], buff, bsize);
131 RegInfo* regInfo = FindSet(setName,
opts);
132 if (!regInfo)
return 0;
133 if (
opts &
F_JSON) bsize = FormJSON(*regInfo, buff, bsize);
134 else bsize = FormXML (*regInfo, buff, bsize);
142#define AddC(x) {if (bsize-- < 1) return 0; *buff++ = x; bLen++;}
144#define Updt(x) {if (x >= bsize) return 0; bsize -= x; buff += x; bLen += x;}
146int XrdMonitor::FormJSON(XrdMonitor::RegInfo& regInfo,
char* buff,
int bsize)
153 n = snprintf(buff, bsize,
"%s", regInfo.Json_hdr);
162 for (
int i = 0; i < regInfo.iCount; i++)
167 if (item.Kind == MRIFam::isSchema)
168 {
if (item.Plan == MRISch::endArray) {
AddC(
']');
continue;}
169 if (item.Plan == MRISch::endObject) {
AddC(
'}');
continue;}
170 }
else if (item.Kind == MRIFam::isMutex)
171 {
if (item.doLK) item.mtxP->Lock();
172 else item.mtxP->UnLock();
178 if (buff != aStart) {
AddC(
',');}
183 {n = snprintf(buff, bsize,
"\"%s\":", item.keyP);
190 {
case MRIFam::isBinary:
191 if (!(n = V2S(regInfo, item, buff, bsize)))
return 0;
194 case MRIFam::isSchema:
195 if (item.Plan == MRISch::begArray)
196 {
AddC(
'['); aStart = buff;}
197 else if (item.Plan == MRISch::begObject)
198 {
AddC(
'{'); aStart = buff;}
201 if (!(n = V2T(regInfo, item, buff, bsize,
true)))
return 0;
204 default: ValErr(regInfo, item.iNum,
205 "Unknown item family encountered!!!");
220int XrdMonitor::FormXML(XrdMonitor::RegInfo& regInfo,
char* buff,
int bsize)
227 n = snprintf(buff, bsize,
"%s", regInfo.Xml_hdr);
232 for (
int i = 0; i < regInfo.iCount; i++)
233 {XrdMonRoll::Item& item = regInfo.iVec[i];
237 if (item.Kind == MRIFam::isSchema)
238 {
if (item.Plan == MRISch::endArray
239 || item.Plan == MRISch::endObject)
240 {n = snprintf(buff, bsize,
"</%s>", item.keyP);
244 }
else if (item.Kind == MRIFam::isMutex)
245 {
if (item.doLK) item.mtxP->Lock();
246 else item.mtxP->UnLock();
252 n = snprintf(buff, bsize,
"<%s>", item.keyP);
258 {
case MRIFam::isBinary:
259 if (!(n = V2S(regInfo, item, buff, bsize)))
return 0;
262 case MRIFam::isSchema:
263 if (item.Plan == MRISch::begArray
264 || item.Plan == MRISch::begObject)
continue;
267 if (!(n = V2T(regInfo, item, buff, bsize,
false)))
return 0;
270 default: ValErr(regInfo, item.iNum,
271 "Unknown item family encountered!!!");
277 n = snprintf(buff, bsize,
"</%s>", item.keyP);
283 n = snprintf(buff, bsize,
"%s",
"</stats>");
292bool XrdMonitor::RegFail(
const char* TName,
const char* SName,
const char* why)
298 snprintf(buff,
sizeof(buff),
"Attempt to register monitor summary for "
299 "%s set %s failed; %s", TName, SName, why);
300 Log.
Say(
"Config warning:", buff);
311 const char* tName =
"Plugin";
325 default: stype = isPlug;
331 if (itemCnt < 1 || itemVec == 0)
332 return RegFail(tName, setName,
"invaled parameters");
336 if (FindSet(setName,-1))
337 return RegFail(tName, setName,
"set name already registered");
342 RegInfo* regInfo =
new RegInfo(setName, tName, stype);
343 regInfo->iCount = itemCnt;
344 regInfo->iVec = itemVec;
348 if (!Validate(*regInfo))
350 return RegFail(tName, setName,
"invalid description");
355 regInfo->eTmplt = strdup(buff);
356 snprintf(buff,
sizeof(buff),
"\"stats_%s\":{", setName);
357 regInfo->Json_hdr = strdup(buff);
358 snprintf(buff,
sizeof(buff),
"<stats id=\"%s\">", setName);
359 regInfo->Xml_hdr = strdup(buff);
363 regVec.push_back(regInfo);
367 snprintf(buff,
sizeof(buff),
"%s set %s registered with %d items(s)",
368 tName, setName,itemCnt);
369 Log.Say(
"Config monitor: ", buff);
381 char* buff,
int blen)
387 if (item.Clan == MRITrt::isAtomic || item.Clan == MRITrt::isBtomic)
try
388 {
if (item.Clan == MRITrt::isAtomic)
389 s = std::visit([](
const auto arg) -> std::string
390 {
auto val = arg->load();
391 return std::to_string(val);
394 s = std::visit([](
const auto arg) -> std::string
395 {
auto val = arg->load();
396 return std::to_string(val);
399 }
catch (
const std::runtime_error& e)
401 snprintf(eBuff,
sizeof(eBuff), rI.eTmplt,
int(item.iNum),
402 " atomic number formatting failed;");
403 Log.
Emsg(
"XrdMonitor", eBuff, e.what());
406 else if (item.Clan == MRITrt::isFloat) s = std::to_string(*item.fltP);
407 else s = std::to_string(*item.dblP);
411 return snprintf(buff, blen,
"%s", s.c_str());
420int XrdMonitor::V2T(XrdMonitor::RegInfo& rI, XrdMonRoll::Item& item,
421 char* buff,
int blen,
bool isJSON)
423 const char* text = (item.Clan == MRITrt::isChar ? item.chrP
424 : item.strP->c_str());
428 if (isJSON)
return snprintf(buff, blen,
"\"%s\"", text);
429 return snprintf(buff, blen,
"%s", text);
436void XrdMonitor::ValEnd(
bool& isBad, XrdMonitor::RegInfo& rI,
const char* aoT,
437 const char* begKey, XrdMonRoll::Item* endP)
445 {
if (!(endP->keyP)) endP->keyP = begKey;
446 else {
if (strcmp(begKey, endP->keyP))
448 snprintf(etxt,
sizeof(etxt),
449 "end%s key differs from beg%s key", aoT, aoT);
450 isBad = ValErr(rI, endP->iNum, etxt);
460bool XrdMonitor::ValErr(XrdMonitor::RegInfo& rInfo,
int iNum,
const char* eTxt)
466 snprintf(eBuff,
sizeof(eBuff), rInfo.eTmplt, iNum,
" incorrect;");
470 Log.
Say(
"Config warning: MonRoll ", eBuff, eTxt);
478void XrdMonitor::ValKey(
bool& isBad, XrdMonitor::RegInfo& rI,
479 XrdMonRoll::Item* itemP)
485 if (itemP->Array) {
if (!(itemP->keyP)) itemP->keyP =
"item";}
486 else {
if (!(itemP->keyP))
487 isBad = ValErr(rI, itemP->iNum,
"key not specified");
495#define VALERR(x) isBad |= ValErr(regInfo, i, x)
497bool XrdMonitor::Validate(XrdMonitor::RegInfo& regInfo)
499 std::set<XrdSysMutex*> lokActv;
500 std::stack<XrdMonRoll::Item*> synStax;
506 synStax.push(&myItem);
510 for (
int i = 0; i < regInfo.iCount; i++)
512 itemP->iNum =
static_cast<short>(i);
513 if (itemP->keyP && *(itemP->keyP) == 0) itemP->keyP = 0;
514 itemP->Array = synStax.top()->Plan == MRISch::begArray;
517 {
case MRIFam::isBinary:
518 ValKey(isBad, regInfo, itemP);
520 case MRIFam::isMutex:
522 {
if (lokActv.find(itemP->mtxP) == lokActv.end())
523 lokActv.insert(itemP->mtxP);
524 else VALERR(
"locks a previously locked mutex");
526 auto it = lokActv.find(itemP->mtxP);
527 if (it != lokActv.end()) lokActv.erase(it);
528 else VALERR(
"unLocks a mutex not previously locked");
531 case MRIFam::isSchema:
532 if (itemP->Plan == MRISch::begArray
533 || itemP->Plan == MRISch::begObject)
534 {ValKey(isBad, regInfo, itemP);
539 if (itemP->Plan == MRISch::endArray)
540 {
if (topP->Plan == MRISch::begArray)
542 ValEnd(isBad, regInfo,
"Array", topP->keyP, itemP);
544 VALERR(
"endArray is not paired with begArray");
548 if (itemP->Plan == MRISch::endObject)
549 {
if (topP->Plan == MRISch::begObject)
551 ValEnd(isBad, regInfo,
"Object", topP->keyP, itemP);
553 VALERR(
"endObject is not paired with begObject");
558 VALERR(
"Invalid schema specification");
561 if (itemP->Clan == MRITrt::isChar && !(itemP->chrP))
562 {
VALERR(
"text value pointer is nil");}
563 ValKey(isBad, regInfo, itemP);
565 default:
VALERR(
"Unknown item family encountered!!!");
574 if (synStax.size() > 1)
575 {snprintf(eBuff,
sizeof(eBuff), regInfo.eTmplt,
576 int(synStax.top()->iNum),
" definition not ended");
577 Log.Say(
"Config warning: MonRoll ", eBuff);
579 if (!lokActv.empty())
580 {snprintf(eBuff,
sizeof(eBuff), regInfo.eTmplt, 0,
581 " one or more locks not unlocked!");
582 Log.Say(
"Config warning: MonRoll ", eBuff);
588 if (isBad)
return false;
bool Register(XrdMonRoll::rollType setType, const char *setName, XrdMonRoll::Item itemVec[], int itemCnt)
int Format(char *buff, int bsize, int &item, int opts=0)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)