diff --git a/CHANGELOG.md b/CHANGELOG.md index 9711c303d..088057561 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- `--no-log-prefix` option for `cartridge start` command to disable instance name prefix in logs when running interactively. + ## [2.6.0] - 2021-01-27 ### Added diff --git a/cli/commands/start.go b/cli/commands/start.go index b90d22d78..d438fb407 100644 --- a/cli/commands/start.go +++ b/cli/commands/start.go @@ -43,18 +43,28 @@ func init() { // stateboard flags addStateboardRunningFlags(startCmd) + // Disable instance name prefix in logs flag + startCmd.Flags().BoolVar(&ctx.Running.DisableLogPrefix, "no-log-prefix", false, disableLogPrefixUsage) + // common running paths addCommonRunningPathsFlags(startCmd) // start-specific paths startCmd.Flags().StringVar(&ctx.Running.DataDir, "data-dir", "", dataDirUsage) startCmd.Flags().StringVar(&ctx.Running.LogDir, "log-dir", "", logDirUsage) startCmd.Flags().StringVar(&ctx.Running.Entrypoint, "script", "", scriptUsage) - } func runStartCmd(cmd *cobra.Command, args []string) error { var err error + if timeoutStr == "" && !ctx.Running.Daemonize { + log.Warnf("--timeout flag is ignored due to starting instances interactively") + } + + if ctx.Running.DisableLogPrefix && ctx.Running.Daemonize { + log.Warnf("--no-log-prefix flag is ignored due to startring instances in background") + } + if err := setDefaultValue(cmd.Flags(), "timeout", defaultStartTimeout.String()); err != nil { return project.InternalError("Failed to set default timeout value: %s", err) } diff --git a/cli/commands/usage.go b/cli/commands/usage.go index 8a3a5060e..e02351fe1 100644 --- a/cli/commands/usage.go +++ b/cli/commands/usage.go @@ -87,6 +87,8 @@ defaults to ./instances.yml ("cfg" in .cartridge.yml)` logFollowUsage = `Output appended data as the log grows` stopForceUsage = `Force instance(s) stop (sends SIGKILL)` + + disableLogPrefixUsage = `Disable prefix in logs when run interactively` ) // REPLICASETS diff --git a/cli/context/context.go b/cli/context/context.go index e5bc5ca3f..ed2b0433d 100644 --- a/cli/context/context.go +++ b/cli/context/context.go @@ -66,8 +66,9 @@ type RunningCtx struct { Daemonize bool StartTimeout time.Duration - LogFollow bool - LogLines int + LogFollow bool + LogLines int + DisableLogPrefix bool StopForced bool diff --git a/cli/running/process.go b/cli/running/process.go index 87a376088..c5919f923 100644 --- a/cli/running/process.go +++ b/cli/running/process.go @@ -153,7 +153,7 @@ func (process *Process) IsRunning() bool { return process.Status == procStatusRunning } -func (process *Process) Start(daemonize bool) error { +func (process *Process) Start(daemonize bool, disableLogPrefix bool) error { var err error if _, err := os.Stat(process.entrypoint); err != nil { @@ -183,7 +183,12 @@ func (process *Process) Start(daemonize bool) error { // initialize logs writer if !daemonize { - logsWriter := newColorizedWriter(process.ID) + var logsWriter *ColorizedWriter + if !disableLogPrefix { + logsWriter = newColorizedWriter(process.ID) + } else { + logsWriter = newDummyWriter() + } process.cmd.Stdout = logsWriter process.cmd.Stderr = logsWriter diff --git a/cli/running/processes_set.go b/cli/running/processes_set.go index 07216f6b9..387979477 100644 --- a/cli/running/processes_set.go +++ b/cli/running/processes_set.go @@ -14,7 +14,7 @@ func (set *ProcessesSet) Add(processes ...*Process) { *set = append(*set, processes...) } -func startProcess(process *Process, daemonize bool, timeout time.Duration, resCh common.ResChan) { +func startProcess(process *Process, daemonize bool, disableLogPrefix bool, timeout time.Duration, resCh common.ResChan) { if process.Status == procStatusError { resCh <- common.Result{ ID: process.ID, @@ -33,7 +33,7 @@ func startProcess(process *Process, daemonize bool, timeout time.Duration, resCh return } - if err := process.Start(daemonize); err != nil { + if err := process.Start(daemonize, disableLogPrefix); err != nil { resCh <- common.Result{ ID: process.ID, Status: common.ResStatusFailed, @@ -73,11 +73,11 @@ func startProcess(process *Process, daemonize bool, timeout time.Duration, resCh } } -func (set *ProcessesSet) Start(daemonize bool, timeout time.Duration) error { +func (set *ProcessesSet) Start(daemonize bool, disableLogPrefix bool, timeout time.Duration) error { resCh := make(chan common.Result) for _, process := range *set { - go startProcess(process, daemonize, timeout, resCh) + go startProcess(process, daemonize, disableLogPrefix, timeout, resCh) // wait for process to print logs if !daemonize { diff --git a/cli/running/running.go b/cli/running/running.go index 37f679495..c2adce9cf 100644 --- a/cli/running/running.go +++ b/cli/running/running.go @@ -86,7 +86,7 @@ func Start(ctx *context.Ctx) error { log.Warnf("Failed to check .rocks directory: %s", err) } - if err := processes.Start(ctx.Running.Daemonize, ctx.Running.StartTimeout); err != nil { + if err := processes.Start(ctx.Running.Daemonize, ctx.Running.DisableLogPrefix, ctx.Running.StartTimeout); err != nil { return err } diff --git a/cli/running/writer.go b/cli/running/writer.go index dafce61c0..5f62f92f7 100644 --- a/cli/running/writer.go +++ b/cli/running/writer.go @@ -105,3 +105,12 @@ func newColorizedWriter(prefix string) *ColorizedWriter { writer.prefix = prefixColor.Sprintf("%s | ", prefix) return &writer } + +func newDummyWriter() *ColorizedWriter { + writer := ColorizedWriter{ + prefix: "", + out: os.Stdout, + } + + return &writer +} diff --git a/cli/running/writer_test.go b/cli/running/writer_test.go index d86e7e788..ad499ae32 100644 --- a/cli/running/writer_test.go +++ b/cli/running/writer_test.go @@ -62,3 +62,35 @@ func TestWrite(t *testing.T) { assert.Equal(len(logBytes), n) assert.Equal(getLogsWithPrefix(id, logs), out.String()) } + +func TestNoPrefixWrite(t *testing.T) { + t.Parallel() + + assert := assert.New(t) + out := bytes.NewBuffer(nil) + + writer := newDummyWriter() + writer.out = out + + out.Reset() + logs := []string{ + "Some long\nmultiline\nlog", + } + + logBytes := getLogsBytes(logs) + n, err := writer.Write(logBytes) + assert.Nil(err) + assert.Equal(len(logBytes), n) + assert.Equal(strings.Join(logs, "\n"), out.String()) + + out.Reset() + logs = []string{ + "One line log without prefix.", + } + + logBytes = getLogsBytes(logs) + n, err = writer.Write(logBytes) + assert.Nil(err) + assert.Equal(len(logBytes), n) + assert.Equal(strings.Join(logs, "\n"), out.String()) +}