From d02f57e5ee36ccadb3e7a2dac02b5849cb5c2ee5 Mon Sep 17 00:00:00 2001 From: fengweihao Date: Thu, 5 Jul 2018 14:05:28 +0800 Subject: [PATCH] =?UTF-8?q?[DEL]=201.=E5=88=A0=E9=99=A4openssl=E9=94=81?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=87=BD=E6=95=B0=20[Modify]=201.?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=B9=B6=E4=BF=AE=E6=94=B9redis=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E5=9B=9E=E8=B0=83=E5=87=BD=E6=95=B0=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=202.=E4=BF=AE=E6=94=B9Makefiel=EF=BC=8C=E5=AF=B9moodycamel=5Ff?= =?UTF-8?q?ield=5Fstat2.cpp=E6=96=87=E4=BB=B6=E4=BD=BF=E7=94=A8g++?= =?UTF-8?q?=E7=BC=96=E8=AF=91=20[Add]=201.=E6=B7=BB=E5=8A=A0=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E4=BF=A1=E6=81=AF=E7=BB=9F=E8=AE=A1=E5=BA=93libMESA?= =?UTF-8?q?=5Ffield=5Fstat2.a=202.=E6=B7=BB=E5=8A=A0=E5=AF=B9C++=E9=9D=99?= =?UTF-8?q?=E6=80=81=E5=BA=93C=E8=B0=83=E7=94=A8=E7=9A=84=E5=86=85?= =?UTF-8?q?=E9=83=A8=E5=B0=81=E8=A3=85=E6=8E=A5=E5=8F=A3=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/cert_store.ini | 4 +- make/application.mk | 16 +- make/common.mk | 6 +- src/Makefile | 6 +- src/cert_session.c | 251 ++++++++++++++++------------- src/cert_session.h | 17 +- src/cert_store.c | 2 +- src/components/syslogd/logging.c | 9 +- src/inc/field_stat2.h | 68 ++++++++ src/inc/inc.mk | 32 ++++ src/inc/moodycamel_field_stat2.cpp | 56 +++++++ src/inc/moodycamel_field_stat2.h | 58 +++++++ src/lib/libMESA_field_stat2.a | Bin 0 -> 58804 bytes src/rt/rt_string.h | 1 - 14 files changed, 385 insertions(+), 141 deletions(-) create mode 100644 src/inc/field_stat2.h create mode 100644 src/inc/inc.mk create mode 100644 src/inc/moodycamel_field_stat2.cpp create mode 100644 src/inc/moodycamel_field_stat2.h create mode 100644 src/lib/libMESA_field_stat2.a diff --git a/conf/cert_store.ini b/conf/cert_store.ini index f79ed39..c61b5b6 100644 --- a/conf/cert_store.ini +++ b/conf/cert_store.ini @@ -4,9 +4,9 @@ DEBUG_SWITCH = 1 #10:DEBUG, 20:INFO, 30:FATAL RUN_LOG_LEVEL = 10 -RUN_LOG_PATH = ./logs/ +RUN_LOG_PATH = ./logs [CONFIG] -thread-nu = 2 +thread-nu = 1 ca-path = ../ca valid-days = 30 [LIBEVENT] diff --git a/make/application.mk b/make/application.mk index 57f6aa4..2b31ae8 100644 --- a/make/application.mk +++ b/make/application.mk @@ -2,7 +2,7 @@ $(OBJ_DIR): mkdir $(OBJ_DIR) - #mkdir $(OBJ_DIR_CPP) + mkdir $(OBJ_DIR_CPP) # applications object suffix rule @@ -12,21 +12,21 @@ $(OBJ_DIR)/%.o: %.c $(OBJ_DIR)/%.o: %.S $(ASSEMBLE) -#$(OBJ_DIR_CPP)/%.o: %.cpp -# $(CPPCOMPILE) +$(OBJ_DIR_CPP)/%.o: %.cpp + $(CPPCOMPILE) # application config check and rules -include $(OBJS:.o=.d) -#-include $(OBJS_CPP:.o=.d) +-include $(OBJS_CPP:.o=.d) application-target: $(TARGET) -#$(TARGET): $(OBJ_DIR) $(OBJS) $(LIBS_LIST) $(OBJ_DIR_CPP) $(OBJS_CPP) -# $(CC) -o $@ $(OBJS) $(OBJS_CPP) $(LDFLAGS_PATH) $(LIBS_LIST) $(LDFLAGS_GLOBAL) +$(TARGET): $(OBJ_DIR) $(OBJS) $(LIBS_LIST) $(OBJ_DIR_CPP) $(OBJS_CPP) + $(CC) -o $@ $(OBJS) $(OBJS_CPP) $(LDFLAGS_PATH) $(LIBS_LIST) $(LDFLAGS_GLOBAL) -$(TARGET): $(OBJ_DIR) $(OBJS) $(LIBS_LIST) - $(CC) -o $@ $(OBJS) $(LDFLAGS_PATH) $(LIBS_LIST) $(LDFLAGS_GLOBAL) +#$(TARGET): $(OBJ_DIR) $(OBJS) $(LIBS_LIST) +# $(CC) -o $@ $(OBJS) $(LDFLAGS_PATH) $(LIBS_LIST) $(LDFLAGS_GLOBAL) $(TARGET).stp: $(TARGET) $(STRIP) -o $(TARGET).stp $(TARGET) diff --git a/make/common.mk b/make/common.mk index 1c5c22d..f4e664e 100644 --- a/make/common.mk +++ b/make/common.mk @@ -32,13 +32,13 @@ STRIP = strip OBJDUMP = objdump NM = nm -#CPP = g++ +CPP = g++ # build object directory OBJ_DIR = obj$(PREFIX) -#OBJ_DIR_CPP = obj$(PREFIX)/cpp +OBJ_DIR_CPP = obj$(PREFIX)/cpp # standard compile line @@ -48,4 +48,4 @@ ASSEMBLE = $(CC) $(ASFLAGS_GLOBAL) $(ASFLAGS_LOCAL) -MD -c -o $@ $< MYARCHIVE = $(AR) -cr $@ $< -#CPPCOMPILE = $(CPP) $(CFLAGS_GLOBAL) $(CFLAGS_LOCAL) -MD -c -o $@ $< +CPPCOMPILE = $(CPP) $(CFLAGS_GLOBAL) $(CFLAGS_LOCAL) -MD -c -o $@ $< diff --git a/src/Makefile b/src/Makefile index 2404d2a..e902554 100644 --- a/src/Makefile +++ b/src/Makefile @@ -40,8 +40,12 @@ dir := ./rt include $(dir)/rt.mk OBJS += $(OBJS_$(dir)) +dir := ./inc +include $(dir)/inc.mk +OBJS += $(OBJS_$(dir)) + LDFLAGS_GLOBAL += -L ./lib -lapps -lcrypto -lssl -levent -lhiredis -lMESA_htable -LDFLAGS_GLOBAL += -L ./lib -lMESA_htable -lMESA_handle_logger -lMESA_prof_load +LDFLAGS_GLOBAL += -L ./lib -lMESA_htable -lMESA_field_stat2 -lMESA_handle_logger -lMESA_prof_load LDFLAGS_GLOBAL += \ -lpthread -lcrypt -lm -lz -ldl -lstdc++ diff --git a/src/cert_session.c b/src/cert_session.c index 4d06445..5b96c5b 100644 --- a/src/cert_session.c +++ b/src/cert_session.c @@ -36,6 +36,7 @@ #include "http.h" #include "buffer.h" #include "util-internal.h" +#include "moodycamel_field_stat2.h" #include "logging.h" #define SG_DATA_SIZE 2048 @@ -45,6 +46,16 @@ static libevent_thread *threads; +struct fs_stats_t{ + int line_ids[3]; + screen_stat_handle_t handle; +}; + +static struct fs_stats_t SGstats = { + .line_ids = {0}, + .handle = NULL, +}; + #define sizeof_seconds(x) (x * 24 * 60 * 60) void connectCallback(const struct redisAsyncContext *c, int status) { @@ -63,56 +74,6 @@ void disconnectCallback(const struct redisAsyncContext *c, int status) { printf("Redis server disconnected...\n"); } -static rt_mutex *mutex_buf = NULL; - -static unsigned long pthreads_thread_id(void) -{ - return ((unsigned long)pthread_self()); -} - -static void pthreads_locking_callback(int mode, int n, const char __attribute__((__unused__))*file, - int __attribute__((__unused__))line) -{ - if(mode & CRYPTO_LOCK) - rt_mutex_lock(&(mutex_buf[n])); - else - rt_mutex_unlock(&(mutex_buf[n])); -} - -int thread_setup(void) -{ - int i; - - mutex_buf = malloc(CRYPTO_num_locks() * sizeof(rt_mutex)); - if(!mutex_buf) - return 0; - - for(i = 0; i < CRYPTO_num_locks(); i++) - rt_mutex_init(&(mutex_buf[i]), NULL); - - CRYPTO_set_id_callback(pthreads_thread_id); - CRYPTO_set_locking_callback(pthreads_locking_callback); - return 1; -} - -int thread_cleanup(void) -{ - int i; - - if(!mutex_buf) - return 0; - - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); - - for(i = 0; i < CRYPTO_num_locks(); i++) - rt_mutex_destroy(&(mutex_buf[i])); - - free(mutex_buf); - mutex_buf = NULL; - return 1; -} - int ssl_rand(void *p, size_t sz) { @@ -607,7 +568,7 @@ int cert_redis_init(struct event_base *base, struct redisAsyncContext **cl_ctx) struct config_bucket_t *redis = cert_default_config(); *cl_ctx = redisAsyncConnect(redis->r_ip, redis->r_port); - if((*cl_ctx)->err) { + if((*cl_ctx)->err ) { mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Redis Connect error : %s", (*cl_ctx)->errstr); goto finish; } @@ -621,7 +582,7 @@ finish: } static void -setCallback(redisAsyncContext __attribute__((__unused__))*c, void *r, +rd_set_callback(redisAsyncContext __attribute__((__unused__))*c, void *r, void *privdata) { redisReply *reply = (redisReply*)r; @@ -672,7 +633,7 @@ release_resources(struct cert_trapper_t *certCtx, char *cert, char *pubkey, int } #endif -int x509_mkcert(char *host, EVP_PKEY *key, X509 *root, char *ca_s, char *pubkey) +int x509_online_append(char *host, EVP_PKEY *key, X509 *root, char *ca_s, char *pubkey) { int xret = -1; struct config_bucket_t *rte = cert_default_config(); @@ -682,7 +643,7 @@ int x509_mkcert(char *host, EVP_PKEY *key, X509 *root, char *ca_s, char *pubkey) goto finish; } X509* x509 = x509_modify_by_cert(root, key, ca, X509_get_pubkey(root), - rte->days, NULL, NULL); + rte->days, NULL, NULL); if (!x509){ goto err; } @@ -696,7 +657,8 @@ finish: return xret; } -int create_x509(struct request_t *request, redisAsyncContext *c, char *sendbuf) +static int +rd_decode_sendbuf(struct request_t *request, redisAsyncContext *c, char *sendbuf) { int xret = -1; @@ -705,27 +667,47 @@ int create_x509(struct request_t *request, redisAsyncContext *c, char *sendbuf) struct config_bucket_t *rte = cert_default_config(); char cert[SG_DATA_SIZE] = {0}, pubkey[SG_DATA_SIZE] = {0}; - x509_mkcert(request->host, thread->key, thread->root, cert, pubkey); + x509_online_append(request->host, thread->key, thread->root, cert, pubkey); if (cert[0] == '\0' && pubkey[0] == '\0'){ mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to issue certificate"); - evhttp_send_error(request->evh_req, HTTP_BADREQUEST, 0); + evhttp_send_error(request->evh_req, HTTP_NOTFOUND, 0); goto finish; } - CA_SIGN_ADD(1); + + FS_internal_operate(SGstats.handle,thread->column_ids,thread->field_ids,SGstats.line_ids[2], FS_OP_ADD, 1); + snprintf(sendbuf, SG_DATA_SIZE * 2, "%s%s", pubkey, cert); - xret = redisAsyncCommand(c, setCallback, request->host, "SETEX %s %d %s", + xret = redisAsyncCommand(c, rd_set_callback, request->host, "SETEX %s %d %s", request->host, sizeof_seconds(rte->days), sendbuf); if (xret < 0){ mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to set information to redis server"); goto finish; } - xret = 0; + + xret = 0; finish: return xret; } -void getCallback(redisAsyncContext *c, void *r, void *privdata) +static int +rd_encode_sendbuf(struct request_t *request, redisReply *reply, char *sendbuf) +{ + int xret = -1; + libevent_thread *thread = threads + request->thread_id; + + if (reply && reply->str){ + FS_internal_operate(SGstats.handle,thread->column_ids,thread->field_ids,SGstats.line_ids[1],FS_OP_ADD,1); + snprintf(sendbuf, SG_DATA_SIZE * 2, "%s", reply->str); + xret = 0; + } + else{ + evhttp_send_error(request->evh_req, HTTP_BADREQUEST, 0); + } + return xret; +} + +void rd_get_callback(redisAsyncContext *c, void *r, void *privdata) { int xret = -1; char sendbuf[SG_DATA_SIZE * 2] = {0}; @@ -737,18 +719,15 @@ void getCallback(redisAsyncContext *c, void *r, void *privdata) switch(reply->type){ case REDIS_REPLY_STRING: mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Sends the certificate information to the requestor"); - CA_STORE_ADD(1); - if (reply->str != NULL){ - snprintf(sendbuf, SG_DATA_SIZE * 2, "%s", reply->str); - xret = 0; - }else{ - evhttp_send_error(request->evh_req, HTTP_BADREQUEST, 0); - } + + xret = rd_encode_sendbuf(request, reply, sendbuf); break; + case REDIS_REPLY_NIL: /* Certificate information modification and Strategy to judge**/ mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Generating certificate information"); - xret = create_x509(request, c, sendbuf); + + xret = rd_decode_sendbuf(request, c, sendbuf); break; default: break; @@ -836,7 +815,7 @@ int cert_session_finish() #endif static int -sample_decode_uri(const char *uri, char *host, +rt_decode_uri(const char *uri, char *host, int *flag, int *valid) { const char *fg = NULL, *vl = NULL; @@ -865,6 +844,17 @@ finish: return 0; } +static void +evhttp_socket_close_cb(struct evhttp_connection *evcon, + void __attribute__((__unused__))*arg) +{ + if (NULL == evcon){ + goto finish; + } +finish: + return; +} + void pthread_work_proc(struct evhttp_request *evh_req, void *arg) { @@ -872,9 +862,11 @@ pthread_work_proc(struct evhttp_request *evh_req, void *arg) const char *cmdtype; struct request_t *request = NULL; struct evhttp_uri *decoded = NULL; - libevent_thread *thread_info = (libevent_thread *)arg; + /* we want to know if this connection closes on us */ + evhttp_connection_set_closecb(evhttp_request_get_connection(evh_req), evhttp_socket_close_cb, NULL); + const char *uri = evhttp_request_get_uri(evh_req); /* Decode the URI */ decoded = evhttp_uri_parse(uri); @@ -882,6 +874,7 @@ pthread_work_proc(struct evhttp_request *evh_req, void *arg) mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "It's not a good URI. Sending BADREQUEST\n"); goto error; } + request = (struct request_t *) kmalloc (sizeof(struct request_t), MPF_CLR, -1); if (request != NULL){ request->thread_id = thread_info->id; @@ -900,28 +893,30 @@ pthread_work_proc(struct evhttp_request *evh_req, void *arg) case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break; default: cmdtype = "unknown"; break; } + FS_internal_operate(SGstats.handle,thread_info->column_ids,-1,SGstats.line_ids[0], FS_OP_ADD, 1); - WEB_REQUEST_ADD(1); - sample_decode_uri(uri, request->host, &request->flag, &request->valid); + rt_decode_uri(uri, request->host, &request->flag, &request->valid); mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "[Thread %d]Received a %s request for %s, host:%s, flag:%d, valid:%d\nHeaders:", request->thread_id, cmdtype, uri, request->host, request->flag, request->valid); if (request->host[0] != '\0' && request->evh_req != NULL){ - xret = redisAsyncCommand(thread_info->cl_ctx, getCallback, request, "GET %s", request->host); - if (xret < 0){ + + xret = redisAsyncCommand(thread_info->cl_ctx, rd_get_callback, request, "GET %s", request->host); + if (xret < 0) mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "Failed to get information from redis server"); - } - }else{ + } + else { kfree(request); evhttp_uri_free(decoded); goto error; } + evhttp_uri_free(decoded); goto finish; error: - evhttp_send_error(evh_req, HTTP_BADREQUEST, 0); + evhttp_send_error(evh_req, HTTP_NOTFOUND, 0); finish: return; } @@ -1032,30 +1027,22 @@ err: return fd; } -void * do_perform_monitor(void __attribute__((__unused__))*_thread_id) +static int +fs_screen_preview(libevent_thread *thread) { -#define EVAL_TM_STYLE_FULL "%Y-%m-%d %H:%M:%S" - char tm[64] = {0}; - int64_t web_req; - int64_t ca_store, ca_sign; + char buff[128] = {0}; - do{ - web_req = WEB_REQUEST_ADD(0); - ca_store = CA_STORE_ADD(0); - ca_sign = CA_SIGN_ADD(0); + snprintf(buff, sizeof(buff),"Thread_%02d", thread->id); + thread->field_ids = FS_internal_register(SGstats.handle, FS_STYLE_FIELD, FS_CALC_CURRENT, buff); - rt_curr_tms2str(EVAL_TM_STYLE_FULL, tm, 63); - printf("%s Web Req=%ld, Ca Total=%ld\n", tm, web_req, ca_store + ca_sign); - printf("\tCa store=%ld, sign=%ld\n", - ca_store, ca_sign); + snprintf(buff, sizeof(buff),"Thread_%d", thread->id); + thread->column_ids = FS_internal_register(SGstats.handle, FS_STYLE_LINE, FS_CALC_CURRENT, buff); - sleep(5); - }while(1); - - return NULL; + return 0; } -int libevent_socket_init() +static int +libevent_socket_init() { struct sockaddr_in sin; evutil_socket_t accept_fd = -1; @@ -1077,15 +1064,12 @@ int libevent_socket_init() goto finish; } - /* one way to set the necessary OpenSSL locking callbacks if you want to do - multi-threaded transfers with HTTPS/FTPS built to use OpenSSL **/ - thread_setup(); - threads = calloc(thread_nu, sizeof(libevent_thread)); if (! threads) { mesa_runtime_log(RLOG_LV_INFO, MODULE_NAME, "Can't allocate thread descriptors"); goto finish; } + memset(threads, 0, thread_nu * sizeof(libevent_thread)); /* Create threads after we've done all the libevent setup. */ for (tid = 0; tid < thread_nu; tid++) { @@ -1095,6 +1079,8 @@ int libevent_socket_init() thread->accept_fd = accept_fd; thread->routine = pthread_worker_libevent; + fs_screen_preview(thread); + if (pthread_create(&thread->pid, thread->attr, thread->routine, &threads[tid])){ mesa_runtime_log(RLOG_LV_FATAL, MODULE_NAME, "%s", strerror(errno)); goto finish; @@ -1106,26 +1092,73 @@ int libevent_socket_init() } } - rt_pthread perform; - long thread_id = 5; - pthread_create(&perform, NULL, do_perform_monitor, (void *) thread_id); - - void * per_res; - pthread_join(perform, &per_res); - FOREVER{ sleep(1); } - - thread_cleanup(); finish: return xret; } +static void +rt_get_pname_by_pid(pid_t pid, char *task_name) +{ +#define BUF_SIZE 1024 + char proc_pid_path[BUF_SIZE]; + char buf[BUF_SIZE]; + sprintf(proc_pid_path, "/proc/%d/status", pid); + FILE* fp = fopen(proc_pid_path, "r"); + if(NULL != fp){ + if( fgets(buf, BUF_SIZE-1, fp)== NULL ){ + fclose(fp); + } + fclose(fp); + sscanf(buf, "%*s %s", task_name); + } +} + +static int +fs_screen_init() +{ + int value=0; + char stat_path[63] = {0}; + char pname[32]= {0}, buff[128] = {0}; + + SGstats.handle = FS_internal_create_handle(); + + rt_get_pname_by_pid(getpid(), &pname[0]); + FS_internal_set_para(SGstats.handle, APP_NAME, pname, strlen(pname)+1); + value=0; + FS_internal_set_para(SGstats.handle, FLUSH_BY_DATE, &value, sizeof(value)); + + snprintf(stat_path, 63, "%s/fs2_%s.status", logging_sc_lid.run_log_path, pname); + FS_internal_set_para(SGstats.handle, OUTPUT_DEVICE, stat_path, strlen(stat_path)+1); + value=1; + FS_internal_set_para(SGstats.handle, PRINT_MODE, &value, sizeof(value)); + value=1; + FS_internal_set_para(SGstats.handle, CREATE_THREAD, &value, sizeof(value)); + value=3; + FS_internal_set_para(SGstats.handle, STAT_CYCLE, &value, sizeof(value)); + + snprintf(buff,sizeof(buff),"%s", "req"); + SGstats.line_ids[0] = FS_internal_register(SGstats.handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + + snprintf(buff,sizeof(buff),"%s", "store"); + SGstats.line_ids[1] = FS_internal_register(SGstats.handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + + snprintf(buff,sizeof(buff),"%s", "sign"); + SGstats.line_ids[2] = FS_internal_register(SGstats.handle, FS_STYLE_COLUMN, FS_CALC_CURRENT, buff); + + FS_internal_start(SGstats.handle); + + return 0; +} + int cert_session_init() { int xret = 0; + fs_screen_init(); + libevent_socket_init(); return xret; diff --git a/src/cert_session.h b/src/cert_session.h index abdb7a4..2512707 100644 --- a/src/cert_session.h +++ b/src/cert_session.h @@ -44,22 +44,13 @@ typedef struct { struct redisAsyncContext *cl_ctx; void * (*routine)(void *); /** Executive entry */ + + int field_ids; /* dispaly */ + + int column_ids; } libevent_thread; -struct rt_ca_statis{ - atomic64_t req_url; - atomic64_t ca_store, ca_sign; -}; - -struct rt_ca_statis ca_writer; - -#define WEB_REQUEST_ADD(n) atomic64_add(&ca_writer.req_url, n); -#define CA_STORE_ADD(n) atomic64_add(&ca_writer.ca_store, n); -#define CA_SIGN_ADD(n) atomic64_add(&ca_writer.ca_sign, n); - extern int cert_session_init(); -extern int cert_session_finish(); - #endif diff --git a/src/cert_store.c b/src/cert_store.c index d2d6216..e4e2b3a 100644 --- a/src/cert_store.c +++ b/src/cert_store.c @@ -1,7 +1,7 @@ /************************************************************************* > File Name: cert_server.c > Author: fengweihao - > Mail: fengweihao158@163.com + > Mail: > Created Time: Tue 29 May 2018 06:45:23 PM PDT ************************************************************************/ diff --git a/src/components/syslogd/logging.c b/src/components/syslogd/logging.c index 9cfa2f0..68fc3fc 100644 --- a/src/components/syslogd/logging.c +++ b/src/components/syslogd/logging.c @@ -22,7 +22,7 @@ #include "MESA_prof_load.h" #include "MESA_handle_logger.h" -void rt_get_pname_by_pid(pid_t pid, char *task_name) +static void rt_get_pname_by_pid(pid_t pid, char *task_name) { #define BUF_SIZE 1024 char proc_pid_path[BUF_SIZE]; @@ -63,6 +63,8 @@ int mesa_logging_mkfile(char *file, size_t size) void cert_syslog_init(char *config) { + char run_log_path[256] = {0}; + MESA_load_profile_int_def(config, (const char *)"SYSTEM",(const char *)"DEBUG_SWITCH", &logging_sc_lid.debug_switch, 1); MESA_load_profile_int_def(config, (const char *)"SYSTEM",(const char *)"RUN_LOG_LEVEL", @@ -72,9 +74,10 @@ void cert_syslog_init(char *config) char file[64] = {0}; mesa_logging_mkfile(file, 63); - STRCAT(logging_sc_lid.run_log_path, file); + //STRCAT(logging_sc_lid.run_log_path, file); + snprintf(run_log_path, 255, "%s/%s", logging_sc_lid.run_log_path, file); - logging_sc_lid.run_log_handle = MESA_create_runtime_log_handle(logging_sc_lid.run_log_path, logging_sc_lid.run_log_level); + logging_sc_lid.run_log_handle = MESA_create_runtime_log_handle(run_log_path, logging_sc_lid.run_log_level); if(logging_sc_lid.run_log_handle == NULL){ printf("Create log runtime_log_handle error, init failed!"); goto finish; diff --git a/src/inc/field_stat2.h b/src/inc/field_stat2.h new file mode 100644 index 0000000..6b7ca4a --- /dev/null +++ b/src/inc/field_stat2.h @@ -0,0 +1,68 @@ +#ifndef H_SCREEN_STAT_H_INCLUDE +#define H_SCREEN_STAT_H_INCLUDE +#include + +#ifndef __cplusplus +#error("This file should be compiled with C++ compiler") +#endif + +enum field_dsp_style_t +{ + FS_STYLE_FIELD=0, + FS_STYLE_COLUMN, + FS_STYLE_LINE, + FS_STYLE_STATUS +}; +enum field_calc_algo +{ + FS_CALC_CURRENT=0, + FS_CALC_SPEED +}; +enum field_op +{ + FS_OP_ADD=1, + FS_OP_SET +}; + + +typedef void* screen_stat_handle_t; + +enum FS_option +{ + OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout. + PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE. + STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds. + PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1. + CREATE_THREAD, //VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function, + //and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0. + ID_INVISBLE, //value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one. + FLUSH_BY_DATE, //value is 1(ture) or 0(false),SIZE=4,DEFAULT: Do not flush by date. + APP_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT is "?". + STATS_SERVER_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT. + STATS_SERVER_PORT, //VALUE is a unsigned short or a signed int, host order, SIZE= sizeof(unsigned short) or sizeof(int). No DEFAULT. + MAX_STAT_FIELD_NUM //VALUE is an interger, SIZE=sizeof(int), DEFAULT:1024. +}; + +//Always success. +screen_stat_handle_t FS_create_handle(void); + +int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size); +void FS_start(screen_stat_handle_t handle); +void FS_stop(screen_stat_handle_t* handle); + +//return field_id/line_id/column_id greater than zero if success,return an interger less than zero if failed. +//should NOT include "|:\n\r.\t<>[]#!@"or space in the parameter name. +//Runtime rregister column is NOT allowed. +int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name); + +//numerator_id and denominator_id must be column/field/status style. +//scaling: negative value: zoom in; positive value: zoom out; +int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name); + +//id: when id's type is FIELD , column_id is ignore. +int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value); + +void FS_passive_output(screen_stat_handle_t handle); + +#endif + diff --git a/src/inc/inc.mk b/src/inc/inc.mk new file mode 100644 index 0000000..43fbc58 --- /dev/null +++ b/src/inc/inc.mk @@ -0,0 +1,32 @@ + + +# standard component Makefile header +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) + +# component specification + +OBJS_$(d) :=\ + $(OBJ_DIR_CPP)/moodycamel_field_stat2.o\ + + +CFLAGS_LOCAL += -I$(d) +$(OBJS_$(d)): CFLAGS_LOCAL := -std=c++11 -W -Wall -g -O3\ + -I$(d)\ + +# standard component Makefile rules + +DEPS_$(d) := $(OBJS_$(d):.o=.d) + +CLEAN_LIST := $(CLEAN_LIST) $(OBJS_$(d)) $(DEPS_$(d)) + +$(OBJ_DIR_CPP)/%.o: $(d)/%.cpp + $(CPPCOMPILE) + +-include $(DEPS_$(d)) + +# standard component Makefile footer + +d := $(dirstack_$(sp)) +sp := $(basename $(sp)) diff --git a/src/inc/moodycamel_field_stat2.cpp b/src/inc/moodycamel_field_stat2.cpp new file mode 100644 index 0000000..d872083 --- /dev/null +++ b/src/inc/moodycamel_field_stat2.cpp @@ -0,0 +1,56 @@ +/************************************************************************* + > File Name: moodycamel_field_stat2.cpp + > Author: + > Mail: + > Created Time: 2018年07月03日 星期二 16时48分52秒 + ************************************************************************/ + +#include +#include "field_stat2.h" + +using namespace std; + +extern "C" screen_stat_handle_t FS_internal_create_handle(void); +extern "C" int FS_internal_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size); +extern "C" void FS_internal_start(screen_stat_handle_t handle); +extern "C" int FS_internal_register(screen_stat_handle_t handle,enum field_dsp_style_t style, + enum field_calc_algo calc_type,const char* name); +extern "C" int FS_internal_operate(screen_stat_handle_t handle,int id,int id2,int column_id,enum field_op op,long long value); + +screen_stat_handle_t FS_internal_create_handle(void) +{ + return FS_create_handle(); +} + +int FS_internal_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size) +{ + return FS_set_para(handle, type, value, size); +} + +void FS_internal_start(screen_stat_handle_t handle) +{ + FS_start(handle); +} + +int FS_internal_register(screen_stat_handle_t handle,enum field_dsp_style_t style, + enum field_calc_algo calc_type,const char* name) +{ + return FS_register(handle, style, calc_type, name); +} + +int FS_internal_operate(screen_stat_handle_t handle,int id,int id2,int column_id,enum field_op op,long long value) +{ + int ret = -1; + + ret = FS_operate(handle, id, column_id, op, value); + if (ret < 0) + goto finish; + + if (id2 < 0) + goto finish; + + ret = FS_operate(handle, id2, 0, op, value); +finish: + return ret; +} + diff --git a/src/inc/moodycamel_field_stat2.h b/src/inc/moodycamel_field_stat2.h new file mode 100644 index 0000000..31b4a10 --- /dev/null +++ b/src/inc/moodycamel_field_stat2.h @@ -0,0 +1,58 @@ +/************************************************************************* + > File Name: moodycamel_field_stat2.h + > Author: + > Mail: + > Created Time: 2018年07月03日 星期二 16时51分41秒 + ************************************************************************/ + +#ifndef _MOODYCAMEL_FIELD_STAT2_H +#define _MOODYCAMEL_FIELD_STAT2_H + +enum field_dsp_style_t +{ + FS_STYLE_FIELD=0, + FS_STYLE_COLUMN, + FS_STYLE_LINE, + FS_STYLE_STATUS +}; +enum field_calc_algo +{ + FS_CALC_CURRENT=0, + FS_CALC_SPEED +}; +enum field_op +{ + FS_OP_ADD=1, + FS_OP_SET +}; + +typedef void* screen_stat_handle_t; + +enum FS_option +{ + OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout. + PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE. + STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds. + PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1. + CREATE_THREAD, //VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function, + //and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0. + ID_INVISBLE, //value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one. + FLUSH_BY_DATE, //value is 1(ture) or 0(false),SIZE=4,DEFAULT: Do not flush by date. + APP_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT is "?". + STATS_SERVER_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT. + STATS_SERVER_PORT, //VALUE is a unsigned short or a signed int, host order, SIZE= sizeof(unsigned short) or sizeof(int). No DEFAULT. + MAX_STAT_FIELD_NUM //VALUE is an interger, SIZE=sizeof(int), DEFAULT:1024. +}; + +screen_stat_handle_t FS_internal_create_handle(void); + +int FS_internal_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size); + +void FS_internal_start(screen_stat_handle_t handle); + +int FS_internal_register(screen_stat_handle_t handle,enum field_dsp_style_t style, + enum field_calc_algo calc_type,const char* name); + +int FS_internal_operate(screen_stat_handle_t handle,int id,int id2,int column_id,enum field_op op,long long value); + +#endif diff --git a/src/lib/libMESA_field_stat2.a b/src/lib/libMESA_field_stat2.a new file mode 100644 index 0000000000000000000000000000000000000000..bc1b2c2c87c6f5a0146258ac707a057ee1bfd393 GIT binary patch literal 58804 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 wTh^counter = val; } - #endif