From 2961ebeb7c8f73936c66feb71af0e1121831aa8b Mon Sep 17 00:00:00 2001 From: lixiumei123 Date: Fri, 21 Oct 2022 03:58:00 +0000 Subject: [PATCH] add(api):added api for download debug files --- include/neuron/errcodes.h | 3 +- plugins/restful/handle.c | 7 +- plugins/restful/http.c | 3 +- plugins/restful/log_handle.c | 207 ++++++++++++++++++++--------------- plugins/restful/log_handle.h | 4 +- 5 files changed, 127 insertions(+), 97 deletions(-) diff --git a/include/neuron/errcodes.h b/include/neuron/errcodes.h index c9e8f173..f3c7ba68 100644 --- a/include/neuron/errcodes.h +++ b/include/neuron/errcodes.h @@ -44,7 +44,8 @@ typedef enum { NEU_ERR_FILE_NOT_EXIST = 1011, NEU_ERR_INVALID_PASSWORD_LEN = 1012, NEU_ERR_DUPLICATE_PASSWORD = 1013, - NEU_ERR_LOG_LEVEL_NOT_EXIST = 1014, + NEU_ERR_LOG_LEVEL_IS_WRONG = 1014, + NEU_ERR_COMMAND_EXECUTION_FAILED = 1015, NEU_ERR_NODE_EXIST = 2002, NEU_ERR_NODE_NOT_EXIST = 2003, diff --git a/plugins/restful/handle.c b/plugins/restful/handle.c index 3af73654..f19f7b2d 100644 --- a/plugins/restful/handle.c +++ b/plugins/restful/handle.c @@ -95,9 +95,6 @@ struct neu_rest_handler cors_handler[] = { { .url = "/api/v2/node/state", }, - { - .url = "/api/v2/log", - }, { .url = "/api/v2/license", }, @@ -284,8 +281,8 @@ struct neu_rest_handler api_handlers[] = { { .method = NEU_REST_METHOD_GET, .type = NEU_REST_HANDLER_FUNCTION, - .url = "/api/v2/log", - .value.handler = handle_download_log, + .url = "/api/v2/logs", + .value.handler = handle_logs_files, }, { .method = NEU_REST_METHOD_PUT, diff --git a/plugins/restful/http.c b/plugins/restful/http.c index f0ac7d63..73e65786 100644 --- a/plugins/restful/http.c +++ b/plugins/restful/http.c @@ -307,7 +307,6 @@ int http_response(nng_aio *aio, neu_err_code_e code, char *content) break; case NEU_ERR_BODY_IS_WRONG: case NEU_ERR_PARAM_IS_WRONG: - case NEU_ERR_LOG_LEVEL_NOT_EXIST: case NEU_ERR_NODE_SETTING_INVALID: case NEU_ERR_LIBRARY_INFO_INVALID: case NEU_ERR_LICENSE_INVALID: @@ -328,6 +327,8 @@ int http_response(nng_aio *aio, neu_err_code_e code, char *content) case NEU_ERR_LICENSE_NOT_FOUND: case NEU_ERR_GROUP_NOT_EXIST: case NEU_ERR_GROUP_NOT_SUBSCRIBE: + case NEU_ERR_LOG_LEVEL_IS_WRONG: + case NEU_ERR_COMMAND_EXECUTION_FAILED: status = NNG_HTTP_STATUS_NOT_FOUND; break; case NEU_ERR_NODE_EXIST: diff --git a/plugins/restful/log_handle.c b/plugins/restful/log_handle.c index a150414d..356898b0 100644 --- a/plugins/restful/log_handle.c +++ b/plugins/restful/log_handle.c @@ -43,69 +43,82 @@ #include "utils/utarray.h" UT_array *collect_log_files(); -// void handle_get_log_files(nng_aio *aio); -// int read_log_file(const char *log_file, void **datap, size_t *lenp); -int read_file(const char *file_name, void **datap, size_t *lenp); -// int update_log_level(const char *file_name, const char *zlog_level); -void handle_download_log(nng_aio *aio) +// void handle_get_log_files(nng_aio *aio); +int read_file(const char *file_name, void **datap, size_t *lenp); +static int http_resp_files(nng_aio *aio, void *data, size_t len, + const char *disposition); + +void handle_logs_files(nng_aio *aio) { - int rv = 0; - char log_file[NEU_NODE_NAME_LEN] = { 0 }; + char path[128] = { 0 }; + char disp[128] = { 0 }; + void * data = NULL; + size_t len = 0; + int rv = 0; VALIDATE_JWT(aio); - rv = http_get_param_str(aio, "node_name", log_file, sizeof(log_file)); - if (-1 == rv || -2 == rv) { - nlog_error("parse query param `node_name` fail"); - NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, { + rv = mkdir("./neuron_logs", S_IRWXU); + if (0 != rv && EEXIST == errno) { + rv = 0; + } + + // check if coredump exists + rv = access("./core", F_OK); + if (0 == rv) { + rv = system("cp -r ./core ./neuron_logs"); + if (0 != rv) { + nlog_error("failed to copy coredump file"); + NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, { + http_response(aio, error_code.error, result_error); + }); + return; + } + } + + rv = system("cp -r ./logs ./neuron_logs"); + if (0 != rv) { + nlog_error("failed to copy logs file"); + NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, { http_response(aio, error_code.error, result_error); - }) - return; - } else if ((size_t) rv >= sizeof(log_file)) { - nlog_error("query param overflow, `log_file`:%s", log_file); - NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, { - http_response(aio, error_code.error, result_error); - }) + }); return; } - void * data = NULL; - size_t len = 0; - nng_http_res *res = NULL; - char path[128] = { 0 }; - - snprintf(path, sizeof(path), "./logs/%s.log", log_file); + rv = system("tar -zcvf neuron_logs.tar.gz ./neuron_logs"); + if (0 != rv) { + nlog_error("failed to create neuron_logs.tar.gz"); + NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, { + http_response(aio, error_code.error, result_error); + }); + return; + } + strcpy(path, "./neuron_logs.tar.gz"); rv = read_file(path, &data, &len); if (0 != rv) { NEU_JSON_RESPONSE_ERROR( rv, { http_response(aio, error_code.error, result_error); }); return; } - if (((rv = nng_http_res_alloc(&res)) != 0) || - ((rv = nng_http_res_set_status(res, NNG_HTTP_STATUS_OK)) != 0) || - ((rv = nng_http_res_set_header(res, "Content-Type", - "application/octet-stream")) != 0) || - ((rv = nng_http_res_set_header(res, "Content-Disposition", - "attachment; filename=log_file.log")) != - 0) || - ((rv = nng_http_res_set_header(res, "Access-Control-Allow-Origin", - "*")) != 0) || - ((rv = nng_http_res_set_header(res, "Access-Control-Allow-Methods", - "POST,GET,PUT,DELETE,OPTIONS")) != 0) || - ((rv = nng_http_res_set_header(res, "Access-Control-Allow-Headers", - "*")) != 0) || - ((rv = nng_http_res_copy_data(res, data, len)) != 0)) { - nng_http_res_free(res); - free(data); - nng_aio_finish(aio, rv); + + // delete neuron_logs folder from build + rv = system("rm -rf neuron_logs.tar.gz neuron_logs"); + if (0 != rv) { + nlog_error("failed to delete neuron_logs folder"); + NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, { + http_response(aio, error_code.error, result_error); + }); return; } - free(data); - nng_aio_set_output(aio, 0, res); - nng_aio_finish(aio, 0); + // handle http response + strcpy(disp, "attachment; filename=neuron_logs.tar.gz"); + rv = http_resp_files(aio, data, len, disp); + if (0 != rv) { + return; + } } void handle_log_level(nng_aio *aio) @@ -113,12 +126,20 @@ void handle_log_level(nng_aio *aio) REST_PROCESS_HTTP_REQUEST_VALIDATE_JWT( aio, neu_json_update_log_level_req_t, neu_json_decode_update_log_level_req, { - int rv = 0; - int lev = 0; - + int lev = 0; char level[NEU_LOG_LEVEL_LEN] = { 0 }; char node_name[NEU_NODE_NAME_LEN] = { 0 }; + UT_array *log_files = collect_log_files(); + + utarray_foreach(log_files, char **, log_file) + { + if (strncmp(*log_file, req->node_name, strlen(*log_file) - 4) == + 0) { + strcpy(node_name, req->node_name); + } + } + strcpy(level, req->level); if (strcmp(level, "DEBUG") == 0) { lev = ZLOG_LEVEL_DEBUG; @@ -132,59 +153,34 @@ void handle_log_level(nng_aio *aio) lev = ZLOG_LEVEL_NOTICE; } else if (strcmp(level, "FATAL") == 0) { lev = ZLOG_LEVEL_FATAL; - } else { - free(req); - - NEU_JSON_RESPONSE_ERROR(NEU_ERR_LOG_LEVEL_NOT_EXIST, { - http_response(aio, error_code.error, result_error); - }); - - return; - } - - UT_array *log_files = collect_log_files(); - utarray_foreach(log_files, char **, log_file) - { - if (strncmp(*log_file, req->node_name, strlen(*log_file) - 4) == - 0) { - strcpy(node_name, req->node_name); - } } if (strlen(node_name) == 0) { - utarray_free(log_files); - free(req); - NEU_JSON_RESPONSE_ERROR(NEU_ERR_NODE_NOT_EXIST, { http_response(aio, error_code.error, result_error); }); - - return; - } - - zlog_category_t *ct = zlog_get_category(node_name); - - rv = zlog_level_switch(ct, lev); - if (rv != 0) { - utarray_free(log_files); - free(req); - - nlog_error("Modify log level fail"); - NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, { + } else if (lev == 0) { + NEU_JSON_RESPONSE_ERROR(NEU_ERR_LOG_LEVEL_IS_WRONG, { http_response(aio, error_code.error, result_error); }); + } else { + zlog_category_t *ct = zlog_get_category(node_name); - return; + int rv = zlog_level_switch(ct, lev); + + if (rv != 0) { + nlog_error("Modify log level fail"); + NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, { + http_response(aio, error_code.error, result_error); + }); + } else { + NEU_JSON_RESPONSE_ERROR(NEU_ERR_SUCCESS, { + http_response(aio, NEU_ERR_SUCCESS, result_error); + }); + } } utarray_free(log_files); - free(req); - - NEU_JSON_RESPONSE_ERROR(NEU_ERR_SUCCESS, { - http_response(aio, NEU_ERR_SUCCESS, result_error); - }); - - return; }) } @@ -288,6 +284,41 @@ void handle_log_level(nng_aio *aio) // utarray_free(log_files); // } +static int http_resp_files(nng_aio *aio, void *data, size_t len, + const char *disposition) +{ + nng_http_res *res = NULL; + int rv = 0; + + if (((rv = nng_http_res_alloc(&res)) != 0) || + ((rv = nng_http_res_set_status(res, NNG_HTTP_STATUS_OK)) != 0) || + ((rv = nng_http_res_set_header(res, "Content-Type", + "application/octet-stream")) != 0) || + ((rv = nng_http_res_set_header(res, "Content-Disposition", + disposition)) != 0) || + ((rv = nng_http_res_set_header(res, "Access-Control-Allow-Origin", + "*")) != 0) || + ((rv = nng_http_res_set_header(res, "Access-Control-Allow-Methods", + "POST,GET,PUT,DELETE,OPTIONS")) != 0) || + ((rv = nng_http_res_set_header(res, "Access-Control-Allow-Headers", + "*")) != 0) || + ((rv = nng_http_res_set_header(res, "Access-Control-Expose-Headers", + "Content-Disposition")) != 0) || + ((rv = nng_http_res_copy_data(res, data, len)) != 0)) { + nng_http_res_free(res); + free(data); + nng_aio_finish(aio, rv); + + return -1; + } + + free(data); + nng_aio_set_output(aio, 0, res); + nng_aio_finish(aio, 0); + + return 0; +} + static inline bool ends_with(const char *str, const char *suffix) { size_t m = strlen(str); diff --git a/plugins/restful/log_handle.h b/plugins/restful/log_handle.h index f81706ff..7173ea7e 100644 --- a/plugins/restful/log_handle.h +++ b/plugins/restful/log_handle.h @@ -22,8 +22,8 @@ #include -void handle_get_log(nng_aio *aio); -void handle_download_log(nng_aio *aio); +// void handle_get_log(nng_aio *aio); +void handle_logs_files(nng_aio *aio); void handle_log_level(nng_aio *aio); #endif