[![Build Status](https://travis-ci.org/firehol/netdata.svg?branch=master)](https://travis-ci.org/firehol/netdata)
-[![User Base](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&label=user%20base&units=null&value_color=blue&precision=0)](https://registry.my-netdata.io/#netdata_registry)
-[![Monitored Servers](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&label=servers%20monitored&units=null&value_color=orange&precision=0)](https://registry.my-netdata.io/#netdata_registry)
-[![Sessions Served](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&label=sessions%20served&units=null&value_color=yellowgreen&precision=0)](https://registry.my-netdata.io/#netdata_registry)
+[![User Base](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&label=user%20base&units=null&value_color=blue&precision=0&v40)](https://registry.my-netdata.io/#netdata_registry)
+[![Monitored Servers](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&label=servers%20monitored&units=null&value_color=orange&precision=0&v40)](https://registry.my-netdata.io/#netdata_registry)
+[![Sessions Served](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&label=sessions%20served&units=null&value_color=yellowgreen&precision=0&v40)](https://registry.my-netdata.io/#netdata_registry)
-[![New Users Today](http://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&after=-86400&options=unaligned&group=incremental-sum&label=new%20users%20today&units=null&value_color=blue&precision=0)](https://registry.my-netdata.io/#netdata_registry)
-[![New Machines Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&group=incremental-sum&after=-86400&options=unaligned&label=servers%20added%20today&units=null&value_color=orange&precision=0)](https://registry.my-netdata.io/#netdata_registry)
-[![Sessions Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&after=-86400&group=incremental-sum&options=unaligned&label=sessions%20served%20today&units=null&value_color=yellowgreen&precision=0)](https://registry.my-netdata.io/#netdata_registry)
+[![New Users Today](http://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&after=-86400&options=unaligned&group=incremental-sum&label=new%20users%20today&units=null&value_color=blue&precision=0&v40)](https://registry.my-netdata.io/#netdata_registry)
+[![New Machines Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&group=incremental-sum&after=-86400&options=unaligned&label=servers%20added%20today&units=null&value_color=orange&precision=0&v40)](https://registry.my-netdata.io/#netdata_registry)
+[![Sessions Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&after=-86400&group=incremental-sum&options=unaligned&label=sessions%20served%20today&units=null&value_color=yellowgreen&precision=0&v40)](https://registry.my-netdata.io/#netdata_registry)
# netdata
# This statement does not require any privilege.
# It requires only the ability to connect to the server.
-mysql_update_every=5
+mysql_update_every=2
mysql_priority=60000
declare -A mysql_cmds=() mysql_opts=() mysql_ids=() mysql_data=()
local oIFS="${IFS}"
mysql_data=()
IFS=$'\t'$'\n'
- arr=($("${@}" -e "SHOW GLOBAL STATUS WHERE value REGEXP '^[0-9]';" | egrep "^(Bytes|Slow_|Queri|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)" ))
+ arr=($("${@}" -e "SHOW GLOBAL STATUS WHERE value REGEXP '^[0-9]';" | egrep "^(Bytes|Slow_|Que|Handl|Table|Selec|Sort_|Creat|Conne|Abort|Binlo|Threa|Innod|Qcach|Key_|Open)" ))
IFS="${oIFS}"
[ "${#arr[@]}" -lt 3 ] && return 1
BEGIN mysql_$x.qcache_ops $1
SET Qcache_hits hits = ${mysql_data[Qcache_hits]}
SET Qcache_lowmem_prunes = ${mysql_data[Qcache_lowmem_prunes]}
-SET Qcache_inserts_inserts = ${mysql_data[Qcache_inserts_inserts]}
+SET Qcache_inserts = ${mysql_data[Qcache_inserts]}
SET Qcache_not_cached = ${mysql_data[Qcache_not_cached]}
END
BEGIN mysql_$x.qcache $1
squid_port=
squid_url=
squid_timeout=2
-squid_update_every=5
+squid_update_every=2
squid_priority=60000
squid_get_stats_internal() {
AC_PROG_INSTALL
PKG_PROG_PKG_CONFIG
AC_USE_SYSTEM_EXTENSIONS
+AC_CHECK_FUNCS_ONCE(accept4)
AC_ARG_ENABLE(
[plugin-nfacct],
if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.installer_backup.${installer_backup_suffix}" ]
then
cp -p "${NETDATA_PREFIX}/etc/netdata/${x}.installer_backup.${installer_backup_suffix}" "${NETDATA_PREFIX}/etc/netdata/${x}"
+ rm -f "${NETDATA_PREFIX}/etc/netdata/${x}.installer_backup.${installer_backup_suffix}"
fi
done
global_update() {
local exit_at \
c=0 dt ret last_ms exec_start_ms exec_end_ms \
- chart now_charts=() next_charts=($run_charts)
+ chart now_charts=() next_charts=($run_charts) \
+ next_ms x seconds millis
# return the current time in ms in $now_ms
current_time_ms
suspend || ( echo >&2 "$PROGRAM_NAME: suspend returned error $?, falling back to sleep."; loopsleepms $debug_time $update_every $time_divisor)
else
# wait the time you are required to
- #loopsleepms $debug_time $update_every $time_divisor
- if [ ${LOOPSLEEPMS_HIGHRES} -eq 1 ]
+ next_ms=$((now_ms + (update_every * 1000 * 100) ))
+ for x in "${charts_next_update[@]}"; do [ ${x} -lt ${next_ms} ] && next_ms=${x}; done
+ next_ms=$((next_ms - now_ms))
+
+ if [ ${LOOPSLEEPMS_HIGHRES} -eq 1 -a ${next_ms} -gt 0 ]
then
- sleep 0.2
+ seconds=$(( next_ms / 1000 ))
+ millis=$(( next_ms % 1000 ))
+ [ ${millis} -lt 10 ] && millis="0${millis}"
+ [ ${millis} -lt 100 ] && millis="0${millis}"
+ [ $debug -eq 1 ] && echo >&2 "$PROGRAM_NAME: sleeping for ${seconds}.${millis} seconds."
+ sleep ${seconds}.${millis}
else
- sleep 1
+ sleep $update_every
fi
fi
if(!cv) cv = config_value_create(co, name, value);
else {
if(((cv->flags & CONFIG_VALUE_USED) && overwrite_used) || !(cv->flags & CONFIG_VALUE_USED)) {
- debug(D_CONFIG, "Overwriting '%s/%s'.", line, co->name, cv->name);
+ debug(D_CONFIG, "Line %d, overwriting '%s/%s'.", line, co->name, cv->name);
free(cv->value);
cv->value = strdup(value);
if(!cv->value) fatal("Cannot allocate config.value");
allocations.allocated -= old_size;
debug(D_MEMORY, "MEMORY: Re-allocated from %zu to %zu bytes for %s/%u@%s."
- " Status: allocated %z in %zu allocs."
+ " Status: allocated %zu in %zu allocs."
, old_size, size
, function, line, file
, allocations.allocated
struct target *n = get_apps_groups_target(s, w);
if(!n) {
- error("Cannot create target '%s' (line %d, word %d)", s, line, word);
+ error("Cannot create target '%s' (line %lu, word %lu)", s, line, word);
continue;
}
}
if(unlikely(debug || w->debug))
- fprintf(stderr, "apps.plugin: \tAgregating %s pid %d on %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->pid, w->name, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
+ fprintf(stderr, "apps.plugin: \tAggregating %s pid %d on %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->pid, w->name, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
/* if(p->utime - p->old_utime > 100) fprintf(stderr, "BIG CHANGE: %d %s utime increased by %llu from %llu to %llu\n", p->pid, p->comm, p->utime - p->old_utime, p->old_utime, p->utime);
if(p->cutime - p->old_cutime > 100) fprintf(stderr, "BIG CHANGE: %d %s cutime increased by %llu from %llu to %llu\n", p->pid, p->comm, p->cutime - p->old_cutime, p->old_cutime, p->cutime);
errno = 0;
fd = open(filename, O_RDWR|O_CREAT|O_NOATIME, 0664);
if(fd != -1) {
- if(lseek(fd, size, SEEK_SET) == (long)size) {
+ if(lseek(fd, size, SEEK_SET) == (off_t)size) {
if(write(fd, "", 1) == 1) {
if(ftruncate(fd, size))
error("Cannot truncate file '%s' to size %ld. Will use the larger file.", filename, size);
if(flags & MAP_SHARED || !enable_ksm || !ksm) {
#endif
mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
- if(mem) {
+ if(mem != MAP_FAILED) {
int advise = MADV_SEQUENTIAL|MADV_DONTFORK;
if(flags & MAP_SHARED) advise |= MADV_WILLNEED;
#ifdef MADV_MERGEABLE
}
else {
- mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
+/*
+ // test - load the file into memory
+ mem = calloc(1, size);
if(mem) {
if(lseek(fd, 0, SEEK_SET) == 0) {
if(read(fd, mem, size) != (ssize_t)size)
}
else
error("Cannot seek to beginning of file '%s'.", filename);
+ }
+*/
+ mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
+ if(mem != MAP_FAILED) {
+ if(lseek(fd, 0, SEEK_SET) == 0) {
+ if(read(fd, mem, size) != (ssize_t)size)
+ error("Cannot read from file '%s'", filename);
+ }
+ else
+ error("Cannot seek to beginning of file '%s'.", filename);
// don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE
if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK) != 0)
return mem;
}
-int savememory(const char *filename, void *mem, unsigned long size)
+int savememory(const char *filename, void *mem, size_t size)
{
char tmpfilename[FILENAME_MAX + 1];
return -1;
}
- if(write(fd, mem, size) != (long)size) {
+ if(write(fd, mem, size) != (ssize_t)size) {
error("Cannot write to file '%s' %ld bytes.", filename, (long)size);
close(fd);
return -1;
close(fd);
- int ret = 0;
if(rename(tmpfilename, filename)) {
error("Cannot rename '%s' to '%s'", tmpfilename, filename);
- ret = -1;
+ return -1;
}
- return ret;
+ return 0;
}
int fd_is_valid(int fd) {
extern int snprintfz(char *dst, size_t n, const char *fmt, ...);
extern void *mymmap(const char *filename, size_t size, int flags, int ksm);
-extern int savememory(const char *filename, void *mem, unsigned long size);
+extern int savememory(const char *filename, void *mem, size_t size);
extern int fd_is_valid(int fd);
void sig_handler(int signo)
{
- if(signo)
+ if(signo) {
+ error_log_limit_unlimited();
+ error("Received signal %d. Exiting...", signo);
netdata_exit = 1;
+ }
}
static void properly_chown_netdata_generated_file(int fd, uid_t uid, gid_t gid) {
debug(D_DICTIONARY, "Creating name value entry for name '%s'.", name);
NAME_VALUE *nv = calloc(1, sizeof(NAME_VALUE));
- if(unlikely(!nv)) fatal("Cannot allocate name_value of size %z", sizeof(NAME_VALUE));
+ if(unlikely(!nv)) fatal("Cannot allocate name_value of size %zu", sizeof(NAME_VALUE));
if(dict->flags & DICTIONARY_FLAG_NAME_LINK_DONT_CLONE)
nv->name = (char *)name;
else {
nv->name = strdup(name);
if (unlikely(!nv->name))
- fatal("Cannot allocate name_value.name of size %z", strlen(name));
+ fatal("Cannot allocate name_value.name of size %zu", strlen(name));
}
nv->hash = (hash)?hash:simple_hash(nv->name);
else {
nv->value = malloc(value_len);
if (unlikely(!nv->value))
- fatal("Cannot allocate name_value.value of size %z", value_len);
+ fatal("Cannot allocate name_value.value of size %zu", value_len);
memcpy(nv->value, value, value_len);
}
*old = nv->value;
if(unlikely(!nv->value))
- fatal("Cannot allocate value of size %z", value_len);
+ fatal("Cannot allocate value of size %zu", value_len);
memcpy(value, value, value_len);
nv->value = value;
void log_date(FILE *out)
{
- char outstr[200];
+ char outstr[24];
time_t t;
struct tm *tmp, tmbuf;
tmp = localtime_r(&t, &tmbuf);
if (tmp == NULL) return;
- if (strftime(outstr, sizeof(outstr), "%y-%m-%d %H:%M:%S", tmp) == 0) return;
+ if (unlikely(strftime(outstr, sizeof(outstr), "%y-%m-%d %H:%M:%S", tmp) == 0)) return;
fprintf(out, "%s: ", outstr);
}
log_date(stdout);
va_start( args, fmt );
- fprintf(stdout, "DEBUG (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
- vfprintf( stdout, fmt, args );
+ printf("DEBUG (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
+ vprintf(fmt, args);
va_end( args );
- fprintf(stdout, "\n");
- // fflush( stdout );
+ putchar('\n');
if(output_log_syslog) {
va_start( args, fmt );
vfprintf( stderr, fmt, args );
va_end( args );
- fprintf(stderr, "\n");
+ fputc('\n', stderr);
if(error_log_syslog) {
va_start( args, fmt );
va_end( args );
if(errno) {
- char buf[200];
- char *s = strerror_r(errno, buf, 200);
- fprintf(stderr, " (errno %d, %s)\n", errno, s);
+ char buf[1024];
+ fprintf(stderr, " (errno %d, %s)\n", errno, strerror_r(errno, buf, 1023));
errno = 0;
}
- else fprintf(stderr, "\n");
+ else
+ fputc('\n', stderr);
if(error_log_syslog) {
va_start( args, fmt );
va_end( args );
perror(" # ");
- fprintf(stderr, "\n");
+ fputc('\n', stderr);
if(error_log_syslog) {
va_start( args, fmt );
va_start( args, fmt );
vfprintf( stdaccess, fmt, args );
va_end( args );
- fprintf( stdaccess, "\n");
- // fflush( stdaccess );
+ fputc('\n', stdaccess);
}
if(access_log_syslog) {
extern int error_log_limit(int reset);
#define error_log_limit_reset() do { error_log_limit(1); } while(0)
+#define error_log_limit_unlimited() do { error_log_throttle_period = 0; } while(0)
#define debug(type, args...) do { if(unlikely(!silent && (debug_flags & type))) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0)
#define info(args...) info_int(__FILE__, __FUNCTION__, __LINE__, ##args)
#define fatal(args...) fatal_int(__FILE__, __FUNCTION__, __LINE__, ##args)
extern void log_date(FILE *out);
-extern void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... );
-extern void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... );
-extern void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... );
-extern void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ ((noreturn));
-extern void log_access( const char *fmt, ... );
+extern void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 4, 5)));
+extern void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 4, 5)));
+extern void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ (( format (printf, 5, 6)));
+extern void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... ) __attribute__ ((noreturn, format (printf, 4, 5)));
+extern void log_access( const char *fmt, ... ) __attribute__ (( format (printf, 1, 2)));
#endif /* NETDATA_LOG_H */
volatile sig_atomic_t netdata_exit = 0;
-void netdata_cleanup_and_exit(int ret)
-{
+void netdata_cleanup_and_exit(int ret) {
netdata_exit = 1;
+
+ error_log_limit_unlimited();
+
+ info("Called: netdata_cleanup_and_exit()");
rrdset_save_all();
// kill_childs();
- // let it log a few more error messages
- error_log_limit_reset();
-
if(pidfile[0]) {
if(unlink(pidfile) != 0)
error("Cannot unlink pidfile '%s'.", pidfile);
else if(!strcmp(s, "fixed"))
web_gzip_strategy = Z_FIXED;
else {
- error("Invalid compression strategy '%s'. Valid strategies are 'default', 'filtered', 'huffman only', 'rle' and 'fixed'. Proceeding with 'default'.");
+ error("Invalid compression strategy '%s'. Valid strategies are 'default', 'filtered', 'huffman only', 'rle' and 'fixed'. Proceeding with 'default'.", s);
web_gzip_strategy = Z_DEFAULT_STRATEGY;
}
web_gzip_level = (int)config_get_number("global", "web compression level", 3);
if(web_gzip_level < 1) {
- error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 1 (fastest compression).");
+ error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 1 (fastest compression).", web_gzip_level);
web_gzip_level = 1;
}
else if(web_gzip_level > 9) {
- error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 9 (best compression).");
+ error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 9 (best compression).", web_gzip_level);
web_gzip_level = 9;
}
#endif /* NETDATA_WITH_ZLIB */
char *access_log_file = NULL;
char *user = NULL;
{
- char buffer[1024];
-
- // --------------------------------------------------------------------
-
- sprintf(buffer, "0x%08llx", 0ULL);
- char *flags = config_get("global", "debug flags", buffer);
+ char *flags = config_get("global", "debug flags", "0x00000000");
setenv("NETDATA_DEBUG_FLAGS", flags, 1);
debug_flags = strtoull(flags, NULL, 0);
// --------------------------------------------------------------------
- if(gethostname(buffer, HOSTNAME_MAX) == -1)
- error("WARNING: Cannot get machine hostname.");
- hostname = config_get("global", "hostname", buffer);
- debug(D_OPTIONS, "hostname set to '%s'", hostname);
+ {
+ char hostnamebuf[HOSTNAME_MAX + 1];
+ if(gethostname(hostnamebuf, HOSTNAME_MAX) == -1)
+ error("WARNING: Cannot get machine hostname.");
+ hostname = config_get("global", "hostname", hostnamebuf);
+ debug(D_OPTIONS, "hostname set to '%s'", hostname);
+ }
// --------------------------------------------------------------------
// let the plugins know the min update_every
{
- char buf[51];
- snprintfz(buf, 50, "%d", rrd_update_every);
+ char buf[16];
+ snprintfz(buf, 15, "%d", rrd_update_every);
setenv("NETDATA_UPDATE_EVERY", buf, 1);
}
// --------------------------------------------------------------------
listen_fd = create_listen_socket();
- if(listen_fd < 0) fatal("Cannot listen socket.");
+ if(listen_fd == -1)
+ fatal("Cannot listen socket.");
}
// never become a problem
RRDDIM *rd = rrddim_find(st, c->id);
if(!rd) {
- debug(D_TC_LOOP, "TC: Adding to chart '%s', dimension '%s'", st->id, c->id, c->name);
+ debug(D_TC_LOOP, "TC: Adding to chart '%s', dimension '%s' (name: '%s')", st->id, c->id, c->name);
// new class, we have to add it
rd = rrddim_add(st, c->id, c->name?c->name:c->id, 8, 1024, RRDDIM_INCREMENTAL);
sleep((unsigned int) (cd->update_every * 10));
}
else {
- error("PLUGINSD: '%s' exited with error code %d, but has given useful output in the past (%zu times). We tried %d times to restart it, but it failed to generate data. Disabling it.", cd->fullfilename, code, cd->successful_collections, cd->serial_failures);
+ error("PLUGINSD: '%s' exited with error code %d, but has given useful output in the past (%zu times). We tried %zu times to restart it, but it failed to generate data. Disabling it.", cd->fullfilename, code, cd->successful_collections, cd->serial_failures);
cd->enabled = 0;
}
}
sleep((unsigned int) (cd->update_every * 10));
}
else {
- error("PLUGINSD: '%s' (pid %d) does not generate useful output, although it reports success (exits with 0), but we have tried %d times to collect something. Disabling it.", cd->fullfilename, cd->pid, cd->serial_failures);
+ error("PLUGINSD: '%s' (pid %d) does not generate useful output, although it reports success (exits with 0), but we have tried %zu times to collect something. Disabling it.", cd->fullfilename, cd->pid, cd->serial_failures);
cd->enabled = 0;
}
}
// fork again to become session leader
pid = fork();
- if(pid == -1) fprintf(stderr, "Cannot fork again on pid %d\n", getpid());
+ if(pid == -1)
+ error("pre-execution of command '%s' on pid %d: Cannot fork 2nd time.", command, getpid());
+
if(pid != 0) {
// the parent
exit(0);
// set a new process group id for just this child
if( setpgid(0, 0) != 0 )
- error("Cannot set a new process group for pid %d (%s)", getpid(), strerror(errno));
+ error("pre-execution of command '%s' on pid %d: Cannot set a new process group.", command, getpid());
if( getpgid(0) != getpid() )
- error("Process group set is incorrect. Expected %d, found %d", getpid(), getpgid(0));
+ error("pre-execution of command '%s' on pid %d: Cannot set a new process group. Process group set is incorrect. Expected %d, found %d", command, getpid(), getpid(), getpgid(0));
if( setsid() != 0 )
- error("Cannot set session id for pid %d (%s)", getpid(), strerror(errno));
+ error("pre-execution of command '%s' on pid %d: Cannot set session id.", command, getpid());
fprintf(stdout, "MYPID %d\n", getpid());
fflush(NULL);
sigset_t sigset;
sigfillset(&sigset);
- if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
- error("Could not block signals for threads");
- }
+ if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1)
+ error("pre-execution of command '%s' on pid %d: could not unblock signals for threads.", command, getpid());
+
// We only need to reset ignored signals.
// Signals with signal handlers are reset by default.
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
- if(sigaction(SIGPIPE, &sa, NULL) == -1) {
- error("Failed to change signal handler for SIGTERM");
- }
+ if(sigaction(SIGPIPE, &sa, NULL) == -1)
+ error("pre-execution of command '%s' on pid %d: failed to set default signal handler for SIGPIPE.", command, getpid());
}
if(waitid(P_PID, (id_t) pid, &info, WEXITED) != -1) {
switch(info.si_code) {
case CLD_EXITED:
- error("pid %d exited with code %d.", info.si_pid, info.si_status);
+ error("child pid %d exited with code %d.", info.si_pid, info.si_status);
return(info.si_status);
break;
case CLD_KILLED:
- error("pid %d killed by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d killed by signal %d.", info.si_pid, info.si_status);
return(-1);
break;
case CLD_DUMPED:
- error("pid %d core dumped by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d core dumped by signal %d.", info.si_pid, info.si_status);
return(-2);
break;
case CLD_STOPPED:
- error("pid %d stopped by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d stopped by signal %d.", info.si_pid, info.si_status);
return(0);
break;
case CLD_TRAPPED:
- error("pid %d trapped by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d trapped by signal %d.", info.si_pid, info.si_status);
return(-4);
break;
case CLD_CONTINUED:
- error("pid %d continued by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d continued by signal %d.", info.si_pid, info.si_status);
return(0);
break;
default:
- error("pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
+ error("child pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
return(-5);
break;
}
}
- else error("Cannot waitid() for pid %d", pid);
+ else
+ error("Cannot waitid() for pid %d", pid);
+
return 0;
}
st->isdetail = 1;
rrddim_add(st, "avail", NULL, 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
- rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
rrddim_add(st, "used" , NULL, 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
+ rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
}
else rrdset_next_usec(st, dt);
rrddim_set(st, "avail", space_avail);
- rrddim_set(st, "reserved_for_root", space_avail_root);
rrddim_set(st, "used", space_used);
+ rrddim_set(st, "reserved_for_root", space_avail_root);
rrdset_done(st);
}
st->isdetail = 1;
rrddim_add(st, "avail", NULL, 1, 1, RRDDIM_ABSOLUTE);
- rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1, RRDDIM_ABSOLUTE);
rrddim_add(st, "used" , NULL, 1, 1, RRDDIM_ABSOLUTE);
+ rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1, RRDDIM_ABSOLUTE);
}
else rrdset_next_usec(st, dt);
rrddim_set(st, "avail", inodes_avail);
- rrddim_set(st, "reserved_for_root", inodes_avail_root);
rrddim_set(st, "used", inodes_used);
+ rrddim_set(st, "reserved_for_root", inodes_avail_root);
rrdset_done(st);
}
}
if(!ff) return 0; // we return 0, so that we will retry to open it next time
// make sure we have 3 lines
- unsigned long lines = procfile_lines(ff), l;
+ size_t lines = procfile_lines(ff), l;
if(lines < 2) {
- error("/proc/net/stat/synproxy has %d lines, expected no less than 2. Disabling it.", lines);
+ error("/proc/net/stat/synproxy has %zu lines, expected no less than 2. Disabling it.", lines);
return 1;
}
debug(D_REGISTRY, "Registry: registry_url_allocate_nolock('%s'): allocating %zu bytes", url, sizeof(URL) + urllen);
URL *u = malloc(sizeof(URL) + urllen);
- if(!u) fatal("Cannot allocate %zu bytes for URL '%s'", sizeof(URL) + urllen);
+ if(!u) fatal("Cannot allocate %zu bytes for URL '%s'", sizeof(URL) + urllen, url);
// a simple strcpy() should do the job
// but I prefer to be safe, since the caller specified urllen
// verify it is valid
if (unlikely(len < 85 || s[1] != '\t' || s[10] != '\t' || s[47] != '\t' || s[84] != '\t')) {
- error("Registry: log line %u is wrong (len = %zu).", line, len);
+ error("Registry: log line %zu is wrong (len = %zu).", line, len);
continue;
}
s[1] = s[10] = s[47] = s[84] = '\0';
char *url = name;
while(*url && *url != '\t') url++;
if(!*url) {
- error("Registry: log line %u does not have a url.", line);
+ error("Registry: log line %zu does not have a url.", line);
continue;
}
*url++ = '\0';
switch(*s) {
case 'T': // totals
if(unlikely(len != 103 || s[1] != '\t' || s[18] != '\t' || s[35] != '\t' || s[52] != '\t' || s[69] != '\t' || s[86] != '\t' || s[103] != '\0')) {
- error("Registry totals line %u is wrong (len = %zu).", line, len);
+ error("Registry totals line %zu is wrong (len = %zu).", line, len);
continue;
}
registry.persons_count = strtoull(&s[2], NULL, 16);
m = NULL;
// verify it is valid
if(unlikely(len != 65 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[65] != '\0')) {
- error("Registry person line %u is wrong (len = %zu).", line, len);
+ error("Registry person line %zu is wrong (len = %zu).", line, len);
continue;
}
p = NULL;
// verify it is valid
if(unlikely(len != 65 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[65] != '\0')) {
- error("Registry person line %u is wrong (len = %zu).", line, len);
+ error("Registry person line %zu is wrong (len = %zu).", line, len);
continue;
}
// verify it is valid
if(len < 69 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[31] != '\t' || s[68] != '\t') {
- error("Registry person URL line %u is wrong (len = %zu).", line, len);
+ error("Registry person URL line %zu is wrong (len = %zu).", line, len);
continue;
}
char *url = &s[69];
while(*url && *url != '\t') url++;
if(!*url) {
- error("Registry person URL line %u does not have a url.", line);
+ error("Registry person URL line %zu does not have a url.", line);
continue;
}
*url++ = '\0';
// verify it is valid
if(len < 32 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[31] != '\t') {
- error("Registry person URL line %u is wrong (len = %zu).", line, len);
+ error("Registry person URL line %zu is wrong (len = %zu).", line, len);
continue;
}
#include "log.h"
#include "appconfig.h"
+#include "main.h"
#include "rrd.h"
#define RRD_DEFAULT_GAP_INTERPOLATIONS 1
info("Memory cleanup completed...");
}
-void rrdset_save_all(void)
-{
- debug(D_RRD_CALLS, "rrdset_save_all()");
-
- // let it log a few error messages
- error_log_limit_reset();
+void rrdset_save_all(void) {
+ info("Saving database...");
RRDSET *st;
RRDDIM *rd;
unsigned long long rrdset_done(RRDSET *st)
{
+ if(unlikely(netdata_exit)) return 0;
+
debug(D_RRD_CALLS, "rrdset_done() for chart %s", st->name);
RRDDIM *rd, *last;
// check if we will re-write the entire data set
if(unlikely(usecdiff(&st->last_collected_time, &st->last_updated) > st->update_every * st->entries * 1000000ULL)) {
- info("%s: too old data (last updated at %u.%u, last collected at %u.%u). Reseting it. Will not store the next entry.", st->name, st->last_updated.tv_sec, st->last_updated.tv_usec, st->last_collected_time.tv_sec, st->last_collected_time.tv_usec);
+ info("%s: too old data (last updated at %zu.%zu, last collected at %zu.%zu). Reseting it. Will not store the next entry.", st->name, st->last_updated.tv_sec, st->last_updated.tv_usec, st->last_collected_time.tv_sec, st->last_collected_time.tv_usec);
rrdset_reset(st);
st->usec_since_last_update = st->update_every * 1000000ULL;
long c; // current line ( -1 ~ n ), ( -1 = none, use rrdr_rows() to get number of rows )
long group; // how many collected values were grouped for each row
- long update_every; // what is the suggested update frequency in seconds
+ int update_every; // what is the suggested update frequency in seconds
calculated_number min;
calculated_number max;
, kq, kq, sq, r->st->name, sq
, kq, kq, r->update_every
, kq, kq, r->st->update_every
- , kq, kq, rrdset_first_entry_t(r->st)
- , kq, kq, rrdset_last_entry_t(r->st)
- , kq, kq, r->before
- , kq, kq, r->after
+ , kq, kq, (uint32_t)rrdset_first_entry_t(r->st)
+ , kq, kq, (uint32_t)rrdset_last_entry_t(r->st)
+ , kq, kq, (uint32_t)r->before
+ , kq, kq, (uint32_t)r->after
, kq, kq);
for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
}
buffer_sprintf(wb, "],\n"
- " %sdimensions%s: %d,\n"
- " %spoints%s: %d,\n"
+ " %sdimensions%s: %ld,\n"
+ " %spoints%s: %ld,\n"
" %sformat%s: %s"
, kq, kq, i
, kq, kq, rows
snprintfz(overflow_annotation, 200, ",{%sv%s:%sRESET OR OVERFLOW%s},{%sv%s:%sThe counters have been wrapped.%s}", kq, kq, sq, sq, kq, kq, sq, sq);
snprintfz(normal_annotation, 200, ",{%sv%s:null},{%sv%s:null}", kq, kq, kq, kq);
- buffer_sprintf(wb, "{\n %scols%s:\n [\n", kq, kq, kq, kq);
+ buffer_sprintf(wb, "{\n %scols%s:\n [\n", kq, kq);
buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%stime%s,%spattern%s:%s%s,%stype%s:%sdatetime%s},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq);
buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotation%s}},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotationText%s}}", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
return r;
cleanup:
- error("Cannot allocate RRDR memory for %d entries", n);
+ error("Cannot allocate RRDR memory for %ld entries", n);
if(likely(r)) rrdr_free(r);
return NULL;
}
#ifdef NETDATA_INTERNAL_CHECKS
if(after_new < first_entry_t) {
- error("after_new %u is too small, minimum %u", after_new, first_entry_t);
+ error("after_new %u is too small, minimum %u", (uint32_t)after_new, (uint32_t)first_entry_t);
}
if(after_new > last_entry_t) {
- error("after_new %u is too big, maximum %u", after_new, last_entry_t);
+ error("after_new %u is too big, maximum %u", (uint32_t)after_new, (uint32_t)last_entry_t);
}
if(before_new < first_entry_t) {
- error("before_new %u is too small, minimum %u", before_new, first_entry_t);
+ error("before_new %u is too small, minimum %u", (uint32_t)before_new, (uint32_t)first_entry_t);
}
if(before_new > last_entry_t) {
- error("before_new %u is too big, maximum %u", before_new, last_entry_t);
+ error("before_new %u is too big, maximum %u", (uint32_t)before_new, (uint32_t)last_entry_t);
}
if(start_at_slot < 0 || start_at_slot >= st->entries) {
- error("start_at_slot is invalid %ld, expected %ld to %ld", start_at_slot, 0, st->entries - 1);
+ error("start_at_slot is invalid %ld, expected 0 to %ld", start_at_slot, st->entries - 1);
}
if(stop_at_slot < 0 || stop_at_slot >= st->entries) {
- error("stop_at_slot is invalid %ld, expected %ld to %ld", stop_at_slot, 0, st->entries - 1);
+ error("stop_at_slot is invalid %ld, expected 0 to %ld", stop_at_slot, st->entries - 1);
}
if(points_new > (before_new - after_new) / group / st->update_every + 1) {
error("points_new %ld is more than points %ld", points_new, (before_new - after_new) / group / st->update_every + 1);
RRDR *r = rrdr_create(st, points);
if(!r) {
#ifdef NETDATA_INTERNAL_CHECKS
- error("Cannot create RRDR for %s, after=%u, before=%u, duration=%u, points=%d", st->id, after, before, duration, points);
+ error("Cannot create RRDR for %s, after=%u, before=%u, duration=%u, points=%ld", st->id, (uint32_t)after, (uint32_t)before, (uint32_t)duration, points);
#endif
return NULL;
}
if(!r->d) {
#ifdef NETDATA_INTERNAL_CHECKS
- error("Returning empty RRDR (no dimensions in RRDSET) for %s, after=%u, before=%u, duration=%u, points=%d", st->id, after, before, duration, points);
+ error("Returning empty RRDR (no dimensions in RRDSET) for %s, after=%u, before=%u, duration=%u, points=%ld", st->id, (uint32_t)after, (uint32_t)before, (uint32_t)duration, points);
#endif
return r;
}
// -------------------------------------------------------------------------
// checks for debugging
- if(debug) debug(D_RRD_STATS, "INFO %s first_t: %lu, last_t: %lu, all_duration: %lu, after: %lu, before: %lu, duration: %lu, points: %ld, group: %ld"
+ if(debug) debug(D_RRD_STATS, "INFO %s first_t: %u, last_t: %u, all_duration: %u, after: %u, before: %u, duration: %u, points: %ld, group: %ld"
, st->id
- , first_entry_t
- , last_entry_t
- , last_entry_t - first_entry_t
- , after
- , before
- , duration
+ , (uint32_t)first_entry_t
+ , (uint32_t)last_entry_t
+ , (uint32_t)(last_entry_t - first_entry_t)
+ , (uint32_t)after
+ , (uint32_t)before
+ , (uint32_t)duration
, points
, group
);
dt = st->update_every,
group_start_t = 0;
- if(unlikely(debug)) debug(D_RRD_STATS, "BEGIN %s after_t: %lu (stop_at_t: %ld), before_t: %lu (start_at_t: %ld), start_t(now): %lu, current_entry: %ld, entries: %ld"
+ if(unlikely(debug)) debug(D_RRD_STATS, "BEGIN %s after_t: %u (stop_at_t: %ld), before_t: %u (start_at_t: %ld), start_t(now): %u, current_entry: %ld, entries: %ld"
, st->id
- , after
+ , (uint32_t)after
, stop_at_slot
- , before
+ , (uint32_t)before
, start_at_slot
- , now
+ , (uint32_t)now
, st->current_entry
, st->entries
);
long count = 0, printed = 0, group_count = 0;
last_timestamp = 0;
- if(st->debug) debug(D_RRD_STATS, "%s: REQUEST after:%lu before:%lu, points:%d, group:%d, CHART cur:%ld first: %lu last:%lu, CALC start_t:%ld, stop_t:%ld"
+ if(st->debug) debug(D_RRD_STATS, "%s: REQUEST after:%u before:%u, points:%ld, group:%ld, CHART cur:%ld first: %u last:%u, CALC start_t:%ld, stop_t:%ld"
, st->id
- , after
- , before
+ , (uint32_t)after
+ , (uint32_t)before
, points
, group
, st->current_entry
- , rrdset_first_entry_t(st)
- , rrdset_last_entry_t(st)
+ , (uint32_t)rrdset_first_entry_t(st)
+ , (uint32_t)rrdset_last_entry_t(st)
, t
, stop_at_t
);
ca->cpu_percpu = malloc(sizeof(unsigned long long) * i);
if(!ca->cpu_percpu)
- fatal("Cannot allocate memory (%z bytes)", sizeof(unsigned long long) * i);
+ fatal("Cannot allocate memory (%zu bytes)", sizeof(unsigned long long) * i);
ca->cpus = i;
}
buffer_overflow_check(wb);
}
-BUFFER *buffer_create(long size)
+BUFFER *buffer_create(size_t size)
{
BUFFER *b;
- debug(D_WEB_BUFFER, "Creating new web buffer of size %d.", size);
+ debug(D_WEB_BUFFER, "Creating new web buffer of size %zu.", size);
b = calloc(1, sizeof(BUFFER));
if(!b) {
b->buffer = malloc(size + sizeof(BUFFER_OVERFLOW_EOF) + 2);
if(!b->buffer) {
- error("Cannot allocate a buffer of size %u.", size + sizeof(BUFFER_OVERFLOW_EOF) + 2);
+ error("Cannot allocate a buffer of size %zu.", size + sizeof(BUFFER_OVERFLOW_EOF) + 2);
free(b);
return NULL;
}
{
buffer_overflow_check(b);
- debug(D_WEB_BUFFER, "Freeing web buffer of size %d.", b->size);
+ debug(D_WEB_BUFFER, "Freeing web buffer of size %zu.", b->size);
if(b->buffer) free(b->buffer);
free(b);
size_t increase = free_size_required - left;
if(increase < WEB_DATA_LENGTH_INCREASE_STEP) increase = WEB_DATA_LENGTH_INCREASE_STEP;
- debug(D_WEB_BUFFER, "Increasing data buffer from size %d to %d.", b->size, b->size + increase);
+ debug(D_WEB_BUFFER, "Increasing data buffer from size %zu to %zu.", b->size, b->size + increase);
b->buffer = realloc(b->buffer, b->size + increase + sizeof(BUFFER_OVERFLOW_EOF) + 2);
- if(!b->buffer) fatal("Failed to increase data buffer from size %d to %d.", b->size + sizeof(BUFFER_OVERFLOW_EOF) + 2, b->size + increase + sizeof(BUFFER_OVERFLOW_EOF) + 2);
+ if(!b->buffer)
+ fatal("Failed to increase data buffer from size %zu to %zu.",
+ b->size + sizeof(BUFFER_OVERFLOW_EOF) + 2,
+ b->size + increase + sizeof(BUFFER_OVERFLOW_EOF) + 2);
b->size += increase;
extern void buffer_date(BUFFER *wb, int year, int month, int day, int hours, int minutes, int seconds);
extern void buffer_jsdate(BUFFER *wb, int year, int month, int day, int hours, int minutes, int seconds);
-extern BUFFER *buffer_create(long size);
+extern BUFFER *buffer_create(size_t size);
extern void buffer_free(BUFFER *b);
extern void buffer_increase(BUFFER *b, size_t free_size_required);
-extern void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...);
+extern void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...) __attribute__ (( format (printf, 3, 4)));
extern void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args);
-extern void buffer_sprintf(BUFFER *wb, const char *fmt, ...);
+extern void buffer_sprintf(BUFFER *wb, const char *fmt, ...) __attribute__ (( format (printf, 2, 3)));
extern void buffer_char_replace(BUFFER *wb, char from, char to);
// svg template from:
// https://raw.githubusercontent.com/badges/shields/master/templates/flat-template.svg
buffer_sprintf(wb,
- "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%zu\" height=\"20\">"
+ "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%d\" height=\"20\">"
"<linearGradient id=\"smooth\" x2=\"0\" y2=\"100%%\">"
"<stop offset=\"0\" stop-color=\"#bbb\" stop-opacity=\".1\"/>"
"<stop offset=\"1\" stop-opacity=\".1\"/>"
"</linearGradient>"
"<mask id=\"round\">"
- "<rect width=\"%zu\" height=\"20\" rx=\"3\" fill=\"#fff\"/>"
+ "<rect width=\"%d\" height=\"20\" rx=\"3\" fill=\"#fff\"/>"
"</mask>"
"<g mask=\"url(#round)\">"
- "<rect width=\"%zu\" height=\"20\" fill=\"%s\"/>"
- "<rect x=\"%zu\" width=\"%zu\" height=\"20\" fill=\"%s\"/>"
- "<rect width=\"%zu\" height=\"20\" fill=\"url(#smooth)\"/>"
+ "<rect width=\"%d\" height=\"20\" fill=\"%s\"/>"
+ "<rect x=\"%d\" width=\"%d\" height=\"20\" fill=\"%s\"/>"
+ "<rect width=\"%d\" height=\"20\" fill=\"url(#smooth)\"/>"
"</g>"
"<g fill=\"#fff\" text-anchor=\"middle\" font-family=\"DejaVu Sans,Verdana,Geneva,sans-serif\" font-size=\"11\">"
- "<text x=\"%zu\" y=\"15\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
- "<text x=\"%zu\" y=\"14\">%s</text>"
- "<text x=\"%zu\" y=\"15\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
- "<text x=\"%zu\" y=\"14\">%s</text>"
+ "<text x=\"%d\" y=\"15\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
+ "<text x=\"%d\" y=\"14\">%s</text>"
+ "<text x=\"%d\" y=\"15\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
+ "<text x=\"%d\" y=\"14\">%s</text>"
"</g>"
"</svg>",
total_width, total_width,
#include "common.h"
#include "log.h"
+#include "main.h"
#include "appconfig.h"
#include "url.h"
#include "web_buffer.h"
int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
#endif /* NETDATA_WITH_ZLIB */
-extern int netdata_exit;
-
struct web_client *web_clients = NULL;
unsigned long long web_clients_count = 0;
sadr = (struct sockaddr*) &w->clientaddr;
addrlen = sizeof(w->clientaddr);
- w->ifd = accept(listener, sadr, &addrlen);
+ w->ifd = accept4(listener, sadr, &addrlen, SOCK_NONBLOCK);
if (w->ifd == -1) {
error("%llu: Cannot accept new incoming connection.", w->id);
free(w);
flag = 1;
if(setsockopt(w->ifd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int)) != 0)
error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
-
-
}
w->response.data = buffer_create(INITIAL_WEB_DATA_LENGTH);
log_access("%llu: (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %s: %d '%s'",
w->id,
- sent, size, -((size > 0) ? ((float) (size - sent) / (float) size * 100.0) : 0.0),
- (float) usecdiff(&w->tv_ready, &w->tv_in) / 1000.0,
- (float) usecdiff(&tv, &w->tv_ready) / 1000.0,
- (float) usecdiff(&tv, &w->tv_in) / 1000.0,
+ sent, size, -((size > 0) ? ((size - sent) / (double) size * 100.0) : 0.0),
+ usecdiff(&w->tv_ready, &w->tv_in) / 1000.0,
+ usecdiff(&tv, &w->tv_ready) / 1000.0,
+ usecdiff(&tv, &w->tv_in) / 1000.0,
(w->mode == WEB_CLIENT_MODE_FILECOPY) ? "filecopy" : ((w->mode == WEB_CLIENT_MODE_OPTIONS)
? "options" : "data"),
w->response.code,
while (*filename == '/') filename++;
// if the filename contain known paths, skip them
- if(strncmp(filename, WEB_PATH_FILE "/", strlen(WEB_PATH_FILE) + 1) == 0) filename = &filename[strlen(WEB_PATH_FILE) + 1];
+ if(strncmp(filename, WEB_PATH_FILE "/", strlen(WEB_PATH_FILE) + 1) == 0)
+ filename = &filename[strlen(WEB_PATH_FILE) + 1];
char *s;
for(s = filename; *s ;s++) {
return 404;
}
}
+ if(fcntl(w->ifd, F_SETFL, O_NONBLOCK) < 0)
+ error("%llu: Cannot set O_NONBLOCK on file '%s'.", w->id, webfilename);
// pick a Content-Type for the file
if(strstr(filename, ".html") != NULL) w->response.data->contenttype = CT_TEXT_HTML;
}
int web_client_api_v1_badge(struct web_client *w, char *url) {
- // chart
- // dimensions
- // before
- // after
- // points
-
int ret = 400;
buffer_flush(w->response.data);
debug(D_WEB_CLIENT, "%llu: Found RRD data with name '%s'.", w->id, tok);
// how many entries does the client want?
- long lines = rrd_default_history_entries;
- long group_count = 1;
+ int lines = rrd_default_history_entries;
+ int group_count = 1;
time_t after = 0, before = 0;
int group_method = GROUP_AVERAGE;
int nonzero = 0;
google_responseHandler, google_version, google_reqId, st->last_updated.tv_sec);
}
- debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %lu after, %lu before).", w->id, st->name, st->id, lines, group_count, group_method, after, before);
- time_t timestamp_in_data = rrd_stats_json(datasource_type, st, w->response.data, lines, group_count, group_method, after, before, nonzero);
+ debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %lu after, %lu before).",
+ w->id, st->name, st->id, lines, group_count, group_method, after, before);
+
+ time_t timestamp_in_data = rrd_stats_json(datasource_type, st, w->response.data, lines, group_count, group_method, (unsigned long)after, (unsigned long)before, nonzero);
if(datasource_type == DATASOURCE_DATATABLE_JSONP) {
if(timestamp_in_data > last_timestamp_in_data)
else
buffer_strcat(w->response.data, "I am doing it already");
+ error("web request to exit received.");
netdata_exit = 1;
}
else if(hash == hash_debug && strcmp(tok, "debug") == 0) {
const char *content_type_string = web_content_type_to_string(w->response.data->contenttype);
const char *code_msg = web_response_code_to_string(code);
- char date[100];
+ char date[32];
struct tm tmbuf, *tm = gmtime_r(&w->response.data->date, &tmbuf);
strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %Z", tm);
, date);
}
else if(w->mode != WEB_CLIENT_MODE_OPTIONS) {
- char edate[100];
+ char edate[32];
time_t et = w->response.data->date + (86400 * 14);
struct tm etmbuf, *etm = gmtime_r(&et, &etmbuf);
strftime(edate, sizeof(edate), "%a, %d %b %Y %H:%M:%S %Z", etm);
buffer_strcat(w->response.header_output, "\r\n");
// sent the HTTP header
- debug(D_WEB_DATA, "%llu: Sending response HTTP header of size %d: '%s'"
+ debug(D_WEB_DATA, "%llu: Sending response HTTP header of size %zu: '%s'"
, w->id
, buffer_strlen(w->response.header_output)
, buffer_tostring(w->response.header_output)
if(bytes > 0)
w->stats_sent_bytes += bytes;
- debug(D_WEB_CLIENT, "%llu: HTTP Header failed to be sent (I sent %d bytes but the system sent %d bytes). Closing web client.", w->id,
- buffer_strlen(w->response.header_output), bytes);
+ debug(D_WEB_CLIENT, "%llu: HTTP Header failed to be sent (I sent %zu bytes but the system sent %zd bytes). Closing web client."
+ , w->id
+ , buffer_strlen(w->response.header_output)
+ , bytes);
WEB_CLIENT_IS_DEAD(w);
return;
// pretty logging
switch(w->mode) {
case WEB_CLIENT_MODE_OPTIONS:
- debug(D_WEB_CLIENT, "%llu: Done preparing the OPTIONS response. Sending data (%d bytes) to client.", w->id, w->response.data->len);
+ debug(D_WEB_CLIENT, "%llu: Done preparing the OPTIONS response. Sending data (%zu bytes) to client.", w->id, w->response.data->len);
break;
case WEB_CLIENT_MODE_NORMAL:
- debug(D_WEB_CLIENT, "%llu: Done preparing the response. Sending data (%d bytes) to client.", w->id, w->response.data->len);
+ debug(D_WEB_CLIENT, "%llu: Done preparing the response. Sending data (%zu bytes) to client.", w->id, w->response.data->len);
break;
case WEB_CLIENT_MODE_FILECOPY:
if(w->response.rlen) {
- debug(D_WEB_CLIENT, "%llu: Done preparing the response. Will be sending data file of %d bytes to client.", w->id, w->response.rlen);
+ debug(D_WEB_CLIENT, "%llu: Done preparing the response. Will be sending data file of %zu bytes to client.", w->id, w->response.rlen);
w->wait_receive = 1;
/*
ssize_t web_client_send_chunk_header(struct web_client *w, size_t len)
{
- debug(D_DEFLATE, "%llu: OPEN CHUNK of %d bytes (hex: %x).", w->id, len, len);
- char buf[1024];
+ debug(D_DEFLATE, "%llu: OPEN CHUNK of %zu bytes (hex: %zx).", w->id, len, len);
+ char buf[24];
sprintf(buf, "%zX\r\n", len);
ssize_t bytes = send(w->ofd, buf, strlen(buf), 0);
if(bytes > 0) {
- debug(D_DEFLATE, "%llu: Sent chunk header %d bytes.", w->id, bytes);
+ debug(D_DEFLATE, "%llu: Sent chunk header %zd bytes.", w->id, bytes);
w->stats_sent_bytes += bytes;
}
ssize_t bytes = send(w->ofd, "\r\n", 2, 0);
if(bytes > 0) {
- debug(D_DEFLATE, "%llu: Sent chunk suffix %d bytes.", w->id, bytes);
+ debug(D_DEFLATE, "%llu: Sent chunk suffix %zd bytes.", w->id, bytes);
w->stats_sent_bytes += bytes;
}
ssize_t bytes = send(w->ofd, "\r\n0\r\n\r\n", 7, 0);
if(bytes > 0) {
- debug(D_DEFLATE, "%llu: Sent chunk suffix %d bytes.", w->id, bytes);
+ debug(D_DEFLATE, "%llu: Sent chunk suffix %zd bytes.", w->id, bytes);
w->stats_sent_bytes += bytes;
}
// when using compression,
// w->response.sent is the amount of bytes passed through compression
- debug(D_DEFLATE, "%llu: web_client_send_deflate(): w->response.data->len = %d, w->response.sent = %d, w->response.zhave = %d, w->response.zsent = %d, w->response.zstream.avail_in = %d, w->response.zstream.avail_out = %d, w->response.zstream.total_in = %d, w->response.zstream.total_out = %d.", w->id, w->response.data->len, w->response.sent, w->response.zhave, w->response.zsent, w->response.zstream.avail_in, w->response.zstream.avail_out, w->response.zstream.total_in, w->response.zstream.total_out);
+ debug(D_DEFLATE, "%llu: web_client_send_deflate(): w->response.data->len = %zu, w->response.sent = %zu, w->response.zhave = %zu, w->response.zsent = %zu, w->response.zstream.avail_in = %d, w->response.zstream.avail_out = %d, w->response.zstream.total_in = %lu, w->response.zstream.total_out = %lu.",
+ w->id, w->response.data->len, w->response.sent, w->response.zhave, w->response.zsent, w->response.zstream.avail_in, w->response.zstream.avail_out, w->response.zstream.total_in, w->response.zstream.total_out);
if(w->response.data->len - w->response.sent == 0 && w->response.zstream.avail_in == 0 && w->response.zhave == w->response.zsent && w->response.zstream.avail_out != 0) {
// there is nothing to send
if(t < 0) return t;
}
- debug(D_DEFLATE, "%llu: Compressing %d new bytes starting from %d (and %d left behind).", w->id, (w->response.data->len - w->response.sent), w->response.sent, w->response.zstream.avail_in);
+ debug(D_DEFLATE, "%llu: Compressing %zu new bytes starting from %zu (and %u left behind).", w->id, (w->response.data->len - w->response.sent), w->response.sent, w->response.zstream.avail_in);
// give the compressor all the data not passed through the compressor yet
if(w->response.data->len > w->response.sent) {
// keep track of the bytes passed through the compressor
w->response.sent = w->response.data->len;
- debug(D_DEFLATE, "%llu: Compression produced %d bytes.", w->id, w->response.zhave);
+ debug(D_DEFLATE, "%llu: Compression produced %zu bytes.", w->id, w->response.zhave);
// open a new chunk
ssize_t t2 = web_client_send_chunk_header(w, w->response.zhave);
t += t2;
}
- debug(D_WEB_CLIENT, "%llu: Sending %d bytes of data (+%d of chunk header).", w->id, w->response.zhave - w->response.zsent, t);
+ debug(D_WEB_CLIENT, "%llu: Sending %zu bytes of data (+%zd of chunk header).", w->id, w->response.zhave - w->response.zsent, t);
len = send(w->ofd, &w->response.zbuffer[w->response.zsent], (size_t) (w->response.zhave - w->response.zsent), MSG_DONTWAIT);
if(len > 0) {
w->stats_sent_bytes += len;
w->response.zsent += len;
len += t;
- debug(D_WEB_CLIENT, "%llu: Sent %d bytes.", w->id, len);
+ debug(D_WEB_CLIENT, "%llu: Sent %zu bytes.", w->id, len);
}
else if(len == 0) {
- debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client (zhave = %ld, zsent = %ld, need to send = %ld).", w->id, w->response.zhave, w->response.zsent, w->response.zhave - w->response.zsent);
+ debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client (zhave = %zu, zsent = %zu, need to send = %zu).",
+ w->id, w->response.zhave, w->response.zsent, w->response.zhave - w->response.zsent);
+
WEB_CLIENT_IS_DEAD(w);
}
else {
if(likely(bytes > 0)) {
w->stats_sent_bytes += bytes;
w->response.sent += bytes;
- debug(D_WEB_CLIENT, "%llu: Sent %d bytes.", w->id, bytes);
+ debug(D_WEB_CLIENT, "%llu: Sent %zu bytes.", w->id, bytes);
}
else if(likely(bytes == 0)) {
debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client.", w->id);
w->response.data->len += bytes;
w->response.data->buffer[w->response.data->len] = '\0';
- debug(D_WEB_CLIENT, "%llu: Received %d bytes.", w->id, bytes);
+ debug(D_WEB_CLIENT, "%llu: Received %zu bytes.", w->id, bytes);
debug(D_WEB_DATA, "%llu: Received data: '%s'.", w->id, &w->response.data->buffer[old]);
if(w->mode == WEB_CLIENT_MODE_FILECOPY) {
break;
}
else if(unlikely(!w->wait_receive && !w->wait_send)) {
- debug(D_WEB_CLIENT, "%llu: client is not set for neither receiving nor sending data.");
+ debug(D_WEB_CLIENT, "%llu: client is not set for neither receiving nor sending data.", w->id);
break;
}
}
#endif
+#ifndef HAVE_ACCEPT4
+int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
+ int fd = accept(sock, addr, addrlen);
+ int newflags = 0;
+
+ if (fd < 0) return fd;
+
+ if (flags & SOCK_NONBLOCK) {
+ newflags |= O_NONBLOCK;
+ flags &= ~SOCK_NONBLOCK;
+ }
+
+ if (flags & SOCK_CLOEXEC) {
+ newflags |= O_CLOEXEC;
+ flags &= ~SOCK_CLOEXEC;
+ }
+
+ if (flags) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ if (fcntl(fd, F_SETFL, newflags) < 0) {
+ int saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return -1;
+ }
+
+ return fd;
+}
+#endif
+
static int is_ip_anything(const char *ip)
{
if(!ip || !*ip
else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6;
else error("Cannot understand ip version '%s'. Assuming 'any'.", ipv);
- if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
- if(listen_fd < 0) {
+ if(ip == 0 || ip == 6)
+ listen_fd = create_listen_socket6(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
+
+ if(listen_fd == -1) {
listen_fd = create_listen_socket4(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
- // if(listen_fd >= 0 && ip != 4) info("Managed to open an IPv4 socket on port %d.", listen_port);
+ //if(listen_fd != -1 && ip != 4)
+ // info("Managed to open an IPv4 socket on port %d.", listen_port);
}
return listen_fd;
sleep(5);
create_listen_socket();
if(listen_fd < 0)
- fatal("Cannot listen for web clients (connected clients %llu).", global_statistics.connected_clients);
+ fatal("Cannot listen for web clients (connected clients %lu).", global_statistics.connected_clients);
failures = 0;
}
}
if(pthread_create(&w->thread, NULL, web_client_main, w) != 0) {
- error("%llu: failed to create new thread for web client.");
+ error("%llu: failed to create new thread for web client.", w->id);
w->obsolete = 1;
}
else if(pthread_detach(w->thread) != 0) {
create_listen_socket();
if(listen_fd < 0 || listen_fd >= FD_SETSIZE)
- fatal("Cannot listen for web clients (connected clients %llu).", global_statistics.connected_clients);
+ fatal("Cannot listen for web clients (connected clients %lu).", global_statistics.connected_clients);
FD_ZERO (&ifds);
FD_ZERO (&ofds);
extern void *socket_listen_main_single_threaded(void *ptr);
extern int create_listen_socket(void);
+#ifndef HAVE_ACCEPT4
+extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 00004000
+#endif /* #ifndef SOCK_NONBLOCK */
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 02000000
+#endif /* #ifndef SOCK_CLOEXEC */
+
+#endif /* #ifndef HAVE_ACCEPT4 */
+
#endif /* NETDATA_WEB_SERVER_H */
'#a6a479', '#a66da8' ],
*/
colors: [ '#66AA00', '#FE3912', '#3366CC', '#D66300', '#0099C6', '#DDDD00',
- '#3B3EAC', '#EE9911', '#BB44CC', '#C83E3E', '#990099', '#CC7700',
- '#22AA99', '#109618', '#6633CC', '#DD4477', '#316395', '#8B0707',
+ '#5054e6', '#EE9911', '#BB44CC', '#e45757', '#ef0aef', '#CC7700',
+ '#22AA99', '#109618', '#905bfd', '#f54882', '#4381bf', '#ff3737',
'#329262', '#3B3EFF' ],
easypiechart_track: '#373b40',
easypiechart_scale: '#373b40',
<meta property="og:description" content="Stunning real-time dashboards, blazingly fast and extremely interactive. Zero configuration, zero dependencies, zero maintenance." />
<script>var netdataTheme = 'slate';</script>
- <script type="text/javascript" src="http://my-netdata.io/dashboard.js?v39"></script>
+ <script type="text/javascript" src="http://my-netdata.io/dashboard.js?v40"></script>
</head>
<body>
and that you have chown it to be owned by netdata:netdata
-->
<!-- <script type="text/javascript" src="http://my.server:19999/dashboard.js"></script> -->
- <script type="text/javascript" src="dashboard.js?v39"></script>
+ <script type="text/javascript" src="dashboard.js?v40"></script>
<script>
// --- OPTIONS FOR THE CHARTS --
</script>
<!-- load the dashboard manager - it will do the rest -->
- <script type="text/javascript" src="dashboard.js?v39"></script>
+ <script type="text/javascript" src="dashboard.js?v40"></script>
</head>
<body data-spy="scroll" data-target="#sidebar">
and that you have chown it to be owned by netdata:netdata
-->
<!-- <script type="text/javascript" src="http://my.server:19999/dashboard.js"></script> -->
- <script type="text/javascript" src="dashboard.js?v39"></script>
+ <script type="text/javascript" src="dashboard.js?v40"></script>
<script>
// Set options for TV operation