Перенаправить вывод паники в файл с отметкой времени в golang

Есть ли способ перенаправить вывод из паники в файл с отметкой времени для каждой паники.

Текущий пример результата файла журнала паники:

goroutine 6 [running]:
_/C_/....func·001(0x11691e80, 0x1a, 0x0, 0x0, 0x10d3550, 0x11691ec0, 0x0, 0x0)
C:/.../Logger.go:309 +0x47
path/filepath.Walk(0x11691e80, 0x1a, 0x1161defc, 0x0, 0x0)
c:/...../path.go:392 +0x97
_/C_/...../Logger.Sample(0x1168ac00, 0x59, 0x0, 0x0)
C:/...../Logger.go:322 +0x1c5
main.handleFileActions()
C:/...../main.go:453 +0x2ad
created by main.main
C:/..../main.go:278 +0x6ea

Ожидаемый результат:

2017-02-27T14:24:22.627Z - goroutine 6 [running]:
_/C_/....func·001(0x11691e80, 0x1a, 0x0, 0x0, 0x10d3550, 0x11691ec0, 0x0, 0x0)
C:/.../Logger.go:309 +0x47
path/filepath.Walk(0x11691e80, 0x1a, 0x1161defc, 0x0, 0x0)
c:/...../path.go:392 +0x97
_/C_/...../Logger.Sample(0x1168ac00, 0x59, 0x0, 0x0)
C:/...../Logger.go:322 +0x1c5
main.handleFileActions()
C:/...../main.go:453 +0x2ad
created by main.main
C:/..../main.go:278 +0x6ea

person Elad    schedule 27.02.2017    source источник
comment
Возможный дубликат Захват panic() в golang.   -  person icza    schedule 27.02.2017
comment
Я, наверное, неправильно объясняю, мне удалось зафиксировать панику, мой вопрос в том, есть ли возможность зарегистрировать панику с отметкой времени, как в примере с ожидаемым результатом, я могу поделиться своим кодом, если это необходимо.   -  person Elad    schedule 27.02.2017
comment
Если вы использовали recover(), то вы можете выполнить print(time.Now().UTC().Format("2006-01-02T15:04:05.000Z - ")) перед регистрацией паники. В противном случае я так не думаю.   -  person icza    schedule 27.02.2017
comment
Я попробую использовать recover(), спасибо.   -  person Elad    schedule 27.02.2017


Ответы (1)


В файл журнала можно добавить временную метку.

Поскольку ошибки также являются просто значениями, вы можете что-то сделать, прежде чем паниковать.

Простой пример:

var buf bytes.Buffer
logger := log.New(&buf, "logger: ", log.Ldate|log.Ltime|log.Llongfile)
logger.Print("Error when calling that code")
fmt.Print(&buf)
logger.Panic("Error")

https://play.golang.org/p/g4mweH4Dex

Здесь не стоит паниковать, как только возникает ваша ошибка. Вы можете написать дополнительную информацию в своем журнале. Например, параметры вашей функции или значения файла конфигурации.

С правильными флагами в вашем определении регистратора log.Ldate|log.Ltime|log.Llongfile вы также получите метку времени.

Отредактировано: спасибо reticentroot за комментарий о восстановлении оболочки. В статье Отсрочка, паника и восстановление описывается способ борьбы с паникой. Здесь вы можете восстановить с помощью defer.

func main() {
    myFunc()
    fmt.Print(&buf)
}

func myFunc() {
    defer func() {
        if r := recover(); r != nil {
            logger.Println("Recovered from panic: ", r)
        }
    }()
    myPanic()
}

func myPanic() {
    panic("Panicking in myPanic")
}

https://play.golang.org/p/8swGF1SoO_

person apxp    schedule 27.02.2017
comment
лучше поместите свой код выше в оболочку recovery (), чтобы OP мог поймать все паники и записать их в файл. Это распространенный шаблон для веб-серверов, но я уверен, что он будет работать и здесь. - person reticentroot; 27.02.2017
comment
Как я могу использовать приведенный выше пример, чтобы поймать все паники и записать их в файл с отметкой времени? - person Elad; 01.03.2017
comment
Я уже добавил ссылку на игровую площадку. Это логика. Внутри этого регистратора используется bytes.Buffer. Вместо печати вы можете записать вывод в файл. Вы также можете использовать другой io.Writer, который записывает прямо в файл. - person apxp; 01.03.2017