diff --git a/src/Alarm.cpp b/src/Alarm.cpp index 5d4a9acc3a70ccb9236506d412c94c9802f0302b..cfdbdde317881a61d2687ce9d215660e5132327e 100644 --- a/src/Alarm.cpp +++ b/src/Alarm.cpp @@ -47,7 +47,6 @@ static const char *RcsId = "$Id: $"; #include "alarm-thread.h" #include "alarm_grammar.h" -#include "log_thread.h" #include "update-thread.h" //#define _DUMP_TREE_XML @@ -196,7 +195,6 @@ void Alarm::delete_device() #ifdef _RW_LOCK alarms.del_rwlock(); #endif - alarms.stop_logdb(); alarms.stop_cmdthread(); sleep(1); //wait for alarm_thread and log_thread to exit //delete almloop; @@ -357,17 +355,6 @@ void Alarm::init_device() #ifdef _RW_LOCK alarms.new_rwlock(); #endif - try { - if((!dbHost.empty()) && (!dbUser.empty()) && (!dbPasswd.empty()) && (!dbName.empty()) && (dbPortint != 0) ) - //logloop = new log_thread(dbhost, dbuser, dbpw, dbname, dbportint,this); - alarms.init_logdb(dbHost, dbUser, dbPasswd, dbName, dbPortint, instanceName); - } catch(string & e) - { - ERROR_STREAM << "Alarm::init_device(): " << e << endl; - cout << "Error: " << e << ". Exiting..." << endl; - exit(-3); - } - try { alarms.init_cmdthread(); } catch(...) @@ -431,7 +418,7 @@ void Alarm::init_device() } }*/ try { - alarms.get_alarm_list_db(tmp_alm_vec); + alarms.get_alarm_list_db(tmp_alm_vec, saved_alarms); } catch(string & e) { ERROR_STREAM << "Alarm::init_device(): " << e << endl; @@ -1269,9 +1256,6 @@ void Alarm::ack(const Tango::DevVarStringArray *argin) } if(found->ack == NOT_ACK) { - alarms.log_alarm_db(TYPE_LOG_STATUS, gettime(), found->name, found->stat, ACK, - "", 0, "", "", "", "", -1); - Tango::DevEnum *attr_value = get_AlarmState_data_ptr(i->second.attr_name); //TODO: if not _SHLVD, _DSUPR, _OOSRV if((i->second.stat == S_NORMAL) && i->second.ack == ACK) @@ -1474,13 +1458,11 @@ void Alarm::load(Tango::DevString argin) (const char*)"Alarm::load()", Tango::ERR); } #endif - string cmd_name_full = alm.cmd_name_a + string(";") + alm.cmd_name_n; - alarms.log_alarm_db(TYPE_LOG_DESC_ADD, ts, alm.name, "", "", //add new alarm on log before subscribe event - alm.formula, alm.on_delay, alm.grp2str(), alm.lev, alm.msg, cmd_name_full, alm.silent_time); //but if it fails remove it from table - - alarms.save_alarm_conf_db(alm.attr_name, ts, alm.name, "", "", //add new alarm on log before subscribe event + alarms.save_alarm_conf_db(alm.attr_name, alm.name, "", "", alm.enabled, //add new alarm on log before subscribe event alm.formula, alm.on_delay, alm.off_delay, alm.grp2str(), alm.lev, alm.msg, alm.cmd_name_a, alm.cmd_name_n, alm.silent_time); //but if it fails remove it from table - + string conf_str; + alm.confstr(conf_str); + saved_alarms.insert(make_pair(alm.attr_name,conf_str)); #ifndef _RW_LOCK @@ -1677,8 +1659,6 @@ void Alarm::remove(Tango::DevString argin) s.replace(i, 1, "_"); } } /* end if */ - alarms.log_alarm_db(TYPE_LOG_DESC_DIS, gettime(), log_alm_name, "", "", //set active to 0 - "", 0, "", "", "", "", -1); alarmedlock->writerIn(); found = find(alarmed.begin(), alarmed.end(), s); //look again because in the meanwhile lock was not acquired if (found != alarmed.end()) @@ -2010,6 +1990,7 @@ void Alarm::modify(Tango::DevString argin) alm.cmd_action_n.clear(); alm.send_arg_n = false; alm.dp_n = NULL; + alm.enabled=1; alm.formula_tree = //boost::spirit::tree_parse_info< std::string::iterator, factory_t> tmp = @@ -2103,6 +2084,7 @@ void Alarm::modify(Tango::DevString argin) i->second.cmd_dp_n = alm.cmd_dp_n; i->second.cmd_action_n = alm.cmd_action_n; //i->second.send_arg_n = alm.send_arg_n; + i->second.enabled = alm.enabled; } else { ostringstream o; @@ -2119,9 +2101,8 @@ void Alarm::modify(Tango::DevString argin) (const char*)__func__, Tango::ERR); } - - alarms.log_alarm_db(TYPE_LOG_DESC_UPDATE, ts, alm.name, "", "", - alm.formula, alm.on_delay, alm.grp2str(), alm.lev, alm.msg, cmd_name_full, alm.silent_time); + //update attribute properties + events->update_property(); //delete proxy for actions if(i->second.dp_a) @@ -2301,6 +2282,7 @@ void Alarm::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) alm.cmd_action_n.clear(); alm.send_arg_n = false; alm.dp_n = NULL; + alm.enabled = 1; evn.clear(); alm.formula_tree = @@ -2390,6 +2372,7 @@ void Alarm::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn) DEBUG_STREAM << " lev = '" << alm.lev << "'" << endl; DEBUG_STREAM << " action_a = '" << alm.cmd_name_a << "'" << endl; DEBUG_STREAM << " action_n = '" << alm.cmd_name_n << "'" << endl; + DEBUG_STREAM << " enabled = '" << (alm.enabled ? "1" : "0") << "'" << endl; if ((alm.name.empty() == false) && \ (alm.formula.empty() == false) && \ ((alm.lev==LEV_LOG)||(alm.lev==LEV_WARNING)|| \ @@ -4135,6 +4118,44 @@ void Alarm::put_signal_property() for(it = alarms.v_alarm.begin(); it != alarms.v_alarm.end(); it++) { prop.push_back(it->first); + + string conf_str; + it->second.confstr(conf_str); + map<string,string>::iterator itmap = saved_alarms.find(it->first); + if(itmap == saved_alarms.end()) + { + DEBUG_STREAM << __func__<<": SAVING " << it->first << endl; + alarms.save_alarm_conf_db(it->second.attr_name, it->second.name, it->second.stat, it->second.ack, it->second.enabled, + it->second.formula, it->second.on_delay, it->second.off_delay, it->second.grp2str(), it->second.lev, it->second.msg, it->second.cmd_name_a, it->second.cmd_name_n, it->second.silent_time); + saved_alarms.insert(make_pair(it->first,conf_str)); + + } + else + { + string conf_string; + it->second.confstr(conf_string); + //alarm found but configuration changed + if(conf_string != itmap->second) + { + DEBUG_STREAM << __func__<<": UPDATING " << it->first << endl; + alarms.save_alarm_conf_db(it->second.attr_name, it->second.name, it->second.stat, it->second.ack, it->second.enabled, + it->second.formula, it->second.on_delay, it->second.off_delay, it->second.grp2str(), it->second.lev, it->second.msg, it->second.cmd_name_a, it->second.cmd_name_n, it->second.silent_time); + itmap->second = conf_string; + } + } + } + map<string, string>::iterator it2=saved_alarms.begin(); + while(it2 != saved_alarms.end()) + { + alarm_container_t::iterator found = alarms.v_alarm.find(it2->first); + if (found == alarms.v_alarm.end()) + { + DEBUG_STREAM << __func__<<": DELETING " << it2->first << endl; + alarms.delete_alarm_conf_db(it2->first); + saved_alarms.erase(it2); + } + if(it2 != saved_alarms.end()) + it2++; } #ifndef _RW_LOCK alarms.unlock(); diff --git a/src/Alarm.h b/src/Alarm.h index 7cf0aa06031e05b1615252b47d72366a05b52d2d..45bc9ddab455215e815a15f5439850f75cd56444 100644 --- a/src/Alarm.h +++ b/src/Alarm.h @@ -342,6 +342,7 @@ private: ReadersWritersLock *internallock; ReadersWritersLock *dslock; int period; //subscribe thread period + map<string, string> saved_alarms; static int instanceCounter; diff --git a/src/alarm_grammar.h b/src/alarm_grammar.h index 32810b18f5904f73ee020a9c1f90b2b33131438f..220888a29fc346407746c01242c6dc9c49e4b730 100644 --- a/src/alarm_grammar.h +++ b/src/alarm_grammar.h @@ -77,6 +77,7 @@ #define MESSAGE_KEY "message" #define ON_COMMAND_KEY "on_command" #define OFF_COMMAND_KEY "off_command" +#define ENABLED_KEY "enabled" #define KEY(S_VAL) S_VAL "=" //////////////////////////////////////////////////////////////////////////// @@ -202,7 +203,8 @@ struct alarm_parse : public grammar<alarm_parse> discard_node_d[group] | discard_node_d[msg] | discard_node_d[on_command] | - discard_node_d[off_command] + discard_node_d[off_command] | + discard_node_d[enabled] ; //------------------------------ALARM NAME-------------------------------------- @@ -305,13 +307,24 @@ struct alarm_parse : public grammar<alarm_parse> ] //discard_node_d | epsilon_p) ; + //------------------------------ENABLED---------------------------------------- + enabled + = discard_node_d[str_p(KEY(ENABLED_KEY))] >> + //lexeme_d[(+alnum_p)] //match only possible levels?? (fault, log, ...) + //(+(alnum_p-'\t')) + //(ch_p('0') | ch_p('1')) + bin_p + [ + assign_a(self.m_alarm.enabled) //save enabled in alarm_t + ] + ; } typedef rule<ScannerT> rule_t; rule_t expression, event, option; rule<typename lexeme_scanner<ScannerT>::type> symbol; //needed to use lexeme_d in rule name rule<typename lexeme_scanner<ScannerT>::type> symbol_attr_name; //needed to use lexeme_d in rule name - rule_t name, name_alm, val, token, oper, msg, group, level, on_delay, off_delay, silent_time, on_command, off_command; + rule_t name, name_alm, val, token, oper, msg, group, level, on_delay, off_delay, silent_time, on_command, off_command, enabled; formula_grammar formula; rule_t const& diff --git a/src/alarm_table.cpp b/src/alarm_table.cpp index dd8ddf5113d1b348dcfa1ffca82d58504cea417e..c693bfaee10be085800c8e1c21fc840e563953ec 100644 --- a/src/alarm_table.cpp +++ b/src/alarm_table.cpp @@ -17,7 +17,6 @@ #include <tango.h> #include "alarm_table.h" #include "alarm_grammar.h" -#include "log_thread.h" #include "cmd_thread.h" @@ -49,6 +48,7 @@ alarm_t::alarm_t() silent_time = -1; cmd_name_a=string(""); cmd_name_n=string(""); + enabled=true; } bool alarm_t::operator==(const alarm_t &that) @@ -185,6 +185,24 @@ void alarm_t::clear() // ts = 0; } +void alarm_t::confstr(string &s) +{ + ostringstream conf; + conf << + name << "\t" << + /*TODO: KEY(FORMULA_KEY)<<*/formula << "\t" << + KEY(ONDELAY_KEY)<<on_delay << "\t" << + KEY(OFFDELAY_KEY)<<off_delay << "\t" << + KEY(LEVEL_KEY)<< lev << "\t" << + KEY(SILENT_TIME_KEY)<<silent_time << "\t" << + KEY(GROUP_KEY)<< grp2str() << "\t" << + KEY(MESSAGE_KEY)<< "\"" << msg << "\"\t" << + KEY(ON_COMMAND_KEY)<< cmd_name_a << "\t" << + KEY(OFF_COMMAND_KEY)<< cmd_name_n << "\t" << + KEY(ENABLED_KEY)<< (enabled ? "1" : "0"); + s = conf.str(); +} + /* * alarm_table class methods */ @@ -356,7 +374,6 @@ bool alarm_table::update(const string& alm_name, Tango::TimeVal ts, formula_res_ bool ret_changed=false; //Tango::TimeVal now = gettime(); TangoSys_MemStream out_stream; - alm_log_t a; #ifndef _RW_LOCK this->lock(); #else @@ -398,19 +415,10 @@ bool alarm_table::update(const string& alm_name, Tango::TimeVal ts, formula_res_ if((status_on_delay && (found->second.stat == S_NORMAL)) || (status_off_delay && (found->second.stat == S_ALARM))) { ret_changed=true; - a.type_log = TYPE_LOG_STATUS; - a.name = alm_name; - a.time_s = ts.tv_sec; - a.time_us = ts.tv_usec; - a.status = (int)(res.value) ? S_ALARM : S_NORMAL; - //a.level = found->second.lev; if((int)(res.value)) found->second.ack = NOT_ACK; //if changing from NORMAL to ALARM -> NACK - a.ack = found->second.ack; - a.values = attr_values; //a.grp = found->second.grp2str(); //a.msg = (int)(res.value) ? found->second.msg : ""; - logloop->log_alarm_db(a); found->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed if((int)(res.value)) { @@ -552,7 +560,6 @@ bool alarm_table::timer_update() bool ret_changed=false; Tango::TimeVal ts = gettime(); TangoSys_MemStream out_stream; - alm_log_t a; #ifndef _RW_LOCK this->lock(); #else @@ -588,17 +595,8 @@ bool alarm_table::timer_update() i->second.silenced = 0; } - a.type_log = TYPE_LOG_STATUS; - a.name = i->second.name; - a.time_s = ts.tv_sec; - a.time_us = ts.tv_usec; - a.status = (status_on_delay) ? S_ALARM : S_NORMAL; - //a.level = found->second.lev; if(status_on_delay) i->second.ack = NOT_ACK; //if changing from NORMAL to ALARM -> NACK - a.ack = i->second.ack; - a.values = i->second.attr_values_delay; - logloop->log_alarm_db(a); i->second.ts = ts; /* store event timestamp into alarm timestamp */ //here update ts only if status changed if(status_on_delay) { @@ -825,22 +823,6 @@ void alarm_table::del_rwlock() } #endif -void alarm_table::init_logdb(string dbhost, string dbuser, string dbpw, string dbname, int dbport, string instance_name) -{ - logloop = new log_thread(dbhost, dbuser, dbpw, dbname, dbport, instance_name); - logloop->start(); -} - -void alarm_table::stop_logdb() -{ - alm_log_t a; - a.name = LOG_THREAD_EXIT; - a.time_s = LOG_THREAD_EXIT_TIME; - logloop->log_alarm_db(a); - //sleep(1); - //delete logloop; -} - void alarm_table::init_cmdthread() { cmdloop = new cmd_thread(); @@ -855,28 +837,7 @@ void alarm_table::stop_cmdthread() cmdloop->list.push_back(arg); } -void alarm_table::log_alarm_db(unsigned int type, Tango::TimeVal ts, string name, string status, string ack, - string formula, unsigned int time_threshold, string grp, string lev, string msg, string action, int silent_time, vector<string> alm_list) -{ - alm_log_t a; - a.type_log = type; - a.name = name; - a.time_s = ts.tv_sec; - a.time_us = ts.tv_usec; - a.time_threshold = time_threshold; - a.status = status; - a.level = lev; - a.ack = ack; - a.grp = grp; - a.msg = msg; - a.action = action; - a.formula = formula; - a.alm_list = alm_list; - a.silent_time = silent_time; - logloop->log_alarm_db(a); -} - -void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string name, string status, string ack, +void alarm_table::save_alarm_conf_db(string att_name, string name, string status, string ack, bool enabled, string formula, unsigned int on_delay, unsigned int off_delay, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list) { // We want to put properties for attribute "att_name" @@ -889,11 +850,12 @@ void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time Tango::DbDatum dbd_group(GROUP_KEY); Tango::DbDatum dbd_message(MESSAGE_KEY); - Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY); //TODO: action - Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY); //TODO: action + Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY); + Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY); + Tango::DbDatum dbd_enabled(ENABLED_KEY); Tango::DbData db_data; - dbd_att_name << 9; // Eigth properties for attribute "att_name" + dbd_att_name << 11; // Ten properties for attribute "att_name" dbd_name << name; dbd_formula << formula; dbd_on_delay << on_delay; @@ -904,6 +866,7 @@ void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string dbd_message << msg; dbd_oncommand << cmd_a; dbd_offcommand << cmd_n; + dbd_enabled << (enabled ? 1 : 0); db_data.push_back(dbd_att_name); db_data.push_back(dbd_name); @@ -916,6 +879,7 @@ void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string db_data.push_back(dbd_message); db_data.push_back(dbd_oncommand); db_data.push_back(dbd_offcommand); + db_data.push_back(dbd_enabled); string dev_name(mydev->get_name()); @@ -923,18 +887,53 @@ void alarm_table::save_alarm_conf_db(string att_name, Tango::TimeVal ts, string db_dev->get_dbase()->put_device_attribute_property(dev_name,db_data); } -void alarm_table::get_alarm_list_db(vector<string> &al_list) +void alarm_table::delete_alarm_conf_db(string att_name) { - //logloop->get_alarm_list(al_list); -/* - * " CONCAT('\t', " << DESC_COL_NAME << ",'\t'," << DESC_COL_FORMULA << - ",'\t'," << "IFNULL(" << DESC_COL_TIME_THRESHOLD << ",0)" << ",'\t'," << DESC_COL_LEVEL << - ",'\t'," << "IFNULL(" << DESC_COL_SILENT_TIME << ",-1)" << - ",'\t'," << DESC_COL_GRP << ",'\t','\"'," << "IFNULL(" << DESC_COL_MSG << ",'')" << - ",'\"','\t'," << "IFNULL(" << DESC_COL_ACTION << ",';')" << ")" << - */ + // We want to put properties for attribute "att_name" + Tango::DbDatum dbd_att_name(att_name); + Tango::DbDatum dbd_name(NAME_KEY); + Tango::DbDatum dbd_formula(FORMULA_KEY); + Tango::DbDatum dbd_on_delay(ONDELAY_KEY); + Tango::DbDatum dbd_off_delay(OFFDELAY_KEY); + Tango::DbDatum dbd_level(LEVEL_KEY); + Tango::DbDatum dbd_silence_time(SILENT_TIME_KEY); //TODO: silent_time + Tango::DbDatum dbd_group(GROUP_KEY); + Tango::DbDatum dbd_message(MESSAGE_KEY); + Tango::DbDatum dbd_oncommand(ON_COMMAND_KEY); + Tango::DbDatum dbd_offcommand(OFF_COMMAND_KEY); + Tango::DbDatum dbd_enabled(ENABLED_KEY); + Tango::DbData db_data; + db_data.push_back(dbd_att_name); + db_data.push_back(dbd_name); + db_data.push_back(dbd_formula); + db_data.push_back(dbd_on_delay); + db_data.push_back(dbd_off_delay); + db_data.push_back(dbd_level); + db_data.push_back(dbd_silence_time); + db_data.push_back(dbd_group); + db_data.push_back(dbd_message); + db_data.push_back(dbd_oncommand); + db_data.push_back(dbd_offcommand); + db_data.push_back(dbd_enabled); + + string dev_name(mydev->get_name()); + + try + { + Tango::DbDevice *db_dev = mydev->get_db_device(); + db_dev->get_dbase()->delete_device_attribute_property(dev_name,db_data); + } + catch(Tango::DevFailed &e) + { + cout << __func__ << ": Exception deleting " << att_name << " = " << e.errors[0].desc<<endl; + } +} + +void alarm_table::get_alarm_list_db(vector<string> &al_list, map<string, string> &saved_alarms) +{ + saved_alarms.clear(); string dev_name(mydev->get_name()); vector<string> att_list; @@ -965,6 +964,7 @@ void alarm_table::get_alarm_list_db(vector<string> &al_list) string alm_message; string alm_on_command(""); string alm_off_command(""); + string alm_enabled("1"); for (long k=0;k < nb_prop;k++) { string &prop_name = db_data[i].name; @@ -989,6 +989,8 @@ void alarm_table::get_alarm_list_db(vector<string> &al_list) db_data[i] >> alm_on_command; else if (prop_name == OFF_COMMAND_KEY) db_data[i] >> alm_off_command; + else if (prop_name == ENABLED_KEY) + db_data[i] >> alm_enabled; else { cout << "att_name="<<att_name<<" UNKWNOWN prop_name="<<prop_name<<endl; @@ -1007,8 +1009,10 @@ void alarm_table::get_alarm_list_db(vector<string> &al_list) KEY(GROUP_KEY)<< alm_group << "\t" << KEY(MESSAGE_KEY)<< "\"" << alm_message << "\"\t" << KEY(ON_COMMAND_KEY)<< alm_on_command << "\t" << - KEY(OFF_COMMAND_KEY)<< alm_off_command; + KEY(OFF_COMMAND_KEY)<< alm_off_command << "\t" << + KEY(ENABLED_KEY)<< alm_enabled; al_list.push_back(alm.str()); + saved_alarms.insert(make_pair(alm_name,alm.str())); } #if 0 diff --git a/src/alarm_table.h b/src/alarm_table.h index 3383184a94bd15fd1bad4da56b875f16e0443f55..c3d974bdcce0cc58fe84ed41f5a3c0890256affe 100644 --- a/src/alarm_table.h +++ b/src/alarm_table.h @@ -268,6 +268,7 @@ class alarm_t { Tango::TimeVal ts; string stat, ack; + bool enabled; unsigned int on_counter; unsigned int off_counter; @@ -315,6 +316,7 @@ class alarm_t { void str2grp(string &s); void insert(const string& s); void clear(); + void confstr(string &s); protected: private: @@ -352,15 +354,11 @@ class alarm_table { void new_rwlock(); void del_rwlock(); #endif - - void init_logdb(string dbhost, string dbuser, string dbpw, string dbname, int dbport, string instance_name); - void stop_logdb(); - void log_alarm_db(unsigned int type, Tango::TimeVal ts, string name, string status, string ack, - string formula, unsigned int time_threshold, string grp, string lev, string msg, string action, int silent_time, vector<string> alm_list=vector<string>()); - void save_alarm_conf_db(string att_name, Tango::TimeVal ts, string name, string status, string ack, + void save_alarm_conf_db(string att_name, string name, string status, string ack, bool enabled, string formula, unsigned int on_delay, unsigned int off_delay, string grp, string lev, string msg, string cmd_a, string cmd_n, int silent_time, vector<string> alm_list=vector<string>()); - void get_alarm_list_db(vector<string> &al_list); + void delete_alarm_conf_db(string att_name); + void get_alarm_list_db(vector<string> &al_list, map<string, string> &saved_alarms); void init_cmdthread(); void stop_cmdthread(); Tango::TimeVal startup_complete; //to disable action execution at startup diff --git a/src/log_thread.cpp b/src/log_thread.cpp deleted file mode 100644 index 21ac238ba9f4dd75963ff193e14fb62d1b10291d..0000000000000000000000000000000000000000 --- a/src/log_thread.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/* - * log_thread.cpp - * - * $Author: graziano $ - * - * $Revision: 1.7 $ - * - * $Log: log_thread.cpp,v $ - * - * - * copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale - * Strada Statale 14 - km 163,5 in AREA Science Park - * 34012 Basovizza, Trieste ITALY - */ - -#include "log_thread.h" -//#define _DEBUG_LOG_THREAD 0 -//#define _DEBUG_LOG_THREAD 1 - -static const char __FILE__rev[] = __FILE__ " $Revision: 1.7 $"; - -/* - * log_thread::log_thread() - */ -log_thread::log_thread(string dbhost, string dbuser, string dbpw, string dbname, int dbport, string instance_name/*, Alarm_ns::Alarm *p*/)/*: Tango::LogAdapter(p)*/ -{ - //p_Alarm = p; - m_dbhost = dbhost; - m_dbuser = dbuser; - m_dbpw = dbpw; - m_dbname = dbname; - m_dbport = dbport; - m_instance_name = instance_name; - - //cout << __FILE__rev << endl; - - ostringstream err; - if(!mysql_init(&log_db)) - { - err << "mysql_init failed for log DB" << ends; - throw err.str(); - } - my_bool my_auto_reconnect=1; - if(mysql_options(&log_db,MYSQL_OPT_RECONNECT,&my_auto_reconnect) !=0) - { - err << "mysql auto reconnection error for log DB: " << mysql_error(&log_db) << ends;; - throw err.str(); - } - - if(!mysql_real_connect(&log_db, m_dbhost.c_str(), m_dbuser.c_str(), m_dbpw.c_str(), m_dbname.c_str(), m_dbport, NULL, 0)) - { - err << "mysql_real_connect failed for log DB" << ends; - throw err.str(); - } -} - -/* - * log_thread::~log_thread() - */ -log_thread::~log_thread() -{ - //p_Alarm = NULL; - mysql_close(&log_db); -} - -/* - * log_thread::run() - */ -void log_thread::run(void *) -{ - while (true) { - /* - * pop_front() will wait() on condition variable - */ - try - { - alm_log_t a = al_list.pop_front(); - if ((a.name == LOG_THREAD_EXIT) && \ - (a.time_s == LOG_THREAD_EXIT_TIME)) - break; - - write_db(a); - } - catch(omni_thread_fatal& ex) - { - ostringstream err; - err << "omni_thread_fatal exception running log thread, err=" << ex.error << ends; - //WARN_STREAM << "alarm_thread::run(): " << err.str() << endl; - printf("log_thread::run(): %s", err.str().c_str()); - } - catch(Tango::DevFailed& ex) - { - ostringstream err; - err << "exception running log thread: '" << ex.errors[0].desc << "'" << ends; - //WARN_STREAM << "alarm_thread::run(): " << err.str() << endl; - printf("log_thread::run(): %s", err.str().c_str()); - Tango::Except::print_exception(ex); - } - catch(...) - { - //WARN_STREAM << "alarm_thread::run(): catched unknown exception!!" << endl; - printf("log_thread::run(): catched unknown exception!!"); - } - } -} /* alarm_thread::run() */ - -void log_thread::log_alarm_db(alm_log_t& a) -{ - al_list.push_back(a); -} - -void log_thread::write_db(alm_log_t& a) -{ - ostringstream query_str; - ostringstream err_msg; - - char *values_escaped = new char [2 * a.values.length() + 1]; - char *name_escaped = new char [2 * a.name.length() + 1]; - char *formula_escaped = new char [2 * a.formula.length() + 1]; - char *grp_escaped = new char [2 * a.grp.length() + 1]; - char *msg_escaped = new char [2 * a.msg.length() + 1]; - char *level_escaped = new char [2 * a.level.length() + 1]; - char *action_escaped = new char [2 * a.action.length() + 1]; - char *instance_escaped = new char [2 * m_instance_name.length() + 1]; - mysql_real_escape_string(&log_db, values_escaped, a.values.c_str(), a.values.length()); - mysql_real_escape_string(&log_db, name_escaped, a.name.c_str(), a.name.length()); - mysql_real_escape_string(&log_db, formula_escaped, a.formula.c_str(), a.formula.length()); - mysql_real_escape_string(&log_db, grp_escaped, a.grp.c_str(), a.grp.length()); - mysql_real_escape_string(&log_db, msg_escaped, a.msg.c_str(), a.msg.length()); - mysql_real_escape_string(&log_db, level_escaped, a.level.c_str(), a.level.length()); - mysql_real_escape_string(&log_db, action_escaped, a.action.c_str(), a.action.length()); - mysql_real_escape_string(&log_db, instance_escaped, m_instance_name.c_str(), m_instance_name.length()); - - char *tmp_name_escaped; - ostringstream tmp_names; - for(vector<string>::iterator it=a.alm_list.begin(); it!=a.alm_list.end(); it++) - { - tmp_name_escaped = new char [2 * it->length() + 1]; - mysql_real_escape_string(&log_db, tmp_name_escaped, it->c_str(), it->length()); - tmp_names << " AND " << DESC_COL_NAME << "!='" << tmp_name_escaped << "'"; - delete [] tmp_name_escaped; - } - - switch (a.type_log) - { - case TYPE_LOG_STATUS: - //example: - //INSERT INTO alarms - // (time_sec, time_usec, status, ack, id_description, attr_values) - // SELECT 1234567890, 123456, 'ALARM', 'NACK', id_description, 'ev/ev/ev/ev2=1.;' //take id_description - // FROM description //from description - // WHERE name='al/al/al/al' AND active=1 AND instance='alarm_1'; //where this alarm is active - if((a.status.size() == 0) || (a.ack.size() == 0) || (strlen(name_escaped) == 0)) - { - err_msg << "log_thread::write_db(): ERROR some mandatory values adding alarm status are empty: status=" << - a.status << " ack=" << a.ack << " name=" << name_escaped << ends; - break; - } - query_str << - "INSERT INTO " << m_dbname << "." << STAT_TABLE_NAME << - " (" << STAT_COL_TIME_S << "," << STAT_COL_TIME_U << "," << - STAT_COL_STATUS << "," << STAT_COL_ACK << "," << - STAT_COL_DESC_ID << "," << STAT_COL_VALUES << - ") SELECT " << a.time_s << "," << a.time_us << ",'" << - a.status << "','" << a.ack << "'," << - DESC_COL_ID << ",'" << values_escaped << "'" << - " FROM " << DESC_TABLE_NAME << - " WHERE " << DESC_COL_NAME << "='" << name_escaped << "'" << - " AND " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - ends; - break; - case TYPE_LOG_DESC_ADD: - //example: - //INSERT INTO description - // (name, active, time_sec, formula, time_threashold, level, grp, msg, action, instance) - // SELECT 'al/al/al/al', 'alarm_1', 1, 1234567890, '(ev/ev/ev/evn < 1.2)', 'log', 'gr_none', 'msg' - // FROM description - // WHERE name='al/al/al/al' AND active=1 AND instance='alarm_1' //look if exists an alarm with the same name and active - // HAVING count(*) = 0; //insert only if it does not exist - if((strlen(name_escaped) == 0) || (strlen(instance_escaped) == 0) || (strlen(formula_escaped) == 0) || (strlen(level_escaped) == 0) || - (strlen(grp_escaped) == 0) || (strlen(msg_escaped) == 0)) - { - err_msg << "log_thread::write_db(): ERROR some mandatory values adding alarm description are empty: name=" << - name_escaped << " instance=" << instance_escaped << " formula=" << formula_escaped << " level=" << level_escaped << " grp=" << grp_escaped << - " msg=" << msg_escaped << ends; - break; - } - query_str << - "INSERT INTO " << m_dbname << "." << DESC_TABLE_NAME << - " (" << DESC_COL_NAME << "," << DESC_COL_ACTIVE << "," << - DESC_COL_TIME_S << "," << DESC_COL_FORMULA << "," << - DESC_COL_TIME_THRESHOLD << "," << DESC_COL_LEVEL << "," << - DESC_COL_GRP << "," << DESC_COL_MSG << "," << - DESC_COL_ACTION << "," << DESC_COL_INSTANCE << "," << - DESC_COL_SILENT_TIME << - ") SELECT '" << name_escaped << "'," << ALARM_ACTIVE << "," << - a.time_s << ",'" << formula_escaped << "','" << - a.time_threshold << "','" << level_escaped << "','" << - grp_escaped << "','" << msg_escaped << "','" << - action_escaped << "','" <<instance_escaped << "','" << - a.silent_time << "'" << - " FROM " << DESC_TABLE_NAME << - " WHERE " << DESC_COL_NAME << "='" << name_escaped << "'" << - " AND " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - " HAVING COUNT(*) = 0" << - ends; - break; - case TYPE_LOG_DESC_DIS: - //example: - //UPDATE description - // SET active=0 //set active to 0 - // WHERE name='al/al/al/al' AND active=1 AND instance='alarm_1'; //in alarm specified that is active - if(strlen(name_escaped) == 0 || strlen(instance_escaped) == 0) - { - err_msg << "log_thread::write_db(): ERROR some mandatory values setting non-active alarm are empty: name=" << - name_escaped << " instance=" << instance_escaped << ends; - break; - } - query_str << - "UPDATE " << m_dbname << "." << DESC_TABLE_NAME << - " SET " << DESC_COL_ACTIVE << "=" << ALARM_REMOVED << - " WHERE " << DESC_COL_NAME << "='" << name_escaped << "'" << - " AND " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - ends; - break; - case TYPE_LOG_DESC_REM: - //example: - //DELETE FROM description - // WHERE name='al/al/al/al' AND active=1 AND instance='alarm_1'; //in alarm specified that is active - if(strlen(name_escaped) == 0 || strlen(instance_escaped) == 0) - { - err_msg << "log_thread::write_db(): ERROR some mandatory values removing alarm are empty: name=" << - name_escaped << " instance=" << instance_escaped<< ends; - break; - } - query_str << - "DELETE FROM " << m_dbname << "." << DESC_TABLE_NAME << - " WHERE " << DESC_COL_NAME << "='" << name_escaped << "'" << - " AND " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - ends; - break; - case TYPE_LOG_DESC_SYNC: - //example: - //UPDATE description - // SET active=0 - // WHERE name='al/al/al/al' //disable this alarm - // AND active=1 //if it is active and - // AND instance='alarm_1' //for this alarm instance and - // AND (formula!='(ev/ev/ev/ev > 1)' //or formula is changed - // OR time_threashold!=5 //or time_threshold is changed - // OR level!='log' //or level is changed - // OR grp!='gr_none' //or grp is changed - // OR msg!='message'); //or msg is changed - // OR action!='act/act/act/act'); //or action is changed - query_str << - "UPDATE " << m_dbname << "." << DESC_TABLE_NAME << - " SET " << DESC_COL_ACTIVE << "=" << ALARM_REMOVED << - " WHERE " << DESC_COL_NAME << "='" << name_escaped << "'" << - " AND " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - " AND (" << DESC_COL_FORMULA << "!='" << formula_escaped << "'" << - " OR " << DESC_COL_TIME_THRESHOLD << "!='" << a.time_threshold << "'" << - " OR " << DESC_COL_LEVEL << "!='" << level_escaped << "'" << - " OR " << DESC_COL_GRP << "!='" << grp_escaped << "'" << - " OR " << DESC_COL_MSG << "!='" << msg_escaped << "'" << - " OR " << DESC_COL_ACTION << "!='" << action_escaped << "'" << - ")" << - ends; - break; - case TYPE_LOG_DESC_UPD_OLD: - //example: - //UPDATE description - // SET active=0 - // WHERE name!='al1/al1/al1/al1' //disable every alarm not in this list - // AND name !='al2/al2/al2/al2' - // AND name !=... - // AND active=1 //if it is active - // AND instance='alarm_1' - query_str << - "UPDATE " << m_dbname << "." << DESC_TABLE_NAME << - " SET " << DESC_COL_ACTIVE << "=" << ALARM_REMOVED << - " WHERE " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - tmp_names.str() << - ends; - break; - case TYPE_LOG_DESC_UPDATE: - //example: - //UPDATE description - // SET time_sec=1234567890, time_threashold=1, level='log', grp='gr_none', msg='msg' - // WHERE name='al1/al1/al1/al1' // - // AND active=1 // - // AND instance='alarm_1' - query_str << - "UPDATE " << m_dbname << "." << DESC_TABLE_NAME << - " SET " << DESC_COL_TIME_S << "=" << a.time_s << - " , " << DESC_COL_TIME_THRESHOLD << "=" << a.time_threshold << - " , " << DESC_COL_LEVEL << "='" << level_escaped << "'" << - " , " << DESC_COL_GRP << "='" << grp_escaped << "'" << - " , " << DESC_COL_MSG << "='" << msg_escaped << "'" << - " , " << DESC_COL_ACTION << "='" << action_escaped << "'" << - " , " << DESC_COL_SILENT_TIME << "='" << a.silent_time << "'" << - " WHERE " << DESC_COL_NAME << "='" << name_escaped << "'" << - " AND " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - ends; - break; - } - delete [] values_escaped; - delete [] name_escaped; - delete [] formula_escaped; - delete [] grp_escaped; - delete [] msg_escaped; - delete [] level_escaped; - delete [] action_escaped; - delete [] instance_escaped; - if(err_msg.str().size() != 0) - { - cout << err_msg.str(); - return; - } - if(mysql_query(&log_db, query_str.str().c_str())) - { - err_msg << " log_thread::write_db(): ERROR in query=" << query_str.str() << endl; - //cout << err_msg.str(); - //throw err_msg.str(); - } - - if(err_msg.str().size() != 0) - { - cout << gettime().tv_sec << err_msg.str(); - return; - } - int num_rows = mysql_affected_rows(&log_db); -#ifdef _DEBUG_LOG_THREAD - cout << gettime().tv_sec << " log_thread::write_db(): Affected rows=" << num_rows << " in query=" << query_str.str() << endl; -#else - if(((a.type_log == TYPE_LOG_STATUS) || (a.type_log == TYPE_LOG_DESC_DIS)) && (num_rows != 1)) - cout << gettime().tv_sec << " log_thread::write_db(): Error num_rows=" << num_rows << " in query=" << query_str.str() << endl; -#endif -} - -void log_thread::get_alarm_list(vector<string> &al_list) -{ - ostringstream query_str; - ostringstream err_msg; - MYSQL_RES *res; - MYSQL_ROW row; - - char *instance_escaped = new char [2 * m_instance_name.length() + 1]; - mysql_real_escape_string(&log_db, instance_escaped, m_instance_name.c_str(), m_instance_name.length()); -// unsigned int num_fields; -// unsigned int i; - - //example: - //SELECT description - // CONCAT('\t',name,'\t',formula, - // '\t',IFNULL(time_threshold,0),'\t',level, - // '\t',grp,'\t','\"',IFNULL(msg,''),'\"', - // '\t',IFNULL(action,'')) - // FROM alarm.description - // WHERE active=1 - // AND instance='alarm_1' - query_str << - "SELECT" << - " CONCAT('\t', " << DESC_COL_NAME << ",'\t'," << DESC_COL_FORMULA << - ",'\t'," << "IFNULL(" << DESC_COL_TIME_THRESHOLD << ",0)" << ",'\t'," << DESC_COL_LEVEL << - ",'\t'," << "IFNULL(" << DESC_COL_SILENT_TIME << ",-1)" << - ",'\t'," << DESC_COL_GRP << ",'\t','\"'," << "IFNULL(" << DESC_COL_MSG << ",'')" << - ",'\"','\t'," << "IFNULL(" << DESC_COL_ACTION << ",';')" << ")" << - " FROM " << m_dbname << "." << DESC_TABLE_NAME << - " WHERE " << DESC_COL_ACTIVE << "=" << ALARM_ACTIVE << - " AND " << DESC_COL_INSTANCE << "='" << instance_escaped << "'" << - ends; - delete [] instance_escaped; - if(mysql_query(&log_db, query_str.str().c_str())) - { - err_msg << "log_thread::get_alarm_list(): ERROR in query=" << query_str.str() << endl; - //cout << err_msg.str(); - throw err_msg.str(); - } -//#define _DEBUG_LOG_THREAD 1 -#ifdef _DEBUG_LOG_THREAD - else - cout << gettime().tv_sec << " log_thread::get_alarm_list(): Success with query=" << query_str.str() << endl; -#endif //_DEBUG_LOG_THREAD - - res = mysql_use_result(&log_db); - if(res == NULL) - { - if(*mysql_error(&log_db)) - err_msg << "log_thread::get_alarm_list(): ERROR while retrieving result, err=" << mysql_error(&log_db) << endl; - else - err_msg << "log_thread::get_alarm_list(): ERROR while retrieving result" << endl; - //cout << err_msg.str(); - throw err_msg.str(); - } - //num_fields = mysql_num_fields(res); - while ((row = mysql_fetch_row(res))) - { - al_list.push_back(row[0]); - -#ifdef _DEBUG_LOG_THREAD - cout << gettime().tv_sec << " log_thread::get_alarm_list(): Retrieved line: " << row[0] << endl; -#endif //_DEBUG_LOG_THREAD - } - mysql_free_result(res); -} -/* - * alarm_list class methods - */ -void alarm_list::push_back(alm_log_t& a) -{ - this->lock(); - try{ - l_alarm.push_back(a); - empty.signal(); - } - catch(omni_thread_fatal& ex) - { - ostringstream err; - err << "omni_thread_fatal exception signaling omni_condition, err=" << ex.error << ends; - //WARN_STREAM << "alarm_list::push_back(): " << err.str() << endl; - printf("alarm_list::push_back(): %s", err.str().c_str()); - } - catch(Tango::DevFailed& ex) - { - ostringstream err; - err << "exception signaling omni_condition: '" << ex.errors[0].desc << "'" << ends; - //WARN_STREAM << "alarm_list::push_back(): " << err.str() << endl; - printf("alarm_list::push_back: %s", err.str().c_str()); - Tango::Except::print_exception(ex); - } - catch(...) - { - //WARN_STREAM << "alarm_list::push_back(): catched unknown exception!!" << endl; - printf("alarm_list::push_back(): catched unknown exception signaling omni_condition!!"); - } - this->unlock(); -} - -const alm_log_t alarm_list::pop_front(void) -{ - this->lock(); - //omni_mutex_lock l((omni_mutex)this); //call automatically unlock on destructor and on exception - try{ - while (l_alarm.empty() == true) - empty.wait(); //wait release mutex while is waiting, then reacquire when signaled - } - catch(omni_thread_fatal& ex) - { - ostringstream err; - err << "omni_thread_fatal exception waiting on omni_condition, err=" << ex.error << ends; - //WARN_STREAM << "alarm_list::pop_front(): " << err.str() << endl; - printf("alarm_list::pop_front(): %s", err.str().c_str()); - alm_log_t a; - this->unlock(); - sleep(1); - return(a); - } - catch(Tango::DevFailed& ex) - { - ostringstream err; - err << "exception waiting on omni_condition: '" << ex.errors[0].desc << "'" << ends; - //WARN_STREAM << "alarm_list::pop_front(): " << err.str() << endl; - printf("alarm_list::pop_front: %s", err.str().c_str()); - Tango::Except::print_exception(ex); - alm_log_t a; - this->unlock(); - sleep(1); - return(a); - } - catch(...) - { - //WARN_STREAM << "alarm_list::pop_front(): catched unknown exception!!" << endl; - printf("alarm_list::pop_front(): catched unknown exception waiting on omni_condition!!"); - alm_log_t a; - this->unlock(); - sleep(1); - return(a); - } - /*const*/ alm_log_t a; - - a = *(l_alarm.begin()); - l_alarm.pop_front(); - - this->unlock(); - return(a); -} - -void alarm_list::clear(void) -{ - //this->lock(); - l_alarm.clear(); - //this->unlock(); -} - -list<alm_log_t> alarm_list::show(void) -{ - list<alm_log_t> al; - - this->lock(); - al = l_alarm; - this->unlock(); - return(al); -} diff --git a/src/log_thread.h b/src/log_thread.h deleted file mode 100644 index 17ab49278206a107ed805a75667cccecea00c4c5..0000000000000000000000000000000000000000 --- a/src/log_thread.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * log_thread.h - * - * $Author: graziano $ - * - * $Revision: 1.4 $ - * - * $Log: log_thread.h,v $ - * - * - * copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale - * Strada Statale 14 - km 163,5 in AREA Science Park - * 34012 Basovizza, Trieste ITALY - */ - -#ifndef LOG_THREAD_H -#define LOG_THREAD_H - -#include <omnithread.h> -#include <tango.h> -#include <Alarm.h> -#include <mysql.h> - -#define LOG_THREAD_EXIT "log_thread_exit" -#define LOG_THREAD_EXIT_TIME 1 - -//############# DB ############ -//#define LOG_DB_NAME "alarm" -//######## ALARM_DESC ######## -#define DESC_TABLE_NAME "description" -#define DESC_COL_ID "id_description" -#define DESC_COL_NAME "name" -#define DESC_COL_INSTANCE "instance" -#define DESC_COL_ACTIVE "active" -#define DESC_COL_TIME_S "time_sec" -#define DESC_COL_FORMULA "formula" -#define DESC_COL_SILENT_TIME "silent_time" -#define DESC_COL_TIME_THRESHOLD "time_threshold" -#define DESC_COL_LEVEL "level" -#define DESC_COL_GRP "grp" -#define DESC_COL_MSG "msg" -#define DESC_COL_ACTION "action" -//######## ALARM_STATUS ####### -#define STAT_TABLE_NAME "alarms" -#define STAT_COL_ID "id_alarms" -#define STAT_COL_TIME_S "time_sec" -#define STAT_COL_TIME_U "time_usec" -#define STAT_COL_STATUS "status" -#define STAT_COL_ACK "ack" -#define STAT_COL_DESC_ID DESC_COL_ID -#define STAT_COL_VALUES "attr_values" - - -#define TYPE_LOG_STATUS 1 -#define TYPE_LOG_DESC_ADD 2 -#define TYPE_LOG_DESC_DIS 3 -#define TYPE_LOG_DESC_REM 4 -#define TYPE_LOG_DESC_SYNC 5 -#define TYPE_LOG_DESC_UPD_OLD 6 -#define TYPE_LOG_DESC_UPDATE 7 - -#define ALARM_ACTIVE 1 -#define ALARM_REMOVED 0 - - -typedef struct { - unsigned int type_log; - unsigned int time_s; - unsigned int time_us; - unsigned int time_threshold; - int silent_time; - string name; - string status; - string ack; - string level; - string grp; - string msg; - string formula; - string action; - string values; - vector<string> alm_list; -} alm_log_t; - -/* - * here Alarm insert data to log, log_thread process data - * and store in db - */ -class alarm_list : public omni_mutex { - public: - alarm_list(void): full(this), empty(this) {} - ~alarm_list(void) {} - void push_back(alm_log_t& a); - const alm_log_t pop_front(void); - void clear(void); - list<alm_log_t> show(void); - protected: - list<alm_log_t> l_alarm; - private: - omni_condition full, - empty; -}; - - -class log_thread : public omni_thread/*, public Tango::LogAdapter*/ -{ - public: - log_thread(string dbhost, string dbuser, string dbpw, string dbname, int dbport, string instance_name/*, Alarm_ns::Alarm *p*/); - ~log_thread(); - - void log_alarm_db(alm_log_t& a); - void get_alarm_list(vector<string> &al_list); - - protected: - void run(void *); - private: - //Alarm_ns::Alarm *p_Alarm; - MYSQL log_db; - - alarm_list al_list; - - string m_dbhost; - string m_dbuser; - string m_dbpw; - string m_dbname; - int m_dbport; - string m_instance_name; - - void write_db(alm_log_t& a); -}; - -#endif /* LOG_THREAD_H */ - -/* EOF */