From d2ec37fbe128da402133c15e765f083b1bdf3729 Mon Sep 17 00:00:00 2001 From: Leo Pang <34628052+allthatjazzleo@users.noreply.github.com> Date: Fri, 21 May 2021 03:29:56 +0800 Subject: [PATCH] cosmovisor: set larger buffer size for cosmovisor to scan log (fix #8651) (#8653) * cosmovisor: set larger buffer for cosmovisor to scan log (fix #8651) * update cosmovisor README and set buffer size to ENV setting Co-authored-by: Marko Co-authored-by: Aaron Craelius Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- cosmovisor/args.go | 14 ++++++++++++++ cosmovisor/process.go | 11 +++++++++++ docs/run-node/cosmovisor.md | 1 + 3 files changed, 26 insertions(+) diff --git a/cosmovisor/args.go b/cosmovisor/args.go index 33fb62e0180f..60cbb7d60167 100644 --- a/cosmovisor/args.go +++ b/cosmovisor/args.go @@ -1,11 +1,13 @@ package cosmovisor import ( + "bufio" "errors" "fmt" "net/url" "os" "path/filepath" + "strconv" ) const ( @@ -21,6 +23,7 @@ type Config struct { Name string AllowDownloadBinaries bool RestartAfterUpgrade bool + LogBufferSize int } // Root returns the root directory where all info lives @@ -99,6 +102,17 @@ func GetConfigFromEnv() (*Config, error) { cfg.RestartAfterUpgrade = true } + logBufferSizeStr := os.Getenv("DAEMON_LOG_BUFFER_SIZE") + if logBufferSizeStr != "" { + logBufferSize, err := strconv.Atoi(logBufferSizeStr) + if err != nil { + return nil, err + } + cfg.LogBufferSize = logBufferSize * 1024 + } else { + cfg.LogBufferSize = bufio.MaxScanTokenSize + } + if err := cfg.validate(); err != nil { return nil, err } diff --git a/cosmovisor/process.go b/cosmovisor/process.go index cfd201e2be99..6a67f65e162e 100644 --- a/cosmovisor/process.go +++ b/cosmovisor/process.go @@ -38,6 +38,17 @@ func LaunchProcess(cfg *Config, args []string, stdout, stderr io.Writer) (bool, scanOut := bufio.NewScanner(io.TeeReader(outpipe, stdout)) scanErr := bufio.NewScanner(io.TeeReader(errpipe, stderr)) + // set scanner's buffer size to cfg.LogBufferSize, and ensure larger than bufio.MaxScanTokenSize otherwise fallback to bufio.MaxScanTokenSize + var maxCapacity int + if cfg.LogBufferSize < bufio.MaxScanTokenSize { + maxCapacity = bufio.MaxScanTokenSize + } else { + maxCapacity = cfg.LogBufferSize + } + bufOut := make([]byte, maxCapacity) + bufErr := make([]byte, maxCapacity) + scanOut.Buffer(bufOut, maxCapacity) + scanErr.Buffer(bufErr, maxCapacity) if err := cmd.Start(); err != nil { return false, fmt.Errorf("launching process %s %s: %w", bin, strings.Join(args, " "), err) diff --git a/docs/run-node/cosmovisor.md b/docs/run-node/cosmovisor.md index f76b4afeefe8..8ff5aac917bf 100644 --- a/docs/run-node/cosmovisor.md +++ b/docs/run-node/cosmovisor.md @@ -25,6 +25,7 @@ binary). command line arguments and flags (but new binary) after a successful upgrade. By default, `cosmovisor` dies afterwards and allows the supervisor to restart it if needed. Note that this will not auto-restart the child if there was an error. +* `DAEMON_LOG_BUFFER_SIZE` (*optional*) is the buffer size for cosmovisor to scan log. If not set, it will use the default [64](https://github.com/golang/go/blob/2217e89ba326875470a856cd0da79f3ec9a896b8/src/bufio/scan.go#L80). (e.g. set to `256` or `512`) It is to avoid scanning stuck in case of long line of the log. ## Data Folder Layout