2 #include "ErrorHandler/MsgAnalyzerDlg.h"
3 #include "ErrorHandler/MessageAnalyzer/ma_participants.h"
4 #include "ErrorHandler/MsgBox.h"
6 #include <cetlib/filepath_maker.h>
7 #include <fhiclcpp/make_ParameterSet.h>
9 #include <QtCore/QDateTime>
10 #include <QtCore/QSettings>
11 #include <QtCore/QTimer>
13 #include <QtWidgets/QFileDialog>
14 #include <QtWidgets/QMenu>
15 #include <QtWidgets/QMessageBox>
19 using fhicl::ParameterSet;
20 using namespace novadaq::errorhandler;
23 read_conf(std::string
const fname)
25 TLOG(TLVL_DEBUG) <<
"message analyzer configuration file: "
32 cet::filepath_lookup_after1 lookup_policy(
"FHICL_FILE_PATH");
33 fhicl::make_ParameterSet(fname, lookup_policy, pset);
35 catch (cet::exception
const &ex)
37 TLOG(TLVL_ERROR) <<
"Unable to load configuration file " << fname <<
": " << ex.explain_self();
43 MsgAnalyzerDlg::MsgAnalyzerDlg(std::string
const &cfgfile,
int partition, QDialog *parent)
45 , pset(read_conf(cfgfile))
47 , receiver(pset.get<fhicl::ParameterSet>(
"receivers", fhicl::ParameterSet()))
54 , rule_display(DESCRIPTION)
55 , cond_display(DESCRIPTION)
58 , context_menu(new QMenu(this))
59 , rule_act_menu(new QMenu(this))
60 , cond_act_menu(new QMenu(this))
68 this->setWindowTitle(
"artdaq Message Analyzer, Partition " + QString::number(partition));
70 connect(&engine, SIGNAL(alarm(QString
const &, QString
const &)),
this, SLOT(onNewAlarm(QString
const &, QString
const &)));
72 connect(&engine, SIGNAL(match(QString
const &)),
this, SLOT(onConditionMatch(QString
const &)));
74 connect(btnReset, SIGNAL(clicked()),
this, SLOT(reset()));
75 connect(btnExit, SIGNAL(clicked()),
this, SLOT(exit()));
77 connect(&receiver, SIGNAL(newMessage(
qt_mf_msg const &)),
this, SLOT(onNewMsg(
qt_mf_msg const &)));
78 connect(&receiver, SIGNAL(newMessage(
qt_mf_msg const &)), &engine, SLOT(feed(
qt_mf_msg const &)));
80 connect(lwMain, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
this, SLOT(onNodeClicked(QListWidgetItem *)));
81 connect(lwDCM, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
this, SLOT(onNodeClicked(QListWidgetItem *)));
82 connect(lwBN, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
this, SLOT(onNodeClicked(QListWidgetItem *)));
84 connect(rbRuleDesc, SIGNAL(toggled(
bool)),
this, SLOT(onRuleDesc(
bool)));
85 connect(rbCondDesc, SIGNAL(toggled(
bool)),
this, SLOT(onCondDesc(
bool)));
87 connect(&sig_mapper, SIGNAL(mapped(
int)),
this, SLOT(reset_rule(
int)));
88 connect(&sig_mapper, SIGNAL(mapped(QString)),
this, SLOT(reset_rule(QString)));
91 connect(lwDCM, SIGNAL(customContextMenuRequested(
const QPoint &)),
this, SLOT(show_dcm_context_menu(
const QPoint &)));
92 connect(lwBN, SIGNAL(customContextMenuRequested(
const QPoint &)),
this, SLOT(show_evb_context_menu(
const QPoint &)));
93 connect(lwMain, SIGNAL(customContextMenuRequested(
const QPoint &)),
this, SLOT(show_main_context_menu(
const QPoint &)));
95 act_reset =
new QAction(
"Reset", 0);
96 context_menu->addAction(act_reset);
98 context_menu->addSeparator();
100 act_warning =
new QAction(
"Alarm on warning", 0);
101 act_warning->setCheckable(
true);
102 context_menu->addAction(act_warning);
104 act_error =
new QAction(
"Alarm on error", 0);
105 act_error->setCheckable(
true);
106 context_menu->addAction(act_error);
109 connect(act_reset, SIGNAL(triggered()),
this, SLOT(context_menu_reset()));
110 connect(act_warning, SIGNAL(triggered()),
this, SLOT(context_menu_warning()));
111 connect(act_error, SIGNAL(triggered()),
this, SLOT(context_menu_error()));
114 act_rule_enable =
new QAction(
"Enable selections", 0);
115 act_rule_disable =
new QAction(
"Disable selections", 0);
116 act_rule_reset =
new QAction(
"Reset selections", 0);
118 rule_act_menu->addAction(act_rule_enable);
119 rule_act_menu->addAction(act_rule_disable);
120 rule_act_menu->addSeparator();
121 rule_act_menu->addAction(act_rule_reset);
123 btnRuleAct->setMenu(rule_act_menu);
126 connect(act_rule_enable, SIGNAL(triggered()),
this, SLOT(rule_enable()));
127 connect(act_rule_disable, SIGNAL(triggered()),
this, SLOT(rule_disable()));
128 connect(act_rule_reset, SIGNAL(triggered()),
this, SLOT(rule_reset_selection()));
134 initRuleEngineTable();
138 QString msg(
"Loaded rule engine configuration from '");
139 msg.append(cfgfile.c_str()).append(
"'");
140 publishMessage(MSG_SYSTEM, msg);
144 if( engine.is_EHS() )
146 qtdds.setHandshakeResponse(
"0");
147 QVector<QString> res = qtdds.handshake();
149 for(
int i=0; i<res.size(); ++i)
150 publishMessage( MSG_SYSTEM, res[i] );
152 qtdds.setHandshakeResponse(
"1");
157 publishMessage(MSG_SYSTEM,
"Rule engine initialization completed.");
161 MsgAnalyzerDlg::~MsgAnalyzerDlg()
166 void MsgAnalyzerDlg::initNodeStatus()
168 ParameterSet null_pset;
169 ParameterSet node = pset.get<ParameterSet>(
"node_status", null_pset);
171 std::vector<std::string> null_strings;
173 std::vector<std::string> aow = node.get<std::vector<std::string>>(
"alarm_on_first_warning", null_strings);
174 std::vector<std::string> aoe = node.get<std::vector<std::string>>(
"alarm_on_first_error", null_strings);
176 for (
size_t i = 0; i < aow.size(); ++i)
184 e_aow.push_back(regex_t(aow[i]));
187 for (
size_t i = 0; i < aoe.size(); ++i)
195 e_aoe.push_back(regex_t(aoe[i]));
199 bool MsgAnalyzerDlg::check_node_aow(std::string
const &key)
201 if (aow_any)
return true;
203 for (
size_t i = 0; i < e_aow.size(); ++i)
205 if (boost::regex_match(key, what_, e_aow[i]))
return true;
211 bool MsgAnalyzerDlg::check_node_aoe(std::string
const &key)
213 if (aoe_any)
return true;
215 for (
size_t i = 0; i < e_aoe.size(); ++i)
217 if (boost::regex_match(key, what_, e_aoe[i]))
return true;
223 void MsgAnalyzerDlg::onNewMsg(
qt_mf_msg const &mfmsg)
227 node_type_t type = get_source_from_msg(key, mfmsg);
230 if (type == UserCode)
232 else if (type == External)
237 node_status status = NORMAL;
241 map_t::iterator it = map.find(key);
245 bool aow = check_node_aow(key);
246 bool aoe = check_node_aoe(key);
249 status = ni->push_msg(mfmsg);
250 map.insert(std::make_pair(key, ni));
254 status = it->second->push_msg(mfmsg);
258 lcdMsgs->display(nmsgs);
262 if (status == FIRST_WARNING)
264 QString str = QString(key.c_str())
265 .append(
" has issued a warning message:\n")
266 .append(mfmsg.
text(
true));
267 publishMessage(MSG_WARNING, str);
269 else if (status == FIRST_ERROR)
271 QString str = QString(key.c_str())
272 .append(
" has issued an error message:\n")
273 .append(mfmsg.
text(
true));
274 publishMessage(MSG_ERROR, str);
278 void MsgAnalyzerDlg::publishMessage(message_type_t type, QString
const &msg)
const
282 txt.append(QDateTime::currentDateTime().toString(
"[MM/dd/yyyy h:m:ss ap] "));
283 txt.append(get_message_type_str(type).c_str())
288 QListWidgetItem *lwi =
new QListWidgetItem(txt);
293 lwi->setForeground(QBrush(Qt::blue));
296 lwi->setForeground(QBrush(Qt::red));
299 lwi->setForeground(QBrush(Qt::magenta));
302 lwi->setForeground(QBrush(Qt::darkGreen));
305 lwAlerts->insertItem(0, lwi);
308 void MsgAnalyzerDlg::onNewAlarm(QString
const &rule_name, QString
const &msg)
310 publishMessage(MSG_ERROR, msg);
312 std::map<QString, int>::const_iterator it = rule_idx_map.find(rule_name);
314 if (it == rule_idx_map.end())
315 throw std::runtime_error(
"MsgAnalyzerDlg::onNewAlarm() rule name '" + std::string(rule_name.toUtf8().constData()) +
"' not found");
317 int alarms = engine.rule_alarm_count(it->first);
318 twRules->item(it->second, 2)->setText(QString(
"x ").append(QString::number(alarms)));
320 QBrush brush(QColor(255, 200, 200));
322 twRules->item(it->second, 0)->setBackground(brush);
323 twRules->item(it->second, 1)->setBackground(brush);
324 twRules->item(it->second, 2)->setBackground(brush);
326 QPushButton *btn =
new QPushButton(
"Rst");
327 btn->setFixedSize(62, 20);
329 twRules->setCellWidget(it->second, 3, btn);
331 sig_mapper.setMapping(btn, it->second);
332 connect(btn, SIGNAL(clicked()), &sig_mapper, SLOT(map()));
335 void MsgAnalyzerDlg::onConditionMatch(QString
const &cond_name)
337 std::map<QString, int>::const_iterator it = cond_idx_map.find(cond_name);
339 if (it == cond_idx_map.end())
340 throw std::runtime_error(
"MsgAnalyzerDlg::onConditionMatch() name '" + std::string(cond_name.toUtf8().constData()) +
"' not found");
342 int msg_count = engine.cond_msg_count(cond_name);
343 twConds->item(it->second, 3)->setText(QString::number(msg_count));
348 QBrush brush(QColor(230, 230, 255));
349 twConds->item(it->second, 0)->setBackground(brush);
350 twConds->item(it->second, 1)->setBackground(brush);
351 twConds->item(it->second, 2)->setBackground(brush);
352 twConds->item(it->second, 3)->setBackground(brush);
356 void MsgAnalyzerDlg::onNewSysMsg(sev_code_t, QString
const &)
360 void MsgAnalyzerDlg::show_dcm_context_menu(QPoint
const &pos)
362 show_context_menu(pos, lwDCM);
365 void MsgAnalyzerDlg::show_evb_context_menu(QPoint
const &pos)
367 show_context_menu(pos, lwBN);
370 void MsgAnalyzerDlg::show_main_context_menu(QPoint
const &pos)
372 show_context_menu(pos, lwMain);
375 void MsgAnalyzerDlg::show_context_menu(QPoint
const &pos, QListWidget *list)
377 list_item = list->itemAt(pos);
379 if (list_item != NULL)
381 QVariant v = list_item->data(Qt::UserRole);
384 act_warning->setChecked(ni->alarm_on_warning());
385 act_error->setChecked(ni->alarm_on_error());
387 context_menu->exec(QCursor::pos());
391 void MsgAnalyzerDlg::context_menu_reset()
393 QVariant v = list_item->data(Qt::UserRole);
399 void MsgAnalyzerDlg::context_menu_warning()
401 bool flag = act_warning->isChecked();
403 QVariant v = list_item->data(Qt::UserRole);
406 ni->set_alarm_on_warning(flag);
409 void MsgAnalyzerDlg::context_menu_error()
411 bool flag = act_error->isChecked();
413 QVariant v = list_item->data(Qt::UserRole);
416 ni->set_alarm_on_error(flag);
419 void MsgAnalyzerDlg::onEstablishPartition(
int )
424 publishMessage(MSG_SYSTEM,
"Message Analyzer has been reset");
425 publishMessage(MSG_SYSTEM,
"Partition established.");
428 void MsgAnalyzerDlg::reset_node_status()
432 for (
int i = lwMain->count(); i > 0; --i)
433 delete lwMain->takeItem(i - 1);
435 for (
int i = lwBN->count(); i > 0; --i)
436 delete lwBN->takeItem(i - 1);
438 for (
int i = lwDCM->count(); i > 0; --i)
439 delete lwDCM->takeItem(i - 1);
441 for (map_t::iterator it = map.begin(); it != map.end(); ++it)
447 lcdMsgs->display(nmsgs);
452 void MsgAnalyzerDlg::reset_rule_engine()
454 std::map<QString, int>::const_iterator it;
457 for (it = cond_idx_map.begin(); it != cond_idx_map.end(); ++it)
459 twConds->item(it->second, 3)->setText(
"0");
461 QBrush brush(QColor(255, 255, 255));
462 twConds->item(it->second, 0)->setBackground(brush);
463 twConds->item(it->second, 1)->setBackground(brush);
464 twConds->item(it->second, 2)->setBackground(brush);
465 twConds->item(it->second, 3)->setBackground(brush);
469 for (it = rule_idx_map.begin(); it != rule_idx_map.end(); ++it)
471 twRules->item(it->second, 2)->setText(
"");
473 QBrush brush(QColor(255, 255, 255));
474 twRules->item(it->second, 0)->setBackground(brush);
475 twRules->item(it->second, 1)->setBackground(brush);
476 twRules->item(it->second, 2)->setBackground(brush);
478 QWidget *temp =
new QWidget();
479 twRules->setCellWidget(it->second, 3, temp);
486 void MsgAnalyzerDlg::reset()
488 int ret = QMessageBox::warning(
this,
"MsgAnalyzer",
"Are you sure you erase all messages and reset the MsgAnalyzer?", QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel);
490 if (ret == QMessageBox::Cancel)
return;
495 publishMessage(MSG_SYSTEM,
"Message Analyzer has been reset");
498 void MsgAnalyzerDlg::exit()
500 int ret = QMessageBox::warning(
this,
"MsgAnalyzer",
"Are you sure you wish to close MsgAnalyzer?", QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel);
502 if (ret == QMessageBox::Cancel)
return;
507 void MsgAnalyzerDlg::closeEvent(QCloseEvent *event)
509 QSettings settings(
"artdaq",
"MsgAnalyzer");
510 settings.setValue(
"geometry", saveGeometry());
511 QDialog::closeEvent(event);
514 void MsgAnalyzerDlg::rule_enable()
516 std::map<QString, int>::const_iterator it = rule_idx_map.begin();
517 for (; it != rule_idx_map.end(); ++it)
519 if (twRules->item(it->second, 0)->checkState() == Qt::Checked)
522 engine.enable_rule(it->first,
true);
525 twRules->item(it->second, 0)->setCheckState(Qt::Unchecked);
528 QBrush black(QColor(0, 0, 0));
529 twRules->item(it->second, 0)->setForeground(black);
530 twRules->item(it->second, 1)->setForeground(black);
531 twRules->item(it->second, 2)->setForeground(black);
532 twRules->cellWidget(it->second, 3)->setEnabled(
true);
534 int alarms = engine.rule_alarm_count(it->first);
537 twRules->item(it->second, 2)->setText(
"");
539 twRules->item(it->second, 2)->setText(QString(
"x ").append(QString::number(alarms)));
544 void MsgAnalyzerDlg::rule_disable()
546 std::map<QString, int>::const_iterator it = rule_idx_map.begin();
547 for (; it != rule_idx_map.end(); ++it)
549 if (twRules->item(it->second, 0)->checkState() == Qt::Checked)
552 engine.enable_rule(it->first,
false);
555 twRules->item(it->second, 0)->setCheckState(Qt::Unchecked);
558 twRules->item(it->second, 2)->setText(
"Disabled");
560 QBrush brush(QColor(200, 200, 200));
561 twRules->item(it->second, 0)->setForeground(brush);
562 twRules->item(it->second, 1)->setForeground(brush);
563 twRules->item(it->second, 2)->setForeground(brush);
564 twRules->cellWidget(it->second, 3)->setEnabled(
false);
569 void MsgAnalyzerDlg::rule_reset_selection()
571 std::map<QString, int>::const_iterator it = rule_idx_map.begin();
572 for (; it != rule_idx_map.end(); ++it)
574 if (twRules->item(it->second, 0)->checkState() == Qt::Checked)
577 reset_rule(it->second);
580 twRules->item(it->second, 0)->setCheckState(Qt::Unchecked);
586 void MsgAnalyzerDlg::reset_rule(QString name)
588 std::map<QString, int>::const_iterator it = rule_idx_map.find(name);
589 this->reset_rule(it->second);
591 twRules->item(it->second, 0)->setCheckState(Qt::Unchecked);
597 void MsgAnalyzerDlg::reset_rule(
int idx)
599 QString rule_name = twRules->item(idx, 0)->text();
601 engine.reset_rule(rule_name);
604 QBrush brush(QColor(255, 255, 255));
605 twRules->item(idx, 0)->setBackground(brush);
606 twRules->item(idx, 1)->setBackground(brush);
607 twRules->item(idx, 2)->setBackground(brush);
610 twRules->item(idx, 2)->setText(
"");
613 QWidget *temp =
new QWidget();
614 twRules->setCellWidget(idx, 3, temp);
617 QVector<QString> cond_names = engine.rule_cond_names(rule_name);
618 for (
int i = 0; i < cond_names.size(); ++i)
620 std::map<QString, int>::const_iterator it = cond_idx_map.find(cond_names[i]);
622 if (it != cond_idx_map.end())
624 QBrush brush(QColor(255, 255, 255));
625 twConds->item(it->second, 0)->setBackground(brush);
626 twConds->item(it->second, 1)->setBackground(brush);
627 twConds->item(it->second, 2)->setBackground(brush);
628 twConds->item(it->second, 3)->setBackground(brush);
630 twConds->item(it->second, 3)->setText(
"0");
634 publishMessage(MSG_SYSTEM,
"reset rule " + twRules->item(idx, 0)->text());
637 void MsgAnalyzerDlg::onNodeClicked(QListWidgetItem *item)
639 QVariant v = item->data(Qt::UserRole);
642 MsgBox msgbox(QString(ni->key_string().c_str()), *ni);
646 void MsgAnalyzerDlg::initRuleEngineTable()
648 twRules->setColumnWidth(0, 100);
649 twRules->setColumnWidth(1, 320);
650 twRules->setColumnWidth(2, 70);
651 twRules->setColumnWidth(3, 62);
653 rule_size = engine.rule_size();
654 twRules->setRowCount(rule_size);
656 rbRuleDesc->setChecked(
true);
657 rbRuleExpr->setChecked(
false);
659 QVector<QString> rule_names = engine.rule_names();
662 for (
size_t i = 0; i < rule_size; ++i)
664 twRules->setRowHeight(i, 20);
665 QString name = rule_names[i];
666 QTableWidgetItem *iname =
new QTableWidgetItem(name);
667 QTableWidgetItem *iexpr =
new QTableWidgetItem();
668 QTableWidgetItem *istat =
new QTableWidgetItem();
669 QWidget *itemp =
new QWidget();
671 iname->setCheckState(Qt::Unchecked);
672 istat->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
674 twRules->setItem(i, 0, iname);
675 twRules->setItem(i, 1, iexpr);
676 twRules->setItem(i, 2, istat);
677 twRules->setCellWidget(i, 3, itemp);
679 rule_idx_map.insert(std::make_pair(name, i));
685 twConds->setColumnWidth(0, 100);
686 twConds->setColumnWidth(1, 90);
687 twConds->setColumnWidth(2, 320);
688 twConds->setColumnWidth(3, 42);
690 cond_size = engine.cond_size();
691 twConds->setRowCount(cond_size);
693 rbCondDesc->setChecked(
true);
694 rbCondRegx->setChecked(
false);
696 QVector<QString> cond_names = engine.cond_names();
698 for (
size_t i = 0; i < cond_size; ++i)
700 twConds->setRowHeight(i, 20);
701 QString name = cond_names[i];
702 QTableWidgetItem *iname =
new QTableWidgetItem(name);
703 QTableWidgetItem *ifrom =
new QTableWidgetItem(engine.cond_sources(name));
704 QTableWidgetItem *iregex =
new QTableWidgetItem();
705 QTableWidgetItem *icount =
new QTableWidgetItem(
"0");
707 iname->setCheckState(Qt::Unchecked);
708 icount->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
710 twConds->setItem(i, 0, iname);
711 twConds->setItem(i, 1, ifrom);
712 twConds->setItem(i, 2, iregex);
713 twConds->setItem(i, 3, icount);
715 cond_idx_map.insert(std::make_pair(name, i));
721 void MsgAnalyzerDlg::updateRuleDisplay()
723 std::map<QString, int>::const_iterator it = rule_idx_map.begin();
725 for (; it != rule_idx_map.end(); ++it)
727 QString txt = (rule_display == DESCRIPTION)
728 ? engine.rule_description(it->first)
729 : engine.rule_expr(it->first);
731 twRules->item(it->second, 1)->setText(txt);
735 void MsgAnalyzerDlg::updateCondDisplay()
737 std::map<QString, int>::const_iterator it = cond_idx_map.begin();
739 for (; it != cond_idx_map.end(); ++it)
741 QString txt = (cond_display == DESCRIPTION)
742 ? engine.cond_description(it->first)
743 : engine.cond_regex(it->first);
745 twConds->item(it->second, 2)->setText(txt);
749 void MsgAnalyzerDlg::initParticipants()
758 p.add_group(
"dcm", 8);
759 p.add_group(
"bn", 8);
762 void MsgAnalyzerDlg::onSetParticipants(QVector<QString>
const &dcm, QVector<QString>
const &bnevb)
768 p.add_group(
"dcm", dcm.size());
769 p.add_group(
"bnevb", bnevb.size());
771 publishMessage(MSG_SYSTEM,
"Initialized participants with " + QString(dcm.size()) +
"dcm(s) and " + QString(bnevb.size()) +
"bnevb(s)");
Qt wrapper around MessageFacility message
void stop()
Stop all receivers
QString const & text(bool mode) const
Get the text of the message