feature: support outputting stderr and file logs at the same time

This commit is contained in:
luwenpeng
2024-08-21 14:55:43 +08:00
parent 415c21440f
commit aed2daa1a4
9 changed files with 47 additions and 60 deletions

View File

@@ -1,4 +1,4 @@
[log] [log]
output = "stderr" # stderr, file output = "both" # stderr, file, both
file = "log/stellar.log" file = "log/stellar.log"
level = "ERROR" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL level = "ERROR" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL

View File

@@ -20,7 +20,7 @@
#include "plugin_manager.h" #include "plugin_manager.h"
#include "session_manager.h" #include "session_manager.h"
#define STELLAR_LOG_STATE(format, ...) LOG_STATE("stellar", format, ##__VA_ARGS__) #define STELLAR_LOG_FATAL(format, ...) LOG_FATAL("stellar", format, ##__VA_ARGS__)
#define STELLAR_LOG_ERROR(format, ...) LOG_ERROR("stellar", format, ##__VA_ARGS__) #define STELLAR_LOG_ERROR(format, ...) LOG_ERROR("stellar", format, ##__VA_ARGS__)
#define STELLAR_LOG_DEBUG(format, ...) LOG_DEBUG("stellar", format, ##__VA_ARGS__) #define STELLAR_LOG_DEBUG(format, ...) LOG_DEBUG("stellar", format, ##__VA_ARGS__)
@@ -210,7 +210,7 @@ static void *work_thread(void *arg)
} }
ATOMIC_SET(&thread->is_runing, 1); ATOMIC_SET(&thread->is_runing, 1);
STELLAR_LOG_STATE("worker thread %d runing", thr_idx); STELLAR_LOG_FATAL("worker thread %d runing", thr_idx);
while (ATOMIC_READ(&runtime->need_exit) == 0) while (ATOMIC_READ(&runtime->need_exit) == 0)
{ {
@@ -352,7 +352,7 @@ static void *work_thread(void *arg)
} }
ATOMIC_SET(&thread->is_runing, 0); ATOMIC_SET(&thread->is_runing, 0);
STELLAR_LOG_STATE("worker thread %d exit", thr_idx); STELLAR_LOG_FATAL("worker thread %d exit", thr_idx);
return NULL; return NULL;
} }
@@ -464,7 +464,7 @@ static void stellar_thread_join(struct stellar *st)
struct stellar_runtime *runtime = &st->runtime; struct stellar_runtime *runtime = &st->runtime;
struct stellar_config *config = &st->config; struct stellar_config *config = &st->config;
STELLAR_LOG_STATE("wait worker thread exit ..."); STELLAR_LOG_FATAL("wait worker thread exit ...");
for (uint16_t i = 0; i < config->pkt_io_opts.nr_threads; i++) for (uint16_t i = 0; i < config->pkt_io_opts.nr_threads; i++)
{ {
struct stellar_thread *thread = &runtime->threads[i]; struct stellar_thread *thread = &runtime->threads[i];
@@ -511,10 +511,10 @@ struct stellar *stellar_new(const char *stellar_cfg_file, const char *plugin_cfg
STELLAR_LOG_ERROR("unable to init log"); STELLAR_LOG_ERROR("unable to init log");
goto error_out; goto error_out;
} }
STELLAR_LOG_STATE("start stellar (version: %s)\n %s", version, logo_str); STELLAR_LOG_FATAL("start stellar (version: %s)\n %s", version, logo_str);
STELLAR_LOG_STATE("stellar config file : %s", st->stellar_cfg_file); STELLAR_LOG_FATAL("stellar config file : %s", st->stellar_cfg_file);
STELLAR_LOG_STATE("plugin config file : %s", st->plugin_cfg_file); STELLAR_LOG_FATAL("plugin config file : %s", st->plugin_cfg_file);
STELLAR_LOG_STATE("log config file : %s", st->log_cfg_file); STELLAR_LOG_FATAL("log config file : %s", st->log_cfg_file);
if (stellar_config_load(config, st->stellar_cfg_file) != 0) if (stellar_config_load(config, st->stellar_cfg_file) != 0)
{ {
@@ -597,7 +597,7 @@ void stellar_run(struct stellar *st)
if (packet_io_isbreak(runtime->packet_io) && all_session_have_freed(runtime, config)) if (packet_io_isbreak(runtime->packet_io) && all_session_have_freed(runtime, config))
{ {
stellar_stat_output(runtime->stat); // flush stat stellar_stat_output(runtime->stat); // flush stat
STELLAR_LOG_STATE("all sessions have been released, notify threads to exit"); STELLAR_LOG_FATAL("all sessions have been released, notify threads to exit");
ATOMIC_SET(&runtime->need_exit, 1); ATOMIC_SET(&runtime->need_exit, 1);
} }
} }
@@ -614,7 +614,7 @@ void stellar_free(struct stellar *st)
packet_io_free(runtime->packet_io); packet_io_free(runtime->packet_io);
plugin_manager_exit(runtime->plug_mgr); plugin_manager_exit(runtime->plug_mgr);
stellar_stat_free(runtime->stat); stellar_stat_free(runtime->stat);
STELLAR_LOG_STATE("stellar exit\n"); STELLAR_LOG_FATAL("stellar exit\n");
log_free(); log_free();
} }
} }
@@ -632,7 +632,7 @@ void stellar_reload_log_level(struct stellar *st)
{ {
if (st) if (st)
{ {
log_reload_level(st->log_cfg_file); log_level_reload(st->log_cfg_file);
} }
} }

