Семплінг

Семплінг — це процес, який обмежує кількість відрізків, що генеруються системою. Семплер, який ви повинні використовувати, залежить від ваших конкретних потреб, але загалом ви повинні приймати рішення на початку трасування і дозволяти рішенню про семплінг поширюватися на інші сервіси.

Sampler можна встановити на постачальника трасувальника за допомогою опції WithSampler, як показано нижче:

provider := trace.NewTracerProvider(
    trace.WithSampler(trace.AlwaysSample()),
)

AlwaysSample та NeverSample є самопояснювальними значеннями. AlwaysSample означає, що кожен відрізок семплюється, тоді як NeverSample означає, що жоден відрізок не семплюється. Коли ви тільки починаєте, або в середовищі розробки, використовуйте AlwaysSample.

Інші семплери включають:

  • TraceIDRatioBased, який семплює частину відрізків, на основі частки, заданої семплеру. Якщо ви встановите .5, половина всіх відрізків буде семплюватися.
  • ParentBased, це декоратор семплера, який поводиться по-різному, залежно від батьківського відрізка. Якщо відрізок не має батька, використовується декорований семплер для прийняття рішення. Типово, ParentBased семплює відрізки, які мають батьків, що були семпльовані, і не семплює відрізки, чиї батьки не були семпльовані.

Стандартно, постачальник трасувальника використовує семплер ParentBased з семплером AlwaysSample.

У промисловому середовищі розгляньте можливість використання семплера ParentBased з семплером TraceIDRatioBased.

Власні семплери

Якщо вбудовані семплери не відповідають вашим потребам, ви можете створити власний семплер, реалізувавши інтерфейс Sampler. Власний семплер повинен реалізовувати два методи:

  • ShouldSample(parameters SamplingParameters) SamplingResult: приймає рішення про вибірку на основі наданих параметрів.
  • Description() string: повертає опис семплера.

Збереження стану трасування

Приклад

Наступний приклад демонструє власний семплер, який відбирає зразки на основі значення атрибута, правильно зберігаючи стан трасування:

package main

import (
    "context"

    "go.opentelemetry.io/otel/attribute"
    sdktrace "go.opentelemetry.io/otel/sdk/trace"
    "go.opentelemetry.io/otel/trace"
)

// AttributeBasedSampler відбирає відрізки на основі значення атрибута.
// Він завжди відбирає відрізки з атрибутом "high.priority", встановленим на true.
type AttributeBasedSampler struct {
    fallback sdktrace.Sampler
}

// NewAttributeBasedSampler створює новий AttributeBasedSampler.
func NewAttributeBasedSampler(fallback sdktrace.Sampler) *AttributeBasedSampler {
    return &AttributeBasedSampler{fallback: fallback}
}

func (s *AttributeBasedSampler) ShouldSample(p sdktrace.SamplingParameters) sdktrace.SamplingResult {
    // Завжди отримуйте контекст батьківського відрізка, щоб отримати стан трасування.
    psc := trace.SpanContextFromContext(p.ParentContext)

    // Перевірте, чи є атрибути, що вказують на високий пріоритет.
    for _, attr := range p.Attributes {
        if attr.Key == "high.priority" && attr.Value.AsBool() {
            return sdktrace.SamplingResult{
                Decision:   sdktrace.RecordAndSample,
                Attributes: p.Attributes,
                // Критично: збереження стану трасування батьківського елемента
                Tracestate: psc.TraceState(),
            }
        }
    }

    // Для інших відрізків поверніться до стандартного (запасного) семплера.
    result := s.fallback.ShouldSample(p)

    // Переконайтеся, що стан трасування зберігається навіть при використанні запасного варіанту.
    // Вбудовані семплери вже обробляють це, але перевіряти це є доцільним.
    return sdktrace.SamplingResult{
        Decision:   result.Decision,
        Attributes: result.Attributes,
        Tracestate: psc.TraceState(),
    }
}

func (s *AttributeBasedSampler) Description() string {
    return "AttributeBasedSampler"
}

Використання власного семплера

Ви можете використовувати власний семплер із провайдером трасування:

sampler := NewAttributeBasedSampler(sdktrace.TraceIDRatioBased(0.1))

provider := sdktrace.NewTracerProvider(
    sdktrace.WithSampler(sampler),
)

Ви також можете скомпонувати його за допомогою семплера ParentBased:

provider := sdktrace.NewTracerProvider(
    sdktrace.WithSampler(
        sdktrace.ParentBased(
            NewAttributeBasedSampler(sdktrace.TraceIDRatioBased(0.1)),
        ),
    ),
)

Додаткові рекомендації

Під час впровадження власних семплерів враховуйте такі моменти:

  1. Ігнорування рішення батьківського семплера: якщо ви хочете дотримуватися рішень батьківського семплера, оберніть свій семплер у ParentBased або вручну перевірте psc.IsSampled().

  2. Важкі обчислення в ShouldSample: Функція ShouldSample викликається синхронно для кожного створення відрізка. Уникайте витратних операцій, таких як мережеві виклики або складні обчислення, які можуть вплинути на продуктивність.


Востаннє змінено December 26, 2024: [uk] Ukrainian documentation for OpenTelemetry (2a3c5648)