Golang OpenTelemetry: фиксация ошибки span.RecordError(err)
span.RecordError(err)
— это метод OpenTelemetry, который позволяет зафиксировать информацию об ошибке в текущем Span
. Эта информация станет частью трассировки и поможет разработчикам проанализировать, что пошло не так.
Как работает RecordError
?
- Фиксация ошибки в
Span
: Метод записывает ошибку (err
) как событие типаexception
вSpan
. - Добавление стандартных атрибутов: OpenTelemetry автоматически добавляет к событию стандартные атрибуты, такие как тип ошибки и её текстовое сообщение.
Когда использовать RecordError
?
- Обработка ошибок: Если во время выполнения кода возникает ошибка, её стоит записать в текущий
Span
. - Дополнительная информация:
RecordError
полезен для анализа ошибок, так как записанные данные будут видны в системе мониторинга.
1234567891011121314151617181920212223242526272829303132333435363738394041424344package mainimport ("context""errors""log""go.opentelemetry.io/otel""go.opentelemetry.io/otel/codes""go.opentelemetry.io/otel/trace")func main() {tracer := otel.Tracer("example-tracer")// Создаём корневой контекст и Spanctx, span := tracer.Start(context.Background(), "main-operation")defer span.End()// Пример вызова функции, которая возвращает ошибкуerr := ProcessTask(ctx)if err != nil {// Записываем ошибку в Spanspan.RecordError(err)// Устанавливаем статус Span как ошибочныйspan.SetStatus(codes.Error, err.Error())}log.Println("Main operation finished")}// ProcessTask - пример функции, которая возвращает ошибкуfunc ProcessTask(ctx context.Context) error {tracer := otel.Tracer("example-tracer")ctx, span := tracer.Start(ctx, "ProcessTask")defer span.End()// Имитация ошибкиerr := errors.New("something went wrong")span.RecordError(err) // Записываем ошибку в Spanreturn err}
Что записывает RecordError
?
- Тип ошибки (
exception.type
):- Отражает тип ошибки (например,
*errors.errorString
).
- Отражает тип ошибки (например,
- Сообщение об ошибке (
exception.message
):- Текст ошибки (
err.Error()
).
- Текст ошибки (
- (Опционально) Стек-трейс (
exception.stacktrace
):- Если стек-трейс доступен, его можно передать вручную.
Как добавить стек-трейс вручную?
OpenTelemetry не всегда автоматически добавляет стек-трейс. Вы можете использовать библиотеку runtime/debug
или другие инструменты для этого.
Пример:
1 2 3 4 5 6 7 8 9 10 |
import ( "runtime/debug" ) func RecordErrorWithStack(ctx context.Context, span trace.Span, err error) { span.RecordError(err, trace.WithAttributes( attribute.String("exception.stacktrace", string(debug.Stack())), )) } |
Использование:
1 2 3 |
err := errors.New("critical failure") RecordErrorWithStack(ctx, span, err) |
Чем полезен RecordError
?
- Улучшает видимость ошибок:
- Ошибки становятся частью трассировки, их легко просмотреть в системах мониторинга (например, Jaeger, Zipkin).
- Сопоставление ошибок с контекстом:
- Ошибки связываются с конкретным
Span
, что помогает понять, где именно произошла ошибка.
- Ошибки связываются с конкретным
- Снижение ручной работы:
- Атрибуты ошибок добавляются автоматически.
Частые ошибки при использовании
- Неуказание статуса
Error
:- Запись ошибки с помощью
RecordError
не устанавливает статусError
. Для этого нужно явно вызвать:12span.SetStatus(codes.Error, err.Error())
- Запись ошибки с помощью
- Избыточное количество записей:
- Не стоит записывать одну и ту же ошибку несколько раз. Это может загрязнить трейс.
- Игнорирование контекста:
- Убедитесь, что контекст правильно передаётся, чтобы ошибка была записана в нужный
Span
.
- Убедитесь, что контекст правильно передаётся, чтобы ошибка была записана в нужный
Итог
Метод span.RecordError(err)
— это эффективный способ записать ошибки в OpenTelemetry. Используйте его для:
- Фиксации подробностей об ошибках.
- Добавления ошибок в трейс.
- Улучшения диагностики в распределённых системах.