From 3e039daf95be43a371f97a9701bc56994c34bd2a Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Wed, 28 Jul 2021 15:17:31 -0700 Subject: [PATCH] logpolicy: actually collect panics (Written with Josh) For #2544 Signed-off-by: David Crawshaw --- cmd/tailscaled/tailscaled.go | 3 +++ logpolicy/logpolicy.go | 5 +++- tstest/integration/integration_test.go | 34 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go index 4d3651a22..675650adc 100644 --- a/cmd/tailscaled/tailscaled.go +++ b/cmd/tailscaled/tailscaled.go @@ -210,6 +210,9 @@ func run() error { logf = logger.RateLimitedFn(logf, 5*time.Second, 5, 100) if args.cleanup { + if os.Getenv("TS_PLEASE_PANIC") != "" { + panic("TS_PLEASE_PANIC asked us to panic") + } dns.Cleanup(logf, args.tunname) router.Cleanup(logf, args.tunname) return nil diff --git a/logpolicy/logpolicy.go b/logpolicy/logpolicy.go index f7f552cda..62dc92a89 100644 --- a/logpolicy/logpolicy.go +++ b/logpolicy/logpolicy.go @@ -435,9 +435,12 @@ func New(collection string) *Policy { c.HTTPC = &http.Client{Transport: newLogtailTransport(u.Host)} } - filchBuf, filchErr := filch.New(filepath.Join(dir, cmdName), filch.Options{}) + filchBuf, filchErr := filch.New(filepath.Join(dir, cmdName), filch.Options{ + ReplaceStderr: true, + }) if filchBuf != nil { c.Buffer = filchBuf + c.Stderr = filchBuf.OrigStderr } lw := logtail.NewLogger(c, log.Printf) log.SetFlags(0) // other logflags are set on console, not here diff --git a/tstest/integration/integration_test.go b/tstest/integration/integration_test.go index eaa1fb29e..bd41ef324 100644 --- a/tstest/integration/integration_test.go +++ b/tstest/integration/integration_test.go @@ -84,6 +84,40 @@ func TestOneNodeUp_NoAuth(t *testing.T) { t.Logf("number of HTTP logcatcher requests: %v", env.LogCatcher.numRequests()) } +func TestCollectPanic(t *testing.T) { + t.Parallel() + bins := BuildTestBinaries(t) + + env := newTestEnv(t, bins) + defer env.Close() + + n := newTestNode(t, env) + + cmd := exec.Command(n.env.Binaries.Daemon, "--cleanup") + cmd.Env = append(os.Environ(), + "TS_PLEASE_PANIC=1", + "TS_LOG_TARGET="+n.env.LogCatcherServer.URL, + ) + got, _ := cmd.CombinedOutput() // we expect it to fail, ignore err + t.Logf("initial run: %s", got) + + // Now we run it again, and on start, it will upload the logs to logcatcher. + cmd = exec.Command(n.env.Binaries.Daemon, "--cleanup") + cmd.Env = append(os.Environ(), "TS_LOG_TARGET="+n.env.LogCatcherServer.URL) + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("cleanup failed: %v: %q", err, out) + } + if err := tstest.WaitFor(20*time.Second, func() error { + const sub = `panic` + if !n.env.LogCatcher.logsContains(mem.S(sub)) { + return fmt.Errorf("log catcher didn't see %#q; got %s", sub, n.env.LogCatcher.logsString()) + } + return nil + }); err != nil { + t.Fatal(err) + } +} + // test Issue 2321: Start with UpdatePrefs should save prefs to disk func TestStateSavedOnStart(t *testing.T) { t.Parallel()