diff options
Diffstat (limited to 'src/libnetdata/log')
-rw-r--r-- | src/libnetdata/log/log.c | 136 | ||||
-rw-r--r-- | src/libnetdata/log/log.h | 8 |
2 files changed, 134 insertions, 10 deletions
diff --git a/src/libnetdata/log/log.c b/src/libnetdata/log/log.c index 501b6632..a31127c4 100644 --- a/src/libnetdata/log/log.c +++ b/src/libnetdata/log/log.c @@ -6,6 +6,10 @@ #include "../libnetdata.h" +#if defined(OS_WINDOWS) +#include <windows.h> +#endif + #ifdef __FreeBSD__ #include <sys/endian.h> #endif @@ -36,6 +40,16 @@ struct nd_log_source; static bool nd_log_limit_reached(struct nd_log_source *source); // ---------------------------------------------------------------------------- + +void errno_clear(void) { + errno = 0; + +#if defined(OS_WINDOWS) + SetLastError(ERROR_SUCCESS); +#endif +} + +// ---------------------------------------------------------------------------- // logging method typedef enum __attribute__((__packed__)) { @@ -514,6 +528,13 @@ int nd_log_health_fd(void) { return STDERR_FILENO; } +int nd_log_collectors_fd(void) { + if(nd_log.sources[NDLS_COLLECTORS].method == NDLM_FILE && nd_log.sources[NDLS_COLLECTORS].fd != -1) + return nd_log.sources[NDLS_COLLECTORS].fd; + + return STDERR_FILENO; +} + void nd_log_set_user_settings(ND_LOG_SOURCES source, const char *setting) { char buf[FILENAME_MAX + 100]; if(setting && *setting) @@ -971,14 +992,38 @@ void nd_log_initialize(void) { nd_log_open(&nd_log.sources[i], i); } -void nd_log_reopen_log_files(void) { - netdata_log_info("Reopening all log files."); +void nd_log_reopen_log_files(bool log) { + if(log) + netdata_log_info("Reopening all log files."); nd_log.std_output.initialized = false; nd_log.std_error.initialized = false; nd_log_initialize(); - netdata_log_info("Log files re-opened."); + if(log) + netdata_log_info("Log files re-opened."); +} + +void nd_log_reopen_log_files_for_spawn_server(void) { + if(nd_log.syslog.initialized) { + closelog(); + nd_log.syslog.initialized = false; + nd_log_syslog_init(); + } + + if(nd_log.journal_direct.initialized) { + close(nd_log.journal_direct.fd); + nd_log.journal_direct.fd = -1; + nd_log.journal_direct.initialized = false; + nd_log_journal_direct_init(NULL); + } + + nd_log.sources[NDLS_UNSET].method = NDLM_DISABLED; + nd_log.sources[NDLS_ACCESS].method = NDLM_DISABLED; + nd_log.sources[NDLS_ACLK].method = NDLM_DISABLED; + nd_log.sources[NDLS_DEBUG].method = NDLM_DISABLED; + nd_log.sources[NDLS_HEALTH].method = NDLM_DISABLED; + nd_log_reopen_log_files(false); } void chown_open_file(int fd, uid_t uid, gid_t gid) { @@ -1011,6 +1056,10 @@ static void errno_annotator(BUFFER *wb, const char *key, struct log_field *lf); static void priority_annotator(BUFFER *wb, const char *key, struct log_field *lf); static void timestamp_usec_annotator(BUFFER *wb, const char *key, struct log_field *lf); +#if defined(OS_WINDOWS) +static void winerror_annotator(BUFFER *wb, const char *key, struct log_field *lf); +#endif + // ---------------------------------------------------------------------------- typedef void (*annotator_t)(BUFFER *wb, const char *key, struct log_field *lf); @@ -1058,6 +1107,13 @@ static __thread struct log_field thread_log_fields[_NDF_MAX] = { .logfmt = "errno", .logfmt_annotator = errno_annotator, }, +#if defined(OS_WINDOWS) + [NDF_WINERROR] = { + .journal = "WINERROR", + .logfmt = "winerror", + .logfmt_annotator = winerror_annotator, + }, +#endif [NDF_INVOCATION_ID] = { .journal = "INVOCATION_ID", // standard journald field .logfmt = NULL, @@ -1563,6 +1619,45 @@ static void errno_annotator(BUFFER *wb, const char *key, struct log_field *lf) { buffer_fast_strcat(wb, "\"", 1); } +#if defined(OS_WINDOWS) +static void winerror_annotator(BUFFER *wb, const char *key, struct log_field *lf) { + DWORD errnum = log_field_to_uint64(lf); + + if(errnum == 0) + return; + + char buf[1024]; + DWORD size = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errnum, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf, + (DWORD)(sizeof(buf) - 1), + NULL + ); + if(size > 0) { + // remove \r\n at the end + while(size > 0 && (buf[size - 1] == '\r' || buf[size - 1] == '\n')) + buf[--size] = '\0'; + } + else + size = snprintf(buf, sizeof(buf) - 1, "unknown error code"); + + buf[size] = '\0'; + + if(buffer_strlen(wb)) + buffer_fast_strcat(wb, " ", 1); + + buffer_strcat(wb, key); + buffer_fast_strcat(wb, "=\"", 2); + buffer_print_int64(wb, errnum); + buffer_fast_strcat(wb, ", ", 2); + buffer_json_strcat(wb, buf); + buffer_fast_strcat(wb, "\"", 1); +} +#endif + static void priority_annotator(BUFFER *wb, const char *key, struct log_field *lf) { uint64_t pri = log_field_to_uint64(lf); @@ -2099,8 +2194,8 @@ static void nd_logger_merge_log_stack_to_thread_fields(void) { } static void nd_logger(const char *file, const char *function, const unsigned long line, - ND_LOG_SOURCES source, ND_LOG_FIELD_PRIORITY priority, bool limit, int saved_errno, - const char *fmt, va_list ap) { + ND_LOG_SOURCES source, ND_LOG_FIELD_PRIORITY priority, bool limit, + int saved_errno, size_t saved_winerror __maybe_unused, const char *fmt, va_list ap) { SPINLOCK *spinlock; FILE *fp; @@ -2168,6 +2263,11 @@ static void nd_logger(const char *file, const char *function, const unsigned lon if(saved_errno != 0 && !thread_log_fields[NDF_ERRNO].entry.set) thread_log_fields[NDF_ERRNO].entry = ND_LOG_FIELD_I64(NDF_ERRNO, saved_errno); +#if defined(OS_WINDOWS) + if(saved_winerror != 0 && !thread_log_fields[NDF_WINERROR].entry.set) + thread_log_fields[NDF_WINERROR].entry = ND_LOG_FIELD_U64(NDF_WINERROR, saved_winerror); +#endif + CLEAN_BUFFER *wb = NULL; if(fmt && !thread_log_fields[NDF_MESSAGE].entry.set) { wb = buffer_create(1024, NULL); @@ -2215,7 +2315,7 @@ static void nd_logger(const char *file, const char *function, const unsigned lon nd_log.sources[source].pending_msg = NULL; } - errno = 0; + errno_clear(); } static ND_LOG_SOURCES nd_log_validate_source(ND_LOG_SOURCES source) { @@ -2234,6 +2334,12 @@ static ND_LOG_SOURCES nd_log_validate_source(ND_LOG_SOURCES source) { void netdata_logger(ND_LOG_SOURCES source, ND_LOG_FIELD_PRIORITY priority, const char *file, const char *function, unsigned long line, const char *fmt, ... ) { int saved_errno = errno; + + size_t saved_winerror = 0; +#if defined(OS_WINDOWS) + saved_winerror = GetLastError(); +#endif + source = nd_log_validate_source(source); if (source != NDLS_DEBUG && priority > nd_log.sources[source].min_priority) @@ -2243,12 +2349,18 @@ void netdata_logger(ND_LOG_SOURCES source, ND_LOG_FIELD_PRIORITY priority, const va_start(args, fmt); nd_logger(file, function, line, source, priority, source == NDLS_DAEMON || source == NDLS_COLLECTORS, - saved_errno, fmt, args); + saved_errno, saved_winerror, fmt, args); va_end(args); } void netdata_logger_with_limit(ERROR_LIMIT *erl, ND_LOG_SOURCES source, ND_LOG_FIELD_PRIORITY priority, const char *file __maybe_unused, const char *function __maybe_unused, const unsigned long line __maybe_unused, const char *fmt, ... ) { int saved_errno = errno; + + size_t saved_winerror = 0; +#if defined(OS_WINDOWS) + saved_winerror = GetLastError(); +#endif + source = nd_log_validate_source(source); if (source != NDLS_DEBUG && priority > nd_log.sources[source].min_priority) @@ -2272,7 +2384,7 @@ void netdata_logger_with_limit(ERROR_LIMIT *erl, ND_LOG_SOURCES source, ND_LOG_F va_start(args, fmt); nd_logger(file, function, line, source, priority, source == NDLS_DAEMON || source == NDLS_COLLECTORS, - saved_errno, fmt, args); + saved_errno, saved_winerror, fmt, args); va_end(args); erl->last_logged = now; erl->count = 0; @@ -2280,12 +2392,18 @@ void netdata_logger_with_limit(ERROR_LIMIT *erl, ND_LOG_SOURCES source, ND_LOG_F void netdata_logger_fatal( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) { int saved_errno = errno; + + size_t saved_winerror = 0; +#if defined(OS_WINDOWS) + saved_winerror = GetLastError(); +#endif + ND_LOG_SOURCES source = NDLS_DAEMON; source = nd_log_validate_source(source); va_list args; va_start(args, fmt); - nd_logger(file, function, line, source, NDLP_ALERT, true, saved_errno, fmt, args); + nd_logger(file, function, line, source, NDLP_ALERT, true, saved_errno, saved_winerror, fmt, args); va_end(args); char date[LOG_DATE_LENGTH]; diff --git a/src/libnetdata/log/log.h b/src/libnetdata/log/log.h index 338a5d53..015c02eb 100644 --- a/src/libnetdata/log/log.h +++ b/src/libnetdata/log/log.h @@ -46,6 +46,9 @@ typedef enum __attribute__((__packed__)) { NDF_LOG_SOURCE, // DAEMON, COLLECTORS, HEALTH, ACCESS, ACLK - set at the log call NDF_PRIORITY, // the syslog priority (severity) - set at the log call NDF_ERRNO, // the ERRNO at the time of the log call - added automatically +#if defined(OS_WINDOWS) + NDF_WINERROR, // Windows GetLastError() +#endif NDF_INVOCATION_ID, // the INVOCATION_ID of Netdata - added automatically NDF_LINE, // the source code file line number - added automatically NDF_FILE, // the source code filename - added automatically @@ -141,15 +144,17 @@ typedef enum __attribute__((__packed__)) { NDFT_CALLBACK, } ND_LOG_STACK_FIELD_TYPE; +void errno_clear(void); void nd_log_set_user_settings(ND_LOG_SOURCES source, const char *setting); void nd_log_set_facility(const char *facility); void nd_log_set_priority_level(const char *setting); void nd_log_initialize(void); -void nd_log_reopen_log_files(void); +void nd_log_reopen_log_files(bool log); void chown_open_file(int fd, uid_t uid, gid_t gid); void nd_log_chown_log_files(uid_t uid, gid_t gid); void nd_log_set_flood_protection(size_t logs, time_t period); void nd_log_initialize_for_external_plugins(const char *name); +void nd_log_reopen_log_files_for_spawn_server(void); bool nd_log_journal_socket_available(void); ND_LOG_FIELD_ID nd_log_field_id_by_name(const char *field, size_t len); int nd_log_priority2id(const char *priority); @@ -157,6 +162,7 @@ const char *nd_log_id2priority(ND_LOG_FIELD_PRIORITY priority); const char *nd_log_method_for_external_plugins(const char *s); int nd_log_health_fd(void); +int nd_log_collectors_fd(void); typedef bool (*log_formatter_callback_t)(BUFFER *wb, void *data); struct log_stack_entry { |