@cryptotaxi247 / netdata-1 / commits / b35ce435d

Minor fixes (#19353)

* log the last sample in the database together with the node connected message * fix libuwind annotator

Costa Tsaousis committed Jan 8, 2025 at 23:59 UTC b35ce435d44e952d46a11a5dbcc0c61d2c96ed15
8 files changed +54 -59
src/libnetdata/config/appconfig_migrate.c
+4 -4
@@ -33,10 +33,10 @@ int appconfig_move(struct config *root, const char *section_old, const char *nam
33
34 DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(sect_old->values, opt_old, prev, next);
35
36 - nd_log(NDLS_DAEMON, NDLP_WARNING,
37 - "CONFIG: option '[%s].%s' has been migrated to '[%s].%s'.",
38 - section_old, name_old,
39 - section_new, name_new);
36 +// nd_log(NDLS_DAEMON, NDLP_WARNING,
37 +// "CONFIG: option '[%s].%s' has been migrated to '[%s].%s'.",
38 +// section_old, name_old,
39 +// section_new, name_new);
40
41 if(!opt_old->migrated.name) {
42 string_freez(opt_old->migrated.section);
src/libnetdata/log/nd_log-format-logfmt.c
+2 -2
@@ -71,8 +71,8 @@ void nd_logger_logfmt(BUFFER *wb, struct log_field *fields, size_t fields_max) {
71
72 const char *key = fields[i].logfmt;
73
74 - if(fields[i].annotator) {
75 - const char *s = fields[i].annotator(&fields[i]);
74 + if(fields[i].logfmt_annotator) {
75 + const char *s = fields[i].logfmt_annotator(&fields[i]);
76 if(!s) continue;
77
78 if(buffer_strlen(wb))
src/libnetdata/log/nd_log-internals.c
+5 -6
@@ -393,13 +393,13 @@ __thread struct log_field thread_log_fields[_NDF_MAX] = {
393 .journal = NULL,
394 .logfmt = NULL,
395 .eventlog = NULL,
396 - .annotator = NULL,
396 + .logfmt_annotator = NULL,
397 },
398 [NDF_TIMESTAMP_REALTIME_USEC] = {
399 .journal = NULL,
400 .eventlog = "Timestamp",
401 .logfmt = "time",
402 - .annotator = timestamp_usec_annotator,
402 + .logfmt_annotator = timestamp_usec_annotator,
403 },
404 [NDF_SYSLOG_IDENTIFIER] = {
405 .journal = "SYSLOG_IDENTIFIER", // standard journald field
@@ -415,13 +415,13 @@ __thread struct log_field thread_log_fields[_NDF_MAX] = {
415 .journal = "PRIORITY", // standard journald field
416 .eventlog = "Level",
417 .logfmt = "level",
418 - .annotator = priority_annotator,
418 + .logfmt_annotator = priority_annotator,
419 },
420 [NDF_ERRNO] = {
421 .journal = "ERRNO", // standard journald field
422 .eventlog = "UnixErrno",
423 .logfmt = "errno",
424 - .annotator = errno_annotator,
424 + .logfmt_annotator = errno_annotator,
425 },
426 [NDF_WINERROR] = {
427 #if defined(OS_WINDOWS)
@@ -705,13 +705,12 @@ __thread struct log_field thread_log_fields[_NDF_MAX] = {
705 .journal = "ND_ALERT_NOTIFICATION_TIMESTAMP_USEC",
706 .eventlog = "AlertNotificationTime",
707 .logfmt = "alert_notification_timestamp",
708 - .annotator = timestamp_usec_annotator,
708 + .logfmt_annotator = timestamp_usec_annotator,
709 },
710 [NDF_STACK_TRACE] = {
711 .journal = "ND_STACK_TRACE",
712 .eventlog = "StackTrace",
713 .logfmt = NULL,
714 - .annotator = stack_trace_annotator,
714 },
715
716 // put new items here
src/libnetdata/log/nd_log-internals.h
+2 -2
@@ -170,7 +170,7 @@ struct log_field {
170 const char *journal;
171 const char *logfmt;
172 const char *eventlog;
173 - annotator_t annotator;
173 + annotator_t logfmt_annotator;
174 struct log_stack_entry entry;
175 };
176
@@ -195,7 +195,7 @@ struct log_field;
195 const char *errno_annotator(struct log_field *lf);
196 const char *priority_annotator(struct log_field *lf);
197 const char *timestamp_usec_annotator(struct log_field *lf);
198 -const char *stack_trace_annotator(struct log_field *lf);
198 +bool stack_trace_formatter(BUFFER *wb, void *data);
199
200 #if defined(OS_WINDOWS)
201 const char *winerror_annotator(struct log_field *lf);
src/libnetdata/log/nd_log-libunwind.c
+15 -15
@@ -5,26 +5,24 @@
5 #ifdef HAVE_LIBUNWIND
6 #include <libunwind.h>
7
8 -const char *stack_trace_annotator(struct log_field *lf __maybe_unused) {
9 - static __thread char stack[4096];
8 +bool stack_trace_formatter(BUFFER *wb, void *data __maybe_unused) {
9 static __thread bool in_stack_trace = false;
10
12 - // prevent recursion
11 + // Prevent recursion
12 if(in_stack_trace)
14 - return "stack trace recursion detected";
13 + return buffer_strcat(wb, "stack trace recursion detected"), true;
14
15 in_stack_trace = true;
16
17 unw_cursor_t cursor;
18 unw_context_t context;
20 - char *d = stack;
19 size_t frames = 0;
20
21 // Initialize context for current thread
22 unw_getcontext(&context);
23 unw_init_local(&cursor, &context);
24
27 - // Skip first 3 frames (our annotator and the logging infrastructure)
25 + // Skip first 3 frames (our logging infrastructure)
26 unw_step(&cursor);
27 unw_step(&cursor);
28 unw_step(&cursor);
@@ -39,23 +37,25 @@ const char *stack_trace_annotator(struct log_field *lf __maybe_unused) {
37
38 const char *name = sym;
39 if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
42 - if(frames++)
43 - d += snprintfz(d, sizeof(stack) - (d - stack), "\n");
44 - d += snprintfz(d, sizeof(stack) - (d - stack), "%s+0x%lx", name, (unsigned long)offset);
40 + if(frames++) buffer_strcat(wb, "\n");
41 + buffer_sprintf(wb, "%s+0x%lx", name, (unsigned long)offset);
42 }
43 else {
44 if(frames++)
48 - d += snprintfz(d, sizeof(stack) - (d - stack), "\n");
49 - d += snprintfz(d, sizeof(stack) - (d - stack), "<unknown>");
45 + buffer_strcat(wb, "\n");
46 + buffer_strcat(wb, "<unknown>");
47 }
48 }
49
50 in_stack_trace = false;
54 - return stack;
51 + return true;
52 }
53
57 -#else
58 -const char *stack_trace_annotator(struct log_field *lf __maybe_unused) {
59 - return "libunwind not available";
54 +#else // !HAVE_LIBUNWIND
55 +
56 +bool stack_trace_formatter(BUFFER *wb, void *data __maybe_unused) {
57 + buffer_strcat(wb, "libunwind not available");
58 + return true;
59 }
60 +
61 #endif
src/libnetdata/log/nd_log.c
+1 -1
@@ -233,7 +233,7 @@ static void nd_logger(const char *file, const char *function, const unsigned lon
233 // set the common fields that are automatically set by the logging subsystem
234
235 if(likely(!thread_log_fields[NDF_STACK_TRACE].entry.set))
236 - thread_log_fields[NDF_STACK_TRACE].entry = ND_LOG_FIELD_U64(NDF_STACK_TRACE, 1);
236 + thread_log_fields[NDF_STACK_TRACE].entry = ND_LOG_FIELD_CB(NDF_STACK_TRACE, stack_trace_formatter, NULL);
237
238 if(likely(!thread_log_fields[NDF_INVOCATION_ID].entry.set))
239 thread_log_fields[NDF_INVOCATION_ID].entry = ND_LOG_FIELD_UUID(NDF_INVOCATION_ID, &nd_log.invocation_id);
src/streaming/stream-receiver-connection.c
+25 -3
@@ -8,6 +8,25 @@
8
9 // --------------------------------------------------------------------------------------------------------------------
10
11 +static void stream_receiver_connected_msg(RRDHOST *host, char *dst, size_t len) {
12 + time_t now = now_realtime_sec();
13 + time_t last_db_entry = 0;
14 + rrdhost_retention(host, now, false, NULL, &last_db_entry);
15 +
16 + if(now < last_db_entry)
17 + last_db_entry = now;
18 +
19 + if(!last_db_entry)
20 + strncpyz(dst, "connected and ready to receive data, new node", len - 1);
21 + else if(last_db_entry == now)
22 + strncpyz(dst, "connected and ready to receive data, last sample in the db just now", len - 1);
23 + else {
24 + char buf[128];
25 + duration_snprintf(buf, sizeof(buf), now - last_db_entry, "s", true);
26 + snprintfz(dst, len, "connected and ready to receive data, last sample in the db %s ago", buf);
27 + }
28 +}
29 +
30 void stream_receiver_log_status(struct receiver_state *rpt, const char *msg, const char *status, ND_LOG_FIELD_PRIORITY priority) {
31 // this function may be called BEFORE we spawn the receiver thread
32 // so, we need to add the fields again (it does not harm)
@@ -28,7 +47,8 @@ void stream_receiver_log_status(struct receiver_state *rpt, const char *msg, con
47
48 nd_log(NDLS_DAEMON, priority, "STREAM RCV '%s' [from [%s]:%s]: %s %s%s%s"
49 , (rpt->hostname && *rpt->hostname) ? rpt->hostname : ""
31 - , rpt->remote_ip, rpt->remote_port, msg
50 + , rpt->remote_ip, rpt->remote_port
51 + , msg
52 , rpt->exit.reason != STREAM_HANDSHAKE_NEVER?" (":""
53 , stream_handshake_error_to_string(rpt->exit.reason)
54 , rpt->exit.reason != STREAM_HANDSHAKE_NEVER?")":""
@@ -171,6 +191,7 @@ static bool stream_receiver_send_first_response(struct receiver_state *rpt) {
191 return false;
192 }
193
194 + // this is not needed since we now have a waiting list for nodes
195 // if (unlikely(!stream_control_children_should_be_accepted())) {
196 // stream_receiver_log_status(
197 // rpt,
@@ -656,9 +677,10 @@ int stream_receiver_accept_connection(struct web_client *w, char *decoded_query_
677 if(stream_receiver_send_first_response(rpt)) {
678 // we are the receiver of the node
679
680 + char msg[256];
681 + stream_receiver_connected_msg(rpt->host, msg, sizeof(msg));
682 stream_receiver_log_status(
660 - rpt,
661 - "connected and ready to receive data",
683 + rpt, msg,
684 STREAM_STATUS_CONNECTED, NDLP_INFO);
685
686 // in case we have cloud connection we inform cloud a new child connected
src/streaming/stream-receiver.c
-26
@@ -373,30 +373,6 @@ static ssize_t send_to_child(const char *txt, void *data, STREAM_TRAFFIC_TYPE ty
373
374 // --------------------------------------------------------------------------------------------------------------------
375
376 -static void stream_receive_log_database_gap(struct receiver_state *rpt) {
377 - RRDHOST *host = rpt->host;
378 -
379 - time_t now = now_realtime_sec();
380 - time_t last_db_entry = 0;
381 - rrdhost_retention(host, now, false, NULL, &last_db_entry);
382 -
383 - if(now < last_db_entry)
384 - last_db_entry = now;
385 -
386 - if(!last_db_entry) {
387 - nd_log(NDLS_DAEMON, NDLP_NOTICE,
388 - "STREAM RCV '%s' [from [%s]:%s]: node connected; for the first time!",
389 - rrdhost_hostname(host), rpt->remote_ip, rpt->remote_port);
390 - }
391 - else {
392 - char buf[128];
393 - duration_snprintf(buf, sizeof(buf), now - last_db_entry, "s", true);
394 - nd_log(NDLS_DAEMON, NDLP_NOTICE,
395 - "STREAM RCV '%s' [from [%s]:%s]: node connected; last sample in the database %s ago",
396 - rrdhost_hostname(host), rpt->remote_ip, rpt->remote_port, buf);
397 - }
398 -}
399 -
376 void stream_receiver_move_to_running_unsafe(struct stream_thread *sth, struct receiver_state *rpt) {
377 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
378
@@ -509,8 +485,6 @@ void stream_receiver_move_to_running_unsafe(struct stream_thread *sth, struct re
485 parser->h2o_ctx = rpt->h2o_ctx;
486 #endif
487
512 - stream_receive_log_database_gap(rpt);
513 -
488 // keep this last - it needs everything ready since to sends data to the child
489 stream_receiver_send_node_and_claim_id_to_child(rpt->host);
490 }