From af432574e5009cc4748e512f6b78b43f40fdc19c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 7 Oct 2015 20:31:35 +0000 Subject: add capability to log per-service resource consumption via ARM --- configure.ac | 6 +-- po/POTFILES.in | 3 +- src/arm/arm.conf.in | 2 + src/arm/gnunet-service-arm.c | 115 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 2d9fe0b06..baf7a5517 100644 --- a/configure.ac +++ b/configure.ac @@ -375,7 +375,7 @@ then bluetooth=1 fi AM_CONDITIONAL(HAVE_LIBBLUETOOTH, [test "$bluetooth" = 1]) -if test "$bluetooth" = 1 +if test "$bluetooth" = 1 then AC_DEFINE([HAVE_LIBBLUETOOTH],[1],[Have bluetooth library]) else @@ -781,7 +781,7 @@ postgres=false AX_LIB_POSTGRESQL([]) if test "$found_postgresql" = "yes"; then CPPFLAGS="$CPPFLAGS $POSTGRESQL_CPPFLAGS" - AC_CHECK_HEADERS([libpq-fe.h], + AC_CHECK_HEADERS([libpq-fe.h], postgres=true) fi @@ -1002,7 +1002,7 @@ AC_FUNC_VPRINTF AC_HEADER_SYS_WAIT AC_TYPE_OFF_T AC_TYPE_UID_T -AC_CHECK_FUNCS([atoll stat64 strnlen mremap getrlimit setrlimit sysconf initgroups strndup gethostbyname2 getpeerucred getpeereid setresuid $funcstocheck getifaddrs freeifaddrs getresgid mallinfo malloc_size malloc_usable_size getrusage random srandom stat statfs statvfs]) +AC_CHECK_FUNCS([atoll stat64 strnlen mremap getrlimit setrlimit sysconf initgroups strndup gethostbyname2 getpeerucred getpeereid setresuid $funcstocheck getifaddrs freeifaddrs getresgid mallinfo malloc_size malloc_usable_size getrusage random srandom stat statfs statvfs wait4]) # restore LIBS LIBS=$SAVE_LIBS diff --git a/po/POTFILES.in b/po/POTFILES.in index ed408ebc1..9e5cbfbe0 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -204,6 +204,8 @@ src/identity/gnunet-service-identity.c src/identity/identity_api.c src/identity/identity_api_lookup.c src/identity/plugin_rest_identity.c +src/identity-token/gnunet-identity-token.c +src/identity-token/plugin_rest_identity_token.c src/multicast/gnunet-multicast.c src/multicast/gnunet-service-multicast.c src/multicast/multicast_api.c @@ -255,7 +257,6 @@ src/psycstore/gnunet-service-psycstore.c src/psycstore/plugin_psycstore_sqlite.c src/psycstore/psycstore_api.c src/psycstore/psyc_util_lib.c -src/psycstore/psyc_util_lib.c src/pt/gnunet-daemon-pt.c src/regex/gnunet-daemon-regexprofiler.c src/regex/gnunet-regex-profiler.c diff --git a/src/arm/arm.conf.in b/src/arm/arm.conf.in index 20d3e1dc0..38cf4599c 100644 --- a/src/arm/arm.conf.in +++ b/src/arm/arm.conf.in @@ -41,6 +41,8 @@ GLOBAL_PREFIX = @MONKEYPREFIX@ # # USER_ONLY = YES +# File where we should log per-service resource consumption on exit. +# RESOURCE_DIAGNOSTICS = resource.log # Name of the user that will be used to provide the service diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index a411546d7..b8cda5945 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c @@ -29,6 +29,19 @@ #include "gnunet_protocols.h" #include "arm.h" +#if HAVE_WAIT4 +/** + * Name of the file for writing resource utilization summaries to. + */ +static char *wait_filename; + +/** + * Handle for the file for writing resource summaries. + */ +static FILE *wait_file; +#endif + + /** * How many messages do we queue up at most for optional * notifications to a client? (this can cause notifications @@ -81,7 +94,7 @@ struct ServiceListeningInfo /** * Task doing the accepting. */ - struct GNUNET_SCHEDULER_Task * accept_task; + struct GNUNET_SCHEDULER_Task *accept_task; }; @@ -1193,12 +1206,76 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) free_service (pos); continue; } +#if HAVE_WAIT4 + if (NULL != wait_file) + { + /* need to use 'wait4()' to obtain and log performance data */ + struct rusage ru; + int status; + pid_t pid; + + pid = GNUNET_OS_process_get_pid (pos->proc); + ret = wait4 (pid, + &status, + WNOHANG, + &ru); + if (ret <= 0) + continue; /* no process done */ + if (WIFEXITED (status)) + { + statusType = GNUNET_OS_PROCESS_EXITED; + statusCode = WEXITSTATUS (status); + } + else if (WIFSIGNALED (status)) + { + statusType = GNUNET_OS_PROCESS_SIGNALED; + statusCode = WTERMSIG (status); + } + else if (WIFSTOPPED (status)) + { + statusType = GNUNET_OS_PROCESS_SIGNALED; + statusCode = WSTOPSIG (status); + } +#ifdef WIFCONTINUED + else if (WIFCONTINUED (status)) + { + statusType = GNUNET_OS_PROCESS_RUNNING; + statusCode = 0; + } +#endif + else + { + statusType = GNUNET_OS_PROCESS_UNKNOWN; + statusCode = 0; + } + if ( (GNUNET_OS_PROCESS_EXITED == statusType) || + (GNUNET_OS_PROCESS_SIGNALED == statusType) ) + { + fprintf (wait_file, + "%s(%u) %llu.%llu %llu.%llu %llu %llu %llu %llu %llu\n", + pos->binary, + (unsigned int) pid, + (unsigned long long) ru.ru_utime.tv_sec, + (unsigned long long) ru.ru_utime.tv_usec, + (unsigned long long) ru.ru_stime.tv_sec, + (unsigned long long) ru.ru_stime.tv_usec, + (unsigned long long) ru.ru_maxrss, + (unsigned long long) ru.ru_inblock, + (unsigned long long) ru.ru_oublock, + (unsigned long long) ru.ru_nvcsw, + (unsigned long long) ru.ru_nivcsw); + } + } + else /* continue with #else */ +#else if ((GNUNET_SYSERR == (ret = - GNUNET_OS_process_status (pos->proc, &statusType, &statusCode))) - || ((ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) - || (statusType == GNUNET_OS_PROCESS_RUNNING))) + GNUNET_OS_process_status (pos->proc, &statusType, &statusCode))) || + ((ret == GNUNET_NO) || + (statusType == GNUNET_OS_PROCESS_STOPPED) || + (statusType == GNUNET_OS_PROCESS_RUNNING) ) ) continue; +#endif if (statusType == GNUNET_OS_PROCESS_EXITED) { statstr = _( /* process termination method */ "exit"); @@ -1501,7 +1578,23 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv, GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), &maint_child_death, NULL); - +#if HAVE_WAIT4 + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, + "ARM", + "RESOURCE_DIAGNOSTICS", + &wait_filename)) + { + wait_file = fopen (wait_filename, + "w"); + if (NULL == wait_file) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "fopen", + wait_filename); + } + } +#endif if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "GLOBAL_PREFIX", &prefix_command)) @@ -1560,6 +1653,18 @@ main (int argc, char *const *argv) (GNUNET_OK == GNUNET_SERVICE_run (argc, argv, "arm", GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, &run, NULL)) ? 0 : 1; +#if HAVE_WAIT4 + if (NULL != wait_file) + { + fclose (wait_file); + wait_file = NULL; + } + if (NULL != wait_filename) + { + GNUNET_free (wait_filename); + wait_filename = NULL; + } +#endif GNUNET_SIGNAL_handler_uninstall (shc_chld); shc_chld = NULL; GNUNET_DISK_pipe_close (sigpipe); -- cgit v1.2.3