Golang OpenTelemetry: span.SetStatus не записывает ошибку?
Нет, метод span.SetStatus
не записывает саму ошибку, а только устанавливает общий статус спана. Если вам нужно сохранить подробности об ошибке (например, текст сообщения или стек-трейс), то для этого используется метод span.RecordError
.
Различия между span.RecordError
и span.SetStatus
Метод | Что делает | Пример использования |
---|---|---|
span.RecordError |
Записывает ошибку как событие в Span с атрибутами типа ошибки, сообщения и (опционально) стека. |
Для логирования ошибок, включая их контекст. |
span.SetStatus |
Устанавливает общий статус Span (OK , Error и т. д.), но не фиксирует детали ошибки. |
Для указания статуса выполнения операции. |
Детали span.SetStatus
1. Установка статуса
Метод позволяет указать статус выполнения операции, например:
codes.Ok
: Операция выполнена успешно.codes.Error
: Операция завершилась с ошибкой.
Пример:
1 2 |
span.SetStatus(codes.Error, "Operation failed") |
2. Отсутствие подробностей
Этот метод только указывает, что произошла ошибка, но:
- Не записывает сообщение об ошибке.
- Не добавляет атрибуты или события в трейс.
Если вы используете только SetStatus
, вы потеряете возможность проанализировать детали ошибки.
Детали span.RecordError
1. Запись ошибки
Метод фиксирует ошибку как событие exception
в спане с атрибутами:
exception.type
: Тип ошибки (например,*errors.errorString
).exception.message
: Сообщение об ошибке (например, текст изerr.Error()
).exception.stacktrace
: (Опционально) Стек вызовов.
Пример:
1 2 |
span.RecordError(err) |
2. Автоматическое создание события
Каждая ошибка становится частью трассировки и доступна в системах наблюдения (например, Jaeger, Zipkin).
Как использовать оба метода вместе
Чтобы записать ошибку и одновременно установить статус Error
, нужно использовать оба метода:
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
func process(ctx context.Context) error { ctx, span := tracer.Start(ctx, "Process") defer span.End() err := doWork() if err != nil { // Записываем ошибку span.RecordError(err) // Устанавливаем статус span.SetStatus(codes.Error, err.Error()) return err } // Успешный статус (по умолчанию ставится OK) span.SetStatus(codes.Ok, "Operation successful") return nil } |
Почему они разделены?
- Разные цели:
SetStatus
— для общего состояния (Error
илиOk
).RecordError
— для сохранения деталей ошибки.
- Гибкость:
- Иногда может быть полезно установить статус
Error
, но не записывать саму ошибку (например, для отладки или в случае ожидаемых ошибок).
- Иногда может быть полезно установить статус
- Совместимость с инструментами:
- Инструменты вроде Jaeger и Zipkin обрабатывают статус и события по-разному:
- Статус важен для общего анализа (
OK
илиError
). - События (
RecordError
) дают детализацию.
- Статус важен для общего анализа (
- Инструменты вроде Jaeger и Zipkin обрабатывают статус и события по-разному:
Итог
Используйте оба метода вместе:
span.RecordError(err)
для фиксации подробностей об ошибке.span.SetStatus(codes.Error, err.Error())
для обозначения статуса выполнения операции.
Такой подход даёт полный контекст: статус операции, сообщение об ошибке, тип ошибки и стек вызовов.