php小编香蕉在这篇文章中将要介绍的是如何将日志写入终端和文件。在开发过程中,日志是非常重要的,它可以帮助我们追踪和调试代码的问题。将日志写入终端和文件是常见的两种方式,它们各有优劣,可以根据具体需求选择合适的方式。接下来,我们将详细讨论如何使用php代码将日志写入终端和文件,并介绍一些常用的日志写入函数和技巧,帮助开发者更好地进行日志管理。
问题内容
我有这个函数可以将日志写入终端和日志文件:
// Run an executable and print its log in real-time and print its log into a file too.
func RunWithLog(pthExe string, arg []string, fLog *os.File, dir string) error {
cmd := exec.Command(pthExe, arg...)
if dir != "" {
cmd.Dir = dir
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return err
}
var wg sync.WaitGroup
wg.Add(4)
go streamRealTime(stdout, &wg)
go streamRealTime(stderr, &wg)
go streamToLogFile(stdout, fLog, &wg)
go streamToLogFile(stderr, fLog, &wg)
err = cmd.Start()
if err != nil {
return err
}
wg.Wait()
err = cmd.Wait()
return err
}
func streamRealTime(output io.ReadCloser, wg *sync.WaitGroup) {
defer wg.Done()
scanner := bufio.NewScanner(output)
scanner.Split(bufio.ScanRunes)
for scanner.Scan() {
fmt.Print(scanner.Text())
}
err := scanner.Err()
if err != nil {
log.Printf("error: write log to terminal: %s", err.Error())
}
}
func streamToLogFile(output io.ReadCloser, fLog *os.File, wg *sync.WaitGroup) {
defer wg.Done()
scanner := bufio.NewScanner(output)
scanner.Split(bufio.ScanRunes)
for scanner.Scan() {
_, err := fLog.WriteString(scanner.Text())
if err != nil {
log.Printf("error: write log to file: %s", err.Error())
}
}
err := scanner.Err()
if err != nil {
log.Printf("error: write log to file: %s", err.Error())
}
}
登录后复制
上面的函数调用:
// Log file.
fLog, err := os.OpenFile(pathLog, os.O_APPEND, os.ModeAppend)
if err != nil {
return err
}
defer fLog.Close()
err = RunWithLog(pathExe, []string{"-b"}, fLog, workDir)
// ...
登录后复制
问题
问题是有些日志行打印到终端,有些行打印到文件,如下所示:
问题
如何确保所有日志行都打印到终端和文件?
解决方法
日志通过以下方式打印到终端和文件:
// Run an executable and print its log real-time and print its log into a file too.
func RunWithLog(pthExe string, arg []string, fLog *os.File, dir string) error {
cmd := exec.Command(pthExe, arg...)
if dir != "" {
cmd.Dir = dir
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return err
}
var wg sync.WaitGroup
wg.Add(2)
go streamLogs(stdout, fLog, &wg)
go streamLogs(stderr, fLog, &wg)
err = cmd.Start()
if err != nil {
return err
}
wg.Wait()
err = cmd.Wait()
return err
}
// Stream logs to both terminal and a file.
func streamLogs(output io.ReadCloser, fLog *os.File, wg *sync.WaitGroup) {
defer wg.Done()
scanner := bufio.NewScanner(output)
scanner.Split(bufio.ScanRunes)
for scanner.Scan() {
// Stream to terminal:
fmt.Print(scanner.Text())
// Stream to a file:
_, err := fLog.WriteString(scanner.Text())
if err != nil {
log.Printf("error: write log to file: %s", err.Error())
}
}
err := scanner.Err()
if err != nil {
log.Printf("error: write log to terminal: %s", err.Error())
}
}
登录后复制
测试
日志是相同的:
以上就是将日志写入终端和文件的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!