eis/eqpalg/.do_not_use/otheralg/exp_sample.cc

348 lines
14 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <eqpalg/algs/exp_sample.h>
#include <zlib/MemVar.h>
int ExpSample::init() {
int ret = 0;
act_started_ = false;
try {
Exp::init();
// 载入样本配置
this->reload_config_sample();
sample_stat_ = std::make_unique<stat_tools::Frame>(
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<std::chrono::milliseconds>(
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<int>();
logger_->Debug() << "archive:" << archive_interval_day_ << endl;
start_date_ =
mix_cc::mix_time_t(
rule_json_.at("sample").at("datestart").at(1).get<std::string>(),
"%Y-%m-%d")
.to_chrono_time();
end_date_ =
mix_cc::mix_time_t(
rule_json_.at("sample").at("dateend").at(1).get<std::string>(),
"%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<std::string>();
exp_str_ = get_macro_replaced_exp(tmp_exp);
if (exp_result_ == nullptr) {
exp_result_ =
std::make_unique<mix_cc::matheval::Expression>(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<bool>(rule_json_.at("alarm_option")
.at("sample_is_infinite_mode")
.at(1)
.get<int>());
}
test_mode_ = static_cast<stat_tools::TestMode>(
rule_json_.at("alarm_option").at("mode").at(1).get<int>());
judge_diff_ = rule_json_.at("alarm_option").at("diff").at(1).get<double>();
error_str_ =
rule_json_.at("alarm_option").at("error").at(1).get<std::string>();
logger_->Debug()
<< "modejudge(0: absolute difference, 1: error percentage (%), 2: "
"normal value signal (%),3. dtw curve distance(%), 4.poly fit(%)"
<< static_cast<int>(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<string> 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<double, Eigen::Dynamic, Eigen::Dynamic> queried_data;
vector<TimePoint> 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<double>::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;
}