From 78f353d9f27396915ab1075f51dd888dc82291fe Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 10 May 2022 14:06:58 +0200 Subject: [PATCH 01/10] Vagrantfile: add dev box --- Vagrantfile | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Vagrantfile b/Vagrantfile index 76175a04d87..c1bd83ca121 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -129,4 +129,43 @@ Vagrant.configure("2") do |config| end end + config.vm.define "dev" do |nodeconfig| + nodeconfig.vm.box = "ubuntu/impish64" + + nodeconfig.vm.hostname = "elastic-agent-dev" + + nodeconfig.vm.network "private_network", + hostname: true, + ip: "192.168.56.42" # only 192.168.56.0/21 range allowed: https://www.virtualbox.org/manual/ch06.html#network_hostonly + nodeconfig.vm.network "forwarded_port", + guest: 4242, + host: 4242, + id: "delve" + + nodeconfig.vm.provider "virtualbox" do |vb| + # Display the VirtualBox GUI when booting the machine + vb.gui = false + vb.customize ["modifyvm", :id, "--vram", "128"] + # Customize the amount of memory on the VM: + vb.memory = "2048" + end + + nodeconfig.vm.provision "shell", inline: <<-SHELL + apt-get update + apt-get install -y \ + build-essential \ + curl \ + delve \ + make \ + unzip + vim \ + wget + curl -sL -o /tmp/go#{GO_VERSION}.linux-amd64.tar.gz https://go.dev/dl/go#{GO_VERSION}.linux-amd64.tar.gz + tar -C /usr/local -xzf /tmp/go#{GO_VERSION}.linux-amd64.tar.gz + echo "alias ll='ls -la'" > /etc/profile.d/ll.sh + echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/go.sh + echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> /etc/profile.d/go.sh + SHELL + end + end From 8f246aa4f916b22616c995f4b61059bd398a122e Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 11 May 2022 10:19:05 +0200 Subject: [PATCH 02/10] so far so good --- internal/pkg/core/plugin/process/start.go | 51 ++++++++++++++++++++++- internal/pkg/core/process/process.go | 25 +++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/internal/pkg/core/plugin/process/start.go b/internal/pkg/core/plugin/process/start.go index db451bf23b8..2df59859c2f 100644 --- a/internal/pkg/core/plugin/process/start.go +++ b/internal/pkg/core/plugin/process/start.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "io" + "os/exec" "path/filepath" "gopkg.in/yaml.v2" @@ -19,6 +20,7 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/core/app" "github.com/elastic/elastic-agent/internal/pkg/core/process" "github.com/elastic/elastic-agent/internal/pkg/core/state" + "github.com/elastic/elastic-agent/pkg/core/logger" "github.com/elastic/elastic-agent/pkg/core/server" ) @@ -30,6 +32,50 @@ func (a *Application) Start(ctx context.Context, t app.Taggable, cfg map[string] return a.start(ctx, t, cfg, false) } +type logStd int + +const ( + logStdOut logStd = iota + logStdErr +) + +func (l logStd) String() string { + switch l { + case logStdOut: + return "stdout" + case logStdErr: + return "stderr" + } + + return "unknown" +} + +type logWriter struct { + format string + logf func(format string, args ...interface{}) +} + +func newLogWriter(appName string, std logStd, log *logger.Logger) logWriter { + log = log.With( + "agent.console.name", appName, + "agent.console.type", std.String()) + + logf := log.Infof + if std == logStdErr { + logf = log.Errorf + } + + return logWriter{ + format: appName + " " + std.String() + ": %q", + logf: logf, + } +} + +func (l logWriter) Write(p []byte) (n int, err error) { + l.logf(l.format, string(p)) + return len(p), nil +} + // Start starts the application without grabbing the lock. func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string]interface{}, isRestart bool) (err error) { defer func() { @@ -132,7 +178,10 @@ func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string] a.processConfig, a.uid, a.gid, - spec.Args) + spec.Args, func(c *exec.Cmd) { + c.Stdout = newLogWriter(a.Name(), logStdOut, a.logger) + c.Stderr = newLogWriter(a.Name(), logStdErr, a.logger) + }) if err != nil { return fmt.Errorf("%q failed to start %q: %w", a.Name(), spec.BinaryPath, err) diff --git a/internal/pkg/core/process/process.go b/internal/pkg/core/process/process.go index 65613fb9978..a98482cea98 100644 --- a/internal/pkg/core/process/process.go +++ b/internal/pkg/core/process/process.go @@ -31,21 +31,38 @@ type Info struct { // Option is an option func to change the underlying command type Option func(c *exec.Cmd) -// Start starts a new process +// Start starts a new process. Pass in opts to change the underlying command. // Returns: // - network address of child process // - process id // - error -func Start(logger *logger.Logger, path string, config *Config, uid, gid int, args []string, opts ...Option) (proc *Info, err error) { +func Start( + logger *logger.Logger, + path string, + config *Config, + uid, + gid int, + args []string, + opts ...Option) (proc *Info, err error) { return StartContext(nil, logger, path, config, uid, gid, args, opts...) //nolint:staticcheck // calls a different function if no ctx } -// StartContext starts a new process with context. +// StartContext starts a new process with context. Pass in opts to change +// the underlying command. // Returns: // - network address of child process // - process id // - error -func StartContext(ctx context.Context, logger *logger.Logger, path string, config *Config, uid, gid int, args []string, opts ...Option) (*Info, error) { +func StartContext( + ctx context.Context, + logger *logger.Logger, + path string, + config *Config, + uid, + gid int, + args []string, + opts ...Option) (*Info, error) { + cmd := getCmd(ctx, logger, path, []string{}, uid, gid, args...) for _, o := range opts { o(cmd) From cf4b6dcf066918cff2b4ef7b0462ef17f92f460e Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 13 May 2022 11:17:06 +0200 Subject: [PATCH 03/10] tidy up and tests --- internal/pkg/core/plugin/process/start.go | 49 +------------- internal/pkg/core/plugin/process/stdlogger.go | 52 +++++++++++++++ .../pkg/core/plugin/process/stdlogger_test.go | 64 +++++++++++++++++++ pkg/core/logger/logger_test.go | 11 ---- pkg/core/logger/testing.go | 21 ++++++ 5 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 internal/pkg/core/plugin/process/stdlogger.go create mode 100644 internal/pkg/core/plugin/process/stdlogger_test.go delete mode 100644 pkg/core/logger/logger_test.go create mode 100644 pkg/core/logger/testing.go diff --git a/internal/pkg/core/plugin/process/start.go b/internal/pkg/core/plugin/process/start.go index 2df59859c2f..29770ae714b 100644 --- a/internal/pkg/core/plugin/process/start.go +++ b/internal/pkg/core/plugin/process/start.go @@ -20,7 +20,6 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/core/app" "github.com/elastic/elastic-agent/internal/pkg/core/process" "github.com/elastic/elastic-agent/internal/pkg/core/state" - "github.com/elastic/elastic-agent/pkg/core/logger" "github.com/elastic/elastic-agent/pkg/core/server" ) @@ -32,50 +31,6 @@ func (a *Application) Start(ctx context.Context, t app.Taggable, cfg map[string] return a.start(ctx, t, cfg, false) } -type logStd int - -const ( - logStdOut logStd = iota - logStdErr -) - -func (l logStd) String() string { - switch l { - case logStdOut: - return "stdout" - case logStdErr: - return "stderr" - } - - return "unknown" -} - -type logWriter struct { - format string - logf func(format string, args ...interface{}) -} - -func newLogWriter(appName string, std logStd, log *logger.Logger) logWriter { - log = log.With( - "agent.console.name", appName, - "agent.console.type", std.String()) - - logf := log.Infof - if std == logStdErr { - logf = log.Errorf - } - - return logWriter{ - format: appName + " " + std.String() + ": %q", - logf: logf, - } -} - -func (l logWriter) Write(p []byte) (n int, err error) { - l.logf(l.format, string(p)) - return len(p), nil -} - // Start starts the application without grabbing the lock. func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string]interface{}, isRestart bool) (err error) { defer func() { @@ -179,8 +134,8 @@ func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string] a.uid, a.gid, spec.Args, func(c *exec.Cmd) { - c.Stdout = newLogWriter(a.Name(), logStdOut, a.logger) - c.Stderr = newLogWriter(a.Name(), logStdErr, a.logger) + c.Stdout = newLoggerWriter(a.Name(), logStdOut, a.logger) + c.Stderr = newLoggerWriter(a.Name(), logStdErr, a.logger) }) if err != nil { return fmt.Errorf("%q failed to start %q: %w", diff --git a/internal/pkg/core/plugin/process/stdlogger.go b/internal/pkg/core/plugin/process/stdlogger.go new file mode 100644 index 00000000000..852205f8ded --- /dev/null +++ b/internal/pkg/core/plugin/process/stdlogger.go @@ -0,0 +1,52 @@ +package process + +import ( + "github.com/elastic/elastic-agent/pkg/core/logger" +) + +type logStd int + +const ( + agentConsoleName = "agent.console.name" + agentConsoleType = "agent.console.type" + + logStdOut logStd = iota + logStdErr +) + +func (l logStd) String() string { + switch l { + case logStdOut: + return "stdout" + case logStdErr: + return "stderr" + } + + return "unknown" +} + +type loggerWriter struct { + format string + logf func(format string, args ...interface{}) +} + +func newLoggerWriter(appName string, std logStd, log *logger.Logger) loggerWriter { + log = log.With( + agentConsoleName, appName, + agentConsoleType, std.String()) + + logf := log.Infof + if std == logStdErr { + logf = log.Errorf + } + + return loggerWriter{ + format: appName + " " + std.String() + ": %q", + logf: logf, + } +} + +func (l loggerWriter) Write(p []byte) (n int, err error) { + l.logf(l.format, string(p)) + return len(p), nil +} diff --git a/internal/pkg/core/plugin/process/stdlogger_test.go b/internal/pkg/core/plugin/process/stdlogger_test.go new file mode 100644 index 00000000000..6fb67a5bd7b --- /dev/null +++ b/internal/pkg/core/plugin/process/stdlogger_test.go @@ -0,0 +1,64 @@ +package process + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/elastic/elastic-agent/pkg/core/logger" +) + +func Test_loggerWriter(t *testing.T) { + tc := []struct { + name string + args struct { + appName string + logTo logStd + } + logMsg string + logLevel zapcore.Level + }{ + {name: "capture stdout", + args: struct { + appName string + logTo logStd + }{ + appName: "somebeats", + logTo: logStdOut, + }, + logMsg: "stdout log", + logLevel: zapcore.InfoLevel, + }, + {name: "capture stderr", + args: struct { + appName string + logTo logStd + }{ + appName: "somebeats", + logTo: logStdErr, + }, + logMsg: "stderr log", + logLevel: zapcore.ErrorLevel, + }, + } + + for _, tt := range tc { + logg, obs := logger.NewTesting("test-loggerWriter") + logg = logg.With("previous-field", "previous-value") + + l := newLoggerWriter(tt.args.appName, tt.args.logTo, logg) + _, _ = l.Write([]byte(tt.logMsg)) + + logs := obs.All() + require.Equal(t, 1, len(logs)) + + log := logs[0] + assert.Equal(t, log.Level, tt.logLevel) + assert.Contains(t, log.Message, tt.logMsg) + assert.Equal(t, log.ContextMap()[agentConsoleName], tt.args.appName) + assert.Equal(t, log.ContextMap()[agentConsoleType], tt.args.logTo.String()) + assert.Equal(t, log.ContextMap()["previous-field"], "previous-value") + } +} diff --git a/pkg/core/logger/logger_test.go b/pkg/core/logger/logger_test.go deleted file mode 100644 index ff9179081b9..00000000000 --- a/pkg/core/logger/logger_test.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -package logger - -import "testing" - -func TestLogger(t *testing.T) { - t.Skip("only checking if test works") -} diff --git a/pkg/core/logger/testing.go b/pkg/core/logger/testing.go new file mode 100644 index 00000000000..0436bf2bc2f --- /dev/null +++ b/pkg/core/logger/testing.go @@ -0,0 +1,21 @@ +package logger + +import ( + "github.com/elastic/elastic-agent-libs/logp" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" +) + +// NewTesting creates a testing logger that buffers the logs in memory and +// logs in debug level. Check observer.ObservedLogs for more details. +func NewTesting(name string) (*Logger, *observer.ObservedLogs) { + core, obs := observer.New(zapcore.DebugLevel) + + logger := logp.NewLogger( + name, + zap.WrapCore(func(in zapcore.Core) zapcore.Core { + return zapcore.NewTee(in, core) + })) + return logger, obs +} From aa93af8b2770f8c106226e24793f90d21c3fe50d Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 13 May 2022 18:29:45 +0200 Subject: [PATCH 04/10] wip --- internal/pkg/agent/control/client/client.go | 4 ++-- internal/pkg/core/plugin/process/configure.go | 2 +- internal/pkg/core/plugin/process/start.go | 2 ++ internal/pkg/core/plugin/process/status.go | 22 ++++++++++++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/internal/pkg/agent/control/client/client.go b/internal/pkg/agent/control/client/client.go index 095d6f3a459..8a40143ff94 100644 --- a/internal/pkg/agent/control/client/client.go +++ b/internal/pkg/agent/control/client/client.go @@ -8,7 +8,6 @@ import ( "context" "encoding/json" "fmt" - "sync" "time" @@ -44,7 +43,8 @@ type Version struct { Snapshot bool } -// ApplicationStatus is a status of an application inside of Elastic Agent. +// ApplicationStatus is a status of an application managed by the Elastic Agent. +// TODO(Anderson): Implement sort.Interface and sort it. type ApplicationStatus struct { ID string Name string diff --git a/internal/pkg/core/plugin/process/configure.go b/internal/pkg/core/plugin/process/configure.go index b80697fd2a5..57f12e191de 100644 --- a/internal/pkg/core/plugin/process/configure.go +++ b/internal/pkg/core/plugin/process/configure.go @@ -51,7 +51,7 @@ func (a *Application) Configure(ctx context.Context, config map[string]interface a.appLock.Unlock() a.Stop() err = a.Start(ctx, a.desc, config) - // lock back so it wont panic on deferred unlock + // lock back so it won't panic on deferred unlock a.appLock.Lock() } diff --git a/internal/pkg/core/plugin/process/start.go b/internal/pkg/core/plugin/process/start.go index 29770ae714b..ffbd779f034 100644 --- a/internal/pkg/core/plugin/process/start.go +++ b/internal/pkg/core/plugin/process/start.go @@ -50,6 +50,8 @@ func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string] // in case app reported status it might still be running and failure timer // in progress. Stop timer and stop failing process + a.logger.Infof("%s is started and state != %s. Stopping failed timer", + a.Name(), state.Restarting.ToProto().String()) a.stopFailedTimer() a.stopWatcher(a.state.ProcessInfo) diff --git a/internal/pkg/core/plugin/process/status.go b/internal/pkg/core/plugin/process/status.go index 92883160398..aa3b2478d61 100644 --- a/internal/pkg/core/plugin/process/status.go +++ b/internal/pkg/core/plugin/process/status.go @@ -60,10 +60,21 @@ func (a *Application) startFailedTimer(cfg map[string]interface{}, proc *process return } + // (AndersonQ) the context is getting cancelled, a.restart is never called. + // After putting the log below I can see it being logged on the 2nd failure. + // This context is cancelled, it should not be reused. However, I'm not seeing + // a.restartCanceller() being called. I added a log before it and the log does not appear. + // Perhaps a.startContext parent's context gets cancelled... + if err := a.startContext.Err(); err != nil { + a.logger.Warnf("a.startContext is done: %v. %s will never restart", + err, a.Name()) + } ctx, cancel := context.WithCancel(a.startContext) a.restartCanceller = cancel a.restartConfig = cfg t := time.NewTimer(a.processConfig.FailureTimeout) + a.logger.Warnf("started a %s failed timer for %s, PID: %d", + a.processConfig.FailureTimeout, a.name, proc.PID) go func() { defer func() { a.appLock.Lock() @@ -72,10 +83,15 @@ func (a *Application) startFailedTimer(cfg map[string]interface{}, proc *process a.appLock.Unlock() }() + a.logger.Infof("waiting on failed timer for %s, PID: %d", a.name, proc.PID) select { case <-ctx.Done(): + a.logger.Infof("%s: failed timer cancelled, PID: %d. ctx: %v", + a.name, proc.PID, ctx.Err()) return case <-t.C: + a.logger.Warnf("invoking a.restart for %s, PID: %d", + a.name, proc.PID) a.restart(proc) } }() @@ -88,6 +104,7 @@ func (a *Application) stopFailedTimer() { if a.restartCanceller == nil { return } + a.logger.Infof("cancelling %s failed timer", a.Name()) a.restartCanceller() a.restartCanceller = nil } @@ -97,12 +114,15 @@ func (a *Application) restart(proc *process.Info) { a.appLock.Lock() defer a.appLock.Unlock() + a.logger.Warnf("restarting %s, PID %d", a.Name(), proc.PID) // stop the watcher a.stopWatcher(proc) // kill the process if proc != nil && proc.Process != nil { - _ = proc.Process.Kill() + if err := proc.Process.Kill(); err != nil { + a.logger.Infof("could not kill %s:%d: %v", a.name, proc.PID, err) + } } if proc != a.state.ProcessInfo { From 62bb6e81e2e00670a3545d9e6f75003e7da6edbd Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 20 May 2022 11:21:30 +0200 Subject: [PATCH 05/10] remove debug --- internal/pkg/core/plugin/process/start.go | 2 -- internal/pkg/core/plugin/process/status.go | 24 +--------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/internal/pkg/core/plugin/process/start.go b/internal/pkg/core/plugin/process/start.go index ffbd779f034..29770ae714b 100644 --- a/internal/pkg/core/plugin/process/start.go +++ b/internal/pkg/core/plugin/process/start.go @@ -50,8 +50,6 @@ func (a *Application) start(ctx context.Context, t app.Taggable, cfg map[string] // in case app reported status it might still be running and failure timer // in progress. Stop timer and stop failing process - a.logger.Infof("%s is started and state != %s. Stopping failed timer", - a.Name(), state.Restarting.ToProto().String()) a.stopFailedTimer() a.stopWatcher(a.state.ProcessInfo) diff --git a/internal/pkg/core/plugin/process/status.go b/internal/pkg/core/plugin/process/status.go index aa3b2478d61..8e9f49f5d8b 100644 --- a/internal/pkg/core/plugin/process/status.go +++ b/internal/pkg/core/plugin/process/status.go @@ -60,21 +60,10 @@ func (a *Application) startFailedTimer(cfg map[string]interface{}, proc *process return } - // (AndersonQ) the context is getting cancelled, a.restart is never called. - // After putting the log below I can see it being logged on the 2nd failure. - // This context is cancelled, it should not be reused. However, I'm not seeing - // a.restartCanceller() being called. I added a log before it and the log does not appear. - // Perhaps a.startContext parent's context gets cancelled... - if err := a.startContext.Err(); err != nil { - a.logger.Warnf("a.startContext is done: %v. %s will never restart", - err, a.Name()) - } ctx, cancel := context.WithCancel(a.startContext) a.restartCanceller = cancel a.restartConfig = cfg t := time.NewTimer(a.processConfig.FailureTimeout) - a.logger.Warnf("started a %s failed timer for %s, PID: %d", - a.processConfig.FailureTimeout, a.name, proc.PID) go func() { defer func() { a.appLock.Lock() @@ -83,15 +72,10 @@ func (a *Application) startFailedTimer(cfg map[string]interface{}, proc *process a.appLock.Unlock() }() - a.logger.Infof("waiting on failed timer for %s, PID: %d", a.name, proc.PID) select { case <-ctx.Done(): - a.logger.Infof("%s: failed timer cancelled, PID: %d. ctx: %v", - a.name, proc.PID, ctx.Err()) return case <-t.C: - a.logger.Warnf("invoking a.restart for %s, PID: %d", - a.name, proc.PID) a.restart(proc) } }() @@ -104,7 +88,6 @@ func (a *Application) stopFailedTimer() { if a.restartCanceller == nil { return } - a.logger.Infof("cancelling %s failed timer", a.Name()) a.restartCanceller() a.restartCanceller = nil } @@ -114,16 +97,11 @@ func (a *Application) restart(proc *process.Info) { a.appLock.Lock() defer a.appLock.Unlock() - a.logger.Warnf("restarting %s, PID %d", a.Name(), proc.PID) // stop the watcher a.stopWatcher(proc) // kill the process - if proc != nil && proc.Process != nil { - if err := proc.Process.Kill(); err != nil { - a.logger.Infof("could not kill %s:%d: %v", a.name, proc.PID, err) - } - } + _ = proc.Process.Kill() if proc != a.state.ProcessInfo { // we're restarting different process than actually running From 11d8f48089cbf744ae0f0e4c909633e7bb0cfcec Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 20 May 2022 11:26:28 +0200 Subject: [PATCH 06/10] remove unrelated changes --- Vagrantfile | 39 ---------------------------- internal/pkg/core/process/process.go | 25 +++--------------- 2 files changed, 4 insertions(+), 60 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index c1bd83ca121..76175a04d87 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -129,43 +129,4 @@ Vagrant.configure("2") do |config| end end - config.vm.define "dev" do |nodeconfig| - nodeconfig.vm.box = "ubuntu/impish64" - - nodeconfig.vm.hostname = "elastic-agent-dev" - - nodeconfig.vm.network "private_network", - hostname: true, - ip: "192.168.56.42" # only 192.168.56.0/21 range allowed: https://www.virtualbox.org/manual/ch06.html#network_hostonly - nodeconfig.vm.network "forwarded_port", - guest: 4242, - host: 4242, - id: "delve" - - nodeconfig.vm.provider "virtualbox" do |vb| - # Display the VirtualBox GUI when booting the machine - vb.gui = false - vb.customize ["modifyvm", :id, "--vram", "128"] - # Customize the amount of memory on the VM: - vb.memory = "2048" - end - - nodeconfig.vm.provision "shell", inline: <<-SHELL - apt-get update - apt-get install -y \ - build-essential \ - curl \ - delve \ - make \ - unzip - vim \ - wget - curl -sL -o /tmp/go#{GO_VERSION}.linux-amd64.tar.gz https://go.dev/dl/go#{GO_VERSION}.linux-amd64.tar.gz - tar -C /usr/local -xzf /tmp/go#{GO_VERSION}.linux-amd64.tar.gz - echo "alias ll='ls -la'" > /etc/profile.d/ll.sh - echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/go.sh - echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> /etc/profile.d/go.sh - SHELL - end - end diff --git a/internal/pkg/core/process/process.go b/internal/pkg/core/process/process.go index a98482cea98..65613fb9978 100644 --- a/internal/pkg/core/process/process.go +++ b/internal/pkg/core/process/process.go @@ -31,38 +31,21 @@ type Info struct { // Option is an option func to change the underlying command type Option func(c *exec.Cmd) -// Start starts a new process. Pass in opts to change the underlying command. +// Start starts a new process // Returns: // - network address of child process // - process id // - error -func Start( - logger *logger.Logger, - path string, - config *Config, - uid, - gid int, - args []string, - opts ...Option) (proc *Info, err error) { +func Start(logger *logger.Logger, path string, config *Config, uid, gid int, args []string, opts ...Option) (proc *Info, err error) { return StartContext(nil, logger, path, config, uid, gid, args, opts...) //nolint:staticcheck // calls a different function if no ctx } -// StartContext starts a new process with context. Pass in opts to change -// the underlying command. +// StartContext starts a new process with context. // Returns: // - network address of child process // - process id // - error -func StartContext( - ctx context.Context, - logger *logger.Logger, - path string, - config *Config, - uid, - gid int, - args []string, - opts ...Option) (*Info, error) { - +func StartContext(ctx context.Context, logger *logger.Logger, path string, config *Config, uid, gid int, args []string, opts ...Option) (*Info, error) { cmd := getCmd(ctx, logger, path, []string{}, uid, gid, args...) for _, o := range opts { o(cmd) From 58d6240293e121d14e658cdc8858fa2e62bf2f23 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 20 May 2022 12:07:30 +0200 Subject: [PATCH 07/10] changelog --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index d71f940248d..82f9cfee9b5 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -101,6 +101,7 @@ - Add fleet-server to output of elastic-agent inspect output command (and diagnostic bundle). {pull}243[243] - Update API calls that the agent makes to Kibana when running the container command. {pull}253[253] - diagnostics collect log names are fixed on Windows machines, command will ignore failures. AgentID is included in diagnostics(and diagnostics collect) output. {issue}81[81] {issue}92[92] {issue}190[190] {pull}262[262] +- Collects stdout and stderr of applications run as a process and logs them. {issue}[88] ==== New features From 6a166d33b1a35b4a7dee183facfa0d2f72ace3b0 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 20 May 2022 15:01:54 +0200 Subject: [PATCH 08/10] Vagrantfile --- Vagrantfile | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Vagrantfile b/Vagrantfile index 76175a04d87..c1bd83ca121 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -129,4 +129,43 @@ Vagrant.configure("2") do |config| end end + config.vm.define "dev" do |nodeconfig| + nodeconfig.vm.box = "ubuntu/impish64" + + nodeconfig.vm.hostname = "elastic-agent-dev" + + nodeconfig.vm.network "private_network", + hostname: true, + ip: "192.168.56.42" # only 192.168.56.0/21 range allowed: https://www.virtualbox.org/manual/ch06.html#network_hostonly + nodeconfig.vm.network "forwarded_port", + guest: 4242, + host: 4242, + id: "delve" + + nodeconfig.vm.provider "virtualbox" do |vb| + # Display the VirtualBox GUI when booting the machine + vb.gui = false + vb.customize ["modifyvm", :id, "--vram", "128"] + # Customize the amount of memory on the VM: + vb.memory = "2048" + end + + nodeconfig.vm.provision "shell", inline: <<-SHELL + apt-get update + apt-get install -y \ + build-essential \ + curl \ + delve \ + make \ + unzip + vim \ + wget + curl -sL -o /tmp/go#{GO_VERSION}.linux-amd64.tar.gz https://go.dev/dl/go#{GO_VERSION}.linux-amd64.tar.gz + tar -C /usr/local -xzf /tmp/go#{GO_VERSION}.linux-amd64.tar.gz + echo "alias ll='ls -la'" > /etc/profile.d/ll.sh + echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/go.sh + echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> /etc/profile.d/go.sh + SHELL + end + end From 7396cb4c24b7b1078a59b26738295ce2182c14d8 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 20 May 2022 17:47:45 +0200 Subject: [PATCH 09/10] pr changes --- internal/pkg/core/plugin/process/status.go | 4 +++- internal/pkg/core/plugin/process/stdlogger_test.go | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/pkg/core/plugin/process/status.go b/internal/pkg/core/plugin/process/status.go index 8e9f49f5d8b..92883160398 100644 --- a/internal/pkg/core/plugin/process/status.go +++ b/internal/pkg/core/plugin/process/status.go @@ -101,7 +101,9 @@ func (a *Application) restart(proc *process.Info) { a.stopWatcher(proc) // kill the process - _ = proc.Process.Kill() + if proc != nil && proc.Process != nil { + _ = proc.Process.Kill() + } if proc != a.state.ProcessInfo { // we're restarting different process than actually running diff --git a/internal/pkg/core/plugin/process/stdlogger_test.go b/internal/pkg/core/plugin/process/stdlogger_test.go index 6fb67a5bd7b..142625c4662 100644 --- a/internal/pkg/core/plugin/process/stdlogger_test.go +++ b/internal/pkg/core/plugin/process/stdlogger_test.go @@ -20,7 +20,8 @@ func Test_loggerWriter(t *testing.T) { logMsg string logLevel zapcore.Level }{ - {name: "capture stdout", + { + name: "capture stdout", args: struct { appName string logTo logStd @@ -31,7 +32,8 @@ func Test_loggerWriter(t *testing.T) { logMsg: "stdout log", logLevel: zapcore.InfoLevel, }, - {name: "capture stderr", + { + name: "capture stderr", args: struct { appName string logTo logStd From 278013194af3762f938385ad501a025d9126e485 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 20 May 2022 15:01:54 +0200 Subject: [PATCH 10/10] Revert "Vagrantfile" This reverts commit 6a166d33b1a35b4a7dee183facfa0d2f72ace3b0. --- Vagrantfile | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index c1bd83ca121..76175a04d87 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -129,43 +129,4 @@ Vagrant.configure("2") do |config| end end - config.vm.define "dev" do |nodeconfig| - nodeconfig.vm.box = "ubuntu/impish64" - - nodeconfig.vm.hostname = "elastic-agent-dev" - - nodeconfig.vm.network "private_network", - hostname: true, - ip: "192.168.56.42" # only 192.168.56.0/21 range allowed: https://www.virtualbox.org/manual/ch06.html#network_hostonly - nodeconfig.vm.network "forwarded_port", - guest: 4242, - host: 4242, - id: "delve" - - nodeconfig.vm.provider "virtualbox" do |vb| - # Display the VirtualBox GUI when booting the machine - vb.gui = false - vb.customize ["modifyvm", :id, "--vram", "128"] - # Customize the amount of memory on the VM: - vb.memory = "2048" - end - - nodeconfig.vm.provision "shell", inline: <<-SHELL - apt-get update - apt-get install -y \ - build-essential \ - curl \ - delve \ - make \ - unzip - vim \ - wget - curl -sL -o /tmp/go#{GO_VERSION}.linux-amd64.tar.gz https://go.dev/dl/go#{GO_VERSION}.linux-amd64.tar.gz - tar -C /usr/local -xzf /tmp/go#{GO_VERSION}.linux-amd64.tar.gz - echo "alias ll='ls -la'" > /etc/profile.d/ll.sh - echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/go.sh - echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> /etc/profile.d/go.sh - SHELL - end - end