@cryptotaxi247 / netdata-1 / commits / 431b1c856

Add libuv thread names support to FATAL log level (#9382)

* Add support for the fatal() family of calls to detect non-netdata thread names from the OS

Markos Fountoulakis committed Jun 20, 2020 at 22:13 UTC 431b1c85698feb33aee2e8cf972dcdf6fb26ba46
4 files changed +38 -4
configure.ac
+6
@@ -265,6 +265,12 @@ LIBS="${PTHREAD_LIBS} ${LIBS}"
265 CFLAGS="${CFLAGS} ${PTHREAD_CFLAGS}"
266 CC="${PTHREAD_CC}"
267
268 +AC_CHECK_LIB(
269 +[pthread],
270 +[pthread_getname_np],
271 +[AC_DEFINE([HAVE_PTHREAD_GETNAME_NP], [1], [Is set if pthread_getname_np is available])]
272 +)
273 +
274
275 # -----------------------------------------------------------------------------
276 # libm
libnetdata/log/log.c
+13 -3
@@ -796,6 +796,8 @@ void fatal_int( const char *file, const char *function, const unsigned long line
796 // save a copy of errno - just in case this function generates a new error
797 int __errno = errno;
798 va_list args;
799 + const char *thread_tag;
800 + char os_threadname[NETDATA_THREAD_NAME_MAX + 1];
801
802 if(error_log_syslog) {
803 va_start( args, fmt );
@@ -803,14 +805,22 @@ void fatal_int( const char *file, const char *function, const unsigned long line
805 va_end( args );
806 }
807
808 + thread_tag = netdata_thread_tag();
809 + if (!netdata_thread_tag_exists()) {
810 + os_thread_get_current_name_np(os_threadname);
811 + if ('\0' != os_threadname[0]) { /* If it is not an empty string replace "MAIN" thread_tag */
812 + thread_tag = os_threadname;
813 + }
814 + }
815 +
816 char date[LOG_DATE_LENGTH];
817 log_date(date, LOG_DATE_LENGTH);
818
819 log_lock();
820
821 va_start( args, fmt );
812 - if(debug_flags) fprintf(stderr, "%s: %s FATAL : %s : (%04lu@%-10.10s:%-15.15s): ", date, program_name, netdata_thread_tag(), line, file, function);
813 - else fprintf(stderr, "%s: %s FATAL : %s :", date, program_name, netdata_thread_tag());
822 + if(debug_flags) fprintf(stderr, "%s: %s FATAL : %s : (%04lu@%-10.10s:%-15.15s): ", date, program_name, thread_tag, line, file, function);
823 + else fprintf(stderr, "%s: %s FATAL : %s : ", date, program_name, thread_tag);
824 vfprintf( stderr, fmt, args );
825 va_end( args );
826
@@ -823,7 +833,7 @@ void fatal_int( const char *file, const char *function, const unsigned long line
833 snprintfz(action_data, 70, "%04lu@%-10.10s:%-15.15s/%d", line, file, function, __errno);
834 char action_result[60+1];
835
826 - snprintfz(action_result, 60, "%s:%s", program_name, strncmp(netdata_thread_tag(), "STREAM_RECEIVER", strlen("STREAM_RECEIVER"))?netdata_thread_tag():"[x]");
836 + snprintfz(action_result, 60, "%s:%s", program_name, strncmp(thread_tag, "STREAM_RECEIVER", strlen("STREAM_RECEIVER")) ? thread_tag : "[x]");
837 send_statistics("FATAL", action_result, action_data);
838
839 netdata_cleanup_and_exit(1);
libnetdata/threads/threads.c
+17 -1
@@ -18,8 +18,12 @@ typedef struct {
18
19 static __thread NETDATA_THREAD *netdata_thread = NULL;
20
21 +inline int netdata_thread_tag_exists(void) {
22 + return (netdata_thread && netdata_thread->tag && *netdata_thread->tag);
23 +}
24 +
25 const char *netdata_thread_tag(void) {
22 - return ((netdata_thread && netdata_thread->tag && *netdata_thread->tag)?netdata_thread->tag:"MAIN");
26 + return (netdata_thread_tag_exists() ? netdata_thread->tag : "MAIN");
27 }
28
29 // ----------------------------------------------------------------------------
@@ -151,6 +155,18 @@ void uv_thread_set_name_np(uv_thread_t ut, const char* name) {
155 info("cannot set libuv thread name to %s. Err: %d", threadname, ret);
156 }
157
158 +void os_thread_get_current_name_np(char threadname[NETDATA_THREAD_NAME_MAX + 1])
159 +{
160 + int ret = 0;
161 +
162 + threadname[0] = '\0';
163 +#if defined(__FreeBSD__)
164 + pthread_get_name_np(pthread_self(), threadname, NETDATA_THREAD_NAME_MAX + 1);
165 +#elif defined(HAVE_PTHREAD_GETNAME_NP) /* Linux & macOS */
166 + (void)pthread_getname_np(pthread_self(), threadname, NETDATA_THREAD_NAME_MAX + 1);
167 +#endif
168 +}
169 +
170 static void *thread_start(void *ptr) {
171 netdata_thread = (NETDATA_THREAD *)ptr;
172
libnetdata/threads/threads.h
+2
@@ -22,6 +22,7 @@ typedef pthread_t netdata_thread_t;
22
23 #define NETDATA_THREAD_TAG_MAX 100
24 extern const char *netdata_thread_tag(void);
25 +extern int netdata_thread_tag_exists(void);
26
27 extern size_t netdata_threads_init(void);
28 extern void netdata_threads_init_after_fork(size_t stacksize);
@@ -33,6 +34,7 @@ extern int netdata_thread_detach(pthread_t thread);
34
35 #define NETDATA_THREAD_NAME_MAX 15
36 extern void uv_thread_set_name_np(uv_thread_t ut, const char* name);
37 +extern void os_thread_get_current_name_np(char threadname[NETDATA_THREAD_NAME_MAX + 1]);
38
39 #define netdata_thread_self pthread_self
40 #define netdata_thread_testcancel pthread_testcancel