diff --git a/.gitignore b/.gitignore index 3a97de8..becfa7a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,8 @@ build .goxc.local.json vendor/ dist -snap -stage -prime -parts +snap/** +stage/** +prime/** +parts/** *.snap \ No newline at end of file diff --git a/Gopkg.lock b/Gopkg.lock index f5a2692..5e83360 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -94,6 +94,30 @@ revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" version = "v1.1.0" +[[projects]] + branch = "master" + digest = "1:7e5c74b1b7c27e6ba7fb0a4417477f6a95dea7cfd00b186ad5a0453e7bde8c84" + name = "github.com/google/pprof" + packages = [ + "driver", + "internal/binutils", + "internal/driver", + "internal/elfexec", + "internal/graph", + "internal/measurement", + "internal/plugin", + "internal/report", + "internal/symbolizer", + "internal/symbolz", + "internal/transport", + "profile", + "third_party/d3", + "third_party/d3flamegraph", + "third_party/svgpan", + ] + pruneopts = "UT" + revision = "e84dfd68c163c45ea47aa24b3dc7eaa93f6675b1" + [[projects]] digest = "1:8f8811f9be822914c3a25c6a071e93beb4c805d7b026cbf298bc577bc1cc945b" name = "github.com/google/uuid" @@ -140,6 +164,14 @@ pruneopts = "UT" revision = "3959339b333561bf62a38b424fd41517c2c90f40" +[[projects]] + branch = "master" + digest = "1:3e658fb4b055816998a967aab8abe0966ce1cfcbb42c2f66a22c7c19568aa1d2" + name = "github.com/ianlancetaylor/demangle" + packages = ["."] + pruneopts = "UT" + revision = "5e5cf60278f657d30daa329dd0e7e893b6b8f027" + [[projects]] digest = "1:1069357a2767ba898fd6c715fb15d005403e5becf9b2e747630fbdde2a340302" name = "github.com/imdario/mergo" @@ -197,11 +229,25 @@ version = "v1.1.1" [[projects]] - digest = "1:2e8f79462685ce92c47687c71fa22bf23e3a530be851af93fa3201d1402ae75d" + branch = "master" + digest = "1:54818a8d2a7887e4b5d639291822fa7d5fa282e03bd61bb13472530316afd98c" + name = "golang.org/x/arch" + packages = [ + "arm/armasm", + "arm64/arm64asm", + "ppc64/ppc64asm", + "x86/x86asm", + ] + pruneopts = "UT" + revision = "5a4828bb704534b8a2fa09c791c67d0fb372f472" + +[[projects]] + digest = "1:e7f3d912bf067f2ee228dbb95853e6e0917d452239663372eb3bf03068ddb37c" name = "golang.org/x/crypto" packages = [ "pbkdf2", "scrypt", + "ssh/terminal", ] pruneopts = "UT" revision = "d172538b2cfce0c13cee31e647d0367aa8cd2486" @@ -214,6 +260,26 @@ pruneopts = "UT" revision = "63fc586f45fe72d95d5240a5d5eb95e6503907d3" +[[projects]] + digest = "1:5e46904bb22d49234fd73a5bcb7cc95f489a5abf5c8eae71ef3e66b3ef47b67b" + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "transform", + "unicode/cldr", + "unicode/norm", + ] + pruneopts = "UT" + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + [[projects]] digest = "1:c06d9e11d955af78ac3bbb26bd02e01d2f61f689e1a3bce2ef6fb683ef8a7f2d" name = "gopkg.in/alecthomas/kingpin.v2" @@ -254,9 +320,18 @@ "github.com/Pallinder/go-randomdata", "github.com/elazarl/go-bindata-assetfs", "github.com/gin-gonic/gin", + "github.com/google/pprof/driver", + "github.com/google/pprof/profile", "github.com/hashicorp/consul/api", "github.com/mitchellh/mapstructure", "github.com/pkg/errors", + "golang.org/x/arch/arm/armasm", + "golang.org/x/arch/arm64/arm64asm", + "golang.org/x/arch/ppc64/ppc64asm", + "golang.org/x/arch/x86/x86asm", + "golang.org/x/crypto/ssh/terminal", + "golang.org/x/text/collate", + "golang.org/x/text/language", "gopkg.in/alecthomas/kingpin.v2", "gopkg.in/telegram-bot-api.v4", "gopkg.in/yaml.v2", diff --git a/cmd/monexec/main.go b/cmd/monexec/main.go index fc0df45..6cd5fb0 100644 --- a/cmd/monexec/main.go +++ b/cmd/monexec/main.go @@ -1,16 +1,16 @@ package main import ( + "context" + "github.com/reddec/monexec/monexec" + "github.com/reddec/monexec/plugins" + "github.com/reddec/monexec/pool" "gopkg.in/alecthomas/kingpin.v2" "gopkg.in/yaml.v2" - "os" - "context" "log" - "github.com/reddec/monexec/monexec" + "os" "os/signal" "syscall" - "github.com/reddec/monexec/plugins" - "github.com/reddec/monexec/pool" ) var ( @@ -27,6 +27,7 @@ var ( runLabel = runCommand.Flag("label", "Label name for executable. Default - autogenerated").Short('l').String() runWorkDir = runCommand.Flag("workdir", "Workdir for executable").Short('w').String() runEnv = runCommand.Flag("env", "Environment addition variables").Short('e').StringMap() + runRawOutput = runCommand.Flag("raw", "Raw stdout without prefixes").Short('R').Bool() runConsulEnable = runCommand.Flag("consul", "Enable consul integration").Bool() runConsulAddress = runCommand.Flag("consul-address", "Consul address").Default("http://localhost:8500").String() @@ -52,6 +53,7 @@ func run() { StopTimeout: *runStopTimeout, WorkDir: *runWorkDir, Environment: *runEnv, + RawOutput: *runRawOutput, }) monexec.FillDefaultExecutable(&config.Services[0]) diff --git a/docs/index.md b/docs/index.md index e2c66b3..dc2b298 100644 --- a/docs/index.md +++ b/docs/index.md @@ -420,3 +420,16 @@ critical: ``` +# Raw stdout + +For several reasons (i.e. use in a bash tools) raw stdout is required from application. + +Since `0.1.12` to disable all prefixes in STDOUT (in STDERR they will still persists) use flag `--raw, -R`. + +**Example:** + +```bash +monexec -R echo 123 > sample.txt # run echo command. Use CTRL+C to interrupt when needed +``` + +The file `sample.txt` will now contains ONLY result of echo command (i.e. `123`) \ No newline at end of file diff --git a/pool/executable.go b/pool/executable.go index c25c3d3..974d6e4 100644 --- a/pool/executable.go +++ b/pool/executable.go @@ -1,15 +1,15 @@ package pool import ( - "time" - "os/exec" - "os" + "context" "io" "log" - "context" - "strings" + "os" + "os/exec" "path/filepath" + "strings" "sync" + "time" ) // Executable - basic information about process @@ -23,6 +23,7 @@ type Executable struct { RestartTimeout time.Duration `yaml:"restart_delay,omitempty"` // Restart delay Restart int `yaml:"restart,omitempty"` // How much restart allowed. -1 infinite LogFile string `yaml:"logFile,omitempty"` // if empty - only to log. If not absolute - relative to workdir + RawOutput bool `yaml:"raw,omitempty"` // print stdout as-is without prefixes log *log.Logger loggerInit sync.Once @@ -94,8 +95,18 @@ func (exe *Executable) run(ctx context.Context) error { setAttrs(cmd) var outputs []io.Writer + var stderr []io.Writer + var stdout []io.Writer + + output := NewLoggerStream(exe.logger(), "out:") + outputs = append(outputs, output) + defer output.Close() + stderr = outputs + stdout = outputs - outputs = append(outputs, NewLoggerStream(exe.logger(), "out:")) + if exe.RawOutput { + stdout = append(stdout, os.Stdout) + } res := make(chan error, 1) @@ -115,10 +126,11 @@ func (exe *Executable) run(ctx context.Context) error { } } - logStream := io.MultiWriter(outputs...) + logStderrStream := io.MultiWriter(stderr...) + logStdoutStream := io.MultiWriter(stdout...) - cmd.Stderr = logStream - cmd.Stdout = logStream + cmd.Stderr = logStderrStream + cmd.Stdout = logStdoutStream err := cmd.Start() if err == nil { diff --git a/pool/logger_stream.go b/pool/logger_stream.go index 13e5bb7..dffef79 100644 --- a/pool/logger_stream.go +++ b/pool/logger_stream.go @@ -9,7 +9,7 @@ type LogInterface interface { Println(v ...interface{}) } -func NewLoggerStream(logger LogInterface, prefix string) (io.WriteCloser) { +func NewLoggerStream(logger LogInterface, prefix string) io.WriteCloser { reader, writer := io.Pipe() go func() { scanner := bufio.NewReader(reader)