Работа с трассировкой в Golang на примере фрагмента кода
Давайте разберем ваш код и определим, в какой момент и как происходит отправка трейса:
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 |
// Создаем OTLP gRPC экспортер для трассировок exporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), // Без TLS (используйте WithTLS() для включения) otlptracegrpc.WithEndpoint("localhost:4317"), // Адрес OpenTelemetry Collector ) if err != nil { log.Fatalf("Ошибка создания OTLP gRPC экспортера: %v", err) } // Настраиваем TracerProvider tp := trace.NewTracerProvider( trace.WithBatcher(exporter), // Отправка трассировок пакетами trace.WithResource(resource.NewSchemaless( semconv.ServiceNameKey.String("daemon-service"), )), ) defer func() { _ = tp.Shutdown(ctx) }() otel.SetTracerProvider(tp) // Используем Tracer для создания трассировки tracer := otel.Tracer("daemon-tracer") ctx, span := tracer.Start(ctx, "daemon-operation") time.Sleep(1 * time.Second) |
1 2 3 4 5 |
exporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), // Без TLS otlptracegrpc.WithEndpoint("localhost:4317"), // Адрес OpenTelemetry Collector ) |
- Что делает?
Создает OTLP gRPC экспортер, который будет отправлять данные трассировки на указанный адрес (localhost:4317
). - Как работает?
Экспортер выступает интерфейсом для передачи данных в Collector. Он ничего не отправляет сам по себе — это задача процессора (например,BatchSpanProcessor
), который взаимодействует с экспортером.
2. Настройка TracerProvider
1 2 3 4 5 6 7 |
tp := trace.NewTracerProvider( trace.WithBatcher(exporter), // Отправка трассировок пакетами trace.WithResource(resource.NewSchemaless( semconv.ServiceNameKey.String("daemon-service"), )), ) |
- Что делает?
СоздаетTracerProvider
, который управляет трассировщиками и отправкой данных. - Особенности
trace.WithBatcher(exporter)
:- Используется BatchSpanProcessor:
- Данные трассировок сначала буферизуются в памяти.
- Буфер отправляется в экспортер либо по истечении заданного времени (
ScheduleDelay
), либо когда буфер достигает заданного размера (MaxExportBatchSize
). - Это позволяет избежать синхронной отправки данных при создании спанов, уменьшая влияние на производительность.
- Отправка данных происходит асинхронно через отдельные горутины.
- Используется BatchSpanProcessor:
3. Создание и завершение спана
1 2 3 4 |
tracer := otel.Tracer("daemon-tracer") ctx, span := tracer.Start(ctx, "daemon-operation") time.Sleep(1 * time.Second) |
- Что делает?
- Создает спан с именем
"daemon-operation"
. - Спан активен до вызова
span.End()
.
- Создает спан с именем
- Когда отправляются данные?
- В момент вызова
span.End()
данные передаются вBatchSpanProcessor
. - Процессор решает, отправлять данные сразу (если буфер заполнен), либо ждать окончания
ScheduleDelay
.
- В момент вызова
4. Закрытие TracerProvider
1 2 |
defer func() { _ = tp.Shutdown(ctx) }() |
- Что делает?
- В момент вызова
tp.Shutdown(ctx)
происходит:- Завершение всех активных спанов.
- Принудительная отправка всех данных, находящихся в буфере
BatchSpanProcessor
, в экспортер. - Завершение работы фоновых горутин.
- В момент вызова
- Особенность: Если вы не вызовете
Shutdown
, часть трассировок может остаться в буфере и не будет отправлена.
Асинхронная или синхронная отправка?
- В момент создания спана (
tracer.Start
) — данных на экспорт не отправляется. - В момент завершения спана (
span.End()
) — данные передаются в буферBatchSpanProcessor
асинхронно. - Фактическая отправка данных — происходит асинхронно в фоне, когда:
- Буфер достигает максимального размера.
- Истекает время ожидания (
ScheduleDelay
). - Принудительно вызывается
tp.Shutdown
.
Итог:
- Отправка данных трассировок происходит асинхронно.
BatchSpanProcessor
минимизирует влияние на основной поток выполнения программы, обрабатывая данные в фоне.- В вашем коде отправка произойдет либо по истечении времени ожидания (
ScheduleDelay
), либо при вызовеtp.Shutdown(ctx)
.
Recommended Posts
Golang Sarama: настройка Partitioner
20.03.2024