Вход необработанный Golang паники - PullRequest
1 голос
/ 04 марта 2020

В моем приложении Golang есть обработчик журнала logrus. Журналы отформатированы с помощью JSONFormatter и передаются в Datadog в виде одной строки, которая объединяет их и отображает их корректно. Однако недавно я обнаружил случай, когда существует необработанный pani c, и это , а не , захваченное с помощью logrus logger. Это приводит к тому, что фактический pani c и трассировка стека распределяются по нескольким выходным строкам, которые Datadog собирает индивидуально. Это стоит нам денег и делает журналы очень трудными для чтения.

Я собираюсь исправить проблему, но в случае возникновения каких-либо дальнейших необработанных паник, я хотел бы иметь возможность захватить их с помощью logrus JSONFormatter.

Примерно так:

package main

import (
    "os"
    "sync"

    "github.com/sirupsen/logrus"
)

var (
    loggerInstance *logrus.Entry
    once           sync.Once
    logger  = GetLogger()
)

// GetLogger initializes and returns a reference to a CustomLogger object.
func GetLogger() *logrus.Entry {
    once.Do(func() {
        logrus.SetFormatter(&logrus.JSONFormatter{})

        // We'll just pipe everything to stdout. It's json so Datadog will parse the level regardless
        logrus.SetOutput(os.Stdout)
        logrus.SetLevel(logrus.TraceLevel)                            // We'll leave this as trace and just filter out logs when we index them
        loggerInstance = logrus.WithFields(logrus.Fields{"env": "local"}) // Add env tag for easy log parsing
    })
    return loggerInstance
}

func main() {
    logger.Info("Logrus using json logging")
    logger.Warn("We are about to panic")

    var things = []string{
        "hi",
        "yes",
        "thing"}

    print("%s", things[len(things)])
}

Это приводит к следующему выводу. Как видите, первые два журнала используют logrus, а необработанный pani c - нет.

{"env":"local","level":"info","msg":"Logrus using json logging","time":"2020-03-03T15:12:30-08:00"}
{"env":"local","level":"warning","msg":"We are about to panic","time":"2020-03-03T15:12:30-08:00"}
panic: runtime error: index out of range

goroutine 1 [running]:
main.main()
        /Users/nathan.deren/Library/Preferences/GoLand2019.3/scratches/scratch.go:38 +0xbe

Process finished with exit code 2

Возможно ли получить эти последние несколько строк для записи в журнал с помощью logrus?

1 Ответ

0 голосов
/ 04 марта 2020

Попробуйте recover, чтобы поймать все паники и записать их. Без этого он запишет pani c msg в stderr:

func main() {
   defer func() {
        if r := recover(); r != nil {
            logger.Errorf("Panic: %v", r)
            os.Exit(1)
        }
    }()
    // rest of main here
}
...