summaryrefslogtreecommitdiffstats
path: root/src/libnetdata/log/log.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libnetdata/log/log.c (renamed from libnetdata/log/log.c)178
1 files changed, 101 insertions, 77 deletions
diff --git a/libnetdata/log/log.c b/src/libnetdata/log/log.c
index c805716ce..bfba93ddb 100644
--- a/libnetdata/log/log.c
+++ b/src/libnetdata/log/log.c
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+// do not REMOVE this, it is used by systemd-journal includes to prevent saving the file, function, line of the
+// source code that makes the calls, allowing our loggers to log the lines of source code that actually log
#define SD_JOURNAL_SUPPRESS_LOCATION
#include "../libnetdata.h"
-#include <daemon/main.h>
#ifdef __FreeBSD__
#include <sys/endian.h>
@@ -13,7 +14,7 @@
#include <machine/endian.h>
#endif
-#ifdef HAVE_BACKTRACE
+#if !defined(ENABLE_SENTRY) && defined(HAVE_BACKTRACE)
#include <execinfo.h>
#endif
@@ -1117,9 +1118,33 @@ static __thread struct log_field thread_log_fields[_NDF_MAX] = {
.journal = "ND_SRC_TRANSPORT",
.logfmt = "src_transport",
},
+ [NDF_ACCOUNT_ID] = {
+ .journal = "ND_ACCOUNT_ID",
+ .logfmt = "account",
+ },
+ [NDF_USER_NAME] = {
+ .journal = "ND_USER_NAME",
+ .logfmt = "user",
+ },
+ [NDF_USER_ROLE] = {
+ .journal = "ND_USER_ROLE",
+ .logfmt = "role",
+ },
+ [NDF_USER_ACCESS] = {
+ .journal = "ND_USER_PERMISSIONS",
+ .logfmt = "permissions",
+ },
[NDF_SRC_IP] = {
- .journal = "ND_SRC_IP",
- .logfmt = "src_ip",
+ .journal = "ND_SRC_IP",
+ .logfmt = "src_ip",
+ },
+ [NDF_SRC_FORWARDED_HOST] = {
+ .journal = "ND_SRC_FORWARDED_HOST",
+ .logfmt = "src_forwarded_host",
+ },
+ [NDF_SRC_FORWARDED_FOR] = {
+ .journal = "ND_SRC_FORWARDED_FOR",
+ .logfmt = "src_forwarded_for",
},
[NDF_SRC_PORT] = {
.journal = "ND_SRC_PORT",
@@ -1353,11 +1378,12 @@ static void nd_logger_json(BUFFER *wb, struct log_field *fields, size_t fields_m
case NDFT_DBL:
buffer_json_member_add_double(wb, key, fields[i].entry.dbl);
break;
- case NDFT_UUID:{
- char u[UUID_COMPACT_STR_LEN];
- uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
- buffer_json_member_add_string(wb, key, u);
- }
+ case NDFT_UUID:
+ if(!uuid_is_null(*fields[i].entry.uuid)) {
+ char u[UUID_COMPACT_STR_LEN];
+ uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
+ buffer_json_member_add_string(wb, key, u);
+ }
break;
case NDFT_CALLBACK: {
if(!tmp)
@@ -1423,10 +1449,7 @@ static int64_t log_field_to_int64(struct log_field *lf) {
break;
case NDFT_CALLBACK:
- if(!tmp)
- tmp = buffer_create(0, NULL);
- else
- buffer_flush(tmp);
+ tmp = buffer_create(0, NULL);
if(lf->entry.cb.formatter(tmp, lf->entry.cb.formatter_data))
s = buffer_tostring(tmp);
@@ -1435,13 +1458,13 @@ static int64_t log_field_to_int64(struct log_field *lf) {
break;
case NDFT_U64:
- return lf->entry.u64;
+ return (int64_t)lf->entry.u64;
case NDFT_I64:
- return lf->entry.i64;
+ return (int64_t)lf->entry.i64;
case NDFT_DBL:
- return lf->entry.dbl;
+ return (int64_t)lf->entry.dbl;
}
if(s && *s)
@@ -1487,10 +1510,7 @@ static uint64_t log_field_to_uint64(struct log_field *lf) {
break;
case NDFT_CALLBACK:
- if(!tmp)
- tmp = buffer_create(0, NULL);
- else
- buffer_flush(tmp);
+ tmp = buffer_create(0, NULL);
if(lf->entry.cb.formatter(tmp, lf->entry.cb.formatter_data))
s = buffer_tostring(tmp);
@@ -1505,7 +1525,7 @@ static uint64_t log_field_to_uint64(struct log_field *lf) {
return lf->entry.i64;
case NDFT_DBL:
- return lf->entry.dbl;
+ return (uint64_t) lf->entry.dbl;
}
if(s && *s)
@@ -1538,7 +1558,7 @@ static void errno_annotator(BUFFER *wb, const char *key, struct log_field *lf) {
return;
char buf[1024];
- const char *s = errno2str(errnum, buf, sizeof(buf));
+ const char *s = errno2str((int)errnum, buf, sizeof(buf));
if(buffer_strlen(wb))
buffer_fast_strcat(wb, " ", 1);
@@ -1562,7 +1582,8 @@ static void priority_annotator(BUFFER *wb, const char *key, struct log_field *lf
buffer_strcat(wb, nd_log_id2priority(pri));
}
-static bool needs_quotes_for_logfmt(const char *s) {
+static bool needs_quotes_for_logfmt(const char *s)
+{
static bool safe_for_logfmt[256] = {
[' '] = true, ['!'] = true, ['"'] = false, ['#'] = true, ['$'] = true, ['%'] = true, ['&'] = true,
['\''] = true, ['('] = true, [')'] = true, ['*'] = true, ['+'] = true, [','] = true, ['-'] = true,
@@ -1593,7 +1614,8 @@ static bool needs_quotes_for_logfmt(const char *s) {
return false;
}
-static void string_to_logfmt(BUFFER *wb, const char *s) {
+static void string_to_logfmt(BUFFER *wb, const char *s)
+{
bool spaces = needs_quotes_for_logfmt(s);
if(spaces)
@@ -1605,7 +1627,8 @@ static void string_to_logfmt(BUFFER *wb, const char *s) {
buffer_fast_strcat(wb, "\"", 1);
}
-static void nd_logger_logfmt(BUFFER *wb, struct log_field *fields, size_t fields_max) {
+static void nd_logger_logfmt(BUFFER *wb, struct log_field *fields, size_t fields_max)
+{
// --- FIELD_PARSER_VERSIONS ---
//
@@ -1670,13 +1693,14 @@ static void nd_logger_logfmt(BUFFER *wb, struct log_field *fields, size_t fields
buffer_fast_strcat(wb, "=", 1);
buffer_print_netdata_double(wb, fields[i].entry.dbl);
break;
- case NDFT_UUID: {
- char u[UUID_COMPACT_STR_LEN];
- uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
- buffer_strcat(wb, key);
- buffer_fast_strcat(wb, "=", 1);
- buffer_fast_strcat(wb, u, sizeof(u) - 1);
- }
+ case NDFT_UUID:
+ if(!uuid_is_null(*fields[i].entry.uuid)) {
+ char u[UUID_COMPACT_STR_LEN];
+ uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
+ buffer_strcat(wb, key);
+ buffer_fast_strcat(wb, "=", 1);
+ buffer_fast_strcat(wb, u, sizeof(u) - 1);
+ }
break;
case NDFT_CALLBACK: {
if(!tmp)
@@ -1745,32 +1769,34 @@ static bool nd_logger_journal_libsystemd(struct log_field *fields, size_t fields
const char *key = fields[i].journal;
char *value = NULL;
+ int rc = 0;
switch (fields[i].entry.type) {
case NDFT_TXT:
if(*fields[i].entry.txt)
- asprintf(&value, "%s=%s", key, fields[i].entry.txt);
+ rc = asprintf(&value, "%s=%s", key, fields[i].entry.txt);
break;
case NDFT_STR:
- asprintf(&value, "%s=%s", key, string2str(fields[i].entry.str));
+ rc = asprintf(&value, "%s=%s", key, string2str(fields[i].entry.str));
break;
case NDFT_BFR:
if(buffer_strlen(fields[i].entry.bfr))
- asprintf(&value, "%s=%s", key, buffer_tostring(fields[i].entry.bfr));
+ rc = asprintf(&value, "%s=%s", key, buffer_tostring(fields[i].entry.bfr));
break;
case NDFT_U64:
- asprintf(&value, "%s=%" PRIu64, key, fields[i].entry.u64);
+ rc = asprintf(&value, "%s=%" PRIu64, key, fields[i].entry.u64);
break;
case NDFT_I64:
- asprintf(&value, "%s=%" PRId64, key, fields[i].entry.i64);
+ rc = asprintf(&value, "%s=%" PRId64, key, fields[i].entry.i64);
break;
case NDFT_DBL:
- asprintf(&value, "%s=%f", key, fields[i].entry.dbl);
+ rc = asprintf(&value, "%s=%f", key, fields[i].entry.dbl);
break;
- case NDFT_UUID: {
- char u[UUID_COMPACT_STR_LEN];
- uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
- asprintf(&value, "%s=%s", key, u);
- }
+ case NDFT_UUID:
+ if(!uuid_is_null(*fields[i].entry.uuid)) {
+ char u[UUID_COMPACT_STR_LEN];
+ uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
+ rc = asprintf(&value, "%s=%s", key, u);
+ }
break;
case NDFT_CALLBACK: {
if(!tmp)
@@ -1778,15 +1804,15 @@ static bool nd_logger_journal_libsystemd(struct log_field *fields, size_t fields
else
buffer_flush(tmp);
if(fields[i].entry.cb.formatter(tmp, fields[i].entry.cb.formatter_data))
- asprintf(&value, "%s=%s", key, buffer_tostring(tmp));
+ rc = asprintf(&value, "%s=%s", key, buffer_tostring(tmp));
}
break;
default:
- asprintf(&value, "%s=%s", key, "UNHANDLED");
+ rc = asprintf(&value, "%s=%s", key, "UNHANDLED");
break;
}
- if (value) {
+ if (rc != -1 && value) {
iov[iov_count].iov_base = value;
iov[iov_count].iov_len = strlen(value);
iov_count++;
@@ -1864,14 +1890,15 @@ static bool nd_logger_journal_direct(struct log_field *fields, size_t fields_max
buffer_print_netdata_double(wb, fields[i].entry.dbl);
buffer_putc(wb, '\n');
break;
- case NDFT_UUID:{
- char u[UUID_COMPACT_STR_LEN];
- uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
- buffer_strcat(wb, key);
- buffer_putc(wb, '=');
- buffer_fast_strcat(wb, u, sizeof(u) - 1);
- buffer_putc(wb, '\n');
- }
+ case NDFT_UUID:
+ if(!uuid_is_null(*fields[i].entry.uuid)) {
+ char u[UUID_COMPACT_STR_LEN];
+ uuid_unparse_lower_compact(*fields[i].entry.uuid, u);
+ buffer_strcat(wb, key);
+ buffer_putc(wb, '=');
+ buffer_fast_strcat(wb, u, sizeof(u) - 1);
+ buffer_putc(wb, '\n');
+ }
break;
case NDFT_CALLBACK: {
if(!tmp)
@@ -1913,7 +1940,7 @@ static bool nd_logger_journal_direct(struct log_field *fields, size_t fields_max
// ----------------------------------------------------------------------------
// syslog logger - uses logfmt
-static bool nd_logger_syslog(int priority, ND_LOG_FORMAT format, struct log_field *fields, size_t fields_max) {
+static bool nd_logger_syslog(int priority, ND_LOG_FORMAT format __maybe_unused, struct log_field *fields, size_t fields_max) {
CLEAN_BUFFER *wb = buffer_create(1024, NULL);
nd_logger_logfmt(wb, fields, fields_max);
@@ -2069,7 +2096,7 @@ static void nd_logger_merge_log_stack_to_thread_fields(void) {
if((type == NDFT_TXT && (!e->txt || !*e->txt)) ||
(type == NDFT_BFR && (!e->bfr || !buffer_strlen(e->bfr))) ||
(type == NDFT_STR && !e->str) ||
- (type == NDFT_UUID && !e->uuid) ||
+ (type == NDFT_UUID && (!e->uuid || uuid_is_null(*e->uuid))) ||
(type == NDFT_CALLBACK && !e->cb.formatter) ||
type == NDFT_UNSET)
continue;
@@ -2110,7 +2137,7 @@ static void nd_logger(const char *file, const char *function, const unsigned lon
else if(thread_log_fields[NDF_LOG_SOURCE].entry.type == NDFT_U64)
src = thread_log_fields[NDF_LOG_SOURCE].entry.u64;
- if(src != source && src >= 0 && src < _NDLS_MAX) {
+ if(src != source && src < _NDLS_MAX) {
source = src;
output = nd_logger_select_output(source, &fp, &spinlock);
if(output != NDLM_FILE && output != NDLM_JOURNAL && output != NDLM_SYSLOG)
@@ -2137,13 +2164,11 @@ static void nd_logger(const char *file, const char *function, const unsigned lon
char os_threadname[NETDATA_THREAD_NAME_MAX + 1];
if(likely(!thread_log_fields[NDF_THREAD_TAG].entry.set)) {
const char *thread_tag = netdata_thread_tag();
- if(!netdata_thread_tag_exists()) {
- if (!netdata_thread_tag_exists()) {
- os_thread_get_current_name_np(os_threadname);
- if ('\0' != os_threadname[0])
- /* If it is not an empty string replace "MAIN" thread_tag */
- thread_tag = os_threadname;
- }
+ if (!netdata_thread_tag_exists()) {
+ os_thread_get_current_name_np(os_threadname);
+ if ('\0' != os_threadname[0])
+ /* If it is not an empty string replace "MAIN" thread_tag */
+ thread_tag = os_threadname;
}
thread_log_fields[NDF_THREAD_TAG].entry = ND_LOG_FIELD_TXT(NDF_THREAD_TAG, thread_tag);
@@ -2224,7 +2249,8 @@ static ND_LOG_SOURCES nd_log_validate_source(ND_LOG_SOURCES source) {
// ----------------------------------------------------------------------------
// public API for loggers
-void netdata_logger(ND_LOG_SOURCES source, ND_LOG_FIELD_PRIORITY priority, const char *file, const char *function, unsigned long line, const char *fmt, ... ) {
+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;
source = nd_log_validate_source(source);
@@ -2285,17 +2311,14 @@ void netdata_logger_fatal( const char *file, const char *function, const unsigne
char action_data[70+1];
snprintfz(action_data, 70, "%04lu@%-10.10s:%-15.15s/%d", line, file, function, saved_errno);
- char action_result[60+1];
char os_threadname[NETDATA_THREAD_NAME_MAX + 1];
const char *thread_tag = netdata_thread_tag();
- if(!netdata_thread_tag_exists()) {
- if (!netdata_thread_tag_exists()) {
- os_thread_get_current_name_np(os_threadname);
- if ('\0' != os_threadname[0])
- /* If it is not an empty string replace "MAIN" thread_tag */
- thread_tag = os_threadname;
- }
+ if (!netdata_thread_tag_exists()) {
+ os_thread_get_current_name_np(os_threadname);
+ if ('\0' != os_threadname[0])
+ /* If it is not an empty string replace "MAIN" thread_tag */
+ thread_tag = os_threadname;
}
if(!thread_tag)
thread_tag = "UNKNOWN";
@@ -2308,10 +2331,10 @@ void netdata_logger_fatal( const char *file, const char *function, const unsigne
if(strncmp(thread_tag, THREAD_TAG_STREAM_SENDER, strlen(THREAD_TAG_STREAM_SENDER)) == 0)
tag_to_send = THREAD_TAG_STREAM_SENDER;
+ char action_result[60+1];
snprintfz(action_result, 60, "%s:%s", program_name, tag_to_send);
- send_statistics("FATAL", action_result, action_data);
-#ifdef HAVE_BACKTRACE
+#if !defined(ENABLE_SENTRY) && defined(HAVE_BACKTRACE)
int fd = nd_log.sources[NDLS_DAEMON].fd;
if(fd == -1)
fd = STDERR_FILENO;
@@ -2328,7 +2351,7 @@ void netdata_logger_fatal( const char *file, const char *function, const unsigne
abort();
#endif
- netdata_cleanup_and_exit(1);
+ netdata_cleanup_and_exit(1, "FATAL", action_result, action_data);
}
// ----------------------------------------------------------------------------
@@ -2407,7 +2430,8 @@ static bool nd_log_limit_reached(struct nd_log_source *source) {
source->limits.logs_per_period,
source->limits.throttle_period,
program_name,
- (int64_t)((source->limits.started_monotonic_ut + (source->limits.throttle_period * USEC_PER_SEC) - now_ut)) / USEC_PER_SEC);
+ (int64_t)(((source->limits.started_monotonic_ut + (source->limits.throttle_period * USEC_PER_SEC) - now_ut)) / USEC_PER_SEC)
+ );
if(source->pending_msg)
freez((void *)source->pending_msg);