git » gofer » commit a4f7155

Implement log reopen

author Alberto Bertogli
2020-06-07 11:17:58 UTC
committer Alberto Bertogli
2020-06-07 11:48:52 UTC
parent b94a405a50be40d74908be7a47161b9c17f37ac7

Implement log reopen

gofer.go +28 -0
reqlog/reqlog.go +6 -0
test/test.sh +52 -2

diff --git a/gofer.go b/gofer.go
index aa86a88..4e2d785 100644
--- a/gofer.go
+++ b/gofer.go
@@ -2,6 +2,9 @@ package main
 
 import (
 	"flag"
+	"os"
+	"os/signal"
+	"syscall"
 	"time"
 
 	"blitiri.com.ar/go/gofer/config"
@@ -26,6 +29,8 @@ func main() {
 		log.Fatalf("error reading config file: %v", err)
 	}
 
+	go signalHandler()
+
 	for name, rlog := range conf.ReqLog {
 		reqlog.FromConfig(name, rlog)
 	}
@@ -50,3 +55,26 @@ func main() {
 		time.Sleep(1 * time.Hour)
 	}
 }
+
+func signalHandler() {
+	var err error
+
+	signals := make(chan os.Signal, 1)
+	signal.Notify(signals, syscall.SIGHUP)
+
+	for {
+		switch sig := <-signals; sig {
+		case syscall.SIGHUP:
+			// SIGHUP triggers a reopen of the log files. This is used for log
+			// rotation.
+			err = log.Default.Reopen()
+			if err != nil {
+				log.Fatalf("Error reopening log: %v", err)
+			}
+
+			reqlog.ReopenAll()
+		default:
+			log.Errorf("Unexpected signal %v", sig)
+		}
+	}
+}
diff --git a/reqlog/reqlog.go b/reqlog/reqlog.go
index 065b3a0..a4774b4 100644
--- a/reqlog/reqlog.go
+++ b/reqlog/reqlog.go
@@ -160,6 +160,12 @@ func FromName(name string) *Log {
 	return registry[name]
 }
 
+func ReopenAll() {
+	for _, rl := range registry {
+		rl.Reopen()
+	}
+}
+
 type ctxKeyT string
 
 const ctxKey = ctxKeyT("reqlog")
diff --git a/test/test.sh b/test/test.sh
index 785d007..b641a0b 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -24,7 +24,7 @@ if [ "$COVER_DIR" != "" ]; then
 		mv gofer.test gofer
 	)
 else
-	( cd ..; go build )
+	( cd ..; go build $GO_FLAGS )
 fi
 ( cd util; go build exp.go )
 
@@ -82,22 +82,38 @@ function snoop() {
 	fi
 }
 
+function waitgrep() {
+	for i in 0.01 0.02 0.05 0.1 0.2; do
+		if grep "$@"; then
+				return 0
+		fi
+		sleep $i
+	done
+	return 1	
+}
+
+
 echo "## Setup"
 
+# Remove old request log files, since we will be checking their contents.
+rm -f .01-fe.requests.log .01-be.requests.log
+
 # Launch the backend serving static files and CGI.
 gofer -logfile=.01-be.log -configfile=01-be.yaml
-DIR_PID=$PID
+BE_PID=$PID
 wait_until_ready 8450
 
 # Launch the test instance.
 generate_certs
 gofer -logfile=.01-fe.log -configfile=01-fe.yaml
+FE_PID=$PID
 wait_until_ready 8441  # http
 wait_until_ready 8442  # https
 wait_until_ready 8445  # raw
 
 snoop
 
+
 #
 # Test cases.
 #
@@ -129,6 +145,7 @@ do
 	exp $base/dir/withoutindex/chau -body 'chau\n'
 
 	exp $base/cgi/ -bodyre '"param 1" "param 2"'
+	exp $base/cgi/lala -bodyre '"param 1" "param 2"'
 	exp "$base/cgi/?cucu=melo&a;b" -bodyre 'QUERY_STRING=cucu=melo&a;b\n'
 
 	exp $base/gogo/ -status 307 -redir https://google.com/
@@ -157,6 +174,7 @@ do
 	exp $base/file -hdrre "X-My-Header: my lovely header"
 done
 
+
 # Good auth.
 for base in \
 	http://oneuser:onepass@localhost:8441 \
@@ -170,6 +188,7 @@ do
 	exp $base/authdir/withoutindex/chau -body 'chau\n'
 done
 
+
 # Bad auth.
 for base in \
 	http://oneuser:bad@localhost:8441 \
@@ -183,6 +202,37 @@ do
 	exp $base/authdir/withoutindex/chau -status 401
 done
 
+
+echo "### Request log"
+function logtest() {
+		exp http://localhost:8441/cgi/logtest
+		for f in .01-be.requests.log .01-fe.requests.log; do
+				EXPECT="localhost:8441 GET /cgi/logtest = 200"
+				if ! waitgrep -q "$EXPECT" $f; then
+						echo "$f: log entry not found"
+						exit 1
+				fi
+		done
+}
+
+# Check that the entry appears.
+logtest
+
+# Log rotation.
+mv .01-fe.requests.log .01-fe.requests.log.old
+mv .01-be.requests.log .01-be.requests.log.old
+kill -HUP $FE_PID $BE_PID
+
+# Expect the entry again, and make sure it's the only one.
+logtest
+for f in .01-be.requests.log .01-fe.requests.log; do
+		if [ "$(wc -l < $f)" != 1 ]; then
+			echo "$f: unexpected number of entries"
+			exit 1
+		fi
+done
+
+
 echo "### Miscellaneous"
 
 # HTTPS-only tests.