#include #include int ExpSample::init() { int ret = 0; act_started_ = false; try { Exp::init(); // 载入样本配置 this->reload_config_sample(); sample_stat_ = std::make_unique( rule_id_, rule_name_, dims_, test_mode_, start_date_, end_date_, padding_low_, padding_up_, is_no_down_limit_); // 目前暂时使用小时作为归档的单位间隔 sample_stat_->set_archive_interval(hours(archive_interval_day_)); this->sample_stat_->set_prob(this->judge_diff_); this->sample_stat_->load_data(); ///<加载db2的统计数据 本地文件的特征数据 } catch (const std::exception& e) { logger_->Info() << "数据载入错误 :" << rule_name_ << endl; // 测试 std::throw_with_nested( mix_cc::Exception(-1, "数据载入发生异常", BOOST_CURRENT_LOCATION)); ret = -1; } return ret; } AlarmInfo ExpSample::exec_mon() { AlarmInfo out_alarm; // 刷新当前时间 this->refresh_now_time(); try { // 如果当前时间比上次数据载入时间晚10小时以上,刷新数据 if (now_time_ - last_load_time_ > hours(archive_interval_day_ * 10)) { // 1.从db2载入数据分布信息;2.从本地文件载入数据特征值;3.计算置信区间 this->sample_stat_->load_data(); last_load_time_ = now_time_; } switch (data_source_) { case DataSource::MEMORY: { // 刷新内存对应的变量数据 refresh_exp_vars_mem(); query_time_range_.set_left(query_time_range_.get_right() - delay_time_); // 2021-10-27 刷新报警开始时间 out_alarm = mon_proc(); break; } case DataSource::IHDB: { // 刷新ihdb缓存 refresh_ihd_cache(); for (auto i = 0; i < queried_data_.rows(); i++) { // 刷新ihdb对应的变量数据 refresh_exp_vars_ihd(i); if (!out_alarm.alarmed) { auto tmp = mon_proc(); if (tmp.alarmed) { out_alarm = (tmp); } } } } break; default: break; } } catch (const std::exception& e) { std::throw_with_nested( mix_cc::Exception(-1, "监控进程执行错误", BOOST_CURRENT_LOCATION)); } return out_alarm; } /** * @brief 计算统计类的第一次 写本地数据特征和db2数据分布信息 * @return mix_cc::json */ mix_cc::json ExpSample::exec_cron() { bool jump_out_flag = false; try { // 1.首次运行cron目的在于计算步长(组距),同时累积rs的样本; // 2.非首次运行cron目的在于累积样本,包括rs和分布信息 // 3.没有组距,则被视作首次运行cron // 4.cron的计算需考虑机组的状态,不要累计停机数据 // if (sample_stat_->is_first_sampling()) { SampleWindow tmp_data; // 存db2 的样本 -2021-10-29 // if (this->test_mode_ >= stat_tools::TestMode::normal_dist_diff) { auto time_end = system_clock::now(); auto time_start = time_end - STASTIC_DAYS * 24h; TimeDur f_delay_time = 5 * delay_time_; this->query_time_range_.set_left(time_start - 2 * f_delay_time); this->query_time_range_.set_right(time_start - f_delay_time); // 目的在于刷pv变量 f_delay_time start end this->now_time_ = time_start; // refresh_ihd_cache(this->delay_time_); refresh_ihd_cache(); //刷 queried_time_, // queried_data_,query_time_range_(左右相差f_delay_time) // 本次查询5天前-f_delay_time 到五天前 for (auto i = 0; i < queried_data_.rows(); i++) { refresh_exp_vars_ihd(i); } // !end or (auto i = 0; i < queried_data_.rows(); i++) // 刷一遍缓存数据 刷到5天前的(4 3 2 1)个50ms之前的值 pv变量 // for (auto t = time_start; t < time_end; t += query_interval_time_) { this->now_time_ = t; gb_logger_->log_info("执行,当前时间" + mix_cc::mix_time_t(now_time_).to_formatted_time()); refresh_ihd_cache(); // 如果机组检查发现没开机,则不累计数据 if (!cron_check_is_line_start()) { gb_logger_->log_info( this->rule_id_ + ":当前时间段:" + mix_cc::mix_time_t(this->query_time_range_.get_left()) .to_formatted_time() + "~" + mix_cc::mix_time_t(this->query_time_range_.get_right()) .to_formatted_time() + "存在机组停机情况"); // return {}; } // queried_data_每一行都进行如下操作 // 每一行相差 ihd_min_time_particles_ // 即iHyperDB数据查询最小时间颗粒(默认50ms) else { for (auto i = 0; i < queried_data_.rows(); i++) { refresh_exp_vars_ihd(i); auto o_value = this->cron_proc_sample(); ///< 筛选后的样本 if (o_value.has_value()) { tmp_data.push_back(o_value.value()); // 3小时的最大数据量为 216000 if (tmp_data.size() > 216000) { gb_logger_->log_error( "数据量异常,超过3小时的最大数据,暂停执行"); jump_out_flag = true; break; } if (jump_out_flag) { break; } } // !end if (o_value.has_value()) } // !end for (auto i = 0; i < queried_data_.rows(); i++) // if (this->test_mode_ == stat_tools::TestMode::degrad && // !tmp_data.empty()) { // gb_logger_->log_info("开始执行-执行完成:" + rule_name_); // this->sample_stat_->cron_sampling_data(tmp_data, now_time_); // tmp_data.clear(); // } if (this->test_mode_ != stat_tools::TestMode::degrad && !tmp_data.empty()) { gb_logger_->log_info("开始执行-执行完成:" + rule_name_); this->sample_stat_->cron_sampling_data(tmp_data, now_time_); tmp_data.clear(); } } //机组开机的情况 } // !end for (auto t = time_start; t < time_end; t += // query_interval_time_) // } // !end if (this->test_mode_ >= // stat_tools::TestMode::normal_dist_diff) } //! end if // (sample_stat_->is_first_sampling()) } //! end try catch (const std::exception& e) { gb_logger_->log_exception(e); } return {}; } AlarmInfo ExpSample::exec_normal_task(mix_cc::time_range_t time_range) { gb_logger_->log_info("exec_normal_task:" + rule_name_); gb_logger_->log_info( "开始时间:" + mix_cc::mix_time_t(time_range.get_left()).to_formatted_time()); gb_logger_->log_info( "结束时间:" + mix_cc::mix_time_t(time_range.get_right()).to_formatted_time()); SampleWindow tmp_data; //刷一遍mmvar TimeDur f_delay_time = 5 * delay_time_; auto time_end = time_range.get_right(); auto time_start = time_range.get_left(); query_interval_time_ = std::chrono::duration_cast( time_end - time_start); this->query_time_range_.set_left(time_start - 2 * query_interval_time_); this->query_time_range_.set_right(time_start - query_interval_time_); // 目的在于刷pv变量 query_interval_time_ start end this->now_time_ = time_start; refresh_ihd_cache(this->delay_time_); //刷 queried_time_,query_time_range_ { gb_logger_->log_info( "ihd查询开始时间1:" + mix_cc::mix_time_t(query_time_range_.get_left()).to_formatted_time()); gb_logger_->log_info( "ihd查询结束时间1:" + mix_cc::mix_time_t(query_time_range_.get_right()).to_formatted_time()); gb_logger_->log_info("ihd查询的时间间隔:" + std::to_string(delay_time_.count())); gb_logger_->log_info("ihd查询的数据量:" + std::to_string(queried_data_.rows())); } for (auto i = 0; i < queried_data_.rows(); i++) { refresh_exp_vars_ihd(i); } // 刷 mmvar this->now_time_ = time_end; // 防止出问题,没有实际用处 refresh_ihd_cache(this->delay_time_); // { // 日志 gb_logger_->log_info( "ihd查询开始时间2:" + mix_cc::mix_time_t(query_time_range_.get_left()).to_formatted_time()); gb_logger_->log_info( "ihd查询结束时间2:" + mix_cc::mix_time_t(query_time_range_.get_right()).to_formatted_time()); gb_logger_->log_info("ihd查询的时间间隔:" + std::to_string(delay_time_.count())); gb_logger_->log_info("ihd查询的数据量:" + std::to_string(queried_data_.rows())); } for (auto i = 0; i < queried_data_.rows(); i++) { refresh_exp_vars_ihd(i); auto o_value = this->cron_proc_sample(); if (o_value.has_value()) { tmp_data.push_back(o_value.value()); } } if (this->test_mode_ == stat_tools::TestMode::normal_dist_diff) { StatAlarm alarm_info; try { alarm_info = this->sample_stat_->get_task_normal_info(tmp_data); } catch (std::exception& e) { logger_->Error() << "get_task_normal_info执行错误: " << this->rule_name_ << std::endl; } if (alarm_info) { gb_logger_->log_info("exec_normal_task:" + rule_name_ + alarm_info.alarm_str); return utility::build_alarm_info(MsgLevel::INFO, rule_id_, rule_name_, "EXPSMP", alarm_info.alarm_str, query_time_range_); } else { gb_logger_->log_info(" alarm_info.alarm_str获取失败:" + rule_name_); } } } int ExpSample::reload_config_sample() { try { archive_interval_day_ = rule_json_.at("sample").at("archive").at(1).get(); logger_->Debug() << "archive:" << archive_interval_day_ << endl; start_date_ = mix_cc::mix_time_t( rule_json_.at("sample").at("datestart").at(1).get(), "%Y-%m-%d") .to_chrono_time(); end_date_ = mix_cc::mix_time_t( rule_json_.at("sample").at("dateend").at(1).get(), "%Y-%m-%d") .to_chrono_time(); if (rule_json_.at("alarm_option").contains("value")) { auto tmp_exp = rule_json_.at("alarm_option").at("value").at(1).get(); exp_str_ = get_macro_replaced_exp(tmp_exp); if (exp_result_ == nullptr) { exp_result_ = std::make_unique(exp_str_, &mm_vars); logger_->Debug() << exp_str_ << ":" << exp_result_->evaluate() << endl; } else { logger_->Info() << "指针已经初始化完成" << exp_str_ << ":" << exp_result_->evaluate() << endl; } } if (rule_json_.at("alarm_option").contains("sample_is_infinite_mode")) { this->is_no_down_limit_ = static_cast(rule_json_.at("alarm_option") .at("sample_is_infinite_mode") .at(1) .get()); } test_mode_ = static_cast( rule_json_.at("alarm_option").at("mode").at(1).get()); judge_diff_ = rule_json_.at("alarm_option").at("diff").at(1).get(); error_str_ = rule_json_.at("alarm_option").at("error").at(1).get(); logger_->Debug() << "modejudge(0: absolute difference, 1: error percentage (%), 2: " "normal value signal (%),3. dtw curve distance(%), 4.poly fit(%)" << static_cast(test_mode_) << " samplediff:" << judge_diff_ << endl; } catch (std::exception& e) { logger_->Error() << "表达式-样本取样异常,表达式为: " << exp_str_ << std::endl; throw_with_nested( mix_cc::Exception(-1, "表达式样本载入错误", BOOST_CURRENT_LOCATION)); } return 0; } int ExpSample::log_action_info(double result_value) { this->print_exp_vars(exp_str_); logger_->Debug() << " action start:" << mix_cc::mix_time_t(act_start_time_).to_formatted_time() << ",end:" << mix_cc::mix_time_t(now_time_).to_formatted_time() << ",timediff:" << mm_vars["time"] << ",value:" << result_value << endl; return 0; } bool ExpSample::cron_check_is_line_start() { // 1.查数据 const string tagname_main_speed = string(CMemVar::Const()->UnitNo) + "_" + string(CMemVar::Const()->eis_tagname_main_speed); vector main_speed_ihd({tagname_main_speed}); TimeDur check_internal = 2s; auto queried_batch_maybe = mix_cc::ihd::make_query_batch_maybe( main_speed_ihd, query_time_range_, check_internal); if (queried_batch_maybe.is_nothing()) { this->gb_logger_->log_error( this->rule_name_ + ":ihd没有查到tagname_main_speed:" + tagname_main_speed + "的信息"); return false; } auto queried_bath = queried_batch_maybe.unsafe_get_just(); auto result_maybe = mix_cc::ihd::read_data_with_time_maybe(&queried_bath); if (result_maybe.is_nothing()) { this->gb_logger_->log_error( this->rule_name_ + ":ihd没有查到tagname_main_speed:" + tagname_main_speed + "的数据"); return false; } // 2.检查机组速度 Eigen::Matrix queried_data; vector queried_time; std::tie(queried_time, queried_data) = result_maybe.unsafe_get_just(); for (size_t i = 0; i < queried_data.rows(); i++) { if (std::abs(queried_data(i, 0)) < std::numeric_limits::min()) { // this->gb_logger_->log_error( // this->rule_name_ + "时间:" + // mix_cc::mix_time_t(queried_time[i]).to_formatted_time() + // "时,机组速度:" + std::to_string(queried_data(i, 0))); return false; } } return true; }