wslog: Improve code modularity and efficiency
Also tweak format for readability.
This commit is contained in:
parent
c025e793dd
commit
82739fc4f5
|
@ -227,8 +227,8 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
ws_init_sockets@Base 3.1.0
|
||||
ws_log@Base 3.5.0
|
||||
ws_log_add_custom_file@Base 3.5.0
|
||||
ws_log_default_writer@Base 3.5.0
|
||||
ws_log_domain_to_string@Base 3.5.0
|
||||
ws_log_fprint@Base 3.5.0
|
||||
ws_log_full@Base 3.5.0
|
||||
ws_log_get_level@Base 3.5.0
|
||||
ws_log_init@Base 3.5.0
|
||||
|
|
36
dumpcap.c
36
dumpcap.c
|
@ -327,8 +327,11 @@ static gboolean need_timeout_workaround;
|
|||
#define WRITER_THREAD_TIMEOUT 100000 /* usecs */
|
||||
|
||||
static void
|
||||
dumpcap_log_writer(const char *message, enum ws_log_domain domain,
|
||||
enum ws_log_level level, void *ptr);
|
||||
dumpcap_log_writer(const char *format, va_list ap,
|
||||
const char *prefix,
|
||||
enum ws_log_domain domain,
|
||||
enum ws_log_level level,
|
||||
void *user_data);
|
||||
|
||||
/* capture related options */
|
||||
static capture_options global_capture_opts;
|
||||
|
@ -5567,29 +5570,30 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
static void
|
||||
dumpcap_log_writer(const char *message, enum ws_log_domain domain _U_,
|
||||
enum ws_log_level level _U_, void *ptr _U_)
|
||||
dumpcap_log_writer(const char *format, va_list ap,
|
||||
const char *prefix,
|
||||
enum ws_log_domain domain _U_,
|
||||
enum ws_log_level level _U_,
|
||||
void *user_data _U_)
|
||||
{
|
||||
#if defined(DEBUG_DUMPCAP) || defined(DEBUG_CHILD_DUMPCAP)
|
||||
#ifdef DEBUG_DUMPCAP
|
||||
fprintf(stderr, "%s\n", message);
|
||||
fflush(stderr);
|
||||
ws_log_fprint(stderr, format, ap, prefix);
|
||||
#endif
|
||||
#ifdef DEBUG_CHILD_DUMPCAP
|
||||
fprintf(debug_log, "%s\n", message);
|
||||
fflush(debug_log);
|
||||
ws_log_fprint(debug_log, format, ap, prefix);
|
||||
#endif
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Messages goto stderr or */
|
||||
/* to parent especially formatted if dumpcap running as child. */
|
||||
#else
|
||||
/* Messages goto stderr or to parent especially formatted if dumpcap
|
||||
* is running as child. */
|
||||
if (capture_child) {
|
||||
sync_pipe_errmsg_to_parent(2, message, "");
|
||||
gchar *msg = g_strdup_vprintf(format, ap);
|
||||
sync_pipe_errmsg_to_parent(2, msg, "");
|
||||
g_free(msg);
|
||||
} else {
|
||||
fprintf(stderr, "%s", message);
|
||||
fflush(stderr);
|
||||
ws_log_fprint(stderr, format, ap, prefix);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
12
ui/console.c
12
ui/console.c
|
@ -19,8 +19,9 @@
|
|||
#include "console.h"
|
||||
|
||||
void
|
||||
console_log_writer(const char *message, enum ws_log_domain domain _U_,
|
||||
enum ws_log_level level, void *ptr _U_)
|
||||
console_log_writer(const char *format, va_list ap,
|
||||
const char *prefix, enum ws_log_domain domain _U_,
|
||||
enum ws_log_level level _U_, void *ptr _U_)
|
||||
{
|
||||
gboolean fatal = level == LOG_LEVEL_ERROR;
|
||||
#ifdef _WIN32
|
||||
|
@ -32,12 +33,7 @@ console_log_writer(const char *message, enum ws_log_domain domain _U_,
|
|||
(void)fatal;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
FILE *fp = stderr;
|
||||
g_assert(message);
|
||||
|
||||
fputs(message, fp);
|
||||
fputc('\n', fp);
|
||||
fflush(fp);
|
||||
ws_log_fprint(stderr, format, ap, prefix);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (fatal) {
|
||||
|
|
|
@ -26,7 +26,8 @@ extern "C" {
|
|||
/** The GUI log writer.
|
||||
*/
|
||||
void
|
||||
console_log_writer(const char *message, enum ws_log_domain domain,
|
||||
console_log_writer(const char *format, va_list ap,
|
||||
const char *prefix, enum ws_log_domain domain,
|
||||
enum ws_log_level level, void *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
191
wsutil/wslog.c
191
wsutil/wslog.c
|
@ -18,7 +18,7 @@
|
|||
#include <wsutil/ws_assert.h>
|
||||
#include <wsutil/time_util.h>
|
||||
|
||||
#define LOGBUFSIZE 256
|
||||
#define PREFIX_BUFSIZE 128
|
||||
|
||||
#define LOGENVVAR "WS_LOG_LEVEL"
|
||||
|
||||
|
@ -27,11 +27,11 @@
|
|||
|
||||
static enum ws_log_level current_log_level = LOG_LEVEL_MESSAGE;
|
||||
|
||||
static ws_log_writer_t *current_log_writer = ws_log_default_writer;
|
||||
static ws_log_writer_cb *registered_log_writer = NULL;
|
||||
|
||||
static void *current_log_writer_data = NULL;
|
||||
static void *registered_log_writer_data = NULL;
|
||||
|
||||
static ws_log_writer_free_data_t *current_log_writer_data_free = NULL;
|
||||
static ws_log_writer_free_data_cb *registered_log_writer_data_free = NULL;
|
||||
|
||||
static FILE *custom_log = NULL;
|
||||
|
||||
|
@ -39,26 +39,17 @@ static FILE *custom_log = NULL;
|
|||
static void ws_log_cleanup(void);
|
||||
|
||||
|
||||
static void
|
||||
log_default_writer_do_work(FILE *fp, const char *message)
|
||||
void
|
||||
ws_log_fprint(FILE *fp, const char *format, va_list ap,
|
||||
const char *prefix)
|
||||
{
|
||||
ws_assert(message);
|
||||
fputs(message, fp);
|
||||
fputs(prefix, fp);
|
||||
vfprintf(fp, format, ap);
|
||||
fputc('\n', fp);
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ws_log_default_writer(const char *message,
|
||||
enum ws_log_domain domain _U_,
|
||||
enum ws_log_level level _U_,
|
||||
void *user_data _U_)
|
||||
{
|
||||
log_default_writer_do_work(stderr, message);
|
||||
}
|
||||
|
||||
|
||||
const char *ws_log_level_to_string(enum ws_log_level level)
|
||||
{
|
||||
switch (level) {
|
||||
|
@ -213,10 +204,10 @@ const char *ws_log_set_level_args(int *argc_ptr, char *argv[])
|
|||
}
|
||||
|
||||
|
||||
void ws_log_init(ws_log_writer_t *_writer)
|
||||
void ws_log_init(ws_log_writer_cb *_writer)
|
||||
{
|
||||
if (_writer) {
|
||||
current_log_writer = _writer;
|
||||
registered_log_writer = _writer;
|
||||
}
|
||||
|
||||
const char *env = g_getenv(LOGENVVAR);
|
||||
|
@ -228,32 +219,32 @@ void ws_log_init(ws_log_writer_t *_writer)
|
|||
}
|
||||
|
||||
|
||||
void ws_log_init_with_data(ws_log_writer_t *writer, void *user_data,
|
||||
ws_log_writer_free_data_t *free_user_data)
|
||||
void ws_log_init_with_data(ws_log_writer_cb *writer, void *user_data,
|
||||
ws_log_writer_free_data_cb *free_user_data)
|
||||
{
|
||||
current_log_writer_data = user_data;
|
||||
current_log_writer_data_free = free_user_data;
|
||||
registered_log_writer_data = user_data;
|
||||
registered_log_writer_data_free = free_user_data;
|
||||
ws_log_init(writer);
|
||||
}
|
||||
|
||||
|
||||
static inline const char *_level_to_string(enum ws_log_level level)
|
||||
static inline const char *_lvl_to_str(enum ws_log_level level)
|
||||
{
|
||||
switch (level) {
|
||||
case LOG_LEVEL_NONE: return "NUL";
|
||||
case LOG_LEVEL_ERROR: return "ERR";
|
||||
case LOG_LEVEL_CRITICAL: return "CRI";
|
||||
case LOG_LEVEL_WARNING: return "WRN";
|
||||
case LOG_LEVEL_MESSAGE: return "MSG";
|
||||
case LOG_LEVEL_INFO: return "NFO";
|
||||
case LOG_LEVEL_DEBUG: return "DBG";
|
||||
case LOG_LEVEL_NONE: return "(NONE)";
|
||||
case LOG_LEVEL_ERROR: return "ERROR";
|
||||
case LOG_LEVEL_CRITICAL: return "CRITICAL";
|
||||
case LOG_LEVEL_WARNING: return "WARNING";
|
||||
case LOG_LEVEL_MESSAGE: return "MESSAGE";
|
||||
case LOG_LEVEL_INFO: return "INFO";
|
||||
case LOG_LEVEL_DEBUG: return "DEBUG";
|
||||
default:
|
||||
return "(BOGUS LOG LEVEL)";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline const char *_domain_to_string(enum ws_log_domain domain)
|
||||
static inline const char *_dom_to_str(enum ws_log_domain domain)
|
||||
{
|
||||
switch (domain) {
|
||||
case LOG_DOMAIN_DEFAULT: return "Dflt";
|
||||
|
@ -270,43 +261,113 @@ static inline const char *_domain_to_string(enum ws_log_domain domain)
|
|||
}
|
||||
|
||||
|
||||
static void ws_log_writev(enum ws_log_domain domain, enum ws_log_level level,
|
||||
const char *location, const char *format, va_list ap)
|
||||
struct logstr {
|
||||
char buffer[PREFIX_BUFSIZE];
|
||||
char *ptr;
|
||||
int free;
|
||||
};
|
||||
|
||||
|
||||
static inline void logstr_init(struct logstr *str)
|
||||
{
|
||||
str->free = (int)(sizeof(str->buffer) - 1);
|
||||
str->buffer[sizeof(str->buffer) - 1] = '\0';
|
||||
str->ptr = str->buffer;
|
||||
|
||||
#ifndef WS_DISABLE_ASSERT
|
||||
memset(str->buffer, 0, sizeof(str->buffer));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline int logstr_snprintf(struct logstr *str, const char *fmt, ...)
|
||||
{
|
||||
int write;
|
||||
va_list ap;
|
||||
|
||||
if (str->free <= 0)
|
||||
return -1;
|
||||
|
||||
va_start(ap, fmt);
|
||||
write = vsnprintf(str->ptr, str->free, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (write < 0 || write >= str->free) {
|
||||
str->ptr = NULL;
|
||||
str->free = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
str->ptr += write;
|
||||
ws_assert(str->ptr < str->buffer + sizeof(str->buffer));
|
||||
str->free -= write;
|
||||
ws_assert(str->free > 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void create_log_time(struct logstr *str)
|
||||
{
|
||||
char timestamp[sizeof("00:00:00.000")];
|
||||
char user_string[LOGBUFSIZE];
|
||||
char message[LOGBUFSIZE*2];
|
||||
time_t curr;
|
||||
struct tm *today;
|
||||
guint64 microseconds;
|
||||
|
||||
/* create a "timestamp" */
|
||||
time(&curr);
|
||||
today = localtime(&curr);
|
||||
guint64 microseconds = create_timestamp();
|
||||
if (today != NULL) {
|
||||
snprintf(timestamp, sizeof(timestamp), "%02d:%02d:%02d.%03" G_GUINT64_FORMAT,
|
||||
today->tm_hour, today->tm_min, today->tm_sec,
|
||||
microseconds % 1000000 / 1000);
|
||||
}
|
||||
else {
|
||||
snprintf(timestamp, sizeof(timestamp), "(notime)");
|
||||
microseconds = create_timestamp();
|
||||
|
||||
if (G_UNLIKELY(today == NULL)) {
|
||||
logstr_snprintf(str, " ** ");
|
||||
return;
|
||||
}
|
||||
|
||||
vsnprintf(user_string, sizeof(user_string), format, ap);
|
||||
logstr_snprintf(str, " ** %02d:%02d:%02d.%03" G_GUINT64_FORMAT,
|
||||
today->tm_hour, today->tm_min, today->tm_sec,
|
||||
microseconds % 1000000 / 1000);
|
||||
}
|
||||
|
||||
snprintf(message, sizeof(message), "%s %s-%s %s : %s",
|
||||
timestamp,
|
||||
_domain_to_string(domain),
|
||||
_level_to_string(level),
|
||||
location ? location : "(nofile)",
|
||||
user_string);
|
||||
|
||||
static void logstr_prefix_print(struct logstr *str,
|
||||
enum ws_log_domain domain, enum ws_log_level level,
|
||||
const char *file, int line, const char *func)
|
||||
{
|
||||
create_log_time(str);
|
||||
|
||||
logstr_snprintf(str, " [%s-%s]", _dom_to_str(domain), _lvl_to_str(level));
|
||||
|
||||
if (func)
|
||||
logstr_snprintf(str, " %s()", func);
|
||||
else if (file && line >= 0)
|
||||
logstr_snprintf(str, " (%d)%s", file, line);
|
||||
else if (file)
|
||||
logstr_snprintf(str, " %s", file);
|
||||
|
||||
logstr_snprintf(str, " -- ");
|
||||
}
|
||||
|
||||
|
||||
static void log_internal_write(enum ws_log_domain domain, enum ws_log_level level,
|
||||
const char *file, int line, const char *func,
|
||||
const char *user_format, va_list user_ap)
|
||||
{
|
||||
struct logstr prefix;
|
||||
|
||||
logstr_init(&prefix);
|
||||
|
||||
logstr_prefix_print(&prefix, domain, level, file, line, func);
|
||||
|
||||
/* Call the registered writer, or the default if one wasn't registered. */
|
||||
current_log_writer(message, domain, level, current_log_writer_data);
|
||||
if (registered_log_writer) {
|
||||
registered_log_writer(user_format, user_ap, prefix.buffer,
|
||||
domain, level, registered_log_writer_data);
|
||||
}
|
||||
else {
|
||||
ws_log_fprint(stderr, user_format, user_ap, prefix.buffer);
|
||||
}
|
||||
|
||||
/* If we have a custom file, write to it _also_. */
|
||||
if (custom_log) {
|
||||
log_default_writer_do_work(custom_log, message);
|
||||
ws_log_fprint(custom_log, user_format, user_ap, prefix.buffer);
|
||||
}
|
||||
|
||||
if (level == LOG_LEVEL_ERROR) {
|
||||
|
@ -322,7 +383,7 @@ void ws_logv(enum ws_log_domain domain, enum ws_log_level level,
|
|||
if (!ws_log_level_is_active(level))
|
||||
return;
|
||||
|
||||
ws_log_writev(domain, level, NULL, format, ap);
|
||||
log_internal_write(domain, level, NULL, -1, NULL, format, ap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -335,7 +396,7 @@ void ws_log(enum ws_log_domain domain, enum ws_log_level level,
|
|||
return;
|
||||
|
||||
va_start(ap, format);
|
||||
ws_log_writev(domain, level, NULL, format, ap);
|
||||
log_internal_write(domain, level, NULL, -1, NULL, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
@ -345,27 +406,21 @@ void ws_log_full(enum ws_log_domain domain, enum ws_log_level level,
|
|||
const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char location[LOGBUFSIZE];
|
||||
|
||||
if (!ws_log_level_is_active(level))
|
||||
return;
|
||||
|
||||
if (func)
|
||||
snprintf(location, sizeof(location), "%s(%d) %s()", file, line, func);
|
||||
else
|
||||
snprintf(location, sizeof(location), "%s(%d)", file, line);
|
||||
|
||||
va_start(ap, format);
|
||||
ws_log_writev(domain, level, location, format, ap);
|
||||
log_internal_write(domain, level, file, line, func, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
static void ws_log_cleanup(void)
|
||||
{
|
||||
if (current_log_writer_data_free) {
|
||||
current_log_writer_data_free(current_log_writer_data);
|
||||
current_log_writer_data = NULL;
|
||||
if (registered_log_writer_data_free) {
|
||||
registered_log_writer_data_free(registered_log_writer_data);
|
||||
registered_log_writer_data = NULL;
|
||||
}
|
||||
if (custom_log) {
|
||||
fclose(custom_log);
|
||||
|
|
|
@ -40,21 +40,22 @@ enum ws_log_level {
|
|||
#endif
|
||||
|
||||
|
||||
/** Signature for registering a log writer. */
|
||||
typedef void (ws_log_writer_t)(const char *message,
|
||||
/** Callback for registering a log writer. */
|
||||
typedef void (ws_log_writer_cb)(const char *format, va_list ap,
|
||||
const char *prefix,
|
||||
enum ws_log_domain domain,
|
||||
enum ws_log_level level,
|
||||
void *user_data);
|
||||
|
||||
|
||||
typedef void (ws_log_writer_free_data_t)(void *user_data);
|
||||
/** Callback for freeing a user data pointer. */
|
||||
typedef void (ws_log_writer_free_data_cb)(void *user_data);
|
||||
|
||||
|
||||
/** Writes to stream a new log line and flushes. */
|
||||
WS_DLL_PUBLIC
|
||||
void ws_log_default_writer(const char *message,
|
||||
enum ws_log_domain domain,
|
||||
enum ws_log_level level,
|
||||
void *user_data);
|
||||
void ws_log_fprint(FILE *fp, const char *format, va_list ap,
|
||||
const char *prefix);
|
||||
|
||||
|
||||
/** Convert a numerical level to its string representation. */
|
||||
|
@ -114,7 +115,7 @@ const char *ws_log_set_level_args(int *argcp, char **argv);
|
|||
* is NULL the default log writer is used.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void ws_log_init(ws_log_writer_t *writer);
|
||||
void ws_log_init(ws_log_writer_cb *writer);
|
||||
|
||||
|
||||
/** Initializes the logging code.
|
||||
|
@ -124,8 +125,8 @@ void ws_log_init(ws_log_writer_t *writer);
|
|||
* is passed it will be called with user_data when the program terminates.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
void ws_log_init_with_data(ws_log_writer_t *writer, void *user_data,
|
||||
ws_log_writer_free_data_t *free_user_data);
|
||||
void ws_log_init_with_data(ws_log_writer_cb *writer, void *user_data,
|
||||
ws_log_writer_free_data_cb *free_user_data);
|
||||
|
||||
|
||||
/** This function is called to output a message to the log.
|
||||
|
|
Loading…
Reference in New Issue