Логический вывод неверен.Логрус на самом деле не знает, как справиться с ошибкой. Обновление Представитель команды Logrus сказал, что это НЕ поддерживаемая функция, https://github.com/sirupsen/logrus/issues/895#issuecomment-457656556.
Ответ Java-ish Для универсальной работы с ошибкойТаким образом, для обработчиков я составил новую версию Entry, которая принадлежит Logrus.Как показано в примере, создайте новую запись с какими-либо общими полями, которые вы хотите (ниже примера - регистратор, установленный в обработчике, который отслеживает идентификатор вызывающего абонента. Пропускайте PgkError через ваши слои, когда вы работаете с записью. Когда вам нужнорегистрируйте конкретные ошибки, например переменные вызова, в которых произошла ошибка, начните с PkgError.WithError (...), затем добавьте свои данные.
Это отправная точка. Если вы хотите использовать это в общем, реализуйте всеинтерфейс Entity на PkgErrorEntry. Продолжайте делегировать внутреннюю запись, но верните новый PkgErrorEntry. Такое изменение приведет к тому, что значение будет заменено на Entry.
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"strings"
unwrappedErrors "errors"
"github.com/pkg/errors"
)
// PkgErrorEntry enables stack frame extraction directly into the log fields.
type PkgErrorEntry struct {
*logrus.Entry
// Depth defines how much of the stacktrace you want.
Depth int
}
// This is dirty pkg/errors.
type stackTracer interface {
StackTrace() errors.StackTrace
}
func (e *PkgErrorEntry) WithError(err error) *logrus.Entry {
out := e.Entry
common := func(pError stackTracer) {
st := pError.StackTrace()
depth := 3
if e.Depth != 0 {
depth = e.Depth
}
valued := fmt.Sprintf("%+v", st[0:depth])
valued = strings.Replace(valued, "\t", "", -1)
stack := strings.Split(valued, "\n")
out = out.WithField("stack", stack[2:])
}
if err2, ok := err.(stackTracer); ok {
common(err2)
}
if err2, ok := errors.Cause(err).(stackTracer); ok {
common(err2)
}
return out.WithError(err)
}
func someWhereElse() error {
return unwrappedErrors.New("Ouch")
}
func level1() error {
return level2()
}
func level2() error {
return errors.WithStack(unwrappedErrors.New("All wrapped up"))
}
func main() {
baseLog := logrus.New()
baseLog.SetFormatter(&logrus.JSONFormatter{})
errorHandling := PkgErrorEntry{Entry: baseLog.WithField("callerid", "1000")}
errorHandling.Info("Hello")
err := errors.New("Hi")
errorHandling.WithError(err).Error("That should have a stack.")
err = someWhereElse()
errorHandling.WithError(err).Info("Less painful error")
err = level1()
errorHandling.WithError(err).Warn("Should have multiple layers of stack")
}
A Gopher-ishway См. https://www.reddit.com/r/golang/comments/ajby88/how_to_get_stack_traces_in_logrus/ для получения более подробной информации.
Бен Джонсон написал о том, как сделать ошибки частью вашего домена. Сокращенная версия заключается в том, что вы должны поместить атрибуты трассировщика вПользовательская ошибка. Когда код находится под вашим контролем или когда происходит ошибка из сторонней библиотеки, код immediaЕсли вы решите проблему с ошибкой, в пользовательскую ошибку должно быть включено уникальное значение.Это значение будет напечатано как часть реализации пользовательской ошибки Error() string
.
Когда разработчики получат файл журнала, они смогут найти базу кода для этого уникального значения.Бен говорит: «Наконец, мы должны быть в состоянии предоставить всю эту информацию, а также трассировку логического стека нашему оператору, чтобы они могли отлаживать проблемы. Go уже предоставляет простой метод error.Error () для вывода информации об ошибках, чтобы мы могли использоватьthat. "
Вот пример Бена
// attachRole inserts a role record for a user in the database
func (s *UserService) attachRole(ctx context.Context, id int, role string) error {
const op = "attachRole"
if _, err := s.db.Exec(`INSERT roles...`); err != nil {
return &myapp.Error{Op: op, Err: err}
}
return nil
}
Проблема, с которой я столкнулся с grep-способным кодом, заключается в том, что значение легко отклоняется от исходного контекста.Например, скажем, имя функции было изменено с attachRole на что-то другое, и функция стала длиннее.Возможно, что значение операции может отличаться от имени функции.В любом случае это, по-видимому, удовлетворяет общую потребность в поиске проблемы, в то же время обрабатывая ошибки, с которыми сталкиваются граждане первого сорта.Оставайтесь в курсе.https://go.googlesource.com/proposal/+/refs/changes/97/159497/3/design/XXXXX-error-values.md