diff --git a/alt_exit.go b/alt_exit.go new file mode 100644 index 0000000..6c354ad --- /dev/null +++ b/alt_exit.go @@ -0,0 +1,60 @@ +package logrus + +// The following code was sourced and modified from the +// https://bitbucket.org/tebeka/atexit package governed by the following license: +// +// Copyright (c) 2012 Miki Tebeka . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import ( +"fmt" +"os" +) + +var handlers = []func(){} + +func runHandler(handler func()) { +defer func() { +if err := recover(); err != nil { +fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) +} +}() + +handler() +} + +func runHandlers() { +for _, handler := range handlers { +runHandler(handler) +} +} + +// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) +func Exit(code int) { +runHandlers() +os.Exit(code) +} + +// RegisterExitHandler adds a Logrus atexit handler, call logrus.Exit to invoke +// all handlers. The handlers will also be invoked when any Fatal log entry is +// made. +func RegisterExitHandler(handler func()) { +handlers = append(handlers, handler) +} + diff --git a/alt_exit_test.go b/alt_exit_test.go new file mode 100644 index 0000000..69a3b5c --- /dev/null +++ b/alt_exit_test.go @@ -0,0 +1,75 @@ +package logrus + +import ( +"os/exec" +"testing" +"io/ioutil" +"time" +) + +func TestRegister(t *testing.T) { +current := len(handlers) +RegisterExitHandler(func() {}) +if len(handlers) != current+1 { +t.Fatalf("can't add handler") +} +} + +func TestHandler(t *testing.T) { +gofile := "/tmp/testprog.go" +if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil { +t.Fatalf("can't create go file") +} + +outfile := "/tmp/testprog.out" +arg := time.Now().UTC().String() +err := exec.Command("go", "run", gofile, outfile, arg).Run() +if err == nil { +t.Fatalf("completed normally, should have failed") +} + +data, err := ioutil.ReadFile(outfile) +if err != nil { +t.Fatalf("can't read output file %s", outfile) +} + +if string(data) != arg { +t.Fatalf("bad data") +} +} + +var testprog = []byte(` +// Test program for atexit, gets output file and data as arguments and writes +// data to output file in atexit handler. +package main + +import ( + "github.com/powerchordinc/logrus" + "flag" + "fmt" + "io/ioutil" +) + +var outfile = "" +var data = "" + +func handler() { + ioutil.WriteFile(outfile, []byte(data), 0666) +} + +func badHandler() { + n := 0 + fmt.Println(1/n) +} + +func main() { + flag.Parse() + outfile = flag.Arg(0) + data = flag.Arg(1) + + logrus.RegisterExitHandler(handler) + logrus.RegisterExitHandler(badHandler) + logrus.Fatal("Bye bye") +} +`) + diff --git a/entry.go b/entry.go index 89e966e..54bfc57 100644 --- a/entry.go +++ b/entry.go @@ -150,7 +150,7 @@ func (entry *Entry) Fatal(args ...interface{}) { if entry.Logger.Level >= FatalLevel { entry.log(FatalLevel, fmt.Sprint(args...)) } - os.Exit(1) + Exit(1) } func (entry *Entry) Panic(args ...interface{}) { @@ -198,7 +198,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) { if entry.Logger.Level >= FatalLevel { entry.Fatal(fmt.Sprintf(format, args...)) } - os.Exit(1) + Exit(1) } func (entry *Entry) Panicf(format string, args ...interface{}) { @@ -245,7 +245,7 @@ func (entry *Entry) Fatalln(args ...interface{}) { if entry.Logger.Level >= FatalLevel { entry.Fatal(entry.sprintlnn(args...)) } - os.Exit(1) + Exit(1) } func (entry *Entry) Panicln(args ...interface{}) { diff --git a/logger.go b/logger.go index 2fdb231..90c46e6 100644 --- a/logger.go +++ b/logger.go @@ -108,7 +108,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) { if logger.Level >= FatalLevel { NewEntry(logger).Fatalf(format, args...) } - os.Exit(1) + Exit(1) } func (logger *Logger) Panicf(format string, args ...interface{}) { @@ -155,7 +155,7 @@ func (logger *Logger) Fatal(args ...interface{}) { if logger.Level >= FatalLevel { NewEntry(logger).Fatal(args...) } - os.Exit(1) + Exit(1) } func (logger *Logger) Panic(args ...interface{}) { @@ -202,7 +202,7 @@ func (logger *Logger) Fatalln(args ...interface{}) { if logger.Level >= FatalLevel { NewEntry(logger).Fatalln(args...) } - os.Exit(1) + Exit(1) } func (logger *Logger) Panicln(args ...interface{}) {