commit 0f5c209486269846f3dbeeb55ac0830d40f22827 Author: yzc Date: Mon Dec 30 12:41:28 2019 +0800 http_check diff --git a/conflist_business.inf b/conflist_business.inf new file mode 100644 index 0000000..286b998 --- /dev/null +++ b/conflist_business.inf @@ -0,0 +1 @@ +./plug/business/http_check/http_check.inf diff --git a/http_check/Makefile b/http_check/Makefile new file mode 100644 index 0000000..33e63d9 --- /dev/null +++ b/http_check/Makefile @@ -0,0 +1,7 @@ +all: + gcc -fPIC -shared src/http_check.c -o http_check.so -levent -lcjson +debug: + gcc -g -fPIC -shared src/http_check.c -o http_check.so -levent -lcjson + +clean: + rm *.so *.o -rf diff --git a/http_check/http_check.conf b/http_check/http_check.conf new file mode 100644 index 0000000..036de03 --- /dev/null +++ b/http_check/http_check.conf @@ -0,0 +1,3 @@ +[HTTP] +SERVER_IP=192.168.40.132 +SERVER_PORT=10000 diff --git a/http_check/http_check.inf b/http_check/http_check.inf new file mode 100644 index 0000000..7143d16 --- /dev/null +++ b/http_check/http_check.inf @@ -0,0 +1,5 @@ +[PLUGINFO] +PLUGNAME=HTTP_CHECK +SO_PATH=./plug/business/http_check/http_check.so +INIT_FUNC=http_check_init +DESTROY_FUNC=http_check_destory diff --git a/http_check/src/cJSON.h b/http_check/src/cJSON.h new file mode 100644 index 0000000..2c53562 --- /dev/null +++ b/http_check/src/cJSON.h @@ -0,0 +1,293 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 12 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* Precision of double variables comparison */ +#ifndef CJSON_DOUBLE_PRECISION +#define CJSON_DOUBLE_PRECISION .0000000000000001 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check if the item is a string and return its valuestring */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable adress area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/http_check/src/http_check.c b/http_check/src/http_check.c new file mode 100644 index 0000000..5c24e6a --- /dev/null +++ b/http_check/src/http_check.c @@ -0,0 +1,464 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "cJSON/cJSON.h" +#include "cJSON.h" +#include "MESA/MESA_prof_load.h" +#include "MESA/stream.h" +#include "MESA/MESA_prof_load.h" +#include "MESA/MESA_handle_logger.h" +#include "MESA/MESA_htable.h" +#include "MESA/MESA_list.h" + +#define BUFSIZE 8192 +#define MAX_LOG_PATH_LEN 256 +#define CPU_START_POS 14 /* stat文件的有效起始行数 */ +int g_http_port; +char g_http_address[MAX_LOG_PATH_LEN]=""; +//const char *http_check_conf_file = "./conf/http_check/http_check.conf"; +const char *http_check_conf_file = "/home/mesasoft/sapp/plug/business/http_check/http_check.conf"; + +struct route_info +{ + u_int dstAddr; + u_int srcAddr; + u_int gateWay; + char ifName[IF_NAMESIZE]; +}; + +//************************************cpu占用******************** +// CPU占用率计算: +// 1、读取/proc/pid/stat文件,其中记录了从开机到现在,本进程所占用的CPU时间(单位jiffies) +// 2、然后再读取/proc/stat文件,其中记录了从开机到现在,系统所占用的CPU时间(单位jiffies) +// 3、取两个时间点,这两个时间点的进程耗时差,除以系统耗时差,得到的就是该进程的CPU占用率 + +//在字符串中寻找第N次空格出现的地方 +char *get_items_by_pos(char *buff, unsigned int numb) +{ + char *crpos; + int i, ttlen, count; + + crpos = buff; + ttlen = strlen(buff); + count = 0; + + for (i = 0; i < ttlen; i++) + { + if (' ' == *crpos) + { /* 以空格为标记符进行识别 */ + count++; + if (count == (numb - 1)) + { /* 全部个数都找完了 */ + crpos++; + break; + } + } + crpos++; + } + + return crpos; +} + +//获取当前进程的CPU时间 +long get_pro_cpu_time(unsigned int pid) +{ + FILE *fd; + char *vpos, buff[1024]; + long utime, stime, cutime, cstime; + + sprintf(buff, "/proc/%d/stat", pid); + + fd = fopen(buff, "r"); + assert(fd != NULL); + assert(fgets(buff, sizeof(buff), fd) != NULL); + + vpos = get_items_by_pos(buff, CPU_START_POS); + sscanf(vpos, "%ld %ld %ld %ld", &utime, &stime, &cutime, &cstime); + //printf("get_data2:%ld %ld %ld %ld\n", utime, stime, cutime, cstime); + fclose(fd); + + return (utime + stime + cutime + cstime); + //return (utime + stime); +} + +//获取整个系统的CPU时间 +long get_sys_cpu_time(void) +{ + FILE *fd; + char name[32], buff[1024]; + long user, nice, syst, idle; + + fd = fopen("/proc/stat", "r"); + assert(fd != NULL); + assert(fgets(buff, sizeof(buff), fd) != NULL); + + sscanf(buff, "%s %ld %ld %ld %ld", name, &user, &nice, &syst, &idle); + //printf("get_data1:%s %ld %ld %ld %ld\n", name, user, nice, syst, idle); + fclose(fd); + + return (user + nice + syst + idle); + //return (user + syst); +} + +//获取进程的CPU使用率 +float get_cpu_stat(unsigned int pid) +{ + float ratio; + long s_cur_pro_cpu, s_pre_pro_cpu; /* 指定程序的本轮/前轮CPU时间 */ + long s_cur_sys_cpu, s_pre_sys_cpu; /* 整个系统的本轮/前轮CPU时间 */ + + s_pre_pro_cpu = get_pro_cpu_time(pid); + s_pre_sys_cpu = get_sys_cpu_time(); + + sleep(1); + s_cur_pro_cpu = get_pro_cpu_time(pid); + s_cur_sys_cpu = get_sys_cpu_time(); + if ((s_cur_pro_cpu == s_pre_pro_cpu) || (s_cur_sys_cpu == s_pre_sys_cpu) || (s_cur_pro_cpu == 0) || (s_cur_sys_cpu == 0)) { + ratio = 0; + } else { + ratio = (100.0 * (s_cur_pro_cpu - s_pre_pro_cpu)) / (s_cur_sys_cpu - s_pre_sys_cpu); + } + + return ratio; +} + +//获取默认网关地址 +int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId) +{ + struct nlmsghdr *nlHdr; + int readLen = 0, msgLen = 0; + do{ + //收到内核的应答 + if((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0) + { + perror("SOCK READ: "); + return -1; + } + + nlHdr = (struct nlmsghdr *)bufPtr; + //检查header是否有效 + if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR)) + { + perror("Error in recieved packet"); + return -1; + } + + if(nlHdr->nlmsg_type == NLMSG_DONE) + { + break; + } + else + { + bufPtr += readLen; + msgLen += readLen; + } + + if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0) + { + break; + } + } while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId)); + + return msgLen; +} + +//分析返回的路由信息 +void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo,char *gateway) +{ + struct rtmsg *rtMsg; + struct rtattr *rtAttr; + int rtLen; + char *tempBuf = NULL; + struct in_addr dst; + struct in_addr gate; + + tempBuf = (char *)malloc(100); + rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr); + // If the route is not for AF_INET or does not belong to main routing table + //then return. + if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN)) + return; + + rtAttr = (struct rtattr *)RTM_RTA(rtMsg); + rtLen = RTM_PAYLOAD(nlHdr); + + for(;RTA_OK(rtAttr,rtLen);rtAttr = RTA_NEXT(rtAttr,rtLen)) + { + switch(rtAttr->rta_type) + { + case RTA_OIF: + if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName); + break; + case RTA_GATEWAY: + rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr); + break; + case RTA_PREFSRC: + rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr); + break; + case RTA_DST: + rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr); + break; + } + } + dst.s_addr = rtInfo->dstAddr; + if (strstr((char *)inet_ntoa(dst), "0.0.0.0")) + { + //printf("oif:%s",rtInfo->ifName); + gate.s_addr = rtInfo->gateWay; + sprintf(gateway, (char *)inet_ntoa(gate)); + //printf("%s\n",gateway); + gate.s_addr = rtInfo->srcAddr; + //printf("src:%s\n",(char *)inet_ntoa(gate)); + gate.s_addr = rtInfo->dstAddr; + //printf("dst:%s\n",(char *)inet_ntoa(gate)); + } + free(tempBuf); + + return; +} + +int get_gateway(char *gateway) +{ + struct nlmsghdr *nlMsg; + //struct rtmsg *rtMsg; + struct route_info *rtInfo; + char msgBuf[BUFSIZE]; + int sock, len, msgSeq = 0; + + if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) + { + perror("Socket Creation: "); + return -1; + } + + memset(msgBuf, 0, BUFSIZE); + nlMsg = (struct nlmsghdr *)msgBuf; + //rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg); + nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message. + nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table . + nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump. + nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet. + nlMsg->nlmsg_pid = getpid(); // PID of process sending the request. + + if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0) + { + printf("Write To Socket Failed…\n"); + return -1; + } + + if((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0) + { + printf("Read From Socket Failed…\n"); + return -1; + } + + rtInfo = (struct route_info *)malloc(sizeof(struct route_info)); + for(;NLMSG_OK(nlMsg,len);nlMsg = NLMSG_NEXT(nlMsg,len)) + { + memset(rtInfo, 0, sizeof(struct route_info)); + parseRoutes(nlMsg, rtInfo,gateway); + } + free(rtInfo); + close(sock); + + return 0; +} + +//status回响应 +void http_handler_status_msg(struct evhttp_request *req,void *arg) +{ + struct sysinfo info; + time_t cur_time = 0; + time_t boot_time = 0; + struct tm *ptm = NULL; + unsigned int run_days,run_hour,run_minute,run_second; + pid_t process_id; + + //启动时间,启动时长 + if (sysinfo(&info)) + { + fprintf(stderr, "Failed to get sysinfo, errno:%u, reason:%s\n", + errno, strerror(errno)); + return ; + } + time(&cur_time); + if (cur_time > info.uptime) + { + boot_time = cur_time - info.uptime; + } + else + { + boot_time = info.uptime - cur_time; + } + ptm = localtime(&boot_time); + /*printf("System boot time:%d-%-d-%d %d:%d:%d\n", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);*/ + + run_days=info.uptime / 86400; + run_hour=(info.uptime % 86400)/3600; + run_minute=(info.uptime % 3600)/60; + run_second=info.uptime % 60; + //printf("system running time:%dday %dhour %dminute %dsecond\n",run_days,run_hour,run_minute,run_second); + + //进程号 + process_id = getpid(); + //printf("process id:%d\n", process_id); + + //默认网关地址 + char buff[256]; + get_gateway(buff); + //printf("gateway:%s\n",buff); + + //内存(虚存,实存) + unsigned int n_rss, n_resident, n_share, n_text, n_lib, n_data, n_dt; + char buf[256]; + char buf1[256]; + char buf2[256]; + char buf3[256]; + FILE *f = fopen("/proc/self/statm","r"); + + if(f) + { + fscanf(f,"%u%u%u%u%u%u%u",&n_rss,&n_resident,&n_share,&n_text,&n_lib,&n_data,&n_dt); + fclose(f); + } + else + { + printf("open /proc/self/statm failed!"); + return; + } + n_rss = n_rss * 4; + n_resident = n_resident *4; + + sprintf(buf, "VmSize=%ukB, VmRss=%ukB", n_rss, n_resident); + //printf("memory info:%s\n",buf); + + //cpu + float cpu_rate; + unsigned int cpu_num; + cpu_rate = get_cpu_stat(process_id); + cpu_num = get_nprocs();//获取可用cpu数 + //printf("cpu usage = %f\n", cpu_rate*cpu_num); + + struct evbuffer *retbuff = NULL; + retbuff = evbuffer_new(); + if(retbuff == NULL) + { + printf("====line:%d,%s\n",__LINE__,"retbuff is null."); + return; + } + sprintf(buf1, "%d-%-d-%d %d:%d:%d", ptm->tm_year + 1900,ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); + sprintf(buf2, "%ddays %dhours %dminutes %dseconds", run_days,run_hour,run_minute,run_second); + sprintf(buf3, "%f", cpu_rate*cpu_num); + cJSON * root = cJSON_CreateObject(); + + //根节点下添加 + cJSON_AddItemToObject(root, "boot time", cJSON_CreateString(buf1)); + cJSON_AddItemToObject(root, "running time", cJSON_CreateString(buf2)); + cJSON_AddItemToObject(root, "process id", cJSON_CreateNumber(process_id)); + cJSON_AddItemToObject(root, "server ip", cJSON_CreateString(g_http_address)); + cJSON_AddItemToObject(root, "default gateway", cJSON_CreateString(buff)); + cJSON_AddItemToObject(root, "memory info", cJSON_CreateString(buf)); + cJSON_AddItemToObject(root, "cpu usage", cJSON_CreateString(buf3)); + + printf("cjson_status_print:%s\n", cJSON_Print(root)); + + //evbuffer_add_printf(retbuff,"System boot time: %d-%-d-%d %d:%d:%d\r\nsystem running time:%dday %dhour %dminute %dsecond\r\nprocess id:%d\r\ngateway:%s\r\nmemory info:%s\r\ncpu% = %f\r\n", + // ptm->tm_year + 1900,ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, run_days,run_hour,run_minute,run_second,process_id,buff,buf,cpu_rate*cpu_num); + evbuffer_add_printf(retbuff,cJSON_Print(root)); + evhttp_send_reply(req,HTTP_OK,"OK",retbuff); + evbuffer_free(retbuff); + if(root) + { + cJSON_Delete(root); + } + + return; +} + +//keepalive回响应 +void http_handler_keepalive_msg(struct evhttp_request *req,void *arg) +{ + struct tm *local; + time_t tt; + tt=time(NULL); + local=localtime(&tt); + + struct evbuffer *retbuff = NULL; + retbuff = evbuffer_new(); + if(retbuff == NULL) + { + printf("====line:%d,%s\n",__LINE__,"retbuff is null."); + return; + } + + cJSON * root = cJSON_CreateObject(); + cJSON_AddItemToObject(root, "current time", cJSON_CreateString(asctime(local))); + printf("cjson_keepalive_print:%s\n", cJSON_Print(root)); + + evbuffer_add_printf(retbuff,cJSON_Print(root)); + evhttp_send_reply(req,HTTP_OK,"OK",retbuff); + evbuffer_free(retbuff); + if(root) + { + cJSON_Delete(root); + } + + return; +} + +//int main() +int http_check_init() +{ + struct evhttp *http_server = NULL; + //short http_port = 10000; + //char *http_addr = "0.0.0.0"; + + MESA_load_profile_int_def(http_check_conf_file, "HTTP", "SERVER_PORT", &g_http_port, 0); + MESA_load_profile_string_def(http_check_conf_file, "HTTP", "SERVER_IP", g_http_address, MAX_LOG_PATH_LEN, NULL); + printf("*v1*******read_ip:%s,read_port:%d\n",g_http_address, g_http_port); + //初始化 + event_init(); + //启动http服务端 + http_server = evhttp_start(g_http_address,g_http_port); + if(http_server == NULL) + { + printf("====line:%d,%s\n",__LINE__,"http server start failed."); + return -1; + } + + //设置请求超时时间(s) + evhttp_set_timeout(http_server,100); + //设置事件处理函数,evhttp_set_cb针对每一个事件(请求)注册一个处理函数, + //区别于evhttp_set_gencb函数,是对所有请求设置一个统一的处理函数 + evhttp_set_cb(http_server,"/status",http_handler_status_msg,NULL);//为特定的URI指定callback + evhttp_set_cb(http_server,"/keepalive",http_handler_keepalive_msg,NULL); + //循环监听 + event_dispatch(); + evhttp_free(http_server); + + return 0; +} + +void http_check_destory() +{ + return; +} + +