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,11 +1,11 @@
1.TH TALLYMAN 1 "July 18, 2018" "TALLYMAN" "Tallyman User Reference" 1.TH TALLYMAN 1 "August 13, 2019" "TALLYMAN" "Tallyman User Reference"
2.SH NAME 2.SH NAME
3tallyman \- health state collector for docker containers 3tallyman \- health state collector for docker containers
4.SH SYNOPSIS 4.SH SYNOPSIS
5.na 5.na
6.nh 6.nh
7\fBtallyman\fR\ 7\fBtallyman\fR\
8 [\fB\-d\fR]\ 8 [\fB\-dq\fR]\
9 [\fB\-h\fR \fINAME\fR]\ 9 [\fB\-h\fR \fINAME\fR]\
10 [\fB\-s\fR \fIHOST:PORT\fR]\ 10 [\fB\-s\fR \fIHOST:PORT\fR]\
11 [\fB\-v\fR \fIJSON\fR]\ 11 [\fB\-v\fR \fIJSON\fR]\
@@ -13,6 +13,7 @@ tallyman \- health state collector for docker containers
13 [\fB\-\-debug\fR]\ 13 [\fB\-\-debug\fR]\
14 [\fB\-\-execution\-timeout=\fISECONDS\fR]\ 14 [\fB\-\-execution\-timeout=\fISECONDS\fR]\
15 [\fB\-\-hostname=\fINAME\fR]\ 15 [\fB\-\-hostname=\fINAME\fR]\
16 [\fB\-\-quiet\fR]\
16 [\fB\-\-server=\fIHOST:PORT\fR]\ 17 [\fB\-\-server=\fIHOST:PORT\fR]\
17 [\fB\-\-value=\fIJSON\fR]\ 18 [\fB\-\-value=\fIJSON\fR]\
18 \fISRVID\fR\ 19 \fISRVID\fR\
@@ -49,6 +50,12 @@ Increase debug verbosity.
49\fB\-h\fR, \fB\-\-hostname=\fINAME\fR 50\fB\-h\fR, \fB\-\-hostname=\fINAME\fR
50Set this server hostname. By default it is determined automatically. 51Set this server hostname. By default it is determined automatically.
51.TP 52.TP
53\fB\-q\fR, \fB\-\-quiet\fR
54By default, \fBtallyman\fR would transparently pass \fICOMMAND\fR's
55stdout and stderr to the corresponding streams. Single \fB\-q\fR
56option suppresses reproducing the stdout. Two \fB\-q\fR options
57suppress both stdout and stderr.
58.TP
52\fB\-s\fR, \fB\-\-server=\fIHOST:PORT\fR 59\fB\-s\fR, \fB\-\-server=\fIHOST:PORT\fR
53Address and port of the data collector. Default is \fIGW\fR:8990, 60Address and port of the data collector. Default is \fIGW\fR:8990,
54where \fIGW\fR is the default gateway of the container. 61where \fIGW\fR is the default gateway of the container.
@@ -74,7 +81,7 @@ Sergey Poznyakoff
74.SH "BUG REPORTS" 81.SH "BUG REPORTS"
75Report bugs to <gray@gnu.org>. 82Report bugs to <gray@gnu.org>.
76.SH COPYRIGHT 83.SH COPYRIGHT
77Copyright \(co 2018 Sergey Poznyakoff 84Copyright \(co 2018\-2019 Sergey Poznyakoff
78.br 85.br
79.na 86.na
80License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 87License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
diff --git a/src/tallyman.c b/src/tallyman.c
index f6b095d..fad97b8 100644
--- a/src/tallyman.c
+++ b/src/tallyman.c
@@ -40,7 +40,7 @@ struct option longopts[] = {
40 { "version", no_argument, 0, 'V' }, 40 { "version", no_argument, 0, 'V' },
41 { NULL } 41 { NULL }
42}; 42};
43static char shortopts[] = "+?ds:h:v:V"; 43static char shortopts[] = "+?ds:h:qv:V";
44 44
45void 45void
46help(void) 46help(void)
@@ -50,6 +50,9 @@ help(void)
50 printf("OPTIONS are:\n\n"); 50 printf("OPTIONS are:\n\n");
51 printf(" -d, --debug increase debug verbosity\n"); 51 printf(" -d, --debug increase debug verbosity\n");
52 printf(" -h, --hostname=NAME set this server hostname\n"); 52 printf(" -h, --hostname=NAME set this server hostname\n");
53 printf(" -q, --quiet don't display COMMAND's stderr;\n");
54 printf(" when used twice, don't display COMMAND's\n");
55 printf(" stdout either\n");
53 printf(" -s, --server=HOST:PORT remote host server\n"); 56 printf(" -s, --server=HOST:PORT remote host server\n");
54 printf(" -v, --value=JSON add JSON object to the report\n"); 57 printf(" -v, --value=JSON add JSON object to the report\n");
55 printf(" --connection-timeout=SECONDS\n"); 58 printf(" --connection-timeout=SECONDS\n");
@@ -175,6 +178,18 @@ sig_alarm(int sig)
175 longjmp(jmpbuf, 1); 178 longjmp(jmpbuf, 1);
176} 179}
177 180
181static void
182stdout_linemon(const char *bufptr, size_t bufsize, void *closure)
183{
184 fwrite(bufptr, bufsize, 1, stdout);
185}
186
187static void
188stderr_linemon(const char *bufptr, size_t bufsize, void *closure)
189{
190 fwrite(bufptr, bufsize, 1, stderr);
191}
192
178int 193int
179main(int argc, char **argv) 194main(int argc, char **argv)
180{ 195{
@@ -189,6 +204,7 @@ main(int argc, char **argv)
189 struct runcap rc; 204 struct runcap rc;
190 struct shttp_connection *shttp; 205 struct shttp_connection *shttp;
191 int status; 206 int status;
207 int rcflags = RCF_TIMEOUT|RCF_STDOUT_LINEMON|RCF_STDERR_LINEMON;
192 208
193 setprogname(argv[0]); 209 setprogname(argv[0]);
194 while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) 210 while ((c = getopt_long(argc, argv, shortopts, longopts, NULL))
@@ -212,6 +228,12 @@ main(int argc, char **argv)
212 case 'V': 228 case 'V':
213 version(); 229 version();
214 exit(0); 230 exit(0);
231 case 'q':
232 if (rcflags & RCF_STDOUT_LINEMON)
233 rcflags &= ~RCF_STDOUT_LINEMON;
234 else
235 rcflags &= ~RCF_STDERR_LINEMON;
236 break;
215 case OPT_CONNECTION_TIMEOUT: 237 case OPT_CONNECTION_TIMEOUT:
216 exec_timeout = get_timeout(optarg); 238 exec_timeout = get_timeout(optarg);
217 break; 239 break;
@@ -266,12 +288,15 @@ main(int argc, char **argv)
266 json_array_flatten(ar); 288 json_array_flatten(ar);
267 json_object_set(obj, "command", ar); 289 json_object_set(obj, "command", ar);
268 290
269
270 rc.rc_argv = argv; 291 rc.rc_argv = argv;
271 rc.rc_timeout = exec_timeout; 292 rc.rc_timeout = exec_timeout;
272 293 if (rcflags & RCF_STDOUT_LINEMON)
294 rc.rc_cap[RUNCAP_STDOUT].sc_linemon = stdout_linemon;
295 if (rcflags & RCF_STDERR_LINEMON)
296 rc.rc_cap[RUNCAP_STDERR].sc_linemon = stderr_linemon;
297
273 status = EX_FAILURE; 298 status = EX_FAILURE;
274 if (runcap(&rc, RCF_TIMEOUT)) { 299 if (runcap(&rc, rcflags)) {
275 json_object_set(obj, "status", json_new_bool(0)); 300 json_object_set(obj, "status", json_new_bool(0));
276 json_object_set(obj, "error", json_new_bool(1)); 301 json_object_set(obj, "error", json_new_bool(1));
277 json_object_set(obj, "message", 302 json_object_set(obj, "message",

Return to:

Send suggestions and report system problems to the System administrator.