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]
output = "stderr" # stderr, file
output = "both" # stderr, file, both
file = "log/stellar.log"
level = "ERROR" # TRACE, DEBUG, INFO, WARN, ERROR, FATAL

View File

@@ -20,7 +20,7 @@
#include "plugin_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_DEBUG(format, ...) LOG_DEBUG("stellar", format, ##__VA_ARGS__)
@@ -210,7 +210,7 @@ static void *work_thread(void *arg)
}
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)
{
@@ -352,7 +352,7 @@ static void *work_thread(void *arg)
}
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;
}
@@ -464,7 +464,7 @@ static void stellar_thread_join(struct stellar *st)
struct stellar_runtime *runtime = &st->runtime;
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++)
{
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");
goto error_out;
}
STELLAR_LOG_STATE("start stellar (version: %s)\n %s", version, logo_str);
STELLAR_LOG_STATE("stellar config file : %s", st->stellar_cfg_file);
STELLAR_LOG_STATE("plugin config file : %s", st->plugin_cfg_file);
STELLAR_LOG_STATE("log config file : %s", st->log_cfg_file);
STELLAR_LOG_FATAL("start stellar (version: %s)\n %s", version, logo_str);
STELLAR_LOG_FATAL("stellar config file : %s", st->stellar_cfg_file);
STELLAR_LOG_FATAL("plugin config file : %s", st->plugin_cfg_file);
STELLAR_LOG_FATAL("log config file : %s", st->log_cfg_file);
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))
{
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);
}
}
@@ -614,7 +614,7 @@ void stellar_free(struct stellar *st)
packet_io_free(runtime->packet_io);
plugin_manager_exit(runtime->plug_mgr);
stellar_stat_free(runtime->stat);
STELLAR_LOG_STATE("stellar exit\n");
STELLAR_LOG_FATAL("stellar exit\n");
log_free();
}
}
@@ -632,7 +632,7 @@ void stellar_reload_log_level(struct stellar *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_FILE,
LOG_OUTPUT_BOTH,
};
struct log_config
@@ -82,10 +83,6 @@ static inline enum log_level check_level(const char *level)
{
return LOG_FATAL;
}
else if (strcasecmp(level, "STATE") == 0)
{
return LOG_STATE;
}
else
{
return LOG_NONE;
@@ -141,14 +138,17 @@ static int parse_config(struct log_config *config, const char *cfg_file)
{
config->output = LOG_OUTPUT_FILE;
}
else if (strcasecmp(temp, "both") == 0)
{
config->output = LOG_OUTPUT_BOTH;
}
else
{
fprintf(stderr, "config file %s invalid log.output\n", cfg_file);
goto error_out;
}
// file
if (config->output == LOG_OUTPUT_FILE)
if (config->output == LOG_OUTPUT_FILE || config->output == LOG_OUTPUT_BOTH)
{
ptr = toml_raw_in(log_section, "file");
temp = NULL;
@@ -244,7 +244,7 @@ int log_init(const char *config_file)
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)
{
@@ -257,7 +257,7 @@ int log_init(const char *config_file)
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)
{
@@ -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;
}
void log_reload_level(const char *config_file)
void log_level_reload(const char *config_file)
{
struct log_config config;
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
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);
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)
{
log_reopen();
}
do
{
nwrite = write(g_log_ctx->log_fd, buf, p - buf);

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,7 +17,7 @@
#include "packet_parser.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 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))
{
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);
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))
{
PACKET_IO_LOG_STATE("dumpfile io thread need exit");
PACKET_IO_LOG_FATAL("dumpfile io thread need exit");
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];
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);
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_close(handle->pcap);
PACKET_IO_LOG_STATE("dumpfile %s processed", resolved_path)
PACKET_IO_LOG_FATAL("dumpfile %s processed", resolved_path)
return 0;
}
@@ -210,7 +210,7 @@ static void *dumpfile_thread(void *arg)
struct dumpfile_io *handle = (struct dumpfile_io *)arg;
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)
{
@@ -257,7 +257,7 @@ static void *dumpfile_thread(void *arg)
}
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)
{
@@ -269,7 +269,7 @@ erro_out:
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);
return NULL;
@@ -485,7 +485,7 @@ uint16_t dumpfile_io_inject(struct dumpfile_io *handle, uint16_t thr_idx, struct
}
else
{
PACKET_IO_LOG_STATE("dump inject packet: %s", file);
PACKET_IO_LOG_FATAL("dump inject packet: %s", file);
}
packet_free(pkt);
}

View File

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