#include "mix_cc/ihyper_db/read_data_stats.h" #include #include #include #include #include #include #include #include TrendSlope2::TrendSlope2(const string name, const mix_cc::json &rule_json, const string ruleId) : AlgBase(name, rule_json, ruleId) { logger_.reset(new LOG("TrendSlope2:" + rule_name_, AUTO_CATCH_PID)); } TrendSlope2::~TrendSlope2() { } int TrendSlope2::init() { int res = 0; try { res += AlgBase::init(); double interval_time = std::stod(rule_json_.at("function") .at("limit_error") .at("param") .at("interval_time") .at("value") .get()); limit_time_interval_ = seconds(int(interval_time)); if (limit_time_interval_ < seconds(1)) { limit_time_interval_ = seconds(1); } limit_slope_ = std::stod(rule_json_.at("function") .at("limit_error") .at("param") .at("diff") .at("value") .get()); string need_tag = rule_json_.at("function") .at("limit_error") .at("value") .get(); need_tag_seq_ = std::stoi(need_tag.substr(3)) - 1; double deltaX = std::stod(rule_json_.at("function") .at("limit_error") .at("param") .at("deltaX") .at("value") .get()); deltaX_ = seconds(int(deltaX * 60)); CS_AVG_SIZE_ = std::stoi(rule_json_.at("function") .at("limit_error") .at("param") .at("CS_AVG_SIZE") .at("value") .get()); this->rule_stat_.limit_down = 0; this->rule_stat_.limit_up = 0; error_content_ = rule_json_.at("output").at("error").at("value").get(); logger_->Debug() << "查询均值时间[s]:" << limit_time_interval_.count() / 1000 << ",监控量变化率:" << limit_slope_ << ",单位间隔时间:" << deltaX_.count() << "ms,连续出现次数:" << CS_AVG_SIZE_ << ",报警内容:" << error_content_ << endl; this->data_source_ = DataSource::IHDB; } catch (const std::exception &e) { std::throw_with_nested( mix_cc::Exception(-1, "load error", BOOST_CURRENT_LOCATION)); } return res; } AlarmInfo TrendSlope2::exec_mon() { AlarmInfo out_alarm{}; int count_error = 0; now_time_ = system_clock::now() - 60s; vector avg; double f_slope = 0.0; double f_slope_max = 0; try { /* before --> now*/ // 检查6个周期的时间内数据的斜率是否小于目标斜率 auto start_time = now_time_ - this->deltaX_ * CS_AVG_SIZE_; for (int i = 0; i < CS_AVG_SIZE_ + 1; i++) { query_time_range_.set_left(start_time - limit_time_interval_); query_time_range_.set_right(start_time); if (!query_time_range_.valid()) { logger_->Error() << "时间数据 不合法" << std::endl; return out_alarm; } logger_->Debug() << "时间范围" << mix_cc::mix_time_t(query_time_range_.get_left()) .to_formatted_time() << " " << mix_cc::mix_time_t(query_time_range_.get_right()) .to_formatted_time() << std::endl; if (refresh_ihd_cache(query_time_range_) != 0) { logger_->Error() << rule_name_ << ":ihd查询异常!" << std::endl; return out_alarm; } if (!get_prr2()) { logger_->Error() << rule_name_ << ":不满足前提表达式" << std::endl; return out_alarm; } double avgi = queried_data_.col(need_tag_seq_).mean(); avg.push_back(avgi); logger_->Debug() << "avg[" << i << "]:" << avgi << endl; start_time = start_time + this->deltaX_; } string msgslope; for (int i = 0; i < CS_AVG_SIZE_ + 1; i++) { if (i > 0) { f_slope = static_cast(1000.0 * (avg[i] - avg[i - 1]) + 0.5); f_slope = f_slope / 1000; f_slope_max = (abs(f_slope_max) > abs(f_slope)) ? f_slope_max : f_slope; if ((limit_slope_ > 0 && f_slope > limit_slope_) || (limit_slope_ < 0 && f_slope < limit_slope_)) { msgslope += " " + DAA::double2str(f_slope, 3); count_error++; logger_->Debug() << msgslope << endl; } else { msgslope = ""; count_error = 0; break; } } } if (count_error == CS_AVG_SIZE_) { rule_stat_.current_value = 1; rule_stat_.alarm_value = f_slope_max; string msg = error_content_ + " 斜率变化量:" + msgslope; logger_->Debug() << msg << endl; query_time_range_.set_right(now_time_); query_time_range_.set_left( now_time_ - (deltaX_ * (CS_AVG_SIZE_)-limit_time_interval_)); return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_, "SLOPE", msg, query_time_range_); } rule_stat_.current_value = 0; } catch (const std::exception &e) { std::throw_with_nested( mix_cc::Exception(-1, "calc error", BOOST_CURRENT_LOCATION)); } return out_alarm; } std::vector TrendSlope2::exec_task(mix_cc::time_range_t time_range) { std::vector result; for (auto now_time = time_range.get_left(); now_time <= time_range.get_right(); now_time += delay_time_) { this->now_time_ = now_time; auto rr1 = this->exec_mon(); if (rr1.alarmed) { result.push_back(rr1); } } return result; } bool TrendSlope2::get_prr2() { if (this->prr_ == 1) { exp_mpdule_ptr_->update(queried_data_, queried_time_); bool prr_result = (bool)exp_mpdule_ptr_->get_value("pre_result"); this->now_prr_ = prr_result; logger_->Debug() << "ruleid:" << this->rule_id_ << ",rulename:" << this->rule_name_ << " get_prr():" << prr_result << std::endl; return prr_result; } this->now_prr_ = true; return true; }