#include "ShmClientInfo.h" #include "Logger.h" #include "ProcessConfig.h" #include "ReportLog.h" #include // 2018-02-22 CHG huibong FHS Disk busy »óȲ½Ã report ·Î±ëÀ» À§ÇÑ ±âÁذª #define REPORT_MAX_DISK_QUEUE 10 // disk queue °ªÀÌ ÇØ´ç Á¤ÀÇ °ª ÀÌ»óÀÎ °æ¿ì #define REPORT_MAX_DISK_BUSY 90.0 // disk busy °ªÀÌ ÇØ´ç Á¤ÀÇ °ª ÀÌ»óÀÎ °æ¿ì // »ý¼ºÀÚ CShmClientInfo::CShmClientInfo( struct ClientInfo * p ) : m_pClient( p ) { // ¼­ºñ½º »óÅ code ¿¡ ´ëÇÑ ¹®ÀÚ¿­ Á¤º¸¸¦ ÀúÀåÇϱâ À§ÇÑ ¸â¹ö º¯¼ö ¼³Á¤. // - may °´Ã¼À̹ǷÎ.. key - value Çü½ÄÀ¸·Î ÀúÀå ó¸® m_mapServiceStatString[SERVICE_STAT_NOT_DEFINE] = "Not Define"; m_mapServiceStatString[SERVICE_STAT_OK] = "OK"; m_mapServiceStatString[SERVICE_STAT_OUT] = "Out"; m_mapServiceStatString[SERVICE_STAT_DISABLE] = "Disable"; m_mapServiceStatString[SERVICE_STAT_RONLY] = "Read-only"; // NEW 2018-01-11 huibong ¸Þ¸ð¸® »ç¿ë·® Ãʰú½Ã report ±â´É Ãß°¡ (#31360, #31679) // check ¿©ºÎ ÆÇ´ÜÀ» À§ÇÑ º¯¼ö ÃʱâÈ­ if( CProcessConfig::GetInstance()->GetReportMemoryMaxUsage() > 0 ) m_bReportMemoryMaxUsage = true; else m_bReportMemoryMaxUsage = false; m_iShmSystemUpdateCount = 0; } // ¼Ò¸êÀÚ CShmClientInfo::~CShmClientInfo() { } // Service »óÅ Á¤º¸¿¡ ´ëÇÑ ¹®ÀÚ¿­ ¹Ýȯ. const char * CShmClientInfo::GetServiceStatString( const int & stat ) { std::map< int, std::string >::iterator pos; pos = m_mapServiceStatString.find( stat ); if( pos != m_mapServiceStatString.end() ) { // ÇØ´ç Ç׸ñ Á¸Àç½Ã return pos->second.c_str(); } else { // ÇØ´ç Ç׸ñÀÌ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì. return m_mapServiceStatString[SERVICE_STAT_NOT_DEFINE].c_str(); } } // ÇöÀç Service »óÅ Á¤º¸¿¡ ´ëÇÑ ¹®ÀÚ¿­ ¹Ýȯ. const char * CShmClientInfo::GetServiceStatString() { std::map< int, std::string >::iterator pos; pos = m_mapServiceStatString.find( m_pClient->service.service_stat); if( pos != m_mapServiceStatString.end() ) { // ÇØ´ç Ç׸ñ Á¸Àç½Ã return pos->second.c_str(); } else { // ÇØ´ç Ç׸ñÀÌ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì. return m_mapServiceStatString[SERVICE_STAT_NOT_DEFINE].c_str(); } } // °øÀ¯ ¸Þ¸ð¸® »óŰ¡ À¯È¿ÇÏÁö ¿©ºÎ ÆÇ´Ü. bool CShmClientInfo::IsValid( const char * pClientAddress ) const { if( m_pClient == NULL ) return false; else { // ÇØ´ç °øÀ¯¸Þ¸ð¸®°¡ ¹Ì»ç¿ë ÁßÀ¸·Î ¸¶Å·µÈ °æ¿ì... if( m_pClient->use == 0 ) return false; // ÇØ´ç °øÀ¯¸Þ¸ð¸®ÀÇ client IP °¡ ¼­·Î ´Ù¸¥ °æ¿ì... if( strcmp( pClientAddress, m_pClient->client_ip ) != 0 ) return false; } return true; } // serviceinfo Á¤º¸¸¦ °øÀ¯¸Þ¸ð¸®¿¡ ÀúÀå ó¸®. // return false : °øÀ¯¸Þ¸ð¸®°¡ À¯È¿ÇÏÁö ¾ÊÀº °æ¿ì... bool CShmClientInfo::UpdateServiceInfo( std::string & strHostname, int iServiceStat ) { // °øÀ¯¸Þ¸ð¸®°¡ À¯È¿ÇÏÁö ¾ÊÀº °æ¿ì.. if( m_pClient == NULL || m_pClient->use == 0 ) return false; int iPreviousServiceStat = 0; // ÇöÀç ½Ã°£ Á¤º¸ ÃßÃâ. time_t currentTime = time( 0 ); struct timespec currentClock; memset( ¤tClock, 0x00, sizeof( struct timespec ) ); clock_gettime( CLOCK_MONOTONIC, ¤tClock ); // Á¤º¸ ¼³Á¤. if( m_pClient->valid == 1 ) { // hostname Á¤º¸ ¼³Á¤. // - ±âÁ¸ °ª°ú ºñ±³ÇÏ¿© º¯°æµÈ °æ¿ì.. °ü·Ã ³»¿ª ·Î±ë. if( strcmp( m_pClient->hostname, strHostname.c_str() ) != 0 ) { LOG( LWAR, "client [%s] hostname changed [%s] -> [%s].", m_pClient->client_ip, m_pClient->hostname, strHostname.c_str() ); // hostname Á¤º¸ º¹»ç strncpy( m_pClient->hostname, strHostname.c_str(), HOST_NAME_LENGTH ); } // ÀÌÀü ¼­ºñ½º »óÅ Á¤º¸ ÀúÀå iPreviousServiceStat = m_pClient->service.service_stat; // ¼­ºñ½º »óÅ Á¤º¸ º¯°æ ¿©ºÎ °ü·Ã ³»¿ª ·Î±ë if( iPreviousServiceStat != iServiceStat ) { _LOG( LINF, "client[%s] hostname[%s] service stat changed. [%s] -> [%s]." , m_pClient->client_ip, m_pClient->hostname, GetServiceStatString( iPreviousServiceStat ), GetServiceStatString( iServiceStat ) ); // ¼­ºñ½º »óÅ Á¤º¸ ¾÷µ¥ÀÌÆ® m_pClient->service.service_stat = iServiceStat; } // update ½Ã°£ ¼³Á¤ m_pClient->service.update_time = currentTime; m_pClient->service.update_time_clock_sec = currentClock.tv_sec; // apllication Á¤º¸ ¼³Á¤. m_pClient->client_app = 0; // 2018-02-22 NEW huibong (#31703) // - ¿î¿µ ÆíÀǼºÀ» À§ÇØ ´ÙÀ½ »óȲÀ» report ·Î±ë ó¸®ÇÑ´Ù. // - 1. ¼­ºñ½º »óŰ¡ OK , Read only »óÅ¿¡¼­ Disable, OUT »óȲÀ¸·Î º¯°æµÇ´Â °æ¿ì // - 2. ¼­ºñ½º »óŰ¡ ºñÁ¤»ó »óȲ(disable, out) »óȲ¿¡¼­ Á¤»ó( ok, read only) »óȲÀ¸·Î º¯°æµÇ´Â °æ¿ì // ¼­ºñ½º »óŰ¡ º¯°æµÈ °æ¿ì - ´ëºÎºÐ »óÅ º¯°æÀº Àß ÀϾÁö ¾ÊÀ¸¹Ç·Î.. ºü¸¥ ·ÎÁ÷ °Ë»ç¸¦ À§ÇØ ºÒÇÊ¿äÇØµµ ³Ö¾î µÒ if( iPreviousServiceStat != iServiceStat ) { // ÇöÀç »óŰ¡ ºñÁ¤»ó »óȲÀÎ °æ¿ì if( iServiceStat == SERVICE_STAT_OUT || iServiceStat == SERVICE_STAT_DISABLE ) { // ÀÌÀü »óȲÀº Á¤»óÀÎ °æ¿ì if( iPreviousServiceStat != SERVICE_STAT_OUT && iPreviousServiceStat != SERVICE_STAT_DISABLE ) { // report ·Î±ë °´Ã¼ »ý¼º CReportLog reportLog; std::string strErrorMessage; strErrorMessage.clear(); if( reportLog.Init( CProcessConfig::GetInstance()->GetLogPath() ) == false ) { reportLog.GetLastError( strErrorMessage ); LOG( LERR, "client[%s] service stat change log init failed.[%s]", strHostname.c_str(), strErrorMessage.c_str() ); } else { reportLog.Write( "WAR", "[%s] [ %s, service stat changed. %s -> %s. check FHS status.]" , PROG_NAME, strHostname.c_str() , GetServiceStatString( iPreviousServiceStat ), GetServiceStatString( iServiceStat ) ); } } } else { // ÇöÀç »óŰ¡ OK, Read only ÀÇ Á¤»ó »óȲÀÎ °æ¿ì // ÀÌÀü »óŰ¡ ºñÁ¤»ó »óȲÀÎ °æ¿ì if( iPreviousServiceStat == SERVICE_STAT_OUT || iPreviousServiceStat == SERVICE_STAT_DISABLE ) { // report ·Î±ë °´Ã¼ »ý¼º CReportLog reportLog; std::string strErrorMessage; strErrorMessage.clear(); if( reportLog.Init( CProcessConfig::GetInstance()->GetLogPath() ) == false ) { reportLog.GetLastError( strErrorMessage ); LOG( LERR, "client[%s] service stat change log init failed.[%s]", strHostname.c_str(), strErrorMessage.c_str() ); } else { reportLog.Write( "INF", "[%s] [ %s, service stat changed. %s -> %s. ]" , PROG_NAME, strHostname.c_str() , GetServiceStatString( iPreviousServiceStat ), GetServiceStatString( iServiceStat ) ); } } } } } else { // hostname Á¤º¸ ¼³Á¤. strncpy( m_pClient->hostname, strHostname.c_str(), HOST_NAME_LENGTH ); // ¼­ºñ½º »óÅ Á¤º¸ ¼³Á¤. m_pClient->service.service_stat = iServiceStat; // update ½Ã°£ ¼³Á¤ m_pClient->service.update_time = currentTime; m_pClient->service.update_time_clock_sec = currentClock.tv_sec; // apllication Á¤º¸ ¼³Á¤. m_pClient->client_app = 0; // Data À¯È¿ ¿©ºÎ ¼³Á¤. m_pClient->valid = 1; } return true; } // systeminfo Á¤º¸¸¦ °øÀ¯¸Þ¸ð¸®¿¡ ÀúÀå ó¸®. // return false : °øÀ¯¸Þ¸ð¸®°¡ À¯È¿ÇÏÁö ¾Ê°Å³ª... valid °¡ À¯È¿ÇÏÁö ¾Ê°Å³ª.. hostname ÀÌ µ¿ÀÏÇÏÁö ¾ÊÀº °æ¿ì. bool CShmClientInfo::UpdateSystemInfo( std::string & strHostname, struct SystemInfo * pData ) { // °øÀ¯¸Þ¸ð¸®°¡ À¯È¿ÇÏÁö ¾ÊÀº °æ¿ì.. if( m_pClient == NULL || m_pClient->use == 0 ) return false; // ÇöÀç ½Ã°£ Á¤º¸ ÃßÃâ. time_t currentTime = time( 0 ); // valid ¼³Á¤°ªÀÌ À¯È¿ÇÏÁö ¾ÊÀº °æ¿ì.. // - service info Á¤º¸°¡ ¸ÕÀú ±â·ÏµÇÁö ¾ÊÀº »óÅÂÀÎ °æ¿ì.... // - Á¤º¸¸¦ ±â·ÏÇÏÁö ¾Ê´Â´Ù. if( m_pClient->valid == 0 ) { LOG( LWAR, "client [%s] hostname[%s] info not valid. [%d].", m_pClient->client_ip, m_pClient->hostname, m_pClient->valid ); return false; } // hostname Á¤º¸°¡ µ¿ÀÏÇÑÁö °Ë»ç. if( strcmp( m_pClient->hostname, strHostname.c_str() ) != 0 ) { LOG( LWAR, "client [%s] hostname[%s] not match. [%s].", m_pClient->client_ip, m_pClient->hostname, strHostname.c_str() ); return false; } // Á¤º¸°¡ µ¿ÀÏÇÑ °æ¿ì.... copy ó¸® memcpy( &(m_pClient->system), pData, sizeof( struct SystemInfo ) ); m_pClient->system.update_time = currentTime; // 2018-02-22 CHG huibong (#31703) // - 2018-01-12 #31544, #31679 ¿¡ ÀÇÇØ Ãß°¡µÈ ´ÙÀ½ ±â´É Á¦°Å // -- FHS Disk hang ¶Ç´Â ÀÌ»ó »óȲÀ¸·Î disk busy ºñÁ¤»ó Áõ°¡½Ã ÀÚµ¿ FHS out ó¸® // - »çÀ¯ // -- Disk Hang ÀÌ ¾Æ´Ñ »óȲ¿¡¼­µµ ±âÁذª(queue 10 & busy 90%)À» ÃʰúÇÏ´Â Disk Busy »óȲ ¹ß»ýÀ¸·Î À߸øµÈ ¼­ºñ½º OUT ¹ß»ý °¡´É // - ±âŸ // -- Disk busy »óȲ½Ã Report ·Î±ë ó¸® ±â´ÉÀº À¯Áö // -- Disk busy ÆÇ´Ü ±âÁذªÀº ±×´ë·Î À¯Áö queue 10, busy 90% // -- Âü°í·Î FHS ´Â queue 7, busy 50% ÀÌ»óÀÎ °æ¿ì ÀÚµ¿À¸·Î read only ·Î º¯°æ ó¸®µÊ // --- FHS ¿Í °°Àº ±âÁذªÀ» »ç¿ëÇÏÁö ¾ÊÀº ÀÌÀ¯´Â FHS ±âÁذªÀº ¼ø°£ÀûÀÎ ÀÀ´äÁö¿¬À» ¸·±â À§ÇÑ ÃÖ¼ÒÇÑÀÇ ±âÁذªÀ̱⠶§¹®. // ÇöÀç »óŰ¡ out, disable »óŰ¡ ¾Æ´Ñ Á¤»ó »óȲÀÎ °æ¿ì if( m_pClient->service.service_stat != SERVICE_STAT_OUT && m_pClient->service.service_stat != SERVICE_STAT_DISABLE ) { // system »óŰ¡ Á¤º¸°¡ disk busy »óȲÀÎ °æ¿ì if( pData->disk_max_queue >= REPORT_MAX_DISK_QUEUE && pData->disk_max_busy >= REPORT_MAX_DISK_BUSY ) { // report ·Î±ë °´Ã¼ »ý¼º CReportLog reportLog; std::string strErrorMessage; strErrorMessage.clear(); if( reportLog.Init( CProcessConfig::GetInstance()->GetLogPath() ) == false ) { reportLog.GetLastError( strErrorMessage ); LOG( LERR, "client[%s] disk busy report log init failed.[%s]", strHostname.c_str(), strErrorMessage.c_str() ); } else { reportLog.Write( "WAR", "[%s] [ %s, disk busy too high. busy %4.1lf%% , queue %ju. check FHS status.]" , PROG_NAME, strHostname.c_str(), pData->disk_max_busy, pData->disk_max_queue ); _LOG( LWAR, "client[%s] disk busy[%4.1lf %%] too high. queue[%ju]. report logging." , strHostname.c_str(), pData->disk_max_busy, pData->disk_max_queue ); } } } // NEW 2018-01-11 huibong ¸Þ¸ð¸® »ç¿ë·® Ãʰú½Ã report ±â´É Ãß°¡ (#31360, #31679) // - FHS memory »ç¿ë·®ÀÌ ÁöÁ¤µÈ °ª ÀÌ»óÀÎ °æ¿ì report ·Î±ë ó¸® // - FHS system Á¤º¸°¡ 10 sec ¸¶´Ù Àü¼ÛµÇ¹Ç·Î.. ÀæÀº ·Î±ë ¹ß»ý °¡´É // - µû¶ó¼­ ºÐ´ç 1ȸ¸¸ check Çϵµ·Ï ÇÑ´Ù (ÃÖÃÊ ¿äûÀº ±âµ¿½Ã ÃʱâÈ­ À̽´ ÀÖÀ¸¹Ç·Î.. ¹ö¸®°í.. 3¹øÂ° ¿äûºÎÅÍ Ã¼Å©) if( m_bReportMemoryMaxUsage == true && m_iShmSystemUpdateCount % 6 == 2) { // FHS memory »ç¿ë·üÀÌ conf ¼³Á¤°ª ÀÌ»óÀÎ °æ¿ì. if( pData->memory_usage >= CProcessConfig::GetInstance()->GetReportMemoryMaxUsage() ) { CReportLog reportLog; std::string strErrorMessage; strErrorMessage.clear(); if( reportLog.Init( CProcessConfig::GetInstance()->GetLogPath() ) == false ) { reportLog.GetLastError( strErrorMessage ); LOG( LERR, "client[%s] memory usage report log init failed.[%s]", strHostname.c_str(), strErrorMessage.c_str() ); } else { reportLog.Write( "WAR", "[%s] [FHS (%s) memory usage too high = %d%%. total=%ju byte. free=%ju byte. check FHS status.]" , PROG_NAME, strHostname.c_str(), pData->memory_usage, pData->memory_total, pData->memory_free ); _LOG( LWAR, "client[%s] memory usage[%d %%] too high. total[%ju] free[%ju]. report logging." , strHostname.c_str(), pData->memory_usage, pData->memory_total, pData->memory_free ); } } } // system °ü·Ã shared memory update count Áõ°¡ ó¸® // - 10 sec ¸¶´Ù ¾÷µ¥ÀÌÆ® µÇ¹Ç·Î.. ÀÏ ´ÜÀ§ count reset m_iShmSystemUpdateCount++; if( m_iShmSystemUpdateCount > 8640 ) m_iShmSystemUpdateCount = 0; return true; }