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())для обозначения статуса выполнения операции.
Такой подход даёт полный контекст: статус операции, сообщение об ошибке, тип ошибки и стек вызовов.
Recommended Posts
Golang map и Swiss Table
16.03.2025
