os.Pipe 未按预期使用日志包
os.Pipe not working as expected with log package
我有一段代码设置了一个 os.Pipe
来捕获 Stdout/Stderr:
https://github.com/sevagh/stdcap/blob/master/stdcap.go
// Capture executes f() and returns the captured data
func (s *stdcap) Capture(f func()) string {
s.mu.Lock()
defer s.mu.Unlock()
var old, r, w *os.File
if s.out {
old = os.Stdout
r, w, _ = os.Pipe()
os.Stdout = w
} else {
old = os.Stderr
r, w, _ = os.Pipe()
os.Stderr = w
}
f()
outC := make(chan string)
defer close(outC)
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
w.Close()
if s.out {
os.Stdout = old
} else {
os.Stderr = old
}
return <-outC
}
今天我尝试将此代码与 log
包一起使用,但它不起作用。
这个有效:
func TestOutCapture(t *testing.T) {
sc := StdoutCapture()
out := sc.Capture(func() {
fmt.Printf("Hello world!")
})
if out != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", out)
}
}
func TestErrCapture(t *testing.T) {
sc := StderrCapture()
err := sc.Capture(func() {
fmt.Fprintf(os.Stderr, "Hello world!")
})
if err != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", err)
}
}
这些不起作用:
func TestLogOutCapture(t *testing.T) {
sc := StdoutCapture()
log.SetOutput(os.Stdout)
out := sc.Capture(func() {
log.Printf("Hello world!")
})
if out != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", out)
}
}
func TestLogErrCapture(t *testing.T) {
sc := StderrCapture()
log.SetOutput(os.Stderr)
err := sc.Capture(func() {
log.Printf("Hello world!")
})
if err != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", err)
}
}
关于我可以在哪里调试它的任何想法? Golang log
包不使用os.Stdout/os.Stderr
吗?
日志包initializes the standard logger with the value os.Stderr
at initialization time. Modifications to the variable os.Stderr
do not change the value in the logger field。
调用 log.SetOutput 更改捕获函数中标准记录器的输出位置。不幸的是,没有办法获得标准记录器的输出,因此您可以在捕获功能中保存和恢复它。
我有一段代码设置了一个 os.Pipe
来捕获 Stdout/Stderr:
https://github.com/sevagh/stdcap/blob/master/stdcap.go
// Capture executes f() and returns the captured data
func (s *stdcap) Capture(f func()) string {
s.mu.Lock()
defer s.mu.Unlock()
var old, r, w *os.File
if s.out {
old = os.Stdout
r, w, _ = os.Pipe()
os.Stdout = w
} else {
old = os.Stderr
r, w, _ = os.Pipe()
os.Stderr = w
}
f()
outC := make(chan string)
defer close(outC)
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
w.Close()
if s.out {
os.Stdout = old
} else {
os.Stderr = old
}
return <-outC
}
今天我尝试将此代码与 log
包一起使用,但它不起作用。
这个有效:
func TestOutCapture(t *testing.T) {
sc := StdoutCapture()
out := sc.Capture(func() {
fmt.Printf("Hello world!")
})
if out != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", out)
}
}
func TestErrCapture(t *testing.T) {
sc := StderrCapture()
err := sc.Capture(func() {
fmt.Fprintf(os.Stderr, "Hello world!")
})
if err != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", err)
}
}
这些不起作用:
func TestLogOutCapture(t *testing.T) {
sc := StdoutCapture()
log.SetOutput(os.Stdout)
out := sc.Capture(func() {
log.Printf("Hello world!")
})
if out != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", out)
}
}
func TestLogErrCapture(t *testing.T) {
sc := StderrCapture()
log.SetOutput(os.Stderr)
err := sc.Capture(func() {
log.Printf("Hello world!")
})
if err != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", err)
}
}
关于我可以在哪里调试它的任何想法? Golang log
包不使用os.Stdout/os.Stderr
吗?
日志包initializes the standard logger with the value os.Stderr
at initialization time. Modifications to the variable os.Stderr
do not change the value in the logger field。
调用 log.SetOutput 更改捕获函数中标准记录器的输出位置。不幸的是,没有办法获得标准记录器的输出,因此您可以在捕获功能中保存和恢复它。