Heim  >  Artikel  >  Backend-Entwicklung  >  Protokolle in Terminal und Datei schreiben

Protokolle in Terminal und Datei schreiben

王林
王林nach vorne
2024-02-09 12:30:091123Durchsuche

Protokolle in Terminal und Datei schreiben

Der Herausgeber von PHP Banana stellt in diesem Artikel vor, wie man Protokolle in das Terminal und in Dateien schreibt. Während des Entwicklungsprozesses sind Protokolle sehr wichtig, da sie uns dabei helfen können, Codeprobleme zu verfolgen und zu beheben. Das Schreiben von Protokollen in das Terminal und in Dateien sind zwei gängige Methoden. Sie haben jeweils ihre eigenen Vor- und Nachteile. Sie können die geeignete Methode entsprechend Ihren spezifischen Anforderungen auswählen. Als nächstes besprechen wir im Detail, wie man PHP-Code zum Schreiben von Protokollen in Terminals und Dateien verwendet, und stellen einige gängige Protokollschreibfunktionen und -techniken vor, um Entwicklern bei der besseren Protokollverwaltung zu helfen.

Frageninhalt

Ich habe diese Funktion zum Schreiben von Protokollen in Terminal- und Protokolldateien:

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

Der obige Funktionsaufruf:

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

Frage

Das Problem besteht darin, dass einige Protokollzeilen auf dem Terminal und einige Zeilen in einer Datei gedruckt werden, wie folgt:

Frage

Wie kann sichergestellt werden, dass alle Protokollzeilen auf dem Terminal und in der Datei gedruckt werden?

Workaround

Protokoll auf Terminal gedruckt und abgelegt über:

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

Das Protokoll ist das gleiche:

Das obige ist der detaillierte Inhalt vonProtokolle in Terminal und Datei schreiben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen