aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-08-13 03:21:44 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-08-13 03:21:44 +0300
commit710c8ef7fc69e47c3ab403bc8c59b22994fb9c43 (patch)
tree3fcfd32bb8e9c7da9d2a89ae040019cbe3f495d2
parentfa83f20f6308e5d0c6344ade276b63d28f6e78ee (diff)
downloadtallyman-710c8ef7fc69e47c3ab403bc8c59b22994fb9c43.tar.gz
tallyman-710c8ef7fc69e47c3ab403bc8c59b22994fb9c43.tar.bz2
tallyman: preserve command's stdout and stderr
* src/tallyman.c: Proxy command's stdout and stderr by default. Use single -q option to suppress proxying stdout. Use two -q options to suppress both stdout and stderr (prior behavior). * src/tallyman.1: Document new behavior
-rw-r--r--src/tallyman.113
-rw-r--r--src/tallyman.c33
2 files changed, 39 insertions, 7 deletions
diff --git a/src/tallyman.1 b/src/tallyman.1
index 90a1baa..9cdbaaa 100644
--- a/src/tallyman.1
+++ b/src/tallyman.1
@@ -1,21 +1,22 @@
-.TH TALLYMAN 1 "July 18, 2018" "TALLYMAN" "Tallyman User Reference"
+.TH TALLYMAN 1 "August 13, 2019" "TALLYMAN" "Tallyman User Reference"
.SH NAME
tallyman \- health state collector for docker containers
.SH SYNOPSIS
.na
.nh
\fBtallyman\fR\
- [\fB\-d\fR]\
+ [\fB\-dq\fR]\
[\fB\-h\fR \fINAME\fR]\
[\fB\-s\fR \fIHOST:PORT\fR]\
[\fB\-v\fR \fIJSON\fR]\
[\fB\-\-connection\-timeout=\fISECONDS\fR]\
[\fB\-\-debug\fR]\
[\fB\-\-execution\-timeout=\fISECONDS\fR]\
[\fB\-\-hostname=\fINAME\fR]\
+ [\fB\-\-quiet\fR]\
[\fB\-\-server=\fIHOST:PORT\fR]\
[\fB\-\-value=\fIJSON\fR]\
\fISRVID\fR\
\fICOMMAND\fR\
\fIARGS\fR...
.sp
@@ -46,12 +47,18 @@ Default port is 8990.
\fB\-d\fR, \fB\-\-debug\fR
Increase debug verbosity.
.TP
\fB\-h\fR, \fB\-\-hostname=\fINAME\fR
Set this server hostname. By default it is determined automatically.
.TP
+\fB\-q\fR, \fB\-\-quiet\fR
+By default, \fBtallyman\fR would transparently pass \fICOMMAND\fR's
+stdout and stderr to the corresponding streams. Single \fB\-q\fR
+option suppresses reproducing the stdout. Two \fB\-q\fR options
+suppress both stdout and stderr.
+.TP
\fB\-s\fR, \fB\-\-server=\fIHOST:PORT\fR
Address and port of the data collector. Default is \fIGW\fR:8990,
where \fIGW\fR is the default gateway of the container.
.TP
\fB\-v\fR, \fB\-\-value=\fIJSON\fR
Add \fIJSON\fR object to each report.
@@ -71,13 +78,13 @@ Display program version and licensing information and exit.
.BR stevedore (8).
.SH AUTHORS
Sergey Poznyakoff
.SH "BUG REPORTS"
Report bugs to <gray@gnu.org>.
.SH COPYRIGHT
-Copyright \(co 2018 Sergey Poznyakoff
+Copyright \(co 2018\-2019 Sergey Poznyakoff
.br
.na
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
.br
.ad
This is free software: you are free to change and redistribute it.
diff --git a/src/tallyman.c b/src/tallyman.c
index f6b095d..fad97b8 100644
--- a/src/tallyman.c
+++ b/src/tallyman.c
@@ -37,22 +37,25 @@ struct option longopts[] = {
{ "debug", no_argument, 0, 'd' },
{ "connection-timeout", required_argument, 0, OPT_CONNECTION_TIMEOUT },
{ "execution-timeout", required_argument, 0, OPT_EXECUTION_TIMEOUT },
{ "version", no_argument, 0, 'V' },
{ NULL }
};
-static char shortopts[] = "+?ds:h:v:V";
+static char shortopts[] = "+?ds:h:qv:V";
void
help(void)
{
printf("usage: tallyman [OPTIONS] [--] ID COMMAND [ARGS...]\n");
printf("\n");
printf("OPTIONS are:\n\n");
printf(" -d, --debug increase debug verbosity\n");
printf(" -h, --hostname=NAME set this server hostname\n");
+ printf(" -q, --quiet don't display COMMAND's stderr;\n");
+ printf(" when used twice, don't display COMMAND's\n");
+ printf(" stdout either\n");
printf(" -s, --server=HOST:PORT remote host server\n");
printf(" -v, --value=JSON add JSON object to the report\n");
printf(" --connection-timeout=SECONDS\n");
printf(" set connection timeout\n");
printf(" --execution-timeout=SECONDS\n");
printf(" set execution timeout\n");
@@ -172,12 +175,24 @@ static jmp_buf jmpbuf;
static void
sig_alarm(int sig)
{
longjmp(jmpbuf, 1);
}
+static void
+stdout_linemon(const char *bufptr, size_t bufsize, void *closure)
+{
+ fwrite(bufptr, bufsize, 1, stdout);
+}
+
+static void
+stderr_linemon(const char *bufptr, size_t bufsize, void *closure)
+{
+ fwrite(bufptr, bufsize, 1, stderr);
+}
+
int
main(int argc, char **argv)
{
int c, i;
char *hostname = NULL;
char *server = 0;
@@ -186,12 +201,13 @@ main(int argc, char **argv)
struct json_value *obj, *ar;
struct timeval tv;
struct timezone tz;
struct runcap rc;
struct shttp_connection *shttp;
int status;
+ int rcflags = RCF_TIMEOUT|RCF_STDOUT_LINEMON|RCF_STDERR_LINEMON;
setprogname(argv[0]);
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL))
!= EOF) {
switch (c) {
case '?':
@@ -209,12 +225,18 @@ main(int argc, char **argv)
case 'd':
shttp_verbose++;
break;
case 'V':
version();
exit(0);
+ case 'q':
+ if (rcflags & RCF_STDOUT_LINEMON)
+ rcflags &= ~RCF_STDOUT_LINEMON;
+ else
+ rcflags &= ~RCF_STDERR_LINEMON;
+ break;
case OPT_CONNECTION_TIMEOUT:
exec_timeout = get_timeout(optarg);
break;
case OPT_EXECUTION_TIMEOUT:
connection_timeout = get_timeout(optarg);
break;
@@ -263,18 +285,21 @@ main(int argc, char **argv)
for (i = 0; i < argc; i++) {
json_array_append(ar, json_new_string(argv[i]));
}
json_array_flatten(ar);
json_object_set(obj, "command", ar);
-
rc.rc_argv = argv;
rc.rc_timeout = exec_timeout;
-
+ if (rcflags & RCF_STDOUT_LINEMON)
+ rc.rc_cap[RUNCAP_STDOUT].sc_linemon = stdout_linemon;
+ if (rcflags & RCF_STDERR_LINEMON)
+ rc.rc_cap[RUNCAP_STDERR].sc_linemon = stderr_linemon;
+
status = EX_FAILURE;
- if (runcap(&rc, RCF_TIMEOUT)) {
+ if (runcap(&rc, rcflags)) {
json_object_set(obj, "status", json_new_bool(0));
json_object_set(obj, "error", json_new_bool(1));
json_object_set(obj, "message",
json_new_string(strerror(errno)));
} else {
if (WIFEXITED(rc.rc_status)) {

Return to:

Send suggestions and report system problems to the System administrator.