Golang OpenTelemetry: вложенность спанов определяется контекстом или порядком открытия-закрытия спанов в коде программы?
В OpenTelemetry (otel), вложенность спанов (или отношения между спанами) определяется контекстом, а не порядком открытия или закрытия спанов в коде.
Как это работает:
- Контекст (
context.Context
):- Контекст в Go используется для передачи информации об операциях, например, для передачи идентификаторов спанов. Когда вы создаете новый спан, он может быть связан с другим спаном, если вы передаёте в него контекст родительского спана.
- Новый спан будет вложен в родительский спан, если при его создании передан соответствующий контекст.
- Порядок создания и завершения спанов:
- Порядок создания и завершения спанов в коде влияет только на время жизни спанов, но не на их вложенность.
- Вложенность спанов зависит только от того, какой контекст был передан при создании спана. То есть, даже если спаны создаются в произвольном порядке, их вложенность будет определяться контекстом.
Пример вложенности спанов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package main import ( "context" "fmt" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" ) func main() { // Получаем стандартный трейс tracer := otel.Tracer("example-tracer") // Создаём корневой контекст и спан ctx, span := tracer.Start(context.Background(), "root-span") defer span.End() // Создаем вложенный спан с использованием контекста родительского спана ctx, childSpan := tracer.Start(ctx, "child-span") defer childSpan.End() // Создаем вложенный спан в пределах уже созданного вложенного спана _, grandChildSpan := tracer.Start(ctx, "grandchild-span") defer grandChildSpan.End() // Пример работы с контекстом и спанами fmt.Println("Spans created and nested") } |
Объяснение:
- Корневой спан (
root-span
): Создаётся с использованием контекстаcontext.Background()
, который является базовым контекстом. - Дочерний спан (
child-span
): Создаётся с использованием контекстаctx
, который уже связан с родительским спаномroot-span
. Это означает, чтоchild-span
будет вложенным по отношению кroot-span
. - Внук (или второй дочерний) спан (
grandchild-span
): Этот спан создаётся с тем же контекстомctx
, что иchild-span
, поэтому он будет вложен вchild-span
.
Контекст передается от родителя к дочернему спану, и это определяет структуру вложенности, а не порядок их создания в коде.
Важные моменты:
- Контекст важен для вложенности: Когда вы создаете новый спан, контекст, который передается в метод
Start()
, определяет родителя для этого спана. Это позволяет автоматически строить иерархию спанов. - Порядок открытия/закрытия спанов: Порядок открытия и завершения спанов влияет только на время их жизни. Он не изменяет отношения между спанами (например, их вложенность).
- Контекст и передача через функции: Контекст передается в функции, которые могут создавать новые спаны. Это обеспечивает правильную иерархию спанов.
Почему это важно?
- Трассировка в распределённых системах: Когда вы передаете контекст между различными компонентами или сервисами, это позволяет точно отслеживать выполнение запросов в распределённой системе, не зависимо от того, когда или где именно был создан тот или иной спан.
- Иерархия и видимость: Правильная вложенность спанов помогает строить более понятные и удобные для анализа трассировки. Программно правильно организованные спаны облегчают диагностику и поиск ошибок.
Итак:
Вложенность спанов определяется контекстом, и правильная передача контекста при создании спанов обеспечивает правильную иерархию. Порядок их открытия и закрытия в коде определяет только их продолжительность жизни, но не их отношения друг к другу.