Merge pull request #1564 from eeff/eeff/dev

feat: support logs to remote syslog server
This commit is contained in:
fengzeroz
2023-10-08 14:33:05 +08:00
committed by GitHub
6 changed files with 143 additions and 17 deletions
+1
View File
@@ -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
View File
@@ -1,5 +1,7 @@
{
"ip": "0.0.0.0",
"port": 7000,
"disable_auth": 0
}
"disable_auth": 0,
"syslog_host": "",
"syslog_port": 541
}
+71 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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()) {
+1
View File
@@ -9,3 +9,4 @@ simple = "%d:%ms [%V] %f:%L %m%n"
[rules]
*.* "./logs/%c.log", 50MB * 1 ~ "./logs/%c.#2s.log"; simple
*.* $remote_syslog; simple