void CHttpServer::http_handle_postdata(struct evhttp_request *req, void *arg) { CHttpServer *pthis = (CHttpServer *)arg; // 请求是用POST发送的,下面的evhttp_request_uri和evhttp_parse_query函数 // 不能正确解析uri中的参数,Libevent库的BUG! char *decode_uri; struct evkeyvalq params; decode_uri = strdup((char *)evhttp_request_uri(req)); evhttp_parse_query(decode_uri, ¶ms); free(decode_uri); // POST int buffer_data_len; buffer_data_len = EVBUFFER_LENGTH(req->input_buffer); //char *post_data; if (buffer_data_len) { char *buffer_data = (char *) malloc(buffer_data_len + 1); memset(buffer_data, '\0', buffer_data_len + 1); memcpy(buffer_data, EVBUFFER_DATA(req->input_buffer), buffer_data_len); //post_data = (char *) EVBUFFER_DATA(req->input_buffer); //printf("------------------------start---------------------------------------------\n"); //printf("%s\n", buffer_data); //printf("------------------------end-----------------------------------------------\n"); //if(NULL == buffer_data) //return; http_reponse(req, ¶ms, 200, "OK"); // 转发给云评估系统 size_t stat_code; char *uri = g_confvalue.url_path; stat_code = httpPostAsyn(uri, buffer_data, strlen(buffer_data)+1, NULL); //logrun("http trans response code:[%d]", stat_code); // 缓存数据等待重发 if (stat_code != 200) { //200:OK #ifdef DEBUG printf("forward datas fail, datas to buffer.\n"); //pthread_mutex_lock(&pthis->m_mutex); logbuf("%s", buffer_data); //pthread_mutex_unlock(&pthis->m_mutex); #else logrun("forward datas fail, datas to buffer."); //pthread_mutex_lock(&pthis->m_mutex); logbuf("%s", buffer_data); //pthread_mutex_unlock(&pthis->m_mutex); #endif } // 解析收到的json格式的OpenStack数据 parse_openstack_data(arg, req, params, buffer_data); free(buffer_data); } else { logrun("rece post data nothing."); http_reponse(req, ¶ms, 400, "ERROR"); } return; }
bool LogReader::onDataAvailable(SocketClient *cli) { prctl(PR_SET_NAME, "logd.reader"); char buffer[255]; int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1); if (len <= 0) { doSocketDelete(cli); return false; } buffer[len] = '\0'; unsigned long tail = 0; static const char _tail[] = " tail="; char *cp = strstr(buffer, _tail); if (cp) { tail = atol(cp + sizeof(_tail) - 1); } log_time start(log_time::EPOCH); static const char _start[] = " start="; cp = strstr(buffer, _start); if (cp) { // Parse errors will result in current time start.strptime(cp + sizeof(_start) - 1, "%s.%q"); } unsigned int logMask = -1; static const char _logIds[] = " lids="; cp = strstr(buffer, _logIds); if (cp) { logMask = 0; cp += sizeof(_logIds) - 1; while (*cp && *cp != '\0') { int val = 0; while (isdigit(*cp)) { val = val * 10 + *cp - '0'; ++cp; } logMask |= 1 << val; if (*cp != ',') { break; } ++cp; } } pid_t pid = 0; static const char _pid[] = " pid="; cp = strstr(buffer, _pid); if (cp) { pid = atol(cp + sizeof(_pid) - 1); } bool nonBlock = false; if (strncmp(buffer, "dumpAndClose", 12) == 0) { nonBlock = true; } // Convert realtime to monotonic time if (start == log_time::EPOCH) { start = LogTimeEntry::EPOCH; } else { class LogFindStart { const pid_t mPid; const unsigned mLogMask; bool startTimeSet; log_time &start; log_time last; public: LogFindStart(unsigned logMask, pid_t pid, log_time &start) : mPid(pid) , mLogMask(logMask) , startTimeSet(false) , start(start) , last(LogTimeEntry::EPOCH) { } static bool callback(const LogBufferElement *element, void *obj) { LogFindStart *me = reinterpret_cast<LogFindStart *>(obj); if (!me->startTimeSet && (!me->mPid || (me->mPid == element->getPid())) && (me->mLogMask & (1 << element->getLogId()))) { if (me->start == element->getRealTime()) { me->start = element->getMonotonicTime(); me->startTimeSet = true; } else { if (me->start < element->getRealTime()) { me->start = me->last; me->startTimeSet = true; } me->last = element->getMonotonicTime(); } } return false; } bool found() { return startTimeSet; } } logFindStart(logMask, pid, start); logbuf().flushTo(cli, LogTimeEntry::EPOCH, FlushCommand::hasReadLogs(cli), logFindStart.callback, &logFindStart); if (!logFindStart.found()) { if (nonBlock) { doSocketDelete(cli); return false; } log_time now(CLOCK_MONOTONIC); start = now; } } FlushCommand command(*this, nonBlock, tail, logMask, pid, start); command.runSocketCommand(cli); return true; }