Skip to content

Commit e72d58b

Browse files
fix: guard server log lumberjack with mutex (#15582)
(Hopefully) closes coder/internal#213.
1 parent 029cd5d commit e72d58b

File tree

2 files changed

+33
-32
lines changed

2 files changed

+33
-32
lines changed

cli/agent.go

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"runtime"
1313
"strconv"
1414
"strings"
15-
"sync"
1615
"time"
1716

1817
"cloud.google.com/go/compute/metadata"
@@ -30,6 +29,7 @@ import (
3029
"github.com/coder/coder/v2/agent/agentssh"
3130
"github.com/coder/coder/v2/agent/reaper"
3231
"github.com/coder/coder/v2/buildinfo"
32+
"github.com/coder/coder/v2/cli/clilog"
3333
"github.com/coder/coder/v2/codersdk"
3434
"github.com/coder/coder/v2/codersdk/agentsdk"
3535
"github.com/coder/serpent"
@@ -110,7 +110,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
110110
// Spawn a reaper so that we don't accumulate a ton
111111
// of zombie processes.
112112
if reaper.IsInitProcess() && !noReap && isLinux {
113-
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
113+
logWriter := &clilog.LumberjackWriteCloseFixer{Writer: &lumberjack.Logger{
114114
Filename: filepath.Join(logDir, "coder-agent-init.log"),
115115
MaxSize: 5, // MB
116116
// Without this, rotated logs will never be deleted.
@@ -153,7 +153,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
153153
// reaper.
154154
go DumpHandler(ctx, "agent")
155155

156-
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
156+
logWriter := &clilog.LumberjackWriteCloseFixer{Writer: &lumberjack.Logger{
157157
Filename: filepath.Join(logDir, "coder-agent.log"),
158158
MaxSize: 5, // MB
159159
// Per customer incident on November 17th, 2023, its helpful
@@ -478,33 +478,6 @@ func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler,
478478
}
479479
}
480480

481-
// lumberjackWriteCloseFixer is a wrapper around an io.WriteCloser that
482-
// prevents writes after Close. This is necessary because lumberjack
483-
// re-opens the file on Write.
484-
type lumberjackWriteCloseFixer struct {
485-
w io.WriteCloser
486-
mu sync.Mutex // Protects following.
487-
closed bool
488-
}
489-
490-
func (c *lumberjackWriteCloseFixer) Close() error {
491-
c.mu.Lock()
492-
defer c.mu.Unlock()
493-
494-
c.closed = true
495-
return c.w.Close()
496-
}
497-
498-
func (c *lumberjackWriteCloseFixer) Write(p []byte) (int, error) {
499-
c.mu.Lock()
500-
defer c.mu.Unlock()
501-
502-
if c.closed {
503-
return 0, io.ErrClosedPipe
504-
}
505-
return c.w.Write(p)
506-
}
507-
508481
// extractPort handles different url strings.
509482
// - localhost:6060
510483
// - http://localhost:6060

cli/clilog/clilog.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"regexp"
88
"strings"
9+
"sync"
910

1011
"golang.org/x/xerrors"
1112
"gopkg.in/natefinch/lumberjack.v2"
@@ -111,12 +112,12 @@ func (b *Builder) Build(inv *serpent.Invocation) (log slog.Logger, closeLog func
111112
sinks = append(sinks, sinkFn(inv.Stderr))
112113

113114
default:
114-
logWriter := &lumberjack.Logger{
115+
logWriter := &LumberjackWriteCloseFixer{Writer: &lumberjack.Logger{
115116
Filename: loc,
116117
MaxSize: 5, // MB
117118
// Without this, rotated logs will never be deleted.
118119
MaxBackups: 1,
119-
}
120+
}}
120121
closers = append(closers, logWriter.Close)
121122
sinks = append(sinks, sinkFn(logWriter))
122123
}
@@ -210,3 +211,30 @@ func (f *debugFilterSink) Sync() {
210211
sink.Sync()
211212
}
212213
}
214+
215+
// LumberjackWriteCloseFixer is a wrapper around an io.WriteCloser that
216+
// prevents writes after Close. This is necessary because lumberjack
217+
// re-opens the file on Write.
218+
type LumberjackWriteCloseFixer struct {
219+
Writer io.WriteCloser
220+
mu sync.Mutex // Protects following.
221+
closed bool
222+
}
223+
224+
func (c *LumberjackWriteCloseFixer) Close() error {
225+
c.mu.Lock()
226+
defer c.mu.Unlock()
227+
228+
c.closed = true
229+
return c.Writer.Close()
230+
}
231+
232+
func (c *LumberjackWriteCloseFixer) Write(p []byte) (int, error) {
233+
c.mu.Lock()
234+
defer c.mu.Unlock()
235+
236+
if c.closed {
237+
return 0, io.ErrClosedPipe
238+
}
239+
return c.Writer.Write(p)
240+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy