Commit 95ad1973 authored by Claes Sjofors's avatar Claes Sjofors

Sev stat table added, and event log first commit

parent 1d727d1f
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#if defined PWRE_CONF_MYSQL #if defined PWRE_CONF_MYSQL
#include <math.h>
#include "pwr.h" #include "pwr.h"
#include "co_cdh.h" #include "co_cdh.h"
...@@ -56,6 +57,7 @@ ...@@ -56,6 +57,7 @@
#include "rt_errh.h" #include "rt_errh.h"
#include "pwr_baseclasses.h" #include "pwr_baseclasses.h"
#define sev_cStatInterval 10
#define sev_cGarbageInterval 120 #define sev_cGarbageInterval 120
#define sev_cGarbageCycle 86400 #define sev_cGarbageCycle 86400
...@@ -403,27 +405,54 @@ int sev_server::delete_item( qcom_sQid tgt, sev_sMsgHistItemDelete *rmsg) ...@@ -403,27 +405,54 @@ int sev_server::delete_item( qcom_sQid tgt, sev_sMsgHistItemDelete *rmsg)
int sev_server::mainloop() int sev_server::mainloop()
{ {
qcom_sQid qid; qcom_sQid qid;
int tmo = 1000; int tmo = 200;
qcom_sGet get; qcom_sGet get;
void *mp; void *mp;
pwr_tStatus sts; pwr_tStatus sts;
pwr_tTime next_garco, currenttime; pwr_tTime next_garco, currenttime;
pwr_tTime next_stat;
pwr_tDeltaTime stat_interval;
pwr_tDeltaTime garco_interval; pwr_tDeltaTime garco_interval;
pwr_tTime before_get;
pwr_tDeltaTime busy = pwr_cNDeltaTime;
pwr_tDeltaTime idle = pwr_cNDeltaTime;
pwr_tDeltaTime dt;
float a = exp(-((float)sev_cStatInterval)/300);
qid.nid = 0; qid.nid = 0;
qid.qix = sev_eProcSevServer; qid.qix = sev_eProcSevServer;
time_FloatToD( &garco_interval, sev_cGarbageInterval); time_FloatToD( &garco_interval, sev_cGarbageInterval);
time_FloatToD( &stat_interval, sev_cStatInterval);
time_GetTime( &currenttime); time_GetTime( &currenttime);
time_Aadd( &next_garco, &currenttime, &garco_interval); time_Aadd( &next_garco, &currenttime, &garco_interval);
time_Aadd( &next_stat, &currenttime, &stat_interval);
m_server_status = PWR__SRUN; m_server_status = PWR__SRUN;
for (;;) { for (;;) {
memset( &get, 0, sizeof(get)); memset( &get, 0, sizeof(get));
time_GetTime( &before_get);
time_Adiff( &dt, &before_get, &currenttime);
time_Dadd( &busy, &busy, &dt);
mp = qcom_Get(&sts, &qid, &get, tmo); mp = qcom_Get(&sts, &qid, &get, tmo);
time_GetTime( &currenttime); time_GetTime( &currenttime);
time_Adiff( &dt, &currenttime, &before_get);
time_Dadd( &idle, &idle, &dt);
if ( time_Acomp( &currenttime, &next_stat) == 1) {
m_stat.current_load = 100.0 * time_DToFloat(0, &busy)/(time_DToFloat(0, &busy)+time_DToFloat(0, &idle));
if ( m_stat.medium_load == 0)
m_stat.medium_load = m_stat.current_load;
else
m_stat.medium_load = a * m_stat.medium_load + (1.0-a) * m_stat.current_load;
m_db->store_stat( &m_stat);
time_Aadd( &next_stat, &next_stat, &stat_interval);
busy = pwr_cNDeltaTime;
idle = pwr_cNDeltaTime;
}
if ( time_Acomp( &currenttime, &next_garco) == 1) { if ( time_Acomp( &currenttime, &next_garco) == 1) {
garbage_collector(); garbage_collector();
time_Aadd( &next_garco, &next_garco, &garco_interval); time_Aadd( &next_garco, &next_garco, &garco_interval);
...@@ -441,12 +470,15 @@ int sev_server::mainloop() ...@@ -441,12 +470,15 @@ int sev_server::mainloop()
case sev_eMsgType_HistItems: case sev_eMsgType_HistItems:
errh_Info("Itemlist received %s", cdh_NodeIdToString( 0, get.reply.nid, 0, 0)); errh_Info("Itemlist received %s", cdh_NodeIdToString( 0, get.reply.nid, 0, 0));
check_histitems( (sev_sMsgHistItems *) mp, get.size); check_histitems( (sev_sMsgHistItems *) mp, get.size);
m_stat.items_msg_cnt++;
break; break;
case sev_eMsgType_HistDataStore: case sev_eMsgType_HistDataStore:
receive_histdata( (sev_sMsgHistDataStore *) mp, get.size); receive_histdata( (sev_sMsgHistDataStore *) mp, get.size);
m_stat.datastore_msg_cnt++;
break; break;
case sev_eMsgType_HistDataGetRequest: case sev_eMsgType_HistDataGetRequest:
send_histdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size); send_histdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size);
m_stat.dataget_msg_cnt++;
break; break;
case sev_eMsgType_HistItemsRequest: case sev_eMsgType_HistItemsRequest:
send_itemlist( get.reply); send_itemlist( get.reply);
...@@ -459,6 +491,12 @@ int sev_server::mainloop() ...@@ -459,6 +491,12 @@ int sev_server::mainloop()
break; break;
case sev_eMsgType_HistObjectDataGetRequest: case sev_eMsgType_HistObjectDataGetRequest:
send_objecthistdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size); send_objecthistdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size);
m_stat.dataget_msg_cnt++;
break;
case sev_eMsgType_EventsStore:
printf( "sev_server Events received\n");
receive_events( (sev_sMsgEventsStore *) mp, get.size);
m_stat.eventstore_msg_cnt++;
break; break;
default: ; default: ;
} }
...@@ -501,6 +539,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size) ...@@ -501,6 +539,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
} }
for ( int i = 0; i < item_cnt; i++) { for ( int i = 0; i < item_cnt; i++) {
if ( msg->Items[i].attrnum > 0) {
// Deadband requires id variable // Deadband requires id variable
if ( msg->Items[i].options & pwr_mSevOptionsMask_UseDeadBand) if ( msg->Items[i].options & pwr_mSevOptionsMask_UseDeadBand)
...@@ -512,7 +551,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size) ...@@ -512,7 +551,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
if(msg->Items[i].attrnum > 1) { if(msg->Items[i].attrnum > 1) {
//printf( "Received: %s.%s AttrNum:%d\n", msg->Items[i].oname, msg->Items[i].attr[0].aname, msg->Items[i].attrnum); //printf( "Received: %s.%s AttrNum:%d\n", msg->Items[i].oname, msg->Items[i].attr[0].aname, msg->Items[i].attrnum);
sev_sHistItem *buffP = &msg->Items[i]; sev_sHistItem *buffP = &msg->Items[i];
while(buffP < &msg->Items[item_cnt]) { while( (char *)buffP < (char *)msg + size) {
//for(size_t j = 0; j < buffP->attrnum; j++) { //for(size_t j = 0; j < buffP->attrnum; j++) {
// printf( "Received: %s.%s\n", buffP->oname, buffP->attr[j].aname); // printf( "Received: %s.%s\n", buffP->oname, buffP->attr[j].aname);
//} //}
...@@ -523,8 +562,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size) ...@@ -523,8 +562,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
strcpy( tmpStr, buffP->oname); strcpy( tmpStr, buffP->oname);
//Point out attribute name //Point out attribute name
s = strchr( tmpStr, '.'); s = strchr( tmpStr, '.');
if (s) if (s) {
{
*s = 0; *s = 0;
strcpy( attributeName, s+1); strcpy( attributeName, s+1);
} }
...@@ -608,8 +646,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size) ...@@ -608,8 +646,7 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
//so that databaseadministrator knows which columns he can delete //so that databaseadministrator knows which columns he can delete
//If something was wrong during checking of attributes we ignore this object //If something was wrong during checking of attributes we ignore this object
if ( ODD(m_sts) ) if ( ODD(m_sts) ) {
{
//Create space for the old values used if we have deadband active //Create space for the old values used if we have deadband active
if( m_db->m_items[idx].old_value != 0 ) { if( m_db->m_items[idx].old_value != 0 ) {
free(m_db->m_items[idx].old_value); free(m_db->m_items[idx].old_value);
...@@ -670,6 +707,22 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size) ...@@ -670,6 +707,22 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
rp->idx = idx; rp->idx = idx;
} }
} }
else {
// SevHistEvents item
printf( "Event item received\n");
if ( !m_db->check_item( &m_sts, msg->Items[i].oid, msg->Items[i].oname, (char *)"Events",
storagetime, (pwr_eType)0, 0,
msg->Items[i].description, (char *)"", msg->Items[i].scantime,
0, msg->Items[i].options, &idx)) {
m_db->add_item( &m_sts, msg->Items[i].oid, msg->Items[i].oname, (char *)"Events",
storagetime, (pwr_eType)0, 0,
msg->Items[i].description, (char *)"", msg->Items[i].scantime,
0, msg->Items[i].options, &idx);
if ( EVEN(m_sts)) return m_sts;
}
}
}
printf( "---- Node up (%d) ----\n", nid); printf( "---- Node up (%d) ----\n", nid);
return 1; return 1;
} }
...@@ -824,6 +877,47 @@ int sev_server::send_objecthistdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest * ...@@ -824,6 +877,47 @@ int sev_server::send_objecthistdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *
return 1; return 1;
} }
int sev_server::receive_events( sev_sMsgEventsStore *msg, unsigned int size)
{
sev_sEvent *ep = (sev_sEvent *)&msg->Events[0];
// Get index
int idx;
int found = 0;
for ( unsigned int i = 0; i < m_db->m_items.size(); i++) {
if ( m_db->m_items[i].deleted)
continue;
if ( cdh_ObjidIsEqual( m_db->m_items[i].oid, msg->Oid)) {
idx = i;
found = 1;
break;
}
}
if ( !found) {
errh_Error( "Unknown event table, objid (%d,%d)", msg->Oid.vid, msg->Oid.oix);
return 1;
}
for ( unsigned int i = 0; i < msg->NumEvents; i++) {
sev_event ev;
printf( "Event Type %d Id %d text \"%s\"\n", ep->type, ep->eventid_idx, ep->eventtext);
ev.type = ep->type;
ev.eventprio = ep->eventprio;
ev.eventid.Nix = ep->eventid_nix;
ev.eventid.BirthTime.tv_sec = ep->eventid_birthtime;
ev.eventid.BirthTime.tv_nsec = 0;
ev.eventid.Idx = ep->eventid_idx;
ev.time = net_NetTimeToTime( &ep->time);
strcpy( ev.eventtext, ep->eventtext);
strcpy( ev.eventname, ep->eventname);
m_db->store_event( &m_sts, idx, &ev);
ep++;
}
return 1;
}
void sev_server::garbage_collector() void sev_server::garbage_collector()
{ {
int item_size = m_db->m_items.size(); int item_size = m_db->m_items.size();
......
...@@ -72,9 +72,9 @@ class sev_server { ...@@ -72,9 +72,9 @@ class sev_server {
public: public:
//TODO should this really be in this file? //TODO should this really be in this file?
static const unsigned int constSevVersion = 2; static const unsigned int constSevVersion = 3;
sev_server() : m_server_status(0), m_refid(0), m_msg_id(0) {} sev_server() : m_server_status(0), m_refid(0), m_msg_id(0) {memset(&m_stat,0,sizeof(m_stat));}
pwr_tStatus m_sts; pwr_tStatus m_sts;
pwr_tStatus m_server_status; pwr_tStatus m_server_status;
...@@ -83,6 +83,7 @@ class sev_server { ...@@ -83,6 +83,7 @@ class sev_server {
unsigned int m_msg_id; unsigned int m_msg_id;
sev_db *m_db; sev_db *m_db;
int m_noneth; int m_noneth;
sev_sStat m_stat;
int init( int noneth); int init( int noneth);
int connect(); int connect();
...@@ -95,6 +96,7 @@ class sev_server { ...@@ -95,6 +96,7 @@ class sev_server {
int send_itemlist( qcom_sQid tgt); int send_itemlist( qcom_sQid tgt);
int send_server_status( qcom_sQid tgt); int send_server_status( qcom_sQid tgt);
int delete_item( qcom_sQid tgt, sev_sMsgHistItemDelete *rmsg); int delete_item( qcom_sQid tgt, sev_sMsgHistItemDelete *rmsg);
int receive_events( sev_sMsgEventsStore *msg, unsigned int size);
void garbage_collector(); void garbage_collector();
void garbage_item( int idx); void garbage_item( int idx);
}; };
......
...@@ -41,9 +41,19 @@ ...@@ -41,9 +41,19 @@
#include "pwr.h" #include "pwr.h"
#include "pwr_class.h" #include "pwr_class.h"
#include "rt_mh_net.h"
using namespace std; using namespace std;
typedef struct {
float current_load;
float medium_load;
unsigned int datastore_msg_cnt;
unsigned int dataget_msg_cnt;
unsigned int items_msg_cnt;
unsigned int eventstore_msg_cnt;
} sev_sStat;
class sev_attr { class sev_attr {
public: public:
pwr_tOName aname; pwr_tOName aname;
...@@ -53,6 +63,16 @@ class sev_attr { ...@@ -53,6 +63,16 @@ class sev_attr {
pwr_tString16 unit; pwr_tString16 unit;
}; };
class sev_event {
public:
unsigned int type;
unsigned int eventprio;
mh_sEventId eventid;
pwr_tTime time;
char eventtext[80];
char eventname[80];
};
class sev_item { class sev_item {
public: public:
sev_item() : deadband_active(0), last_id(0), value_size(0), old_value(0), first_storage(1), status(0), logged_status(0), sev_item() : deadband_active(0), last_id(0), value_size(0), old_value(0), first_storage(1), status(0), logged_status(0),
...@@ -122,6 +142,7 @@ class sev_db { ...@@ -122,6 +142,7 @@ class sev_db {
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx) { return 0;} pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx) { return 0;}
virtual int store_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname, virtual int store_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime, char *description, pwr_tFloat32 scantime, pwr_tFloat32 deadband, pwr_tMask options) { return 0;} pwr_tDeltaTime storagetime, char *description, pwr_tFloat32 scantime, pwr_tFloat32 deadband, pwr_tMask options) { return 0;}
virtual int store_event( pwr_tStatus *sts, int item_idx, sev_event *ep) { return 0;}
virtual int get_item( pwr_tStatus *sts, sev_item *item, pwr_tOid oid, char *attributename) { return 0;} virtual int get_item( pwr_tStatus *sts, sev_item *item, pwr_tOid oid, char *attributename) { return 0;}
virtual int get_objectitem( pwr_tStatus *sts, sev_item *item, pwr_tOid oid, char *attributename) { return 0;} virtual int get_objectitem( pwr_tStatus *sts, sev_item *item, pwr_tOid oid, char *attributename) { return 0;}
virtual int get_objectitems( pwr_tStatus *sts) { return 0;} virtual int get_objectitems( pwr_tStatus *sts) { return 0;}
...@@ -135,6 +156,7 @@ class sev_db { ...@@ -135,6 +156,7 @@ class sev_db {
virtual int handle_objectchange(pwr_tStatus *sts, char *tablename, unsigned int item_idx, bool newObject) { return 0;} virtual int handle_objectchange(pwr_tStatus *sts, char *tablename, unsigned int item_idx, bool newObject) { return 0;}
virtual int repair_table( pwr_tStatus *sts, char *tablename) { return 0;} virtual int repair_table( pwr_tStatus *sts, char *tablename) { return 0;}
virtual int alter_engine( pwr_tStatus *sts, char *tablename) { return 0;} virtual int alter_engine( pwr_tStatus *sts, char *tablename) { return 0;}
virtual int store_stat( sev_sStat *stat) { return 0;}
}; };
#endif #endif
...@@ -290,6 +290,7 @@ MYSQL *sev_dbms_env::createDb(void) ...@@ -290,6 +290,7 @@ MYSQL *sev_dbms_env::createDb(void)
if (rc) printf( "Create items table: %s\n", mysql_error(m_con)); if (rc) printf( "Create items table: %s\n", mysql_error(m_con));
createSevVersion2Tables(); createSevVersion2Tables();
createSevVersion3Tables();
return con; return con;
} }
...@@ -330,6 +331,10 @@ int sev_dbms_env::checkAndUpdateVersion(unsigned int version) ...@@ -330,6 +331,10 @@ int sev_dbms_env::checkAndUpdateVersion(unsigned int version)
printf("Updating database tables to sev version 2\n"); printf("Updating database tables to sev version 2\n");
updateDBToSevVersion2(); updateDBToSevVersion2();
} }
if (old_version < 3) {
printf("Updating database tables to sev version 3\n");
createSevVersion3Tables();
}
if(old_version != version) { if(old_version != version) {
char query[100]; char query[100];
...@@ -464,6 +469,24 @@ int sev_dbms_env::createSevVersion2Tables(void) ...@@ -464,6 +469,24 @@ int sev_dbms_env::createSevVersion2Tables(void)
return 1; return 1;
} }
int sev_dbms_env::createSevVersion3Tables(void)
{
char query[400];
sprintf( query, "create table sev_stat (current_load float,medium_load float,datastore_msg_cnt int unsigned,dataget_msg_cnt int unsigned,items_msg_cnt int unsigned,eventstore_msg_cnt int unsigned);");
int rc = mysql_query( m_con, query);
if (rc) {
printf("In %s row %d:\n", __FILE__, __LINE__);
printf( "Create sev_stat table: %s\n", mysql_error(m_con));
}
sprintf( query, "insert into sev_stat (current_load, medium_load) values(0,0)");
rc = mysql_query( m_con, query);
if (rc) {
printf("In %s row %d:\n", __FILE__, __LINE__);
printf( "Insert into table sev_stat: %s\n", mysql_error(m_con));
}
return 1;
}
MYSQL *sev_dbms_env::openDb() MYSQL *sev_dbms_env::openDb()
{ {
...@@ -719,6 +742,83 @@ int sev_dbms::delete_table( pwr_tStatus *sts, char *tablename) ...@@ -719,6 +742,83 @@ int sev_dbms::delete_table( pwr_tStatus *sts, char *tablename)
return 1; return 1;
} }
int sev_dbms::create_event_table( pwr_tStatus *sts, char *tablename, pwr_tMask options)
{
char query[400];
char timeformatstr[80];
char jumpstr[80];
char idtypestr[20];
char readoptstr[80];
char engine[80];
char enginestr[100] = "";
if ( cnf_get_value( "sevMysqlEngine", engine, sizeof(engine)) != 0)
snprintf( enginestr, sizeof(enginestr), " engine=%s", engine);
if ( options & pwr_mSevOptionsMask_PosixTime) {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
strcpy( timeformatstr, "time int unsigned, ntime int unsigned");
strcpy( idtypestr, "bigint");
}
else {
// Posix time, low resolution
strcpy( timeformatstr, "time int unsigned");
strcpy( idtypestr, "int");
}
}
else {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
strcpy( timeformatstr, "time datetime not null, ntime int unsigned");
strcpy( idtypestr, "bigint");
}
else {
// Sql time, low resolution
strcpy( timeformatstr, "time datetime not null");
strcpy( idtypestr, "int");
}
}
if ( options & pwr_mSevOptionsMask_ReadOptimized)
sprintf( readoptstr, "id %s unsigned not null primary key auto_increment,", idtypestr);
else
strcpy( readoptstr, "");
strcpy( jumpstr, "");
sprintf( query, "create table %s ( %s"
"%s, eventtype int, eventprio int, eventid_nix int, eventid_birthtime int, eventid_idx int,"
"eventtext varchar(80), eventname varchar(80), index (time))%s;",
tablename, readoptstr, timeformatstr, enginestr);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf("In %s row %d:\n", __FILE__, __LINE__);
printf( "Create table: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
return 1;
}
int sev_dbms::delete_event_table( pwr_tStatus *sts, char *tablename)
{
char query[200];
sprintf( query, "drop table %s;", tablename);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf("In %s row %d:\n", __FILE__, __LINE__);
printf( "Delete table: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
return 1;
}
int sev_dbms::store_item( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, int sev_dbms::store_item( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname,
char *aname, pwr_tDeltaTime storagetime, pwr_eType vtype, char *aname, pwr_tDeltaTime storagetime, pwr_eType vtype,
unsigned int vsize, char *description, char *unit, pwr_tFloat32 scantime, unsigned int vsize, char *description, char *unit, pwr_tFloat32 scantime,
...@@ -1663,6 +1763,76 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo ...@@ -1663,6 +1763,76 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
return 1; return 1;
} }
int sev_dbms::store_event( pwr_tStatus *sts, int item_idx, sev_event *ep)
{
char query[400];
char timstr[40];
*sts = time_AtoAscii( &ep->time, time_eFormat_NumDateAndTime, timstr, sizeof(timstr));
if ( EVEN(*sts)) return 0;
timstr[19] = 0;
if ( m_items[item_idx].options & pwr_mSevOptionsMask_PosixTime) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
sprintf( query, "insert into %s (time, ntime, eventtype, eventprio, eventid_nix, eventid_birthtime,"
"eventid_idx, eventtext, eventname) values (%ld,%ld,%d,%d,%d,%d,%d,'%s','%s')",
m_items[item_idx].tablename,
(long int)ep->time.tv_sec, (long int)ep->time.tv_nsec,
ep->type, ep->eventprio, ep->eventid.Nix, ep->eventid.BirthTime.tv_sec, ep->eventid.Idx, ep->eventtext,
ep->eventname);
}
else {
// Posix time, low resolution
sprintf( query, "insert into %s (time, eventtype, eventprio, eventid_nix, eventid_birthtime,"
"eventid_idx, eventtext, eventname) values (%ld,%d,%d,%d,%d,%d,'%s','%s')",
m_items[item_idx].tablename,
(long int)ep->time.tv_sec,
ep->type, ep->eventprio, ep->eventid.Nix, ep->eventid.BirthTime.tv_sec, ep->eventid.Idx, ep->eventtext,
ep->eventname);
}
}
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
sprintf( query, "insert into %s (time, ntime, eventtype, eventprio, eventid_nix, eventid_birthtime,"
"eventid_idx, eventtext, eventname) values ('%s',%ld,%d,%d,%d,%d,%d,'%s','%s')",
m_items[item_idx].tablename,
timstr, (long int)ep->time.tv_sec,
ep->type, ep->eventprio, ep->eventid.Nix, ep->eventid.BirthTime.tv_sec, ep->eventid.Idx, ep->eventtext,
ep->eventname);
}
else {
// Sql time, low resolution
sprintf( query, "insert into %s (time, eventtype, eventprio, eventid_nix, eventid_birthtime,"
"eventid_idx, eventtext, eventname) values ('%s',%d,%d,%d,%d,%d,'%s','%s')",
m_items[item_idx].tablename,
timstr,
ep->type, ep->eventprio, ep->eventid.Nix, ep->eventid.BirthTime.tv_sec, ep->eventid.Idx, ep->eventtext,
ep->eventname);
}
}
int rc = mysql_query( m_env->con(), query);
if (rc) {
// printf( "Store value: %s \"%s\"\n", mysql_error(m_env->con()), query);
*sts = SEV__DBERROR;
m_items[item_idx].status = *sts;
if ( m_items[item_idx].status != m_items[item_idx].logged_status) {
m_items[item_idx].logged_status = m_items[item_idx].status;
errh_Error( "Database store error: %s, table: %s object: %s",
mysql_error(m_env->con()), m_items[item_idx].tablename, m_items[item_idx].oname);
}
return 0;
}
*sts = SEV__SUCCESS;
m_items[item_idx].status = *sts;
m_items[item_idx].logged_status = 1;
return 1;
}
int sev_dbms::check_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname, int sev_dbms::check_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime, pwr_eType type, unsigned int size, pwr_tDeltaTime storagetime, pwr_eType type, unsigned int size,
...@@ -1765,6 +1935,9 @@ int sev_dbms::add_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname ...@@ -1765,6 +1935,9 @@ int sev_dbms::add_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname
scantime, deadband, options); scantime, deadband, options);
if ( EVEN(*sts)) return 0; if ( EVEN(*sts)) return 0;
if ( strcmp( aname, "Events") == 0)
create_event_table( sts, tablename, options);
else
create_table( sts, tablename, type, size, options, deadband); create_table( sts, tablename, type, size, options, deadband);
if ( EVEN(*sts)) return 0; if ( EVEN(*sts)) return 0;
...@@ -2261,8 +2434,7 @@ pwr_tUInt64 sev_dbms::get_nextAutoIncrement( char *tablename ) ...@@ -2261,8 +2434,7 @@ pwr_tUInt64 sev_dbms::get_nextAutoIncrement( char *tablename )
{ {
char query[200]; char query[200];
pwr_tUInt64 retVal = 0; pwr_tUInt64 retVal = 0;
sprintf( query, "SELECT Auto_increment FROM information_schema.tables WHERE table_name='%s'", tablename); sprintf( query, "SELECT Auto_increment FROM information_schema.tables WHERE table_name='%s' && table_schema='%s'", tablename, m_env->dbName());
//printf( "%s: %s\n", __FUNCTION__ ,query); //printf( "%s: %s\n", __FUNCTION__ ,query);
int rc = mysql_query( m_env->con(), query); int rc = mysql_query( m_env->con(), query);
if (rc) { if (rc) {
...@@ -3553,6 +3725,22 @@ int sev_dbms::alter_engine( pwr_tStatus *sts, char *tablename) ...@@ -3553,6 +3725,22 @@ int sev_dbms::alter_engine( pwr_tStatus *sts, char *tablename)
return 1; return 1;
} }
int sev_dbms::store_stat( sev_sStat *stat)
{
char query[250];
int rc;
sprintf( query, "update sev_stat set current_load = %f,medium_load = %f,datastore_msg_cnt=%d,dataget_msg_cnt=%d,items_msg_cnt=%d,eventstore_msg_cnt=%d",
stat->current_load, stat->medium_load, stat->datastore_msg_cnt, stat->dataget_msg_cnt, stat->items_msg_cnt,
stat->eventstore_msg_cnt);
rc = mysql_query( m_env->con(), query);
if (rc) {
printf("In %s row %d:\n", __FILE__, __LINE__);
printf( "Update sev_stat: %s\n", mysql_error(m_env->con()));
return 0;
}
return 1;
}
sev_dbms::~sev_dbms() sev_dbms::~sev_dbms()
{ {
......
...@@ -74,7 +74,7 @@ class sev_dbms_env ...@@ -74,7 +74,7 @@ class sev_dbms_env
sev_dbms_env(const sev_dbms_env &); sev_dbms_env(const sev_dbms_env &);
void operator = (const sev_dbms_env &); void operator = (const sev_dbms_env &);
virtual ~ sev_dbms_env() { close();} virtual ~sev_dbms_env() { close();}
int create(const char *fileName, const char *host, const char *user, const char *passwd, int create(const char *fileName, const char *host, const char *user, const char *passwd,
const char *dbName, unsigned int port, const char *socket); const char *dbName, unsigned int port, const char *socket);
...@@ -87,6 +87,7 @@ class sev_dbms_env ...@@ -87,6 +87,7 @@ class sev_dbms_env
int checkAndUpdateVersion(unsigned int version); int checkAndUpdateVersion(unsigned int version);
int updateDBToSevVersion2(void); int updateDBToSevVersion2(void);
int createSevVersion2Tables(void); int createSevVersion2Tables(void);
int createSevVersion3Tables(void);
MYSQL *createDb(void); MYSQL *createDb(void);
MYSQL *openDb(void); MYSQL *openDb(void);
bool exists() { return m_exists;} bool exists() { return m_exists;}
...@@ -183,6 +184,9 @@ class sev_dbms : public sev_db { ...@@ -183,6 +184,9 @@ class sev_dbms : public sev_db {
int check_deadband(pwr_eType type, unsigned int size, pwr_tFloat32 deadband, void *value, void *oldvalue); int check_deadband(pwr_eType type, unsigned int size, pwr_tFloat32 deadband, void *value, void *oldvalue);
int get_objectvalues( pwr_tStatus *sts, sev_item *item, unsigned int size, pwr_tTime *starttime, pwr_tTime *endtime, int get_objectvalues( pwr_tStatus *sts, sev_item *item, unsigned int size, pwr_tTime *starttime, pwr_tTime *endtime,
int maxsize, pwr_tTime **tbuf, void **vbuf, unsigned int *bsize); int maxsize, pwr_tTime **tbuf, void **vbuf, unsigned int *bsize);
int delete_event_table( pwr_tStatus *sts, char *tablename);
int create_event_table( pwr_tStatus *sts, char *tablename, pwr_tMask options);
int store_event( pwr_tStatus *sts, int item_idx, sev_event *ep);
pwr_tUInt64 get_minFromIntegerColumn( char *tablename, char *colname ); pwr_tUInt64 get_minFromIntegerColumn( char *tablename, char *colname );
pwr_tUInt64 get_maxFromIntegerColumn( char *tablename, char *colname ); pwr_tUInt64 get_maxFromIntegerColumn( char *tablename, char *colname );
pwr_tUInt64 get_nextAutoIncrement( char *tablename ); pwr_tUInt64 get_nextAutoIncrement( char *tablename );
...@@ -190,6 +194,7 @@ class sev_dbms : public sev_db { ...@@ -190,6 +194,7 @@ class sev_dbms : public sev_db {
int handle_objectchange(pwr_tStatus *sts, char *tablename, unsigned int item_idx, bool newObject); int handle_objectchange(pwr_tStatus *sts, char *tablename, unsigned int item_idx, bool newObject);
int repair_table( pwr_tStatus *sts, char *tablename); int repair_table( pwr_tStatus *sts, char *tablename);
int alter_engine( pwr_tStatus *sts, char *tablename); int alter_engine( pwr_tStatus *sts, char *tablename);
int store_stat( sev_sStat *stat);
inline char* create_colName(unsigned int index, char *attributename) { inline char* create_colName(unsigned int index, char *attributename) {
static char colName[constMaxColNameLength]; static char colName[constMaxColNameLength];
strncpy(colName, attributename, constMaxColNameLength); strncpy(colName, attributename, constMaxColNameLength);
......
This diff is collapsed.
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
#include "pwr.h" #include "pwr.h"
#include "pwr_class.h" #include "pwr_class.h"
#define ev_cInit 0xFFFF
class rt_sevhistmon;
class sev_sevhist { class sev_sevhist {
public: public:
pwr_tAttrRef aref; pwr_tAttrRef aref;
...@@ -62,6 +66,30 @@ class sev_sevhist { ...@@ -62,6 +66,30 @@ class sev_sevhist {
pwr_tBoolean disabled; pwr_tBoolean disabled;
}; };
class sev_sevhistevents {
public:
sev_sevhistevents( rt_sevhistmon *m) : event_thread_idx(0), evbuf_oldest(ev_cInit), evbuf_last(ev_cInit),
evbuf_sent(ev_cInit), monitor(m) {}
pwr_sClass_SevHistEvents *hsp;
pwr_tString80 description;
pwr_tOid hs_oid;
pwr_tRefId hs_refid;
pwr_tDeltaTime storagetime;
pwr_tMask options;
pwr_tBoolean disabled;
unsigned int event_thread_idx;
sev_sEvent event_buffer[20];
unsigned int evbuf_oldest;
unsigned int evbuf_last;
unsigned int evbuf_sent;
rt_sevhistmon *monitor;
pwr_tOName oname;
void evbuf_insert( sev_sEvent *ev);
void evbuf_send();
};
class sev_sevhistobjectattr { class sev_sevhistobjectattr {
public: public:
pwr_tAttrRef aref; pwr_tAttrRef aref;
...@@ -117,11 +145,12 @@ class sev_node { ...@@ -117,11 +145,12 @@ class sev_node {
pwr_tStatus status; pwr_tStatus status;
}; };
class rt_sevhistmon { class rt_sevhistmon {
public: public:
rt_sevhistmon() : m_msg_id(0), m_next_rix(0), m_loopcnt(0), m_allconnected(0), m_server_status(0), rt_sevhistmon() : m_msg_id(0), m_next_rix(0), m_loopcnt(0), m_allconnected(0), m_server_status(0),
m_swap(0) {} m_swap(0), m_sevhistevents(0) {}
pwr_tStatus m_sts; pwr_tStatus m_sts;
vector<sev_sevhistthread> m_hs; vector<sev_sevhistthread> m_hs;
...@@ -131,14 +160,17 @@ class rt_sevhistmon { ...@@ -131,14 +160,17 @@ class rt_sevhistmon {
unsigned int m_loopcnt; unsigned int m_loopcnt;
float m_scantime; float m_scantime;
pwr_sClass_SevHistMonitor *m_confp; pwr_sClass_SevHistMonitor *m_confp;
pwr_tOid m_confoid;
pwr_tRefId m_conf_refid; pwr_tRefId m_conf_refid;
int m_allconnected; int m_allconnected;
pwr_tStatus m_server_status; pwr_tStatus m_server_status;
int m_swap; int m_swap;
sev_sevhistevents *m_sevhistevents;
int init(); int init();
int init_objects(); int init_objects();
int init_sevhistobjects(); int init_sevhistobjects();
int init_events();
void insert_sevhistobjectattr(pwr_sAttrRef *aref, void insert_sevhistobjectattr(pwr_sAttrRef *aref,
pwr_tAName objectname, pwr_tAName objectname,
int hs_idx, int hs_idx,
...@@ -160,5 +192,16 @@ class rt_sevhistmon { ...@@ -160,5 +192,16 @@ class rt_sevhistmon {
void receive_server_status( sev_sMsgServerStatus *msg, pwr_tNid nid); void receive_server_status( sev_sMsgServerStatus *msg, pwr_tNid nid);
int send_itemlist( pwr_tNid nid); int send_itemlist( pwr_tNid nid);
int send_data(); int send_data();
void evbuf_insert( sev_sEvent *ev);
void evbuf_send();
static pwr_tStatus mh_ack_bc( mh_sAck *MsgP);
static pwr_tStatus mh_return_bc( mh_sReturn *MsgP);
static pwr_tStatus mh_alarm_bc( mh_sMessage *MsgP);
static pwr_tStatus mh_block_bc( mh_sBlock *MsgP);
static pwr_tStatus mh_cancel_bc( mh_sReturn *MsgP);
static pwr_tStatus mh_info_bc( mh_sMessage *MsgP);
static pwr_tStatus mh_clear_alarmlist_bc( pwr_tNodeIndex nix);
static pwr_tStatus mh_clear_blocklist_bc( pwr_tNodeIndex nix);
}; };
#endif #endif
...@@ -168,7 +168,8 @@ enum mh_eOutunitType{ ...@@ -168,7 +168,8 @@ enum mh_eOutunitType{
mh_eOutunitType_Terminal = 4, mh_eOutunitType_Terminal = 4,
mh_eOutunitType_Logger = 5, mh_eOutunitType_Logger = 5,
mh_eOutunitType_Post = 6, mh_eOutunitType_Post = 6,
mh_eOutunitType_ = 7 mh_eOutunitType_SevHistEvents = 7,
mh_eOutunitType_ = 8
}; };
enum mh_eSource { enum mh_eSource {
......
...@@ -314,6 +314,11 @@ mh_OutunitConnect ( ...@@ -314,6 +314,11 @@ mh_OutunitConnect (
l.pSelL = (void *)&((pwr_sClass_PostConfig*) p)->EventSelectList[0]; l.pSelL = (void *)&((pwr_sClass_PostConfig*) p)->EventSelectList[0];
l.SelectListIsUpdated = NULL; l.SelectListIsUpdated = NULL;
break; break;
case pwr_cClass_SevHistEvents:
type = mh_eOutunitType_SevHistEvents;
l.pSelL = (void *)&((pwr_sClass_SevHistEvents*) p)->EventSelectList[0];
l.SelectListIsUpdated = NULL;
break;
default: default:
return MH__NOOUTUNIT; return MH__NOOUTUNIT;
break; break;
......
...@@ -61,9 +61,30 @@ typedef enum { ...@@ -61,9 +61,30 @@ typedef enum {
sev_eMsgType_ServerStatusRequest, sev_eMsgType_ServerStatusRequest,
sev_eMsgType_ServerStatus, sev_eMsgType_ServerStatus,
sev_eMsgType_HistObjectDataGetRequest, sev_eMsgType_HistObjectDataGetRequest,
sev_eMsgType_HistObjectDataGet sev_eMsgType_HistObjectDataGet,
sev_eMsgType_EventsStore
} sev_eMsgType; } sev_eMsgType;
typedef enum {
sev_eEventType_Info,
sev_eEventType_Return,
sev_eEventType_Ack,
sev_eEventType_Alarm,
sev_eEventType_Block,
sev_eEventType_Cancel
} sev_eEventType;
typedef struct {
sev_eEventType type;
unsigned int eventprio;
unsigned int eventid_nix;
unsigned int eventid_birthtime;
unsigned int eventid_idx;
net_sTime time;
char eventtext[80];
char eventname[80];
} sev_sEvent;
typedef struct { typedef struct {
pwr_tOName aname; pwr_tOName aname;
pwr_eType type; pwr_eType type;
...@@ -114,6 +135,13 @@ typedef struct { ...@@ -114,6 +135,13 @@ typedef struct {
int Data[1]; int Data[1];
} sev_sMsgHistDataStore; } sev_sMsgHistDataStore;
typedef struct {
sev_eMsgType Type;
pwr_tOid Oid;
unsigned int NumEvents;
sev_sEvent Events[1];
} sev_sMsgEventsStore;
typedef struct { typedef struct {
sev_eMsgType Type; sev_eMsgType Type;
pwr_tOid Oid; pwr_tOid Oid;
......
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2012 SSAB EMEA AB.
!
! This file is part of Proview.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! pwrb_c_sevhistevents.wb_load -- Defines the class SevHistEvents.
!
SObject pwrb:Class
!/**
! @Version 1.0
! @Group Servers,NodeConfiguration
! Configures historical storage of events.
!
! @b See also
! @classlink SevHistMonitor pwrb_sevhistmonitor.html
! @classlink SevHistThread pwrb_sevhistthread.html
! @classlink SevHist pwrb_sevhist.html
! @classlink SevHistObject pwrb_sevhistobject.html
! @classlink SevHistServer pwrb_sevhistserver.html
!*/
Object SevHistEvents $ClassDef 603
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
EndBody
Object RtBody $ObjBodyDef 1
Body SysBody
Attr StructName = "SevHistEvents"
EndBody
!/**
! Optional description.
!*/
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! SelectList specifies the hierarchies from which
! messages are to be sent to the user. Up to 40 different
! hierarchies can be specified. If messages from e.g. a
! Watchdog object in a node will be received, then the
! name of the node will be specified.
!
! Note! If the SelectList is left blank no message at all is
! sent to the user.
!*/
Object EventSelectList $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
Attr Flags |= PWR_MASK_ARRAY
Attr Elements = 40
EndBody
EndObject
!/**
! Specifies type of stored events.
!*/
Object EventTypes $Attribute 3
Body SysBody
Attr TypeRef = "pwrb:Type-EventListMask"
EndBody
EndObject
!/**
! SevHistThread object that specifies the storage scantime
! and in which server the events are stored.
!*/
Object ThreadObject $Attribute 4
Body SysBody
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Time the data will be stored in the database.
! Data that is older than this time will be removed from
! the database by a garbage collector.
!*/
Object StorageTime $Attribute 5
Body SysBody
Attr TypeRef = "pwrs:Type-$DeltaTime"
EndBody
EndObject
!/**
! Storage options.
!*/
Object Options $Attribute 6
Body SysBody
Attr TypeRef = "pwrb:Type-SevHistOptionsMask"
EndBody
EndObject
!/**
! Disable storage.
!*/
Object Disable $Attribute 7
Body SysBody
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
EndObject
Object Template SevHistEvents
Body RtBody
Attr EventTypes = 3
Attr Options = 0
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "SevHistEvents-PostCreate"
EndBody
EndObject
Object ConfiguratorPoson $Menu
Object Pointed $Menu
Object ConnectThread $MenuButton
Body SysBody
Attr ButtonName = "Connect SevHistThread"
Attr MethodName = "$Objid-Connect"
Attr MethodArguments[0] = "ThreadObject"
Attr MethodArguments[1] = "SevHistThread"
Attr FilterName = "$Objid-IsOkConnect"
Attr FilterArguments[0] = "ThreadObject"
Attr FilterArguments[1] = "SevHistThread"
EndBody
EndObject
EndObject
EndObject
EndObject
EndSObject
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment