123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- // datalogger.h :
- //
- #if !defined(AGD_DATALOGGER_H__21BAEB7B_E478_4ED1_B9F6_FDBCE620C55B__INCLUDED_)
- #define AGD_DATALOGGER_H__21BAEB7B_E478_4ED1_B9F6_FDBCE620C55B__INCLUDED_
- #include <limits.h>
- #include <vector>
- #include <pthread.h>
- #ifndef _LIBBUILD
- #include <gfa/svc/common/mysqlwrap.h>
- #include <gfa/svc/common/logfile.h>
- #else // _LIBBUILD
- #include "common/mysqlwrap.h"
- #include "common/logfile.h"
- #endif // _LIBBUILD
- /////////////////////////////////////////////////////////////////////////////
- // datalogger.h - Declarations:
- #define _DL_DATABASE_ENGINE_INNODB 1
- #define _DL_DATABASE_ENGINE_MYISAM 2
- /////////////////////////////////////////////////////////////////////////////
- #define _DL_USE_NEW_TABLES_LAYOUT 1
- #define _DL_DATABSE_ENGINE _DL_DATABASE_ENGINE_INNODB
- /////////////////////////////////////////////////////////////////////////////
- #if _DL_DATABSE_ENGINE == _DL_DATABASE_ENGINE_INNODB
- #define _DL_DATABSE_ENGINE_NAME "InnoDB"
- #define _DL_MAX_VARPATH_LENGTH 767
- #elif _DL_DATABSE_ENGINE == _DL_DATABASE_ENGINE_MYISAM
- #define _DL_DATABSE_ENGINE_NAME "MyISAM"
- #define _DL_MAX_VARPATH_LENGTH 1000
- #else // _DL_DATABSE_ENGINE
- #error Invalid database engine!
- #endif // _DL_DATABSE_ENGINE
- /////////////////////////////////////////////////////////////////////////////
- #define _DL_NANOSECS_PER_SEC 1000000000
- #define _DL_MAX_DB_NAME_LENGTH 64
- #define _DL_MAX_DB_USER_LENGTH 64
- #define _DL_MAX_DB_PASS_LENGTH 64
- #define _DL_MAX_TABLE_NAME_LENGTH 64
- #define _SECONDS_PER_DAY 86400
- #define _MIDNIGHT_TIMESTAMP_UTC(t) ((t) / _SECONDS_PER_DAY * _SECONDS_PER_DAY)
- typedef enum _LogTypes
- {
- LT_NoLog,
- LT_IntervalConditional,
- LT_IntervalUnconditional,
- LT_ValueChangeConditional,
- LT_ValueChangeUnconditional,
- LT_IntervalConditionalRem,
- LT_IntervalUnconditionalRem,
- LT_ValueChangeConditionalRem,
- LT_ValueChangeUnconditionalRem
- }LogTypes, *LPLogTypes;
- #define _IS_VALID_LOGTYPE(lt) (((lt) > LT_NoLog) && ((lt) <= LT_ValueChangeUnconditionalRem))
- #define _IS_VALUE_CHANGE_LOGTYPE(lt) (((lt) == LT_ValueChangeConditional) || ((lt) == LT_ValueChangeUnconditional) || ((lt) == LT_ValueChangeConditionalRem) || ((lt) == LT_ValueChangeUnconditionalRem))
- #define _IS_INTERVAL_LOGTYPE(lt) (((lt) == LT_IntervalConditional) || ((lt) == LT_IntervalUnconditional) || ((lt) == LT_IntervalConditionalRem) || ((lt) == LT_IntervalUnconditionalRem))
- #define _IS_CONDITIONAL_LOGTYPE(lt) (((lt) == LT_ValueChangeConditional) || ((lt) == LT_IntervalConditional) || ((lt) == LT_ValueChangeConditionalRem) || ((lt) == LT_IntervalConditionalRem))
- #define _IS_UNCONDITIONAL_LOGTYPE(lt) (((lt) == LT_IntervalUnconditional) || ((lt) == LT_ValueChangeUnconditional) || ((lt) == LT_IntervalUnconditionalRem) || ((lt) == LT_ValueChangeUnconditionalRem))
- #define _IS_DB_PERSISTENT_LOGTYPE(lt) (((lt) >= LT_IntervalConditionalRem) && ((lt) <= LT_ValueChangeUnconditionalRem))
- typedef struct _DLPARAMS
- {
- char szDBName[_DL_MAX_DB_NAME_LENGTH];
- char szDBUser[_DL_MAX_DB_USER_LENGTH];
- char szDBPass[_DL_MAX_DB_PASS_LENGTH];
- char szTagsTable[_DL_MAX_TABLE_NAME_LENGTH];
- char szLogsTable[_DL_MAX_TABLE_NAME_LENGTH];
- char szLogsTableBD[_DL_MAX_TABLE_NAME_LENGTH]; // bad date logs table
- const char *pszBaseDir;
- unsigned int nIntvSample; // sample interval
- unsigned int nIntvLog; // log interval
- unsigned int nIntvFlush; // flush interval
- unsigned int nMaxAge; // Max age of Logs entries in days
- unsigned long long nMaxSize; // max. Logs table size in Byte
- bool bMinMax; // log min max values as well?
- }DLPARAMS, *LPDLPARAMS;
- typedef const DLPARAMS *LPCDLPARAMS;
- typedef struct _DL_LOG_ENTRY
- {
- unsigned long nTagID;
- time_t nTimestamp;
- double fValue;
- double fMin;
- double fMax;
- int nIndex;
- LogTypes lt;
- bool bNull;
- }DL_LOG_ENTRY, *LPDL_LOG_ENTRY;
- typedef const DL_LOG_ENTRY *LPCDL_LOG_ENTRY;
- typedef struct _MYSQL_GLOBAL_VARS
- {
- bool bLogsTblIsInnoDB;
- bool bInnoDbFilePerTable;
- bool bInnoDbIsBarracuda;
- bool bInnoDbIsStrictMode;
- char szInnoDbFileFormat[64];
- char szDataDir[PATH_MAX];
- }MYSQL_GLOBAL_VARS, *LPMYSQL_GLOBAL_VARS;
- typedef const MYSQL_GLOBAL_VARS *LPCMYSQL_GLOBAL_VARS;
- /////////////////////////////////////////////////////////////////////////////
- class CDataLogger
- {
- public:
- CDataLogger(LPCDLPARAMS pdlp, CLogfile &rlf);
- virtual ~CDataLogger(void);
-
- bool InitDatabase(bool bEnforceCreate = false);
- void Release(void);
- unsigned long GetTagID(const char *pszVarPath, int nDataType, int nLogType);
- bool Log(unsigned long nTagID, double fValue, double fMin, double fMax, time_t nTimestamp, int nIndex, LogTypes lt, bool bNull = false, bool bNoBadDateCheck = false);
- bool Flush(time_t nTimestamp);
- bool TableFileExists(const char *pszTableName);
- int64_t TableFileSize(const char *pszTableName);
- void SizeGuardTrigger(time_t ts);
- time_t LastLogTimestamp(void){
- return m_nLastLogTimestamp;}
- bool SizeGuardDayWorkDone(time_t ts){
- return m_nSGLastPassUTC == (unsigned long long)_MIDNIGHT_TIMESTAMP_UTC(ts);}
- bool Lock(void){
- return !::pthread_mutex_lock(&m_mtx);}
- bool TryLock(void){
- return !::pthread_mutex_trylock(&m_mtx);}
- bool Unlock(void){
- return !::pthread_mutex_unlock(&m_mtx);}
- private:
- bool CreateDatabase(CMySqlDB &rdb, bool bEnforceCreate = false);
- bool CreateTagsTable(CMySqlDB &rdb);
- bool AlterTagsTable(CMySqlDB &rdb);
- bool CreateLogsTable(CMySqlDB &rdb);
- bool CreateLogsBDTable(CMySqlDB &rdb);
- bool CheckTable(CMySqlDB &rdb, const char *pszTableName, bool &bExists, bool &bUseResortTable, bool &bIsInnoDB);
- // bool QueryTableSizes(CMySqlDB &rdb, const char *pszTableName);
- bool DoSizeGuard(void);
- bool ReadGlobalOptions(CMySqlDB &rdb);
- bool QueryServerVariable(CMySqlDB &rdb, const char *pszVarname, CMySqlVar &val);
- // bool QueryStatusVariable(CMySqlDB &rdb, const char *pszVarname, CMySqlVar &val);
- static void* SizeGuardWorker(void* pParam);
- unsigned long long SizeGuardLastPassRead(void);
- void SizeGuardLastPassWrite(unsigned long long ts);
- static size_t Timestamp2String(time_t t, char *pszBuffer, size_t nCbBuffer);
- static const char* Ns2String(unsigned long long nNs, char *pszBuffer, size_t nCbBuffer);
- static const char* Ms2String(double fMs, char *pszBuffer, size_t nCbBuffer);
- time_t GetLastLogTimestamp(CMySqlDB &rdb);
-
- private:
- CLogfile &m_lf;
- DLPARAMS m_dlp;
- MYSQL_GLOBAL_VARS m_gv;
- char m_szAppDir[PATH_MAX];
- std::vector<DL_LOG_ENTRY> m_logs;
- std::vector<DL_LOG_ENTRY> m_logsBD;
- pthread_t m_tidSGThread;
- bool m_bSGHasSizeLimitPrerequisites;
- bool m_bSGInProgress;
- bool m_bSGConfigured;
- unsigned long long m_nSGCurPassUTC;
- unsigned long long m_nSGLastPassUTC;
- pthread_mutex_t m_mtx;
- pthread_mutexattr_t m_mutexAttr;
- pthread_mutex_t m_condmtx1;
- pthread_cond_t m_cond1;
- time_t m_nLastLogTimestamp;
- bool m_bBadDateLogsDetected;
- };
- /////////////////////////////////////////////////////////////////////////////
- class CDataLoggerClock
- {
- public:
- CDataLoggerClock(unsigned long long nSampleTimeNs);
- virtual ~CDataLoggerClock(void);
- static unsigned long long GetNanoTick(struct timespec *pts = NULL);
- inline static unsigned long long GetMicroTick(struct timespec *pts = NULL){
- return GetNanoTick(pts) / 1000;}
- inline static unsigned long long GetMilliTick(struct timespec *pts = NULL){
- return GetNanoTick(pts) / 1000000;}
- inline static unsigned long long Timespec2NanoSec(const struct timespec *pts){
- return (unsigned long long)pts->tv_sec * _DL_NANOSECS_PER_SEC + (unsigned long long)pts-> tv_nsec;}
- inline static void NanoSec2Timespec(unsigned long long n, struct timespec *pts){
- if(pts){
- pts->tv_sec = n / _DL_NANOSECS_PER_SEC;
- pts->tv_nsec = n % _DL_NANOSECS_PER_SEC;
- }}
- inline static long long CompareTimespec(const struct timespec *pts1, const struct timespec *pts2){
- unsigned long long n1 = Timespec2NanoSec(pts1);
- unsigned long long n2 = Timespec2NanoSec(pts2);
- return (long long)(n1 - n2);}
- bool Sleep(bool &bTimerUnderrun, bool fAvoidCatchUpRaceOnTimerUnderrun);
- private:
- inline unsigned long long IncTime(struct timespec *pts, long long ns) const {
- unsigned long long n = Timespec2NanoSec(pts);
- n += ns;
- NanoSec2Timespec(n, pts);
- return n;}
- private:
- struct timespec m_tsDueTime;
- bool m_fSleepStarted;
- const long long m_nSampleTimeNs;
- };
- /////////////////////////////////////////////////////////////////////////////
- #endif // !defined(AGD_DATALOGGER_H__21BAEB7B_E478_4ED1_B9F6_FDBCE620C55B__INCLUDED_)
|