View File

@@ -15,6 +15,7 @@ enum log_output
{ {
LOG_OUTPUT_STDERR, LOG_OUTPUT_STDERR,
LOG_OUTPUT_FILE, LOG_OUTPUT_FILE,
LOG_OUTPUT_BOTH,
}; };
struct log_config struct log_config
@@ -82,10 +83,6 @@ static inline enum log_level check_level(const char *level)
{ {
return LOG_FATAL; return LOG_FATAL;
} }
else if (strcasecmp(level, "STATE") == 0)
{
return LOG_STATE;
}
else else
{ {
return LOG_NONE; return LOG_NONE;
@@ -141,14 +138,17 @@ static int parse_config(struct log_config *config, const char *cfg_file)
{ {
config->output = LOG_OUTPUT_FILE; config->output = LOG_OUTPUT_FILE;
} }
else if (strcasecmp(temp, "both") == 0)
{
config->output = LOG_OUTPUT_BOTH;
}
else else
{ {
fprintf(stderr, "config file %s invalid log.output\n", cfg_file); fprintf(stderr, "config file %s invalid log.output\n", cfg_file);
goto error_out; goto error_out;
} }
// file if (config->output == LOG_OUTPUT_FILE || config->output == LOG_OUTPUT_BOTH)
if (config->output == LOG_OUTPUT_FILE)
{ {
ptr = toml_raw_in(log_section, "file"); ptr = toml_raw_in(log_section, "file");
temp = NULL; temp = NULL;
@@ -244,7 +244,7 @@ int log_init(const char *config_file)
return -1; return -1;
} }
if (g_log_context.config.output == LOG_OUTPUT_FILE) if (g_log_context.config.output == LOG_OUTPUT_FILE || g_log_context.config.output == LOG_OUTPUT_BOTH)
{ {
if (log_reopen() != 0) if (log_reopen() != 0)
{ {
@@ -257,7 +257,7 @@ int log_init(const char *config_file)
void log_free() void log_free()
{ {
if (g_log_ctx->config.output == LOG_OUTPUT_FILE) if (g_log_ctx->config.output == LOG_OUTPUT_FILE || g_log_ctx->config.output == LOG_OUTPUT_BOTH)
{ {
if (g_log_ctx->log_fd > 0) if (g_log_ctx->log_fd > 0)
{ {
@@ -267,12 +267,12 @@ void log_free()
} }
} }
int log_level_enabled(enum log_level level) int log_level_check(enum log_level level)
{ {
return level >= g_log_ctx->config.level; return level >= g_log_ctx->config.level;
} }
void log_reload_level(const char *config_file) void log_level_reload(const char *config_file)
{ {
struct log_config config; struct log_config config;
if (parse_config(&config, config_file) != 0) if (parse_config(&config, config_file) != 0)
@@ -308,18 +308,17 @@ void log_print(enum log_level level, const char *module, const char *fmt, ...)
// add end of line // add end of line
p += snprintf(p, end - p, "\n"); p += snprintf(p, end - p, "\n");
if (g_log_ctx->config.output == LOG_OUTPUT_STDERR) if (g_log_ctx->config.output == LOG_OUTPUT_STDERR || g_log_ctx->config.output == LOG_OUTPUT_BOTH)
{ {
fprintf(stderr, "%s", buf); fprintf(stderr, "%s", buf);
return;
} }
else
if (g_log_ctx->config.output == LOG_OUTPUT_FILE || g_log_ctx->config.output == LOG_OUTPUT_BOTH)
{ {
if (g_log_ctx->log_file_reopen_day != local.tm_mday) if (g_log_ctx->log_file_reopen_day != local.tm_mday)
{ {
log_reopen(); log_reopen();
} }
do do
{ {
nwrite = write(g_log_ctx->log_fd, buf, p - buf); nwrite = write(g_log_ctx->log_fd, buf, p - buf);

View File

@@ -14,58 +14,51 @@ enum log_level
LOG_WARN = 3, LOG_WARN = 3,
LOG_ERROR = 4, LOG_ERROR = 4,
LOG_FATAL = 5, LOG_FATAL = 5,
LOG_STATE = 6,
}; };
#define LOG_TRACE(module, format, ...) \ #define LOG_TRACE(module, format, ...) \
if (log_level_enabled(LOG_TRACE)) \ if (log_level_check(LOG_TRACE)) \
{ \ { \
log_print(LOG_TRACE, module, format, ##__VA_ARGS__); \ log_print(LOG_TRACE, module, format, ##__VA_ARGS__); \
} }
#define LOG_DEBUG(module, format, ...) \ #define LOG_DEBUG(module, format, ...) \
if (log_level_enabled(LOG_DEBUG)) \ if (log_level_check(LOG_DEBUG)) \
{ \ { \
log_print(LOG_DEBUG, module, format, ##__VA_ARGS__); \ log_print(LOG_DEBUG, module, format, ##__VA_ARGS__); \
} }
#define LOG_INFO(module, format, ...) \ #define LOG_INFO(module, format, ...) \
if (log_level_enabled(LOG_INFO)) \ if (log_level_check(LOG_INFO)) \
{ \ { \
log_print(LOG_INFO, module, format, ##__VA_ARGS__); \ log_print(LOG_INFO, module, format, ##__VA_ARGS__); \
} }
#define LOG_WARN(module, format, ...) \ #define LOG_WARN(module, format, ...) \
if (log_level_enabled(LOG_WARN)) \ if (log_level_check(LOG_WARN)) \
{ \ { \
log_print(LOG_WARN, module, format, ##__VA_ARGS__); \ log_print(LOG_WARN, module, format, ##__VA_ARGS__); \
} }
#define LOG_ERROR(module, format, ...) \ #define LOG_ERROR(module, format, ...) \
if (log_level_enabled(LOG_ERROR)) \ if (log_level_check(LOG_ERROR)) \
{ \ { \
log_print(LOG_ERROR, module, format, ##__VA_ARGS__); \ log_print(LOG_ERROR, module, format, ##__VA_ARGS__); \
} }
#define LOG_FATAL(module, format, ...) \ #define LOG_FATAL(module, format, ...) \
if (log_level_enabled(LOG_FATAL)) \ if (log_level_check(LOG_FATAL)) \
{ \ { \
log_print(LOG_FATAL, module, format, ##__VA_ARGS__); \ log_print(LOG_FATAL, module, format, ##__VA_ARGS__); \
} }
#define LOG_STATE(module, format, ...) \
if (log_level_enabled(LOG_STATE)) \
{ \
log_print(LOG_STATE, module, format, ##__VA_ARGS__); \
}
// return 0: success // return 0: success
// return -1: failed // return -1: failed
int log_init(const char *config_file); int log_init(const char *config_file);
void log_free(); void log_free();
int log_level_enabled(enum log_level level); int log_level_check(enum log_level level);
void log_reload_level(const char *config_file); void log_level_reload(const char *config_file);
void log_print(enum log_level level, const char *module, const char *fmt, ...); void log_print(enum log_level level, const char *module, const char *fmt, ...);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -1,4 +1,4 @@
[log] [log]
output = "file" # stderr, file output = "file" # stderr, file, both
file = "stellar.log" file = "stellar.log"
level = "DEBUG" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL level = "DEBUG" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL

View File

@@ -1,4 +1,4 @@
[log] [log]
output = "stderr" # stderr, file output = "stderr" # stderr, file, both
file = "stellar.log" file = "stellar.log"
level = "DEBUG" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL level = "DEBUG" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL

View File

@@ -16,10 +16,9 @@ TEST(LOG, STDERR)
LOG_WARN("test", "test log 1"); LOG_WARN("test", "test log 1");
LOG_ERROR("test", "test log 1"); LOG_ERROR("test", "test log 1");
LOG_FATAL("test", "test log 1"); LOG_FATAL("test", "test log 1");
LOG_STATE("test", "test log 1");
system(buffer); system(buffer);
log_reload_level(config); log_level_reload(config);
LOG_TRACE("test", "test log 2"); LOG_TRACE("test", "test log 2");
LOG_DEBUG("test", "test log 2"); LOG_DEBUG("test", "test log 2");
@@ -27,7 +26,6 @@ TEST(LOG, STDERR)
LOG_WARN("test", "test log 2"); LOG_WARN("test", "test log 2");
LOG_ERROR("test", "test log 2"); LOG_ERROR("test", "test log 2");
LOG_FATAL("test", "test log 2"); LOG_FATAL("test", "test log 2");
LOG_STATE("test", "test log 2");
log_free(); log_free();
} }
@@ -47,10 +45,9 @@ TEST(LOG, FILE)
LOG_WARN("test", "test log 1"); LOG_WARN("test", "test log 1");
LOG_ERROR("test", "test log 1"); LOG_ERROR("test", "test log 1");
LOG_FATAL("test", "test log 1"); LOG_FATAL("test", "test log 1");
LOG_STATE("test", "test log 1");
system(buffer); system(buffer);
log_reload_level(config); log_level_reload(config);
LOG_TRACE("test", "test log 2"); LOG_TRACE("test", "test log 2");
LOG_DEBUG("test", "test log 2"); LOG_DEBUG("test", "test log 2");
@@ -58,7 +55,6 @@ TEST(LOG, FILE)
LOG_WARN("test", "test log 2"); LOG_WARN("test", "test log 2");
LOG_ERROR("test", "test log 2"); LOG_ERROR("test", "test log 2");
LOG_FATAL("test", "test log 2"); LOG_FATAL("test", "test log 2");
LOG_STATE("test", "test log 2");
log_free(); log_free();
} }
@@ -85,7 +81,6 @@ TEST(LOG, REOPEN)
LOG_WARN("test", "test log %d", i); LOG_WARN("test", "test log %d", i);
LOG_ERROR("test", "test log %d", i); LOG_ERROR("test", "test log %d", i);
LOG_FATAL("test", "test log %d", i); LOG_FATAL("test", "test log %d", i);
LOG_STATE("test", "test log %d", i);
if (i == 1) if (i == 1)
{ {
system(buffer2); // set date to 2099/01/01 system(buffer2); // set date to 2099/01/01

View File

@@ -17,7 +17,7 @@
#include "packet_parser.h" #include "packet_parser.h"
#include "packet_dump.h" #include "packet_dump.h"
#define PACKET_IO_LOG_STATE(format, ...) LOG_STATE("dumpfile", format, ##__VA_ARGS__) #define PACKET_IO_LOG_FATAL(format, ...) LOG_FATAL("dumpfile", format, ##__VA_ARGS__)
#define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("dumpfile", format, ##__VA_ARGS__) #define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("dumpfile", format, ##__VA_ARGS__)
#define MAX_PACKET_QUEUE_SIZE (4096 * 1000) #define MAX_PACKET_QUEUE_SIZE (4096 * 1000)
@@ -157,7 +157,7 @@ static void pcap_pkt_handler(u_char *user, const struct pcap_pkthdr *h, const u_
if (ATOMIC_READ(&handle->io_thread_need_exit)) if (ATOMIC_READ(&handle->io_thread_need_exit))
{ {
free(pcap_pkt); free(pcap_pkt);
PACKET_IO_LOG_STATE("dumpfile io thread need exit"); PACKET_IO_LOG_FATAL("dumpfile io thread need exit");
pcap_breakloop(handle->pcap); pcap_breakloop(handle->pcap);
break; break;
} }
@@ -166,7 +166,7 @@ static void pcap_pkt_handler(u_char *user, const struct pcap_pkthdr *h, const u_
if (ATOMIC_READ(&handle->io_thread_need_exit)) if (ATOMIC_READ(&handle->io_thread_need_exit))
{ {
PACKET_IO_LOG_STATE("dumpfile io thread need exit"); PACKET_IO_LOG_FATAL("dumpfile io thread need exit");
pcap_breakloop(handle->pcap); pcap_breakloop(handle->pcap);
} }
} }
@@ -177,7 +177,7 @@ static int dumpfile_handler(struct dumpfile_io *handle, const char *pcap_file)
char pcap_errbuf[PCAP_ERRBUF_SIZE]; char pcap_errbuf[PCAP_ERRBUF_SIZE];
realpath(pcap_file, resolved_path); realpath(pcap_file, resolved_path);
PACKET_IO_LOG_STATE("dumpfile %s in-processing", resolved_path) PACKET_IO_LOG_FATAL("dumpfile %s in-processing", resolved_path)
handle->pcap = pcap_open_offline(resolved_path, pcap_errbuf); handle->pcap = pcap_open_offline(resolved_path, pcap_errbuf);
if (handle->pcap == NULL) if (handle->pcap == NULL)
@@ -188,7 +188,7 @@ static int dumpfile_handler(struct dumpfile_io *handle, const char *pcap_file)
pcap_loop(handle->pcap, -1, pcap_pkt_handler, (u_char *)handle); pcap_loop(handle->pcap, -1, pcap_pkt_handler, (u_char *)handle);
pcap_close(handle->pcap); pcap_close(handle->pcap);
PACKET_IO_LOG_STATE("dumpfile %s processed", resolved_path) PACKET_IO_LOG_FATAL("dumpfile %s processed", resolved_path)
return 0; return 0;
} }
@@ -210,7 +210,7 @@ static void *dumpfile_thread(void *arg)
struct dumpfile_io *handle = (struct dumpfile_io *)arg; struct dumpfile_io *handle = (struct dumpfile_io *)arg;
ATOMIC_SET(&handle->io_thread_is_runing, 1); ATOMIC_SET(&handle->io_thread_is_runing, 1);
PACKET_IO_LOG_STATE("dumpfile io thread is running"); PACKET_IO_LOG_FATAL("dumpfile io thread is running");
if (handle->mode == PACKET_IO_DUMPFILE) if (handle->mode == PACKET_IO_DUMPFILE)
{ {
@@ -257,7 +257,7 @@ static void *dumpfile_thread(void *arg)
} }
erro_out: erro_out:
PACKET_IO_LOG_STATE("dumpfile io thread processed all pcap files"); PACKET_IO_LOG_FATAL("dumpfile io thread processed all pcap files");
while (ATOMIC_READ(&handle->io_thread_need_exit) == 0) while (ATOMIC_READ(&handle->io_thread_need_exit) == 0)
{ {
@@ -269,7 +269,7 @@ erro_out:
usleep(1000); // 1ms usleep(1000); // 1ms
} }
PACKET_IO_LOG_STATE("dumpfile io thread exit"); PACKET_IO_LOG_FATAL("dumpfile io thread exit");
ATOMIC_SET(&handle->io_thread_is_runing, 0); ATOMIC_SET(&handle->io_thread_is_runing, 0);
return NULL; return NULL;
@@ -485,7 +485,7 @@ uint16_t dumpfile_io_inject(struct dumpfile_io *handle, uint16_t thr_idx, struct
} }
else else
{ {
PACKET_IO_LOG_STATE("dump inject packet: %s", file); PACKET_IO_LOG_FATAL("dump inject packet: %s", file);
} }
packet_free(pkt); packet_free(pkt);
} }

View File

@@ -1,4 +1,4 @@
[log] [log]
output = "stderr" # stderr, file output = "stderr" # stderr, file, both
level = "DEBUG" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL level = "DEBUG" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL
file = "log/stellar.log" file = "log/stellar.log"