diff --git a/internal/lsp/cmd/serve.go b/internal/lsp/cmd/serve.go index 924cdcce3c..0e7d211631 100644 --- a/internal/lsp/cmd/serve.go +++ b/internal/lsp/cmd/serve.go @@ -54,9 +54,11 @@ func (s *Serve) Run(ctx context.Context, args ...string) error { return tool.CommandLineErrorf("server does not take arguments, got %v", args) } - if err := s.app.debug.SetLogFile(s.Logfile); err != nil { + err, closeLog := s.app.debug.SetLogFile(s.Logfile) + if err != nil { return err } + defer closeLog() s.app.debug.ServerAddress = s.Address s.app.debug.DebugAddress = s.Debug s.app.debug.Serve(ctx) diff --git a/internal/lsp/debug/serve.go b/internal/lsp/debug/serve.go index 3316817aea..3b10a37bfd 100644 --- a/internal/lsp/debug/serve.go +++ b/internal/lsp/debug/serve.go @@ -258,21 +258,27 @@ func (i *Instance) Prepare(ctx context.Context) { export.AddExporters(i.ocagent, i.prometheus, i.rpcs, i.traces) } -func (i *Instance) SetLogFile(logfile string) error { +func (i *Instance) SetLogFile(logfile string) (error, func()) { + // TODO: probably a better solution for deferring closure to the caller would + // be for the debug instance to itself be closed, but this fixes the + // immediate bug of logs not being captured. + closeLog := func() {} if logfile != "" { if logfile == "auto" { logfile = filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.log", os.Getpid())) } f, err := os.Create(logfile) if err != nil { - return fmt.Errorf("Unable to create log file: %v", err) + return fmt.Errorf("Unable to create log file: %v", err), nil + } + closeLog = func() { + defer f.Close() } - defer f.Close() stdlog.SetOutput(io.MultiWriter(os.Stderr, f)) i.LogWriter = f } i.Logfile = logfile - return nil + return nil, closeLog } // Serve starts and runs a debug server in the background.