#ifdef ENABLE_COUNT_DEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "libuv_dbus.h" #define LOG_SAVE_TIME (1000) typedef struct { long long maxValue; long long minValue; long long avgValue; } STATISTICAL_VALUE, *PSTATISTICAL_VALUE; typedef struct { long long curVaule; long long tolValue; unsigned int tolCount; STATISTICAL_VALUE cVal; } CSTATISTICAL_INFO, *PSTATISTICAL_INFO; typedef struct { char* pMonName; unsigned long nCount; CSTATISTICAL_INFO nCstInfo; uv_rwlock_t rwLock; uv_timer_t logTimer; unsigned int logTime; UT_hash_handle hh; ///< UT Hash handle } MONITOR_INFO, *PMONITOR_INFO; static uv_rwlock_t g_uvMonRwLock; static PMONITOR_INFO g_MonTbl = NULL; static uv_loop_t* g_MonLogLoop = NULL; static void __uvMonLogProc(void *pParams) { RunUVLoop(g_MonLogLoop); while(TRUE) { usleep(1000); } pthread_detach(pthread_self()); } static void __logMonTimerProc(uv_timer_t* pTimer) { PMONITOR_INFO pInfo = (PMONITOR_INFO)pTimer->data; if(pInfo && (pInfo->nCount + pInfo->nCstInfo.tolCount > 0)) { UT_string* pMsg = NULL; utstring_new(pMsg); uv_rwlock_rdlock(&pInfo->rwLock); utstring_printf(pMsg, "%s Statistical Information:\n", pInfo->pMonName); //LOG_EX(LOG_Debug, "%s Statistical Information:\n", pInfo->pMonName); if(pInfo->nCount) { UT_string* pMsgCount = NULL; utstring_new(pMsgCount); utstring_printf(pMsgCount, " Total Count = %lu\n", pInfo->nCount); utstring_concat(pMsg, pMsgCount); utstring_free(pMsgCount); //LOG_EX(LOG_Debug, " Total Count = %u\n", pInfo->nCount); } if(pInfo->nCstInfo.tolCount > 0) { UT_string* pMsgStat = NULL; utstring_new(pMsgStat); utstring_printf(pMsgStat, " Max Value = %lld\n" " Min Value = %lld\n" " Avg Value = %lld\n" " ---- Statistical by total %lld of %u times\n", pInfo->nCstInfo.cVal.maxValue, pInfo->nCstInfo.cVal.minValue, pInfo->nCstInfo.cVal.avgValue, pInfo->nCstInfo.tolValue, pInfo->nCstInfo.tolCount); utstring_concat(pMsg, pMsgStat); utstring_free(pMsgStat); #if 0 LOG_EX(LOG_Debug, " Max Value = %lld\n", pInfo->nCstInfo.cVal.maxValue); LOG_EX(LOG_Debug, " Min Value = %lld\n", pInfo->nCstInfo.cVal.minValue); LOG_EX(LOG_Debug, " Avg Value = %lld\n", pInfo->nCstInfo.cVal.avgValue); LOG_EX(LOG_Debug, " ---- Statistical by total %lld of %u times\n", pInfo->nCstInfo.tolValue, pInfo->nCstInfo.tolCount); #endif } LOG_EX(LOG_Debug, "%s", utstring_body(pMsg)); uv_rwlock_rdunlock(&pInfo->rwLock); utstring_free(pMsg); } } int MonitorInit(void) { uv_thread_t uvMonLogThread; g_MonLogLoop = uv_loop_new(); uv_rwlock_init(&g_uvMonRwLock); uv_thread_create(&uvMonLogThread, __uvMonLogProc, NULL); return 0; } int MonAddNewItem(const char* pName, int logSaveTime) { PMONITOR_INFO pInfo; if(pName == NULL || strlen(pName) == 0) { return -ERR_INPUT_PARAMS; } uv_rwlock_rdlock(&g_uvMonRwLock); HASH_FIND_STR(g_MonTbl, pName, pInfo); uv_rwlock_rdunlock(&g_uvMonRwLock); if(pInfo != NULL) { return -ERR_CFG_ITEM_EXIST; } pInfo = (PMONITOR_INFO)malloc(sizeof(MONITOR_INFO)); if(pInfo == NULL) { return -ERR_MALLOC_MEMORY; } memset(pInfo, 0, sizeof(MONITOR_INFO)); pInfo->nCstInfo.cVal.minValue = INT_MAX; pInfo->logTime = logSaveTime; pInfo->pMonName = strdup(pName); if(pInfo->logTime > 0) { pInfo->logTimer.data = pInfo; uv_timer_init(g_MonLogLoop, &pInfo->logTimer); uv_timer_start(&pInfo->logTimer, __logMonTimerProc, pInfo->logTime, pInfo->logTime); } else { pInfo->logTime = 0; } uv_rwlock_init(&pInfo->rwLock); uv_rwlock_wrlock(&g_uvMonRwLock); HASH_ADD_STR(g_MonTbl, pMonName, pInfo); uv_rwlock_wrunlock(&g_uvMonRwLock); return 0; } int MonIncreaseCount(const char* pName) { PMONITOR_INFO pInfo; if(pName == NULL || strlen(pName) == 0) { return -ERR_INPUT_PARAMS; } uv_rwlock_rdlock(&g_uvMonRwLock); HASH_FIND_STR(g_MonTbl, pName, pInfo); uv_rwlock_rdunlock(&g_uvMonRwLock); if(pInfo == NULL) { return -ERR_CFG_NOITEM; } uv_rwlock_wrlock(&pInfo->rwLock); pInfo->nCount++; uv_rwlock_wrunlock(&pInfo->rwLock); return 0; } int MonDiffStatistical(const char* pName, long long newVal) { PMONITOR_INFO pInfo; if(pName == NULL || strlen(pName) == 0) { return -ERR_INPUT_PARAMS; } uv_rwlock_rdlock(&g_uvMonRwLock); HASH_FIND_STR(g_MonTbl, pName, pInfo); uv_rwlock_rdunlock(&g_uvMonRwLock); if(pInfo == NULL) { return -ERR_CFG_NOITEM; } uv_rwlock_wrlock(&pInfo->rwLock); if(pInfo->nCstInfo.curVaule != 0) { long long diffValue = newVal - pInfo->nCstInfo.curVaule; pInfo->nCstInfo.tolValue += diffValue; pInfo->nCstInfo.tolCount++; if(pInfo->nCstInfo.tolCount > 10) { pInfo->nCstInfo.cVal.avgValue = pInfo->nCstInfo.tolValue / pInfo->nCstInfo.tolCount; if(pInfo->nCstInfo.cVal.maxValue < diffValue) { pInfo->nCstInfo.cVal.maxValue = diffValue; } if(pInfo->nCstInfo.cVal.minValue > diffValue) { pInfo->nCstInfo.cVal.minValue = diffValue; } } } pInfo->nCstInfo.curVaule = newVal; uv_rwlock_wrunlock(&pInfo->rwLock); //fprintf(stdout, "%s value %lld diffValue %lld\n", pName, newVal, diffValue); return 0; } int MonUpgradeStatistical(const char* pName, long newVal) { PMONITOR_INFO pInfo; if(pName == NULL || strlen(pName) == 0) { return -ERR_INPUT_PARAMS; } uv_rwlock_rdlock(&g_uvMonRwLock); HASH_FIND_STR(g_MonTbl, pName, pInfo); uv_rwlock_rdunlock(&g_uvMonRwLock); if(pInfo == NULL) { return -ERR_CFG_NOITEM; } uv_rwlock_wrlock(&pInfo->rwLock); pInfo->nCstInfo.curVaule = newVal; pInfo->nCstInfo.tolValue += newVal; pInfo->nCstInfo.tolCount++; pInfo->nCstInfo.cVal.avgValue = pInfo->nCstInfo.tolValue / pInfo->nCstInfo.tolCount; if(pInfo->nCstInfo.cVal.maxValue < newVal) { pInfo->nCstInfo.cVal.maxValue = newVal; } if(pInfo->nCstInfo.cVal.minValue > newVal) { pInfo->nCstInfo.cVal.minValue = newVal; } uv_rwlock_wrunlock(&pInfo->rwLock); //fprintf(stdout, "%s value %ld\n", pName, newVal); return 0; } int MonItemLogout(const char* pName) { PMONITOR_INFO pInfo; if(pName == NULL || strlen(pName) == 0) { return -ERR_INPUT_PARAMS; } uv_rwlock_rdlock(&g_uvMonRwLock); HASH_FIND_STR(g_MonTbl, pName, pInfo); uv_rwlock_rdunlock(&g_uvMonRwLock); if(pInfo == NULL) { return -ERR_CFG_NOITEM; } if(pInfo->nCount + pInfo->nCstInfo.tolCount == 0) { LOG_EX(LOG_Debug, "%s Statistical Unchanged\n", pInfo->pMonName); return 0; } uv_rwlock_rdlock(&pInfo->rwLock); LOG_EX(LOG_Debug, "%s Statistical Information:\n", pInfo->pMonName); if(pInfo->nCount) { LOG_EX(LOG_Debug, " Total Count = %u\n", pInfo->nCount); } if(pInfo->nCstInfo.tolCount > 0) { LOG_EX(LOG_Debug, " Max Value = %lld\n", pInfo->nCstInfo.cVal.maxValue); LOG_EX(LOG_Debug, " Min Value = %lld\n", pInfo->nCstInfo.cVal.minValue); LOG_EX(LOG_Debug, " Avg Value = %lld\n", pInfo->nCstInfo.cVal.avgValue); LOG_EX(LOG_Debug, " ---- Statistical by total %lld of %u times\n", pInfo->nCstInfo.tolValue, pInfo->nCstInfo.tolCount); } uv_rwlock_rdunlock(&pInfo->rwLock); return 0; } #endif