Skip to content

Commit 7b796de

Browse files
committed
feat(env): add thread-safe writers for stdout and stderr
1 parent 705fae5 commit 7b796de

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

e/env.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package e
22

33
import (
4+
"io"
45
"os"
56
"strings"
7+
"sync"
68

79
"github.com/rs/zerolog"
810
"github.com/rs/zerolog/log"
@@ -13,6 +15,24 @@ var (
1315
V = Configure{}
1416
)
1517

18+
// SyncWriter 是一个线程安全的 writer,用于防止并发写入时输出混乱
19+
type SyncWriter struct {
20+
mu sync.Mutex
21+
w io.Writer
22+
}
23+
24+
func (sw *SyncWriter) Write(p []byte) (n int, err error) {
25+
sw.mu.Lock()
26+
defer sw.mu.Unlock()
27+
return sw.w.Write(p)
28+
}
29+
30+
// 全局同步 writer,供日志和程序输出共用
31+
var (
32+
StdoutWriter = &SyncWriter{w: os.Stdout}
33+
StderrWriter = &SyncWriter{w: os.Stderr}
34+
)
35+
1636
type (
1737
Configure struct {
1838
Log Log `mapstructure:"log"`
@@ -40,7 +60,11 @@ type (
4060
)
4161

4262
func init() {
43-
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, NoColor: false, TimeFormat: "2006-01-02T15:04:05Z"})
63+
log.Logger = log.Output(zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
64+
w.Out = StderrWriter
65+
w.NoColor = false
66+
w.TimeFormat = "2006-01-02T15:04:05Z"
67+
}))
4468
viper.SetConfigType("toml")
4569
viper.SetConfigName("sohot")
4670
viper.AddConfigPath(".")

watch/watch.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import (
88
"os/exec"
99
"os/signal"
1010
"path/filepath"
11-
"github.com/qwenode/sohot/e"
1211
"strings"
1312
"sync"
1413
"syscall"
1514
"time"
1615

16+
"github.com/qwenode/sohot/e"
17+
1718
"github.com/fsnotify/fsnotify"
1819
"github.com/rs/zerolog/log"
1920
)
@@ -87,8 +88,8 @@ func Running(input e.Run) {
8788
log.Err(err).Send()
8889
return
8990
}
90-
go io.Copy(os.Stdout, stdoutPipe)
91-
go io.Copy(os.Stderr, pipe)
91+
go io.Copy(e.StdoutWriter, stdoutPipe)
92+
go io.Copy(e.StderrWriter, pipe)
9293
// 捕获 cmd 的本地副本,避免竞态条件
9394
go func(runCmd *exec.Cmd) {
9495
<-stopRunning

0 commit comments

Comments
 (0)