feature: support outputting stderr and file logs at the same time
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user