Changeset: 56447bc0d7ee for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=56447bc0d7ee Modified Files: tools/merovingian/client/monetdb.c tools/merovingian/daemon/controlrunner.c tools/merovingian/daemon/forkmserver.c tools/merovingian/daemon/forkmserver.h Branch: default Log Message:
Started work for stethoscope handling through merovingian Usage: $ monetdb set profilerlogpath=/path/to/log/directory <db> $ monetdb profilerstart <db> [db...] $ monetdb profilerstop <db> [db...] At most one stethoscope should be running for each database. This should produce files in the directory specified by profilerlogpath, each time profilerstart is called. The file name should be: proflog_<db>_YYYY-MM-DD-HH-MM-SS.json diffs (150 lines): diff --git a/tools/merovingian/client/monetdb.c b/tools/merovingian/client/monetdb.c --- a/tools/merovingian/client/monetdb.c +++ b/tools/merovingian/client/monetdb.c @@ -101,6 +101,14 @@ command_help(int argc, char *argv[]) printf(" Brings back a database from maintenance mode. A released\n"); printf(" database is available again for normal use. Use the\n"); printf(" \"lock\" command to take a database under maintenance.\n"); + } else if (strcmp(argv[1], "profilerstart") == 0) { + printf("Usage: monetdb profilerstart database [database ...]\n"); + printf(" Starts the collection of profiling events. The property\n"); + printf(" \"profiler_path\" should be set. Use the \"profilerstop\"\n"); + printf(" command to stop the profiler.\n"); + } else if (strcmp(argv[1], "profilerstop") == 0) { + printf("Usage: monetdb profilerstop database [database ...]\n"); + printf(" Stops the collection of profiling events.\n"); } else if (strcmp(argv[1], "status") == 0) { printf("Usage: monetdb status [-lc] [expression ...]\n"); printf(" Shows the state of a given glob-style database match, or\n"); @@ -1629,6 +1637,18 @@ command_release(int argc, char *argv[]) simple_command(argc, argv, "release", "taken database out of maintenance mode", 1); } +static void +command_profilerstart(int argc, char *argv[]) +{ + simple_command(argc, argv, "profilerstart", "started profiler", 1); +} + +static void +command_profilerstop(int argc, char *argv[]) +{ + simple_command(argc, argv, "profilerstop", "stopped profiler", 1); +} + int main(int argc, char *argv[]) { @@ -1807,6 +1827,10 @@ main(int argc, char *argv[]) command_lock(argc - i, &argv[i]); } else if (strcmp(argv[i], "release") == 0) { command_release(argc - i, &argv[i]); + } else if (strcmp(argv[i], "profilerstart") == 0) { + command_profilerstart(argc - i, &argv[i]); + } else if (strcmp(argv[i], "profilerstop") == 0) { + command_profilerstop(argc - i, &argv[i]); } else if (strcmp(argv[i], "status") == 0) { command_status(argc - i, &argv[i]); } else if (strcmp(argv[i], "start") == 0) { diff --git a/tools/merovingian/daemon/controlrunner.c b/tools/merovingian/daemon/controlrunner.c --- a/tools/merovingian/daemon/controlrunner.c +++ b/tools/merovingian/daemon/controlrunner.c @@ -619,6 +619,27 @@ static void ctl_handle_client( len = snprintf(buf2, sizeof(buf2), "OK\n"); send_client("="); } + } else if (strncmp(p, "profilerstart", strlen("profilerstart")) == 0) { + char *log_path = NULL; + char *e = fork_profiler(q, &stats, &log_path); + if (e != NULL) { + Mfprintf(_mero_ctlerr, "%s: failed to start the profiler " + "database '%s': %s\n", origin, q, getErrMsg(e)); + len = snprintf(buf2, sizeof(buf2), + "%s\n", getErrMsg(e)); + send_client("!"); + freeErr(e); + } else { + len = snprintf(buf2, sizeof(buf2), "OK\n"); + send_client("="); + Mfprintf(_mero_ctlout, "%s: started profiler for '%s'\n", + origin, q); + Mfprintf(_mero_ctlout, "%s: logs at: %s\n", + origin, log_path); + } + msab_freeStatus(&stats); + } else if (strncmp(p, "profilerstop", strlen("profilerstop")) == 0) { + } else if (strncmp(p, "name=", strlen("name=")) == 0) { char *e; diff --git a/tools/merovingian/daemon/forkmserver.c b/tools/merovingian/daemon/forkmserver.c --- a/tools/merovingian/daemon/forkmserver.c +++ b/tools/merovingian/daemon/forkmserver.c @@ -753,4 +753,56 @@ forkMserver(char *database, sabdb** stat return(newErr("%s", strerror(errno))); } +/** + * Fork stethoscope and detatch, after performing sanity checks. The assumption + * is that each mserver5 process can have at most one stethoscope process + * attached to it. + */ +err +fork_profiler(char *dbname, sabdb **stats, char **log_path) +{ + pid_t pid; + char *error = NO_ERR; + confkeyval *ckv, *kv; + + (void) pid; + (void) log_path; + error = msab_getStatus(stats, dbname); + if (error != NULL) { + err er = NULL; + er = newErr("%s", er); + free(error); + return er; + } + + if (*stats == NULL) { + /* TODO: What now? */ + return error; + } + + pthread_mutex_lock(&fork_lock); + + if ((*stats)->state != SABdbRunning) { + /* server is not running, shoo */ + error = newErr("Database is not running."); + goto cleanup; + } + + ckv = getDefaultProps(); + readAllProps(ckv, (*stats)->path); + kv = findConfKey(ckv, "profilerlogpath"); + + if (kv == NULL) { + error = newErr("Property 'profilerlogpath' not set for db %s\n", + dbname); + goto cleanup; + } + + *log_path = GDKstrdup(kv->val); + + cleanup: + pthread_mutex_unlock(&fork_lock); + return error; +} + /* vim:set ts=4 sw=4 noexpandtab: */ diff --git a/tools/merovingian/daemon/forkmserver.h b/tools/merovingian/daemon/forkmserver.h --- a/tools/merovingian/daemon/forkmserver.h +++ b/tools/merovingian/daemon/forkmserver.h @@ -13,6 +13,7 @@ #include "merovingian.h" /* err */ err forkMserver(char* database, sabdb** stats, int force); +err fork_profiler(char *database, sabdb **stats, char **log_path); #endif _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list