diff --git a/go.mod b/go.mod index 07c0ca9..e8b18f3 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/julienschmidt/httprouter v1.2.0 github.com/kr/pretty v0.1.0 // indirect github.com/mcuadros/go-defaults v1.1.0 + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee github.com/onsi/ginkgo v1.8.0 // indirect github.com/onsi/gomega v1.5.0 // indirect diff --git a/go.sum b/go.sum index a3516be..1f30294 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/mcuadros/go-defaults v1.1.0 h1:K0LgSNfsSUrbEHR7HgfZpOHVWYsPnYh/dKTA7pGeZ/I= github.com/mcuadros/go-defaults v1.1.0/go.mod h1:vl9cJiNIIHISQeboDhZBUCiCOa3GkeioLe3Y95NXF6Y= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee h1:IquUs3fIykn10zWDIyddanhpTqBvAHMaPnFhQuyYw5U= github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee/go.mod h1:eT2/Pcsim3XBjbvldGiJBvvgiqZkAFyiOJJsDKXs/ts= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/server/crash.go b/server/crash.go index 5e19b43..7b7c53c 100644 --- a/server/crash.go +++ b/server/crash.go @@ -1,6 +1,7 @@ package server import ( + "fmt" "github.com/pkg/errors" "github.com/pterodactyl/wings/config" "go.uber.org/zap" @@ -33,8 +34,10 @@ func (s *Server) handleServerCrash() error { // is no reason to do a crash detection event. If the server crash detection is // disabled we want to skip anything after this as well. if s.State != ProcessOfflineState || !s.CrashDetection.Enabled { - if s.CrashDetection.Enabled { + if !s.CrashDetection.Enabled { zap.S().Debugw("server triggered crash detection but handler is disabled for server process", zap.String("server", s.Uuid)) + + s.SendConsoleOutputFromDaemon("Server detected as crashed; crash detection is disabled for this instance.") } return nil @@ -53,10 +56,16 @@ func (s *Server) handleServerCrash() error { return nil } + s.SendConsoleOutputFromDaemon("---------- Detected server process in a crashed state! ----------") + s.SendConsoleOutputFromDaemon(fmt.Sprintf("Exit code: %d", exitCode)) + s.SendConsoleOutputFromDaemon(fmt.Sprintf("Out of memory: %t", oomKilled)) + c := s.CrashDetection.lastCrash // If the last crash time was within the last 60 seconds we do not want to perform // an automatic reboot of the process. Return an error that can be handled. if !c.IsZero() && c.Add(time.Second * 60).After(time.Now()) { + s.SendConsoleOutputFromDaemon("Aborting automatic reboot: last crash occurred less than 60 seconds ago.") + return &crashTooFrequent{} } diff --git a/server/events.go b/server/events.go index 948e6e5..58c1478 100644 --- a/server/events.go +++ b/server/events.go @@ -1,5 +1,10 @@ package server +import ( + "fmt" + "github.com/mitchellh/colorstring" +) + type EventListeners map[string][]EventListenerFunction type EventListenerFunction *func(string) @@ -8,8 +13,8 @@ type EventListenerFunction *func(string) // noinspection GoNameStartsWithPackageName const ( ConsoleOutputEvent = "console output" - StatusEvent = "status" - StatsEvent = "stats" + StatusEvent = "status" + StatsEvent = "stats" ) // Adds an event listener for the server instance. @@ -41,9 +46,18 @@ func (s *Server) RemoveListener(event string, f EventListenerFunction) { func (s *Server) Emit(event string, data string) { if _, ok := s.listeners[event]; ok { for _, handler := range s.listeners[event] { - go func (f EventListenerFunction, d string) { + go func(f EventListenerFunction, d string) { (*f)(d) }(handler, data) } } -} \ No newline at end of file +} + +// Sends output to the server console formatted to appear correctly as being sent +// from Wings. +func (s *Server) SendConsoleOutputFromDaemon(data string) { + s.Emit( + ConsoleOutputEvent, + colorstring.Color(fmt.Sprintf("[yellow][bold][Pterodactyl Daemon]:[default] %s", data)), + ) +}