isearch/comm/monitor.cc
2021-03-19 18:38:34 +08:00

171 lines
4.6 KiB
C++

#include <stdio.h>
#include <sys/types.h>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "monitor.h"
#include "json/json.h"
#include "log.h"
namespace common {
const int statistic_period = 5;
void * ProfilerMonitor::ProcessCycle(void * arg)
{
pthread_mutex_lock(&ProfilerMonitor::GetInstance()._Mutex);
std::vector<InfoItem> temp_result;
int last_append_time = time(NULL);
while (!ProfilerMonitor::GetInstance()._StopFlag) {
if (ProfilerMonitor::GetInstance()._InfoHead == NULL) {
pthread_cond_wait(&ProfilerMonitor::GetInstance()._NotEmpty, &ProfilerMonitor::GetInstance()._Mutex);
continue;
}
InfoItem *head = ProfilerMonitor::GetInstance()._InfoHead;
ProfilerMonitor::GetInstance()._InfoHead = ProfilerMonitor::GetInstance()._InfoTail = NULL;
pthread_mutex_unlock(&ProfilerMonitor::GetInstance()._Mutex);
ProfilerMonitor::GetInstance().Coalesce(head, temp_result);
int now_time = time(NULL);
if (now_time - last_append_time >= statistic_period) {
last_append_time = now_time;
std::stringstream report_info;
for (std::vector<InfoItem>::iterator it = temp_result.begin(); it != temp_result.end(); it++) {
report_info << it->ToProfilerItem() << "\n";
}
temp_result.clear();
ProfilerMonitor::GetInstance()._FileAppender.DoAppend(report_info.str());
}
pthread_mutex_lock(&ProfilerMonitor::GetInstance()._Mutex);
}
return NULL;
}
void ProfilerMonitor::Coalesce(InfoItem * head, std::vector<InfoItem>& temp_result)
{
InfoItem *p = head;
InfoItem *q;
while (p != NULL) {
std::vector<InfoItem>::iterator it = temp_result.begin();
for ( ; it != temp_result.end(); it++) {
if (*it == *p) {
it->_Count++;
break;
}
}
if (temp_result.size() == 0 || it == temp_result.end()) {
temp_result.push_back(*p);
}
q = p;
p = p->_Next;
delete q;
}
}
bool ProfilerMonitor::GetLocalIpAddr(){
char hname[128];
gethostname(hname, sizeof(hname));
struct hostent *host;
host = gethostbyname(hname);
_LocalIpAddr = inet_ntoa(*(struct in_addr*)(host->h_addr_list[0]));
return true;
}
bool ProfilerMonitor::Initialize(){
_InfoHead = _InfoTail = NULL;
_InitialzeSuccess = GetLocalIpAddr() && _FileAppender.Initialize();
return _InitialzeSuccess;
}
CallerInfo ProfilerMonitor::RegisterInfo(const std::string& key) {
CallerInfo caller_info;
if(!_InitialzeSuccess) return caller_info;
struct timeval tv_begin;
gettimeofday(&tv_begin, NULL);
caller_info._Key = key;
caller_info._BeginTimeStamp = tv_begin.tv_sec * 1000 + tv_begin.tv_usec / 1000;
return caller_info;
}
void ProfilerMonitor::RegisterInfoEnd(CallerInfo& call_info) {
if(!_InitialzeSuccess) return ;
struct timeval tv_begin;
gettimeofday(&tv_begin, NULL);
InfoItem *item = new InfoItem();
if (item != NULL) {
uint64_t end_timestamp = tv_begin.tv_sec * 1000 + tv_begin.tv_usec / 1000;
item->_Key = call_info._Key;
item->_ElapsedTime = end_timestamp - call_info._BeginTimeStamp;
item->_ProcessState = "0";
item->_NowTimeStamp = time(NULL) ;
PushReportItem(item);
}
}
void ProfilerMonitor::FunctionError(CallerInfo& call_info) {
if(!_InitialzeSuccess) return ;
InfoItem *item = new InfoItem();
if (item != NULL) {
item->_Key = call_info._Key;
item->_ElapsedTime = -1;
item->_ProcessState = "1";
item->_NowTimeStamp = time(NULL) ;
PushReportItem(item);
}
}
std::string InfoItem::ToProfilerItem(){
Json::Value info;
Json::FastWriter wr;
char now_time[64];
struct tm* p = localtime(&_NowTimeStamp);
strftime(now_time, 64, "%Y%m%d%H%M%S000", p);
info["time"] = now_time;
info["key"] = _Key;
info["hostname"] = ProfilerMonitor::GetInstance().GetIp();
info["processState"] = _ProcessState;
std::stringstream elapse_oss;
elapse_oss << _ElapsedTime;
info["elapsedTime"] = elapse_oss.str();
std::stringstream count_oss;
count_oss << _Count;
info["count"] = count_oss.str();
return wr.write(info);
}
};
#ifdef DEBUG_PROFILER
int main() {
_init_log_("test", "./");
_set_log_level_(7);
log_error("begin test");
common::ProfilerMonitor::GetInstance().Initialize();
log_error("iniialize success");
while (true) {
common::CallerInfo caller_info = common::ProfilerMonitor::GetInstance().RegisterInfo(std::string("userInfoExport"));
sleep(1);
common::ProfilerMonitor::GetInstance().RegisterInfoEnd(caller_info);
}
}
#endif // DDEBUG_PROFILER