[master] a19457ac1 vsl: Write to stdout when opening "-"

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Nov 29 16:12:07 UTC 2021


commit a19457ac1971a611cc5bb9d09af1fd5dd78e4dac
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Tue Nov 23 09:41:29 2021 +0100

    vsl: Write to stdout when opening "-"
    
    Just like the file cursor reads from stdin when opening "-". And in
    addition, teach varnishlog to also write to stdout when it is opening
    the file directly. Likewise, put varnishncsa on par with varnishlog in
    that regard.
    
    It is now possible to compress binary VSL on the fly without taking
    a detour to the file system, see u00019.vtc for an example.
    
    Considering how VUT daemonizes, a "-w -" option in daemon mode becomes
    an error as well.
    
    Refs #3740

diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c
index 0e049f003..2b3de1383 100644
--- a/bin/varnishlog/varnishlog.c
+++ b/bin/varnishlog/varnishlog.c
@@ -72,9 +72,12 @@ openout(int append)
 {
 
 	AN(LOG.w_arg);
-	if (LOG.A_opt)
-		LOG.fo = fopen(LOG.w_arg, append ? "a" : "w");
-	else
+	if (LOG.A_opt) {
+		if (!strcmp(LOG.w_arg, "-"))
+			LOG.fo = stdout;
+		else
+			LOG.fo = fopen(LOG.w_arg, append ? "a" : "w");
+	} else
 		LOG.fo = VSL_WriteOpen(vut->vsl, LOG.w_arg, append, LOG.u_opt);
 	if (LOG.fo == NULL)
 		VUT_Error(vut, 2, "Cannot open output file (%s)",
@@ -148,6 +151,9 @@ main(int argc, char * const *argv)
 	if (vut->D_opt && !LOG.w_arg)
 		VUT_Error(vut, 1, "Missing -w option");
 
+	if (vut->D_opt && !strcmp(LOG.w_arg, "-"))
+		VUT_Error(vut, 1, "Daemon cannot write to stdout");
+
 	/* Setup output */
 	if (LOG.A_opt || !LOG.w_arg) {
 		vut->dispatch_f = VSL_PrintTransactions;
diff --git a/bin/varnishlog/varnishlog_options.h b/bin/varnishlog/varnishlog_options.h
index 470023060..39d07b913 100644
--- a/bin/varnishlog/varnishlog_options.h
+++ b/bin/varnishlog/varnishlog_options.h
@@ -58,7 +58,9 @@
 	    " reopened allowing the old one to be rotated away. The"	\
 	    " file can then be read by varnishlog and other tools with"	\
 	    " the -r option, unless the -A option was specified. This"	\
-	    " option is required when running in daemon mode."		\
+	    " option is required when running in daemon mode. If the"	\
+	    " filename is -, varnishlog writes to the standard output"	\
+	    " and cannot work as a daemon."				\
 	)
 
 LOG_OPT_a
diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c
index 9ae918b0e..7b1e4234e 100644
--- a/bin/varnishncsa/varnishncsa.c
+++ b/bin/varnishncsa/varnishncsa.c
@@ -167,7 +167,10 @@ openout(int append)
 {
 
 	AN(CTX.w_arg);
-	CTX.fo = fopen(CTX.w_arg, append ? "a" : "w");
+	if (!strcmp(CTX.w_arg, "-"))
+		CTX.fo = stdout;
+	else
+		CTX.fo = fopen(CTX.w_arg, append ? "a" : "w");
 	if (CTX.fo == NULL)
 		VUT_Error(vut, 1, "Can't open output file (%s)",
 		    strerror(errno));
@@ -1217,6 +1220,9 @@ main(int argc, char * const *argv)
 	if (vut->D_opt && !CTX.w_arg)
 		VUT_Error(vut, 1, "Missing -w option");
 
+	if (vut->D_opt && !strcmp(CTX.w_arg, "-"))
+		VUT_Error(vut, 1, "Daemon cannot write to stdout");
+
 	/* Check for valid grouping mode */
 	assert(vut->g_arg < VSL_g__MAX);
 	if (vut->g_arg != VSL_g_vxid && vut->g_arg != VSL_g_request)
diff --git a/bin/varnishncsa/varnishncsa_options.h b/bin/varnishncsa/varnishncsa_options.h
index fa2dd57d1..ccd2a3098 100644
--- a/bin/varnishncsa/varnishncsa_options.h
+++ b/bin/varnishncsa/varnishncsa_options.h
@@ -34,7 +34,8 @@
 #define NCSA_OPT_a							\
 	VOPT("a", "[-a]", "Append to file",				\
 	    "When writing output to a file, append to it rather than"	\
-	    " overwrite it."						\
+	    " overwrite it. This option has no effect without the -w"	\
+	    " option."							\
 	)
 
 #define NCSA_OPT_F							\
@@ -62,7 +63,9 @@
 	    " unless the -a option was specified. If the application"	\
 	    " receives a SIGHUP in daemon mode the file will be"	\
 	    " reopened allowing the old one to be rotated away. This"	\
-	    " option is required when running in daemon mode."		\
+	    " option is required when running in daemon mode. If the"	\
+	    " filename is -, varnishncsa writes to the standard output"	\
+	    " and cannot work as a daemon."				\
 	)
 #define NCSA_OPT_b							\
 	VOPT("b", "[-b]", "Backend mode",				\
diff --git a/bin/varnishtest/tests/u00003.vtc b/bin/varnishtest/tests/u00003.vtc
index e67962a28..65aadee41 100644
--- a/bin/varnishtest/tests/u00003.vtc
+++ b/bin/varnishtest/tests/u00003.vtc
@@ -69,6 +69,8 @@ shell -expect "Copyright (c) 2006 Verdens Gang AS" \
 	"varnishncsa -V"
 shell -err -expect "Missing -w option" \
 	{varnishncsa -D}
+shell -err -expect "Daemon cannot write to stdout" \
+	"varnishlog -D -w -"
 shell -err -expect "Unknown format specifier at: %{foo}A" \
 	{varnishncsa -F "%{foo}A"}
 shell -err -expect "Unknown format specifier at: %A" \
diff --git a/bin/varnishtest/tests/u00006.vtc b/bin/varnishtest/tests/u00006.vtc
index a79d592e8..6fe729929 100644
--- a/bin/varnishtest/tests/u00006.vtc
+++ b/bin/varnishtest/tests/u00006.vtc
@@ -26,6 +26,8 @@ shell -err -match "Usage: .*varnishlog <options>" \
 	"varnishlog extra"
 shell -err -expect "Missing -w option" \
 	"varnishlog -D"
+shell -err -expect "Daemon cannot write to stdout" \
+	"varnishlog -D -w -"
 shell -err -expect "Ambiguous grouping type: r" \
 	"varnishlog -g r"
 shell -err -expect "Unknown grouping type: foo" \
diff --git a/bin/varnishtest/tests/u00019.vtc b/bin/varnishtest/tests/u00019.vtc
new file mode 100644
index 000000000..9683d6967
--- /dev/null
+++ b/bin/varnishtest/tests/u00019.vtc
@@ -0,0 +1,18 @@
+varnishtest "varnishlog write vsl to stdout"
+
+feature cmd "command -v gzip"
+feature cmd "command -v zcat"
+
+varnish v1 -vcl {
+	backend be none;
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 503
+} -run
+
+shell {varnishlog -d -w - -n ${v1_name} | gzip >vsl.gz}
+shell {ls -l}
+shell -match "RespStatus +503" {zcat vsl.gz | varnishlog -r -}
diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c
index 7fadba364..e5f2ddaf1 100644
--- a/lib/libvarnishapi/vsl.c
+++ b/lib/libvarnishapi/vsl.c
@@ -413,14 +413,17 @@ VSL_WriteOpen(struct VSL_data *vsl, const char *name, int append, int unbuf)
 {
 	const char head[] = VSL_FILE_ID;
 	FILE* f;
-	f = fopen(name, append ? "a" : "w");
+	if (!strcmp(name, "-"))
+		f = stdout;
+	else
+		f = fopen(name, append ? "a" : "w");
 	if (f == NULL) {
 		vsl_diag(vsl, "%s", strerror(errno));
 		return (NULL);
 	}
 	if (unbuf)
 		setbuf(f, NULL);
-	if (0 == ftell(f)) {
+	if (ftell(f) == 0 || f == stdout) {
 		if (fwrite(head, 1, sizeof head, f) != sizeof head) {
 			vsl_diag(vsl, "%s", strerror(errno));
 			(void)fclose(f);


More information about the varnish-commit mailing list