mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: guard server log lumberjack with mutex (#15582)
(Hopefully) closes https://github.com/coder/internal/issues/213.
This commit is contained in:
+3
-30
@@ -12,7 +12,6 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
@@ -30,6 +29,7 @@ import (
|
||||
"github.com/coder/coder/v2/agent/agentssh"
|
||||
"github.com/coder/coder/v2/agent/reaper"
|
||||
"github.com/coder/coder/v2/buildinfo"
|
||||
"github.com/coder/coder/v2/cli/clilog"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/codersdk/agentsdk"
|
||||
"github.com/coder/serpent"
|
||||
@@ -110,7 +110,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
|
||||
// Spawn a reaper so that we don't accumulate a ton
|
||||
// of zombie processes.
|
||||
if reaper.IsInitProcess() && !noReap && isLinux {
|
||||
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
|
||||
logWriter := &clilog.LumberjackWriteCloseFixer{Writer: &lumberjack.Logger{
|
||||
Filename: filepath.Join(logDir, "coder-agent-init.log"),
|
||||
MaxSize: 5, // MB
|
||||
// Without this, rotated logs will never be deleted.
|
||||
@@ -153,7 +153,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
|
||||
// reaper.
|
||||
go DumpHandler(ctx, "agent")
|
||||
|
||||
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
|
||||
logWriter := &clilog.LumberjackWriteCloseFixer{Writer: &lumberjack.Logger{
|
||||
Filename: filepath.Join(logDir, "coder-agent.log"),
|
||||
MaxSize: 5, // MB
|
||||
// Per customer incident on November 17th, 2023, its helpful
|
||||
@@ -478,33 +478,6 @@ func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler,
|
||||
}
|
||||
}
|
||||
|
||||
// lumberjackWriteCloseFixer is a wrapper around an io.WriteCloser that
|
||||
// prevents writes after Close. This is necessary because lumberjack
|
||||
// re-opens the file on Write.
|
||||
type lumberjackWriteCloseFixer struct {
|
||||
w io.WriteCloser
|
||||
mu sync.Mutex // Protects following.
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (c *lumberjackWriteCloseFixer) Close() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.closed = true
|
||||
return c.w.Close()
|
||||
}
|
||||
|
||||
func (c *lumberjackWriteCloseFixer) Write(p []byte) (int, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.closed {
|
||||
return 0, io.ErrClosedPipe
|
||||
}
|
||||
return c.w.Write(p)
|
||||
}
|
||||
|
||||
// extractPort handles different url strings.
|
||||
// - localhost:6060
|
||||
// - http://localhost:6060
|
||||
|
||||
+30
-2
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
@@ -111,12 +112,12 @@ func (b *Builder) Build(inv *serpent.Invocation) (log slog.Logger, closeLog func
|
||||
sinks = append(sinks, sinkFn(inv.Stderr))
|
||||
|
||||
default:
|
||||
logWriter := &lumberjack.Logger{
|
||||
logWriter := &LumberjackWriteCloseFixer{Writer: &lumberjack.Logger{
|
||||
Filename: loc,
|
||||
MaxSize: 5, // MB
|
||||
// Without this, rotated logs will never be deleted.
|
||||
MaxBackups: 1,
|
||||
}
|
||||
}}
|
||||
closers = append(closers, logWriter.Close)
|
||||
sinks = append(sinks, sinkFn(logWriter))
|
||||
}
|
||||
@@ -210,3 +211,30 @@ func (f *debugFilterSink) Sync() {
|
||||
sink.Sync()
|
||||
}
|
||||
}
|
||||
|
||||
// LumberjackWriteCloseFixer is a wrapper around an io.WriteCloser that
|
||||
// prevents writes after Close. This is necessary because lumberjack
|
||||
// re-opens the file on Write.
|
||||
type LumberjackWriteCloseFixer struct {
|
||||
Writer io.WriteCloser
|
||||
mu sync.Mutex // Protects following.
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (c *LumberjackWriteCloseFixer) Close() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.closed = true
|
||||
return c.Writer.Close()
|
||||
}
|
||||
|
||||
func (c *LumberjackWriteCloseFixer) Write(p []byte) (int, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.closed {
|
||||
return 0, io.ErrClosedPipe
|
||||
}
|
||||
return c.Writer.Write(p)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user