@cryptotaxi247 / netdata-1 / commits / 66d3b9e72

disk statistics got proper names; isolated a performance issue with strftime() which did excessive calls to stat(/etc/localtime); added backtrace call and increase core dump size when in debug mode; added task id (pid) in logs to help strace system calls

Costa Tsaousis (ktsaou) committed Oct 27, 2015 at 02:34 UTC 66d3b9e72b54c4e0e2fccf95c9ef35760316a0ec
15 files changed +121 -63
netdata.start
+4
@@ -105,6 +105,10 @@ echo >&2
105 # -----------------------------------------------------------------------------
106 # run netdata
107
108 +# avoid extended stat(/etc/localtime)
109 +# http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
110 +export TZ=":/etc/localtime"
111 +
112 echo >&2 "Starting netdata..."
113 `pwd`/netdata "${@}"
114
src/Makefile
+1
@@ -37,6 +37,7 @@ COMMON_FLAGS += debug=1
37 CFLAGS = -Wall -Wextra -O -ggdb -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fno-omit-frame-pointer
38 # CFLAGS := -Wall -Wextra -O -g -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fsanitize=thread -fno-omit-frame-pointer -fPIE
39 # libs += -pie -ltsan
40 +libs += -rdynamic
41 else
42 CFLAGS := -Wall -Wextra -O3 -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fomit-frame-pointer
43 endif
src/common.c
+7 -1
@@ -1,6 +1,6 @@
1 // enable O_NOATIME
2 #define _GNU_SOURCE
3 -
3 +#include <sys/syscall.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <errno.h>
@@ -187,3 +187,9 @@ void get_HZ(void)
187
188 hz = (unsigned int) ticks;
189 }
190 +
191 +pid_t gettid(void)
192 +{
193 + return syscall(SYS_gettid);
194 +}
195 +
src/common.h
+4
@@ -1,4 +1,6 @@
1 #include <inttypes.h>
2 +#include <sys/types.h>
3 +#include <unistd.h>
4
5 #ifndef NETDATA_COMMON_H
6 #define NETDATA_COMMON_H 1
@@ -34,4 +36,6 @@ extern char *global_host_prefix;
36 extern unsigned int hz;
37 extern void get_HZ(void);
38
39 +extern pid_t gettid(void);
40 +
41 #endif /* NETDATA_COMMON_H */
src/daemon.c
+32 -3
@@ -10,6 +10,7 @@
10 #include <pthread.h>
11 #include <sys/wait.h>
12 #include <sys/stat.h>
13 +#include <execinfo.h>
14
15 #include "config.h"
16 #include "log.h"
@@ -21,17 +22,45 @@
22 #include "main.h"
23 #include "daemon.h"
24
25 +#define BACKTRACE_SIZE 4096
26 +
27 +void print_backtrace()
28 +{
29 + void *buffer[BACKTRACE_SIZE];
30 + int nptrs;
31 +
32 + nptrs = backtrace(buffer, BACKTRACE_SIZE);
33 + fprintf(stderr, "\n\nSTACK TRACE (%d addresses):\n\n", nptrs);
34 + backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO);
35 + fprintf(stderr, "\n\n");
36 +}
37 +
38 void sig_handler(int signo)
39 {
40 switch(signo) {
41 + case SIGILL:
42 + case SIGABRT:
43 + case SIGFPE:
44 + case SIGSEGV:
45 + case SIGBUS:
46 + case SIGSYS:
47 + case SIGTRAP:
48 + case SIGXCPU:
49 + case SIGXFSZ:
50 + info("Death signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
51 + print_backtrace();
52 + signal(signo, SIG_DFL);
53 + break;
54 +
55 + case SIGKILL:
56 case SIGTERM:
57 case SIGQUIT:
58 case SIGINT:
59 case SIGHUP:
31 - case SIGFPE:
32 - case SIGSEGV:
60 + case SIGUSR1:
61 + case SIGUSR2:
62 info("Signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
34 - signal(SIGCHLD, SIG_IGN);
63 + print_backtrace();
64 signal(SIGPIPE, SIG_IGN);
65 signal(SIGTERM, SIG_IGN);
66 signal(SIGQUIT, SIG_IGN);
src/main.c
+8
@@ -8,6 +8,8 @@
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 +#include <sys/time.h>
12 +#include <sys/resource.h>
13
14 #include "common.h"
15 #include "log.h"
@@ -244,6 +246,12 @@ int main(int argc, char **argv)
246 debug_flags = strtoull(flags, NULL, 0);
247 debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);
248
249 + if(debug_flags != 0) {
250 + struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
251 + if(setrlimit(RLIMIT_CORE, &rl) != 0)
252 + info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
253 + }
254 +
255 // --------------------------------------------------------------------
256
257 global_host_prefix = config_get("global", "host access prefix", "");
src/plugin_checks.c
+2
@@ -14,6 +14,8 @@ void *checks_main(void *ptr)
14 {
15 if(ptr) { ; }
16
17 + info("CHECKS thread created with task id %d", gettid());
18 +
19 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
20 error("Cannot set pthread cancel type to DEFERRED.");
21
src/plugin_idlejitter.c
+2
@@ -17,6 +17,8 @@ void *cpuidlejitter_main(void *ptr)
17 {
18 if(ptr) { ; }
19
20 + info("CPU Idle Jitter thread created with task id %d", gettid());
21 +
22 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
23 error("Cannot set pthread cancel type to DEFERRED.");
24
src/plugin_nfacct.c
+2
@@ -76,6 +76,8 @@ static int nfacct_callback(const struct nlmsghdr *nlh, void *data) {
76 void *nfacct_main(void *ptr) {
77 if(ptr) { ; }
78
79 + info("NFACCT thread created with task id %d", gettid());
80 +
81 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
82 error("nfacct.plugin: Cannot set pthread cancel type to DEFERRED.");
83
src/plugin_proc.c
+2
@@ -15,6 +15,8 @@ void *proc_main(void *ptr)
15 {
16 if(ptr) { ; }
17
18 + info("PROC Plugin thread created with task id %d", gettid());
19 +
20 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
21 error("Cannot set pthread cancel type to DEFERRED.");
22
src/plugin_tc.c
+3 -1
@@ -1,7 +1,7 @@
1 -#include <inttypes.h>
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 +#include <sys/types.h>
5
6 #include "avl.h"
7 #include "log.h"
@@ -437,6 +437,8 @@ void *tc_main(void *ptr)
437 {
438 if(ptr) { ; }
439
440 + info("TC thread created with task id %d", gettid());
441 +
442 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
443 error("Cannot set pthread cancel type to DEFERRED.");
444
src/plugins_d.c
+2
@@ -392,6 +392,8 @@ void *pluginsd_main(void *ptr)
392 {
393 if(ptr) { ; }
394
395 + info("PLUGINS.D thread created with task id %d", gettid());
396 +
397 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
398 error("Cannot set pthread cancel type to DEFERRED.");
399
src/proc_diskstats.c
+46 -55
@@ -19,17 +19,17 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
19 static procfile *ff = NULL;
20 static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
21 static int enable_new_disks = -1;
22 - static int do_io = -1, do_ops = -1, do_merged_ops = -1, do_iotime = -1, do_cur_ops = -1, do_util = -1, do_qsize = -1;
22 + static int do_io = -1, do_ops = -1, do_mops = -1, do_iotime = -1, do_qops = -1, do_util = -1, do_backlog = -1;
23
24 if(enable_new_disks == -1) enable_new_disks = config_get_boolean("plugin:proc:/proc/diskstats", "enable new disks detected at runtime", 1);
25
26 - if(do_io == -1) do_io = config_get_boolean("plugin:proc:/proc/diskstats", "bandwidth for all disks", 1);
27 - if(do_ops == -1) do_ops = config_get_boolean("plugin:proc:/proc/diskstats", "operations for all disks", 1);
28 - if(do_merged_ops == -1) do_merged_ops = config_get_boolean("plugin:proc:/proc/diskstats", "merged operations for all disks", 1);
29 - if(do_iotime == -1) do_iotime = config_get_boolean("plugin:proc:/proc/diskstats", "i/o time for all disks", 1);
30 - if(do_cur_ops == -1) do_cur_ops = config_get_boolean("plugin:proc:/proc/diskstats", "current operations for all disks", 1);
31 - if(do_util == -1) do_util = config_get_boolean("plugin:proc:/proc/diskstats", "utilization percentage for all disks", 1);
32 - if(do_qsize == -1) do_qsize = config_get_boolean("plugin:proc:/proc/diskstats", "queue size for all disks", 1);
26 + if(do_io == -1) do_io = config_get_boolean("plugin:proc:/proc/diskstats", "bandwidth for all disks", 1);
27 + if(do_ops == -1) do_ops = config_get_boolean("plugin:proc:/proc/diskstats", "operations for all disks", 1);
28 + if(do_mops == -1) do_mops = config_get_boolean("plugin:proc:/proc/diskstats", "merged operations for all disks", 1);
29 + if(do_iotime == -1) do_iotime = config_get_boolean("plugin:proc:/proc/diskstats", "i/o time for all disks", 1);
30 + if(do_qops == -1) do_qops = config_get_boolean("plugin:proc:/proc/diskstats", "queued operations for all disks", 1);
31 + if(do_util == -1) do_util = config_get_boolean("plugin:proc:/proc/diskstats", "utilization percentage for all disks", 1);
32 + if(do_backlog == -1)do_backlog = config_get_boolean("plugin:proc:/proc/diskstats", "backlog for all disks", 1);
33
34 if(!ff) {
35 char filename[FILENAME_MAX + 1];
@@ -53,13 +53,13 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
53 for(l = 0; l < lines ;l++) {
54 char *disk;
55 unsigned long long major = 0, minor = 0,
56 - reads = 0, reads_merged = 0, readsectors = 0, readms = 0,
57 - writes = 0, writes_merged = 0, writesectors = 0, writems = 0,
58 - currentios = 0, iosms = 0, wiosms = 0;
56 + reads = 0, mreads = 0, readsectors = 0, readms = 0,
57 + writes = 0, mwrites = 0, writesectors = 0, writems = 0,
58 + queued_ios = 0, busy_ms = 0, backlog_ms = 0;
59
60 unsigned long long last_reads = 0, last_readsectors = 0, last_readms = 0,
61 last_writes = 0, last_writesectors = 0, last_writems = 0,
62 - last_iosms = 0;
62 + last_busy_ms = 0;
63
64 words = procfile_linewords(ff, l);
65 if(words < 14) continue;
@@ -77,8 +77,8 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
77 // Reads and writes which are adjacent to each other may be merged for
78 // efficiency. Thus two 4K reads may become one 8K read before it is
79 // ultimately handed to the disk, and so it will be counted (and queued)
80 - reads_merged = strtoull(procfile_lineword(ff, l, 4), NULL, 10); // rd_merges_or_rd_sec
81 - writes_merged = strtoull(procfile_lineword(ff, l, 8), NULL, 10); // wr_merges
80 + mreads = strtoull(procfile_lineword(ff, l, 4), NULL, 10); // rd_merges_or_rd_sec
81 + mwrites = strtoull(procfile_lineword(ff, l, 8), NULL, 10); // wr_merges
82
83 // # of sectors read # of sectors written
84 // This is the total number of sectors read or written successfully.
@@ -94,19 +94,19 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
94 // # of I/Os currently in progress
95 // The only field that should go to zero. Incremented as requests are
96 // given to appropriate struct request_queue and decremented as they finish.
97 - currentios = strtoull(procfile_lineword(ff, l, 11), NULL, 10); // ios_pgr
97 + queued_ios = strtoull(procfile_lineword(ff, l, 11), NULL, 10); // ios_pgr
98
99 // # of milliseconds spent doing I/Os
100 - // This field increases so long as field currentios is nonzero.
101 - iosms = strtoull(procfile_lineword(ff, l, 12), NULL, 10); // tot_ticks
100 + // This field increases so long as field queued_ios is nonzero.
101 + busy_ms = strtoull(procfile_lineword(ff, l, 12), NULL, 10); // tot_ticks
102
103 // weighted # of milliseconds spent doing I/Os
104 // This field is incremented at each I/O start, I/O completion, I/O
105 // merge, or read of these stats by the number of I/Os in progress
106 - // (field currentios) times the number of milliseconds spent doing I/O since the
106 + // (field queued_ios) times the number of milliseconds spent doing I/O since the
107 // last update of this field. This can provide an easy measure of both
108 // I/O completion time and the backlog that may be accumulating.
109 - wiosms = strtoull(procfile_lineword(ff, l, 13), NULL, 10); // rq_ticks
109 + backlog_ms = strtoull(procfile_lineword(ff, l, 13), NULL, 10); // rq_ticks
110
111 int def_enabled = 0;
112
@@ -270,7 +270,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
270 }
271 else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename);
272
273 - st = rrdset_create(RRD_TYPE_DISK, disk, NULL, disk, "Disk I/O", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
273 + st = rrdset_create(RRD_TYPE_DISK, disk, NULL, disk, "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
274
275 rrddim_add(st, "reads", NULL, sector_size, 1024 * update_every, RRDDIM_INCREMENTAL);
276 rrddim_add(st, "writes", NULL, sector_size * -1, 1024 * update_every, RRDDIM_INCREMENTAL);
@@ -287,7 +287,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
287 if(do_ops) {
288 st = rrdset_find_bytype("disk_ops", disk);
289 if(!st) {
290 - st = rrdset_create("disk_ops", disk, NULL, disk, "Disk Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
290 + st = rrdset_create("disk_ops", disk, NULL, disk, "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
291 st->isdetail = 1;
292
293 rrddim_add(st, "reads", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
@@ -302,58 +302,58 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
302
303 // --------------------------------------------------------------------
304
305 - if(do_util) {
306 - st = rrdset_find_bytype("disk_util", disk);
305 + if(do_qops) {
306 + st = rrdset_find_bytype("disk_qops", disk);
307 if(!st) {
308 - st = rrdset_create("disk_util", disk, NULL, disk, "Disk Utilization", "%", 2002, update_every, RRDSET_TYPE_AREA);
308 + st = rrdset_create("disk_qops", disk, NULL, disk, "Disk Queued I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
309 st->isdetail = 1;
310
311 - rrddim_add(st, "utilization", NULL, 1, 10 * update_every, RRDDIM_INCREMENTAL);
311 + rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
312 }
313 else rrdset_next_usec(st, dt);
314
315 - last_iosms = rrddim_set(st, "utilization", iosms);
315 + rrddim_set(st, "operations", queued_ios);
316 rrdset_done(st);
317 }
318
319 // --------------------------------------------------------------------
320
321 - if(do_qsize) {
322 - st = rrdset_find_bytype("disk_qsize", disk);
321 + if(do_backlog) {
322 + st = rrdset_find_bytype("disk_backlog", disk);
323 if(!st) {
324 - st = rrdset_create("disk_qsize", disk, NULL, disk, "Disk Average Queue Size", "queue size", 2003, update_every, RRDSET_TYPE_AREA);
324 + st = rrdset_create("disk_backlog", disk, NULL, disk, "Disk Backlog", "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
325 st->isdetail = 1;
326
327 - rrddim_add(st, "queue_size", NULL, 1, 1000 * update_every, RRDDIM_INCREMENTAL);
327 + rrddim_add(st, "backlog", NULL, 1, 1000 * update_every, RRDDIM_INCREMENTAL);
328 }
329 else rrdset_next_usec(st, dt);
330
331 - rrddim_set(st, "queue_size", wiosms);
331 + rrddim_set(st, "backlog", backlog_ms);
332 rrdset_done(st);
333 }
334
335 // --------------------------------------------------------------------
336
337 - if(do_cur_ops) {
338 - st = rrdset_find_bytype("disk_cur_ops", disk);
337 + if(do_util) {
338 + st = rrdset_find_bytype("disk_util", disk);
339 if(!st) {
340 - st = rrdset_create("disk_cur_ops", disk, NULL, disk, "Current Disk I/O operations", "operations", 2004, update_every, RRDSET_TYPE_LINE);
340 + st = rrdset_create("disk_util", disk, NULL, disk, "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
341 st->isdetail = 1;
342
343 - rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
343 + rrddim_add(st, "utilization", NULL, 1, 10 * update_every, RRDDIM_INCREMENTAL);
344 }
345 else rrdset_next_usec(st, dt);
346
347 - rrddim_set(st, "operations", currentios);
347 + last_busy_ms = rrddim_set(st, "utilization", busy_ms);
348 rrdset_done(st);
349 }
350
351 // --------------------------------------------------------------------
352
353 - if(do_merged_ops) {
354 - st = rrdset_find_bytype("disk_merged_ops", disk);
353 + if(do_mops) {
354 + st = rrdset_find_bytype("disk_mops", disk);
355 if(!st) {
356 - st = rrdset_create("disk_merged_ops", disk, NULL, disk, "Disk Merged Operations", "operations/s", 2021, update_every, RRDSET_TYPE_LINE);
356 + st = rrdset_create("disk_mops", disk, NULL, disk, "Disk Merged Operations", "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
357 st->isdetail = 1;
358
359 rrddim_add(st, "reads", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
@@ -361,8 +361,8 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
361 }
362 else rrdset_next_usec(st, dt);
363
364 - rrddim_set(st, "reads", reads_merged);
365 - rrddim_set(st, "writes", writes_merged);
364 + rrddim_set(st, "reads", mreads);
365 + rrddim_set(st, "writes", mwrites);
366 rrdset_done(st);
367 }
368
@@ -371,7 +371,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
371 if(do_iotime) {
372 st = rrdset_find_bytype("disk_iotime", disk);
373 if(!st) {
374 - st = rrdset_create("disk_iotime", disk, NULL, disk, "Disk I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
374 + st = rrdset_create("disk_iotime", disk, NULL, disk, "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
375 st->isdetail = 1;
376
377 rrddim_add(st, "reads", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
@@ -392,7 +392,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
392 if(do_iotime && do_ops) {
393 st = rrdset_find_bytype("disk_await", disk);
394 if(!st) {
395 - st = rrdset_create("disk_await", disk, NULL, disk, "Average Wait Time", "ms per operation", 2005, update_every, RRDSET_TYPE_AREA);
395 + st = rrdset_create("disk_await", disk, NULL, disk, "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_AREA);
396 st->isdetail = 1;
397
398 rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
@@ -408,7 +408,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
408 if(do_io && do_ops) {
409 st = rrdset_find_bytype("disk_avgsz", disk);
410 if(!st) {
411 - st = rrdset_create("disk_avgsz", disk, NULL, disk, "Average Operation Size", "kilobytes", 2006, update_every, RRDSET_TYPE_AREA);
411 + st = rrdset_create("disk_avgsz", disk, NULL, disk, "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
412 st->isdetail = 1;
413
414 rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_ABSOLUTE);
@@ -427,23 +427,14 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
427 st = rrdset_create("disk_svctm", disk, NULL, disk, "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_AREA);
428 st->isdetail = 1;
429
430 - rrddim_add(st, "svctm", NULL, -1, 1, RRDDIM_ABSOLUTE);
430 + rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
431 }
432 else rrdset_next_usec(st, dt);
433
434 - rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (iosms - last_iosms) / ((reads - last_reads) + (writes - last_writes)) : 0);
434 + rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
435 rrdset_done(st);
436 }
437 }
438 -
439 - // TODO
440 - // the differential (readms + writems) / (reads + writes) = average wait time
441 - // the differential (readms ) / (reads ) = the average wait time for reads
442 - // the differential (writems) / (writes) = the average wait time for writes
443 -
444 - // similarly for bytes to find the average read and write size
445 -
446 - // svctm = % of utilization per request (reads + writes)
438 }
439
440 return 0;
src/web_client.c
+3
@@ -1208,6 +1208,8 @@ void *web_client_main(void *ptr)
1208 fd_set ifds, ofds, efds;
1209 int fdmax = 0;
1210
1211 + log_access("%llu: %s port %s connected on thread task id %d", w->id, w->client_ip, w->client_port, gettid());
1212 +
1213 for(;;) {
1214 FD_ZERO (&ifds);
1215 FD_ZERO (&ofds);
@@ -1286,6 +1288,7 @@ void *web_client_main(void *ptr)
1288 }
1289 }
1290
1291 + log_access("%llu: %s port %s disconnected from thread task id %d", w->id, w->client_ip, w->client_port, gettid());
1292 debug(D_WEB_CLIENT, "%llu: done...", w->id);
1293
1294 web_client_reset(w);
src/web_server.c
+3 -3
@@ -136,6 +136,9 @@ int create_listen_socket6(int port, int listen_backlog)
136 void *socket_listen_main(void *ptr)
137 {
138 if(ptr) { ; }
139 +
140 + info("WEB SERVER thread created with task id %d", gettid());
141 +
142 struct web_client *w;
143 struct timeval tv;
144 int retval;
@@ -193,8 +196,6 @@ void *socket_listen_main(void *ptr)
196 error("%llu: Cannot request detach of newly created web client thread.", w->id);
197 w->obsolete = 1;
198 }
196 -
197 - log_access("%llu: %s port %s connected", w->id, w->client_ip, w->client_port);
199 }
200 else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
201
@@ -206,7 +207,6 @@ void *socket_listen_main(void *ptr)
207 // cleanup unused clients
208 for(w = web_clients; w ; w = w?w->next:NULL) {
209 if(w->obsolete) {
209 - log_access("%llu: %s port %s disconnected", w->id, w->client_ip, w->client_port);
210 debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
211 // pthread_join(w->thread, NULL);
212 w = web_client_free(w);