refactor: 算法子类化 — LogicAlg/BoundAlg/BoundHoldAlg/FeedbackAlg 消除 exp_type_ 分支
将 ExpBase::mon_proc() 中的 exp_type_ 分支逻辑提取为 4 个子类,通过 doMonProc() 虚函数实现多态分发: - LogicAlg (exp_type 1):实时逻辑判断 - BoundAlg (exp_type 2):监控变量上下限检测 - BoundHoldAlg (exp_type 5):持续超限检测(继承 BoundAlg) - FeedbackAlg (exp_type 3/4):动作反馈处理 ExpBase 新增纯虚函数 doMonProc() 和钩子函数 doInitExtend(), init() 和 mon_proc() 中所有类型分支替换为虚函数委托调用。
This commit is contained in:
parent
4f8eecd828
commit
ae7834adaa
66
eqpalg/algs/bound_alg.cpp
Normal file
66
eqpalg/algs/bound_alg.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include <eqpalg/algs/bound_alg.h>
|
||||||
|
#include <eqpalg/feature_extraction/daa.h>
|
||||||
|
#include <eqpalg/utility/build_alarm_info.h>
|
||||||
|
#include <shm/RuleStatShm.h>
|
||||||
|
|
||||||
|
BoundAlg::BoundAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId, size_t exp_type)
|
||||||
|
: ExpBase(name, rule_json, ruleId, exp_type) {
|
||||||
|
logger_.reset(new LOG("BoundAlg:" + rule_name_, AUTO_CATCH_PID));
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundAlg::~BoundAlg() = default;
|
||||||
|
|
||||||
|
int BoundAlg::init() {
|
||||||
|
int ret = ExpBase::init();
|
||||||
|
if (ret == 0) {
|
||||||
|
exp_is_wrong_ = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoundAlg::doInitExtend() {
|
||||||
|
// BoundAlg 额外的初始化:上下限
|
||||||
|
reload_config_up_down();
|
||||||
|
reload_ci_dist();
|
||||||
|
last_load_time_ = std::chrono::system_clock::now();
|
||||||
|
stat_collector_.configure(rule_id_, rule_name_, dist_mode_, is_learning_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoundAlg::checkFilter() {
|
||||||
|
if (!expr_engine_->exps_.count("feedback")) {
|
||||||
|
return true; // 无筛选表达式,所有数据参与
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return expr_engine_->evaluateBool("feedback");
|
||||||
|
} catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AlarmInfo BoundAlg::doMonProc() {
|
||||||
|
double result_value = expr_engine_->evaluate("act");
|
||||||
|
filter_flag_ = false;
|
||||||
|
|
||||||
|
// 数据筛选
|
||||||
|
filter_flag_ = checkFilter();
|
||||||
|
|
||||||
|
// 自学习统计
|
||||||
|
if (is_learning_ && filter_flag_) {
|
||||||
|
rule_stat_.current_value = result_value;
|
||||||
|
SingletonTemp<EqpStat>::GetInstance().add_stat_values(rule_id_, result_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超限检测
|
||||||
|
if (filter_flag_ && bound_checker_.isOutOfBounds(result_value)) {
|
||||||
|
rule_stat_.alarm_value = result_value;
|
||||||
|
auto msg = error_str_ + ":" + DAA::double2str(result_value) + unit_ +
|
||||||
|
",合理区间:[" + DAA::double2strLimit(bound_checker_.limitDown()) +
|
||||||
|
"," + DAA::double2strLimit(bound_checker_.limitUp()) + "]" + unit_;
|
||||||
|
query_time_range_.set_left(query_time_range_.get_right() - delay_time_);
|
||||||
|
expr_engine_->markFunVarsNeedReset();
|
||||||
|
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
|
||||||
|
"EXP2", msg, get_alarm_time());
|
||||||
|
}
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
19
eqpalg/algs/bound_alg.h
Normal file
19
eqpalg/algs/bound_alg.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <eqpalg/algs/exp_base.h>
|
||||||
|
|
||||||
|
class BoundAlg : public ExpBase {
|
||||||
|
public:
|
||||||
|
BoundAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId,
|
||||||
|
size_t exp_type = ExpType::Bound);
|
||||||
|
~BoundAlg() override;
|
||||||
|
|
||||||
|
int init() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AlarmInfo doMonProc() override;
|
||||||
|
void doInitExtend() override;
|
||||||
|
|
||||||
|
// 数据筛选检查
|
||||||
|
bool checkFilter();
|
||||||
|
};
|
||||||
62
eqpalg/algs/bound_hold_alg.cpp
Normal file
62
eqpalg/algs/bound_hold_alg.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include <eqpalg/algs/bound_hold_alg.h>
|
||||||
|
#include <eqpalg/feature_extraction/daa.h>
|
||||||
|
#include <eqpalg/utility/build_alarm_info.h>
|
||||||
|
|
||||||
|
BoundHoldAlg::BoundHoldAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId)
|
||||||
|
: BoundAlg(name, rule_json, ruleId, ExpType::BoundHoldTime) {
|
||||||
|
logger_.reset(new LOG("BoundHoldAlg:" + rule_name_, AUTO_CATCH_PID));
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundHoldAlg::~BoundHoldAlg() = default;
|
||||||
|
|
||||||
|
int BoundHoldAlg::init() {
|
||||||
|
int ret = BoundAlg::init();
|
||||||
|
if (ret == 0) {
|
||||||
|
reload_config_up_down_hold_time();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlarmInfo BoundHoldAlg::doMonProc() {
|
||||||
|
double result_value = expr_engine_->evaluate("act");
|
||||||
|
filter_flag_ = checkFilter();
|
||||||
|
|
||||||
|
if (is_learning_ && filter_flag_) {
|
||||||
|
rule_stat_.current_value = result_value;
|
||||||
|
SingletonTemp<EqpStat>::GetInstance().add_stat_values(rule_id_, result_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_over = bound_checker_.isOutOfBounds(result_value);
|
||||||
|
|
||||||
|
if (!filter_flag_) {
|
||||||
|
act_start_time_ = now_time_;
|
||||||
|
act_started_ = false;
|
||||||
|
} else {
|
||||||
|
if (is_over) {
|
||||||
|
if (!act_started_) {
|
||||||
|
act_started_ = true;
|
||||||
|
act_start_time_ = now_time_;
|
||||||
|
}
|
||||||
|
if ((hold_time_ <= delay_time_) ||
|
||||||
|
(now_time_ - act_start_time_ > hold_time_)) {
|
||||||
|
rule_stat_.alarm_value = result_value;
|
||||||
|
auto msg = error_str_ + ":" + DAA::double2str(result_value) + unit_ +
|
||||||
|
",合理区间:[" + DAA::double2strLimit(bound_checker_.limitDown()) +
|
||||||
|
"," + DAA::double2strLimit(bound_checker_.limitUp()) + "]" + unit_;
|
||||||
|
query_time_range_.set_left(query_time_range_.get_right() - delay_time_);
|
||||||
|
expr_engine_->markFunVarsNeedReset();
|
||||||
|
act_start_time_ = now_time_;
|
||||||
|
act_started_ = false;
|
||||||
|
return utility::build_alarm_info(
|
||||||
|
utility::get_msg_level(bound_checker_.limitDown(),
|
||||||
|
bound_checker_.limitUp(), result_value),
|
||||||
|
rule_id_, rule_name_, "EXP5", msg, get_alarm_time());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
act_start_time_ = now_time_;
|
||||||
|
act_started_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
14
eqpalg/algs/bound_hold_alg.h
Normal file
14
eqpalg/algs/bound_hold_alg.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <eqpalg/algs/bound_alg.h>
|
||||||
|
|
||||||
|
class BoundHoldAlg : public BoundAlg {
|
||||||
|
public:
|
||||||
|
BoundHoldAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId);
|
||||||
|
~BoundHoldAlg() override;
|
||||||
|
|
||||||
|
int init() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AlarmInfo doMonProc() override;
|
||||||
|
};
|
||||||
@ -44,16 +44,7 @@ int ExpBase::init() {
|
|||||||
fb_fsm_.configure(keep_mode_, time_out_);
|
fb_fsm_.configure(keep_mode_, time_out_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exp_type_ == ExpType::Bound || exp_type_ == ExpType::CondBound ||
|
doInitExtend();
|
||||||
exp_type_ == ExpType::BoundHoldTime) {
|
|
||||||
ret += this->reload_config_up_down(); /*7.上下限*/
|
|
||||||
this->reload_ci_dist();
|
|
||||||
this->last_load_time_ = chrono::system_clock::now();
|
|
||||||
stat_collector_.configure(rule_id_, rule_name_, dist_mode_, is_learning_);
|
|
||||||
}
|
|
||||||
if (exp_type_ == ExpType::BoundHoldTime) {
|
|
||||||
ret += this->reload_config_up_down_hold_time(); /*8.上下限-保持时间*/
|
|
||||||
}
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
logger_->Debug() << e.what() << ".location:" << BOOST_CURRENT_LOCATION
|
logger_->Debug() << e.what() << ".location:" << BOOST_CURRENT_LOCATION
|
||||||
<< endl;
|
<< endl;
|
||||||
@ -268,195 +259,13 @@ std::vector<AlarmInfo> ExpBase::exec_task(mix_cc::time_range_t time_range) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AlarmInfo ExpBase::mon_proc() {
|
AlarmInfo ExpBase::mon_proc() {
|
||||||
// 监控基本过程
|
|
||||||
double result_value;
|
|
||||||
filter_flag_ = false;
|
|
||||||
expr_engine_->autoResetFunVars();
|
expr_engine_->autoResetFunVars();
|
||||||
try {
|
try {
|
||||||
// 获得是否满足前提条件表达式
|
return doMonProc();
|
||||||
result_value = expr_engine_->evaluate("act");
|
|
||||||
if (exp_type_ == ExpType::Bound || exp_type_ == ExpType::BoundHoldTime) {
|
|
||||||
try {
|
|
||||||
/*有数据筛选*/
|
|
||||||
filter_flag_ = expr_engine_->evaluateBool("feedback");
|
|
||||||
} catch (...) {
|
|
||||||
/*无数据筛选*/
|
|
||||||
logger_->Debug() << "ruleid:" << rule_id_ << ",feedback evaluate ERROR!"
|
|
||||||
<< endl;
|
|
||||||
filter_flag_ = true;
|
|
||||||
}
|
|
||||||
if (is_learning_ && filter_flag_ == true) {
|
|
||||||
rule_stat_.current_value = result_value;
|
|
||||||
SingletonTemp<EqpStat>::GetInstance().add_stat_values(this->rule_id_,
|
|
||||||
result_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool act_triggered = static_cast<bool>(result_value);
|
|
||||||
// 如果是反馈模式
|
|
||||||
if (feedback_mode_) {
|
|
||||||
// === 使用 FbStateMachine ===
|
|
||||||
auto [fbState, needFunReset] = fb_fsm_.update(
|
|
||||||
act_triggered, now_time_, expr_engine_->vars(), m_tags.size());
|
|
||||||
|
|
||||||
if (needFunReset) {
|
|
||||||
expr_engine_->markFunVarsNeedReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbState == FbState::Started) {
|
|
||||||
// 刚启动,下周期继续
|
|
||||||
// query_time_range 左边界设为动作开始时间
|
|
||||||
query_time_range_.set_left(now_time_);
|
|
||||||
return AlarmInfo{};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbState == FbState::NotHold) {
|
|
||||||
return AlarmInfo{};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbState == FbState::InProgress) {
|
|
||||||
// 检查反馈条件
|
|
||||||
bool fbCond = expr_engine_->evaluateBool("feedback");
|
|
||||||
bool done = fb_fsm_.checkFeedback(fbCond, now_time_, expr_engine_->vars());
|
|
||||||
if (done) {
|
|
||||||
// 动作完成,计算结果
|
|
||||||
query_time_range_.set_left(
|
|
||||||
query_time_range_.get_right() -
|
|
||||||
milliseconds(static_cast<int>(expr_engine_->vars()["time"])));
|
|
||||||
result_value = expr_engine_->evaluate("result");
|
|
||||||
expr_engine_->markFunVarsNeedReset();
|
|
||||||
rule_stat_.limit_down = limit_down_;
|
|
||||||
rule_stat_.limit_up = limit_up_;
|
|
||||||
rule_stat_.current_value = result_value;
|
|
||||||
|
|
||||||
if (exp_type_ == ExpType::CondBound) {
|
|
||||||
if (is_learning_) {
|
|
||||||
SingletonTemp<EqpStat>::GetInstance().add_stat_values(
|
|
||||||
rule_id_, result_value);
|
|
||||||
}
|
|
||||||
if (bound_checker_.isOutOfBounds(result_value)) {
|
|
||||||
rule_stat_.alarm_value = result_value;
|
|
||||||
std::string msg = "";
|
|
||||||
if (fb_fsm_.isTimeMode()) {
|
|
||||||
msg = error_str_ + ":" + DAA::double2str(result_value) +
|
|
||||||
"ms,时间范围:[0," + DAA::double2str(bound_checker_.limitUp()) + "] ms";
|
|
||||||
} else {
|
|
||||||
msg = error_str_ + ":" + DAA::double2str(result_value) + unit_ +
|
|
||||||
",合理区间:[" + DAA::double2strLimit(bound_checker_.limitDown()) + "," +
|
|
||||||
DAA::double2strLimit(bound_checker_.limitUp()) + "]" + unit_;
|
|
||||||
}
|
|
||||||
return utility::build_alarm_info(
|
|
||||||
utility::get_msg_level(bound_checker_.limitDown(), bound_checker_.limitUp(), result_value),
|
|
||||||
rule_id_, rule_name_, "EXP4", msg, get_alarm_time());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (result_value) {
|
|
||||||
rule_stat_.alarm_value = result_value;
|
|
||||||
auto msg = rule_name_ + " " + error_str_;
|
|
||||||
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_,
|
|
||||||
rule_name_, "EXP3", msg,
|
|
||||||
get_alarm_time());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// fbCondition 不满足,继续 InProgress
|
|
||||||
return AlarmInfo{};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbState == FbState::Timeout) {
|
|
||||||
if (!fb_fsm_.isTimeMode()) {
|
|
||||||
return AlarmInfo{};
|
|
||||||
}
|
|
||||||
string msg =
|
|
||||||
rule_name_ + " 反馈超时:" + std::to_string(time_out_.count()) + " ms";
|
|
||||||
logger_->Debug() << msg << endl;
|
|
||||||
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
|
|
||||||
"EXPACT", msg, query_time_range_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Idle state (from terminal auto-reset) — nothing to do
|
|
||||||
return AlarmInfo{};
|
|
||||||
}
|
|
||||||
// 不是动作反馈
|
|
||||||
else {
|
|
||||||
if (exp_type_ == ExpType::Bound) {
|
|
||||||
if (filter_flag_ == true && bound_checker_.isOutOfBounds(result_value)) {
|
|
||||||
rule_stat_.alarm_value = result_value;
|
|
||||||
auto msg = error_str_ + ":" + DAA::double2str(result_value) + unit_ +
|
|
||||||
",合理区间:[" + DAA::double2strLimit(bound_checker_.limitDown()) + "," +
|
|
||||||
DAA::double2strLimit(bound_checker_.limitUp()) + "]" + unit_;
|
|
||||||
logger_->Debug() << msg << endl;
|
|
||||||
this->query_time_range_.set_left(query_time_range_.get_right() -
|
|
||||||
delay_time_);
|
|
||||||
expr_engine_->markFunVarsNeedReset();
|
|
||||||
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_,
|
|
||||||
rule_name_, "EXP2", msg,
|
|
||||||
this->get_alarm_time());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (exp_type_ == ExpType::BoundHoldTime) {
|
|
||||||
|
|
||||||
bool is_over_up_down =
|
|
||||||
bound_checker_.isOutOfBounds(result_value);
|
|
||||||
if (!filter_flag_) {
|
|
||||||
/*前提条件不满足*/
|
|
||||||
act_start_time_ = this->now_time_;
|
|
||||||
act_started_ = false;
|
|
||||||
} else {
|
|
||||||
/*前提条件满足*/
|
|
||||||
/*检查范围*/
|
|
||||||
if (is_over_up_down) {
|
|
||||||
/*超范围*/
|
|
||||||
if (!act_started_) {
|
|
||||||
// 首次检测到异常,记录开始时间
|
|
||||||
act_started_ = true;
|
|
||||||
act_start_time_ = this->now_time_;
|
|
||||||
}
|
|
||||||
/*检查时间*/
|
|
||||||
if ((hold_time_ <= delay_time_) ||
|
|
||||||
(now_time_ - act_start_time_ > hold_time_)) {
|
|
||||||
rule_stat_.alarm_value = result_value;
|
|
||||||
auto msg = error_str_ + ":" + DAA::double2str(result_value) +
|
|
||||||
unit_ + ",合理区间:[" +
|
|
||||||
DAA::double2strLimit(bound_checker_.limitDown()) + "," +
|
|
||||||
DAA::double2strLimit(bound_checker_.limitUp()) + "]" + unit_;
|
|
||||||
expr_engine_->printVars();
|
|
||||||
this->query_time_range_.set_left(query_time_range_.get_right() -
|
|
||||||
delay_time_);
|
|
||||||
expr_engine_->markFunVarsNeedReset();
|
|
||||||
act_start_time_ =
|
|
||||||
this->now_time_;
|
|
||||||
act_started_ = false;
|
|
||||||
return utility::build_alarm_info(
|
|
||||||
utility::get_msg_level(bound_checker_.limitDown(), bound_checker_.limitUp(), result_value),
|
|
||||||
rule_id_, rule_name_, "EXP5", msg, this->get_alarm_time());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
act_start_time_ = this->now_time_;
|
|
||||||
act_started_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (act_triggered) {
|
|
||||||
rule_stat_.alarm_value = act_triggered;
|
|
||||||
expr_engine_->printVars();
|
|
||||||
auto msg = rule_name_ + " " + error_str_;
|
|
||||||
logger_->Debug() << msg << endl;
|
|
||||||
this->query_time_range_.set_left(query_time_range_.get_right() -
|
|
||||||
delay_time_);
|
|
||||||
expr_engine_->markFunVarsNeedReset();
|
|
||||||
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_,
|
|
||||||
rule_name_, "EXP1", msg,
|
|
||||||
this->get_alarm_time());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
gb_logger_->log_error("rule_name:" + rule_name_ + ",error:" + e.what());
|
gb_logger_->log_error("rule_name:" + rule_name_ + ",error:" + e.what());
|
||||||
return AlarmInfo{};
|
return AlarmInfo{};
|
||||||
}
|
}
|
||||||
return AlarmInfo{};
|
|
||||||
}
|
}
|
||||||
bool ExpBase::get_cycled_cron() {
|
bool ExpBase::get_cycled_cron() {
|
||||||
auto now = system_clock::now();
|
auto now = system_clock::now();
|
||||||
|
|||||||
@ -103,6 +103,17 @@ public:
|
|||||||
bool get_prr() override;
|
bool get_prr() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* @brief 子类实现的具体算法逻辑
|
||||||
|
* @return AlarmInfo
|
||||||
|
*/
|
||||||
|
virtual AlarmInfo doMonProc() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 子类扩展初始化(钩子)
|
||||||
|
*/
|
||||||
|
virtual void doInitExtend() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 重新载入数据源信息
|
* @brief 重新载入数据源信息
|
||||||
* @return int
|
* @return int
|
||||||
@ -120,7 +131,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
bool get_cycled_cron();
|
bool get_cycled_cron();
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
/**
|
||||||
* @brief 载入上下限
|
* @brief 载入上下限
|
||||||
* @return int
|
* @return int
|
||||||
|
|||||||
116
eqpalg/algs/feedback_alg.cpp
Normal file
116
eqpalg/algs/feedback_alg.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include <eqpalg/algs/feedback_alg.h>
|
||||||
|
#include <eqpalg/feature_extraction/daa.h>
|
||||||
|
#include <eqpalg/utility/build_alarm_info.h>
|
||||||
|
#include <shm/RuleStatShm.h>
|
||||||
|
|
||||||
|
FeedbackAlg::FeedbackAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId, size_t exp_type)
|
||||||
|
: ExpBase(name, rule_json, ruleId, exp_type),
|
||||||
|
hasBoundCheck_(exp_type == ExpType::CondBound) {
|
||||||
|
logger_.reset(new LOG("FeedbackAlg:" + rule_name_, AUTO_CATCH_PID));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedbackAlg::~FeedbackAlg() = default;
|
||||||
|
|
||||||
|
void FeedbackAlg::doInitExtend() {
|
||||||
|
if (hasBoundCheck_) {
|
||||||
|
reload_config_up_down();
|
||||||
|
reload_ci_dist();
|
||||||
|
last_load_time_ = std::chrono::system_clock::now();
|
||||||
|
stat_collector_.configure(rule_id_, rule_name_, dist_mode_, is_learning_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AlarmInfo FeedbackAlg::doMonProc() {
|
||||||
|
double result_value = expr_engine_->evaluate("act");
|
||||||
|
|
||||||
|
// CondBound: filter + statistics
|
||||||
|
if (hasBoundCheck_) {
|
||||||
|
bool filter_ok = true;
|
||||||
|
try {
|
||||||
|
filter_ok = expr_engine_->evaluateBool("feedback");
|
||||||
|
} catch (...) {}
|
||||||
|
if (is_learning_ && filter_ok) {
|
||||||
|
rule_stat_.current_value = result_value;
|
||||||
|
SingletonTemp<EqpStat>::GetInstance().add_stat_values(rule_id_, result_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool triggered = static_cast<bool>(result_value);
|
||||||
|
|
||||||
|
// === FbStateMachine ===
|
||||||
|
auto [fbState, needFunReset] = fb_fsm_.update(
|
||||||
|
triggered, now_time_, expr_engine_->vars(), m_tags.size());
|
||||||
|
|
||||||
|
if (needFunReset) {
|
||||||
|
expr_engine_->markFunVarsNeedReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbState == FbState::Started) {
|
||||||
|
query_time_range_.set_left(now_time_);
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbState == FbState::NotHold) {
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbState == FbState::InProgress) {
|
||||||
|
bool fbCond = expr_engine_->evaluateBool("feedback");
|
||||||
|
bool done = fb_fsm_.checkFeedback(fbCond, now_time_, expr_engine_->vars());
|
||||||
|
if (done) {
|
||||||
|
query_time_range_.set_left(
|
||||||
|
query_time_range_.get_right() -
|
||||||
|
std::chrono::milliseconds(static_cast<int>(expr_engine_->vars()["time"])));
|
||||||
|
result_value = expr_engine_->evaluate("result");
|
||||||
|
expr_engine_->markFunVarsNeedReset();
|
||||||
|
rule_stat_.limit_down = bound_checker_.limitDown();
|
||||||
|
rule_stat_.limit_up = bound_checker_.limitUp();
|
||||||
|
rule_stat_.current_value = result_value;
|
||||||
|
|
||||||
|
if (hasBoundCheck_) {
|
||||||
|
if (is_learning_) {
|
||||||
|
SingletonTemp<EqpStat>::GetInstance().add_stat_values(
|
||||||
|
rule_id_, result_value);
|
||||||
|
}
|
||||||
|
if (bound_checker_.isOutOfBounds(result_value)) {
|
||||||
|
rule_stat_.alarm_value = result_value;
|
||||||
|
std::string msg;
|
||||||
|
if (fb_fsm_.isTimeMode()) {
|
||||||
|
msg = error_str_ + ":" + DAA::double2str(result_value) +
|
||||||
|
"ms,时间范围:[0," + DAA::double2str(bound_checker_.limitUp()) + "] ms";
|
||||||
|
} else {
|
||||||
|
msg = error_str_ + ":" + DAA::double2str(result_value) + unit_ +
|
||||||
|
",合理区间:[" + DAA::double2strLimit(bound_checker_.limitDown()) +
|
||||||
|
"," + DAA::double2strLimit(bound_checker_.limitUp()) + "]" + unit_;
|
||||||
|
}
|
||||||
|
return utility::build_alarm_info(
|
||||||
|
utility::get_msg_level(bound_checker_.limitDown(),
|
||||||
|
bound_checker_.limitUp(), result_value),
|
||||||
|
rule_id_, rule_name_, "EXP4", msg, get_alarm_time());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (static_cast<bool>(result_value)) {
|
||||||
|
rule_stat_.alarm_value = result_value;
|
||||||
|
auto msg = rule_name_ + " " + error_str_;
|
||||||
|
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_,
|
||||||
|
rule_name_, "EXP3", msg,
|
||||||
|
get_alarm_time());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbState == FbState::Timeout) {
|
||||||
|
if (fb_fsm_.isTimeMode()) {
|
||||||
|
std::string msg = rule_name_ + " 反馈超时:" +
|
||||||
|
std::to_string(time_out_.count()) + " ms";
|
||||||
|
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
|
||||||
|
"EXPACT", msg, query_time_range_);
|
||||||
|
}
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
|
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
16
eqpalg/algs/feedback_alg.h
Normal file
16
eqpalg/algs/feedback_alg.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <eqpalg/algs/exp_base.h>
|
||||||
|
|
||||||
|
class FeedbackAlg : public ExpBase {
|
||||||
|
public:
|
||||||
|
FeedbackAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId, size_t exp_type);
|
||||||
|
~FeedbackAlg() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AlarmInfo doMonProc() override;
|
||||||
|
void doInitExtend() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool hasBoundCheck_; // CondBound (exp_type 4) vs Logic (exp_type 3)
|
||||||
|
};
|
||||||
24
eqpalg/algs/logic_alg.cpp
Normal file
24
eqpalg/algs/logic_alg.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <eqpalg/algs/logic_alg.h>
|
||||||
|
#include <eqpalg/utility/build_alarm_info.h>
|
||||||
|
|
||||||
|
LogicAlg::LogicAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId)
|
||||||
|
: ExpBase(name, rule_json, ruleId, ExpType::Logic) {
|
||||||
|
logger_.reset(new LOG("LogicAlg:" + rule_name_, AUTO_CATCH_PID));
|
||||||
|
}
|
||||||
|
|
||||||
|
LogicAlg::~LogicAlg() = default;
|
||||||
|
|
||||||
|
AlarmInfo LogicAlg::doMonProc() {
|
||||||
|
double result_value = expr_engine_->evaluate("act");
|
||||||
|
|
||||||
|
if (static_cast<bool>(result_value)) {
|
||||||
|
rule_stat_.alarm_value = result_value;
|
||||||
|
auto msg = rule_name_ + " " + error_str_;
|
||||||
|
query_time_range_.set_left(query_time_range_.get_right() - delay_time_);
|
||||||
|
expr_engine_->markFunVarsNeedReset();
|
||||||
|
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
|
||||||
|
"EXP1", msg, get_alarm_time());
|
||||||
|
}
|
||||||
|
return AlarmInfo{};
|
||||||
|
}
|
||||||
12
eqpalg/algs/logic_alg.h
Normal file
12
eqpalg/algs/logic_alg.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <eqpalg/algs/exp_base.h>
|
||||||
|
|
||||||
|
class LogicAlg : public ExpBase {
|
||||||
|
public:
|
||||||
|
LogicAlg(const std::string& name, const mix_cc::json& rule_json,
|
||||||
|
const std::string& ruleId);
|
||||||
|
~LogicAlg() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AlarmInfo doMonProc() override;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user