Home  >  Article  >  Backend Development  >  Write logs to terminal and file

Write logs to terminal and file

王林
王林forward
2024-02-09 12:30:091123browse

Write logs to terminal and file

php editor Banana will introduce in this article how to write logs to the terminal and files. During the development process, logs are very important, as they can help us track and debug code problems. Writing logs to the terminal and to files are two common methods. They each have their own advantages and disadvantages. You can choose the appropriate method according to your specific needs. Next, we will discuss in detail how to use PHP code to write logs to terminals and files, and introduce some common log writing functions and techniques to help developers better manage logs.

Question content

I have this function to write logs to the terminal and log file:

// 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())
    }
}

The above function call:

    // 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)
    // ...

question

The problem is that some log lines are printed to the terminal and some lines are printed to the file, as shown below:

question

How to ensure that all log lines are printed to the terminal and file?

Solution

The log is printed to the terminal and file via:

// 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())
    }
}

test

The logs are the same:

The above is the detailed content of Write logs to terminal and file. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete