mirror of
https://github.com/emqx/neuron.git
synced 2026-10-29 07:06:32 +08:00
Merge pull request #1564 from eeff/eeff/dev
feat: support logs to remote syslog server
This commit is contained in:
@@ -11,3 +11,4 @@ file_format = "%d:%ms [%V] %f:%L %m%n"
|
||||
|
||||
*.* "./logs/%c.log", 50MB * 1 ~ "./logs/%c.#2s.log"; file_format
|
||||
*.* >stdout; stdout_format
|
||||
*.* $remote_syslog; file_format
|
||||
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"ip": "0.0.0.0",
|
||||
"port": 7000,
|
||||
"disable_auth": 0
|
||||
}
|
||||
"disable_auth": 0,
|
||||
"syslog_host": "",
|
||||
"syslog_port": 541
|
||||
}
|
||||
|
||||
+71
-4
@@ -78,6 +78,8 @@ const char *usage_text =
|
||||
" --config_file <PATH> startup parameter configuration file\n"
|
||||
" --config_dir <DIR> directory from which neuron reads configuration\n"
|
||||
" --plugin_dir <DIR> directory from which neuron loads plugin lib files\n"
|
||||
" --syslog_host <HOST> syslog server host to which neuron will send logs\n"
|
||||
" --syslog_port <PORT> syslog server port (default 541 if not provided)\n"
|
||||
"\n";
|
||||
// clang-format on
|
||||
|
||||
@@ -225,6 +227,25 @@ static inline int load_env(neu_cli_args_t *args, char **log_level_out,
|
||||
}
|
||||
*plugin_dir_out = strdup(plugin_dir);
|
||||
}
|
||||
|
||||
char *syslog_host = getenv(NEU_ENV_SYSLOG_HOST);
|
||||
if (NULL != syslog_host) {
|
||||
if (NULL != args->syslog_host) {
|
||||
free(args->syslog_host);
|
||||
}
|
||||
args->syslog_host = strdup(syslog_host);
|
||||
}
|
||||
|
||||
char *syslog_port = getenv(NEU_ENV_SYSLOG_PORT);
|
||||
if (NULL != syslog_port) {
|
||||
int port = atoi(syslog_port);
|
||||
if (port < 1 || 65535 < port) {
|
||||
printf("neuron %s setting invalid!\n", NEU_ENV_SYSLOG_PORT);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
args->syslog_port = port;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
@@ -262,9 +283,13 @@ static inline int load_config_file(int argc, char *argv[],
|
||||
int fd = -1;
|
||||
void *root = NULL;
|
||||
|
||||
neu_json_elem_t elems[] = { { .name = "disable_auth", .t = NEU_JSON_INT },
|
||||
{ .name = "ip", .t = NEU_JSON_STR },
|
||||
{ .name = "port", .t = NEU_JSON_INT } };
|
||||
neu_json_elem_t elems[] = {
|
||||
{ .name = "disable_auth", .t = NEU_JSON_INT },
|
||||
{ .name = "ip", .t = NEU_JSON_STR },
|
||||
{ .name = "port", .t = NEU_JSON_INT },
|
||||
{ .name = "syslog_host", .t = NEU_JSON_STR },
|
||||
{ .name = "syslog_port", .t = NEU_JSON_INT },
|
||||
};
|
||||
|
||||
resolve_config_file_path(argc, argv, long_options, opts, &config_file);
|
||||
|
||||
@@ -298,7 +323,8 @@ static inline int load_config_file(int argc, char *argv[],
|
||||
break;
|
||||
}
|
||||
|
||||
if (neu_json_decode_by_json(root, 3, elems) == 0) {
|
||||
if (neu_json_decode_by_json(root, NEU_JSON_ELEM_SIZE(elems), elems) ==
|
||||
0) {
|
||||
if (elems[0].v.val_int == 1) {
|
||||
args->disable_auth = true;
|
||||
} else if (elems[0].v.val_int == 0) {
|
||||
@@ -325,6 +351,24 @@ static inline int load_config_file(int argc, char *argv[],
|
||||
break;
|
||||
}
|
||||
|
||||
if (elems[3].v.val_str != NULL) {
|
||||
if (strlen(elems[3].v.val_str) > 0) {
|
||||
args->syslog_host = strdup(elems[3].v.val_str);
|
||||
}
|
||||
} else {
|
||||
printf("config file %s syslog_host setting error!\n",
|
||||
config_file);
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 < elems[4].v.val_int && elems[4].v.val_int < 65536) {
|
||||
args->syslog_port = elems[4].v.val_int;
|
||||
} else {
|
||||
printf("config file %s syslog_port setting invalid!\n",
|
||||
config_file);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
} else {
|
||||
printf("config file %s elems error! must had ip, port and "
|
||||
@@ -350,6 +394,10 @@ static inline int load_config_file(int argc, char *argv[],
|
||||
free(elems[1].v.val_str);
|
||||
}
|
||||
|
||||
if (elems[3].v.val_str != NULL) {
|
||||
free(elems[3].v.val_str);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -374,6 +422,8 @@ void neu_cli_args_init(neu_cli_args_t *args, int argc, char *argv[])
|
||||
{ "config_dir", required_argument, NULL, 'c' },
|
||||
{ "plugin_dir", required_argument, NULL, 'p' },
|
||||
{ "stop", no_argument, NULL, 's' },
|
||||
{ "syslog_host", required_argument, NULL, 'S' },
|
||||
{ "syslog_port", required_argument, NULL, 'P' },
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
||||
@@ -451,6 +501,22 @@ void neu_cli_args_init(neu_cli_args_t *args, int argc, char *argv[])
|
||||
}
|
||||
plugin_dir = strdup(optarg);
|
||||
break;
|
||||
case 'P': {
|
||||
int syslog_port = atoi(optarg);
|
||||
if (syslog_port < 1 || 65535 < syslog_port) {
|
||||
fprintf(stderr, "%s: option '--syslog_port' invalid : `%s`\n",
|
||||
argv[0], optarg);
|
||||
goto quit;
|
||||
}
|
||||
args->syslog_port = syslog_port;
|
||||
break;
|
||||
}
|
||||
case 'S':
|
||||
if (args->syslog_host) {
|
||||
free(args->syslog_host);
|
||||
}
|
||||
args->syslog_host = strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@@ -525,5 +591,6 @@ void neu_cli_args_fini(neu_cli_args_t *args)
|
||||
free(args->config_dir);
|
||||
free(args->plugin_dir);
|
||||
free(args->ip);
|
||||
free(args->syslog_host);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-10
@@ -33,6 +33,8 @@
|
||||
#define NEU_ENV_DISABLE_AUTH "NEURON_DISABLE_AUTH"
|
||||
#define NEU_ENV_CONFIG_DIR "NEURON_CONFIG_DIR"
|
||||
#define NEU_ENV_PLUGIN_DIR "NEURON_PLUGIN_DIR"
|
||||
#define NEU_ENV_SYSLOG_HOST "NEURON_SYSLOG_HOST"
|
||||
#define NEU_ENV_SYSLOG_PORT "NEURON_SYSLOG_PORT"
|
||||
|
||||
#define NEURON_CONFIG_FNAME "./config/neuron.json"
|
||||
|
||||
@@ -41,6 +43,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern const char *g_config_dir;
|
||||
@@ -49,16 +52,18 @@ extern const char *g_plugin_dir;
|
||||
/** Neuron command line arguments.
|
||||
*/
|
||||
typedef struct {
|
||||
bool daemonized; // flag indicating whether to run as daemon process
|
||||
bool dev_log; // logging for development
|
||||
size_t restart; // restart policy
|
||||
bool disable_auth;
|
||||
char * log_init_file;
|
||||
char * config_dir;
|
||||
char * plugin_dir;
|
||||
bool stop;
|
||||
char * ip;
|
||||
int port;
|
||||
bool daemonized; // flag indicating whether to run as daemon process
|
||||
bool dev_log; // logging for development
|
||||
size_t restart; // restart policy
|
||||
bool disable_auth;
|
||||
char * log_init_file;
|
||||
char * config_dir;
|
||||
char * plugin_dir;
|
||||
bool stop;
|
||||
char * ip;
|
||||
int port;
|
||||
char * syslog_host;
|
||||
uint16_t syslog_port;
|
||||
} neu_cli_args_t;
|
||||
|
||||
/** Parse command line arguments.
|
||||
|
||||
+51
-1
@@ -17,8 +17,13 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -39,6 +44,11 @@ char host_port[32] = { 0 };
|
||||
|
||||
int64_t global_timestamp = 0;
|
||||
|
||||
struct {
|
||||
struct sockaddr_in addr;
|
||||
int fd;
|
||||
} g_remote_syslog_ctx;
|
||||
|
||||
static void sig_handler(int sig)
|
||||
{
|
||||
nlog_warn("recv sig: %d", sig);
|
||||
@@ -52,6 +62,40 @@ static void sig_handler(int sig)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static int remote_syslog(zlog_msg_t *msg)
|
||||
{
|
||||
sendto(g_remote_syslog_ctx.fd, msg->buf, msg->len, 0,
|
||||
(const struct sockaddr *) &g_remote_syslog_ctx.addr,
|
||||
sizeof(g_remote_syslog_ctx.addr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config_remote_syslog(const char *host, uint16_t port)
|
||||
{
|
||||
g_remote_syslog_ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (g_remote_syslog_ctx.fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_remote_syslog_ctx.addr.sin_family = AF_INET;
|
||||
g_remote_syslog_ctx.addr.sin_port = htons(port);
|
||||
g_remote_syslog_ctx.addr.sin_addr.s_addr = inet_addr(host);
|
||||
|
||||
if (0 == inet_pton(AF_INET, host, &g_remote_syslog_ctx.addr.sin_addr)) {
|
||||
// not an valid ip address, try resolve as host name
|
||||
struct hostent *he = gethostbyname(host);
|
||||
if (NULL == he) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&g_remote_syslog_ctx.addr.sin_addr, he->h_addr_list[0],
|
||||
he->h_length);
|
||||
}
|
||||
|
||||
zlog_set_record("remote_syslog", remote_syslog);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int neuron_run(const neu_cli_args_t *args)
|
||||
{
|
||||
struct rlimit rl = { 0 };
|
||||
@@ -107,8 +151,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
zlog_init(args.log_init_file);
|
||||
neuron = zlog_get_category("neuron");
|
||||
|
||||
if (args.syslog_host && strlen(args.syslog_host) > 0 &&
|
||||
0 != config_remote_syslog(args.syslog_host, args.syslog_port)) {
|
||||
nlog_fatal("neuron setup remote syslog fail, exit.");
|
||||
goto main_end;
|
||||
}
|
||||
|
||||
neuron = zlog_get_category("neuron");
|
||||
zlog_level_switch(neuron, default_log_level);
|
||||
|
||||
if (neuron_already_running()) {
|
||||
|
||||
Reference in New Issue
Block a user