mirror of
https://github.com/emqx/neuron.git
synced 2026-10-28 14:07:20 +08:00
Merge pull request #850 from lixiumei123/main
add(api):added api for download debug files
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
+119
-88
@@ -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);
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
#include <nng/nng.h>
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user