Go OpenTelemetry

Материал из Документация Ключ-АСТРОМ
Версия от 16:20, 15 октября 2025; IKuznetsov (обсуждение | вклад) (Новая страница: «В этом пошаговом руководстве показано, как добавить возможность наблюдения в ваше прило...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)

В этом пошаговом руководстве показано, как добавить возможность наблюдения в ваше приложение Go с помощью библиотек и инструментов OpenTelemetry Go.

Особенность Поддержка
Автоматические инструменты Да
Трассировки Да
Метрики Да
Логи Нет

Предустановка

  • Ключ-АСТРОМ версии 1.222+
  • Для трассировки включен контекст трассировки W3C.
    1. Перейдите в Настройки > Предустановка > Функции ЕдиногоАгента.
    2. Включите опцию Отправлять HTTP-заголовки контекста трассировки W3C.

Получение данных для доступа к Ключ-АСТРОМ

Определение базового URL API

Подробную информацию о сборке базового URL-адреса конечной точки OTLP см. в разделе Экспорт с помощью OTLP. URL-адрес должен заканчиваться на /api/v2/otlp.

Получение токена доступа API

Токен доступа для сбора трассировок, логов и метрик можно создать в разделе Токены доступа.

Экспорт с помощью OTLP содержит более подробную информацию о формате и необходимых областях доступа.

Выберите, как вы хотите инструментировать свое приложение

OpenTelemetry поддерживает автоматическое и ручное инструментирование на Go, а также их комбинацию.

Какой инструментарий выбрать?

Рекомендуется начать с автоматического измерения и добавить ручное измерение, если автоматический подход не работает или не дает достаточно информации.

Инициализирование OpenTelemetry

1. Добавьте следующие операторы импорта.

import (

  "context"

  "github.com/astromkey/OneAgent-SDK-for-Go/sdk"

  "go.opentelemetry.io/otel"

  "go.opentelemetry.io/otel/attribute"

  "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"

  "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"

  "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"

  "go.opentelemetry.io/otel/propagation"

  "go.opentelemetry.io/otel/trace"

  sdkmetric "go.opentelemetry.io/otel/sdk/metric"

  "go.opentelemetry.io/otel/sdk/metric/metricdata"

  "go.opentelemetry.io/otel/sdk/resource"

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

  semconv "go.opentelemetry.io/otel/semconv/v1.20.0"

  "log"

  "time"

  "log/slog"

  "go.opentelemetry.io/contrib/bridges/otelslog"

  "go.opentelemetry.io/otel/log/global"

  sdklog "go.opentelemetry.io/otel/sdk/log"

)

2. Запустите команду Go mod tidy для установки зависимостей.

go mod tidy

3. Добавьте следующий код в стартовый файл и укажите соответствующие значения для DT_API_HOST и DT_API_TOKEN.

  • DT_API_HOST должен содержать только имя хоста вашего URL-адреса Ключ-АСТРОМ (например, XXXXX.live.astromkey.com); он не является URL-адресом и не должен содержать никаких схем или путей
  • DT_API_TOKEN должен содержать токен доступа
func InitOpenTelemetry() {

  // ===== GENERAL SETUP =====

  DT_API_HOST := "" // Only the host part of your astromkey URL

  DT_API_BASE_PATH := "/api/v2/otlp"

  DT_API_TOKEN := ""

  authHeader := map[string]string{"Authorization": "Api-Token " + DT_API_TOKEN}

  ctx := context.Background()

  oneagentsdk := sdk.CreateInstance()

  dtMetadata := oneagentsdk.GetEnrichmentMetadata()

  var attributes []attribute.KeyValue

  for k, v := range dtMetadata {

    attributes = append(attributes, attribute.KeyValue{Key: attribute.Key(k), Value: attribute.StringValue(v)})

  }

  attributes = append(attributes,

    semconv.ServiceNameKey.String("go-quickstart"), //TODO Replace with the name of your application

    semconv.ServiceVersionKey.String("1.0.1"),      //TODO Replace with the version of your application

  )

  res, err := resource.New(ctx, resource.WithAttributes(attributes...))

  if err != nil {

    log.Fatalf("Failed to create resource: %v", err)

  }

 

  // ===== TRACING SETUP =====

  exporter, err := otlptracehttp.New(

    ctx,

    otlptracehttp.WithEndpoint(DT_API_HOST),

    otlptracehttp.WithURLPath(DT_API_BASE_PATH+"/v1/traces"),

    otlptracehttp.WithHeaders(authHeader),

  )

  if err != nil {

    log.Fatalf("Failed to create OTLP exporter: %v", err)

  }

  tp := sdktrace.NewTracerProvider(

    sdktrace.WithResource(res),

    sdktrace.WithSampler(sdktrace.AlwaysSample()),

    sdktrace.WithBatcher(exporter),

  )

  otel.SetTracerProvider(tp)

  otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

  // ===== METRIC SETUP =====

  var deltaTemporalitySelector = func(sdkmetric.InstrumentKind) metricdata.Temporality { return metricdata.DeltaTemporality }

  metricsExporter, err := otlpmetrichttp.New(

    ctx,

    otlpmetrichttp.WithEndpoint(DT_API_HOST),

    otlpmetrichttp.WithURLPath(DT_API_BASE_PATH+"/v1/metrics"),

    otlpmetrichttp.WithHeaders(authHeader),

    otlpmetrichttp.WithTemporalitySelector(deltaTemporalitySelector),

  )

  if err != nil {

    log.Fatalf("Failed to create OTLP exporter: %v", err)

  }

  mp := sdkmetric.NewMeterProvider(

    sdkmetric.WithResource(res),

    sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricsExporter, sdkmetric.WithInterval(2*time.Second))),

  )

  otel.SetMeterProvider(mp)

  // ===== LOG SETUP =====

  logExporter, err := otlploghttp.New(

    ctx,

    otlploghttp.WithEndpoint(DT_API_HOST),

    otlploghttp.WithURLPath(DT_API_BASE_PATH+"/v1/logs"),

    otlploghttp.WithHeaders(authHeader),

  )

  if err != nil {

    log.Fatalf("Failed to create OTLP exporter: %v", err)

  }

  lp := sdklog.NewLoggerProvider(

    sdklog.WithProcessor(sdklog.NewBatchProcessor(logExporter)),

    sdklog.WithResource(res),

  )

  global.SetLoggerProvider(lp)

  logger := otelslog.NewLogger("my-logger-scope", otelslog.WithLoggerProvider(lp))

  slog.SetDefault(logger) // here we are overwriting the sdtout to http logger exporter

}

4. Обязательно вызовите функцию OpenTelemetry InitOpenTelemetry как можно раньше в коде запуска, чтобы инициализировать ее.

Автоматическое инструментирование приложения (необязательно)

1. Просмотрите реестр OpenTelemetry и выберите библиотеки инструментария, соответствующие библиотекам вашего приложения.

2. Добавьте соответствующие пакеты в ваши заявления об импорте.

import (

  "go.opentelemetry.io/[PACKAGE]"

)

3. Запустите команду Go mod tiny для установки зависимостей.

go mod tidy

4. Оберните существующий код вызовами вспомогательных библиотек.

Пример для net/http

1. Установить библиотеку инструментов для net/http.

2. Добавьте пакет в ваши импортные заявления.

import (

  // other packages

  "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

)

3. Оберните функцию обработчика HTTP.

handler := http.HandlerFunc(httpHandler)

wrappedHandler := otelhttp.NewHandler(handler, "my-span") //TODO Replace with the name of your span

//Use the wrappedHandler with your handle

http.Handle("/", wrappedHandler)

Инструментирование приложения вручную

Добавление трассировки

1. Сначала вам нужно получить объект трассировки.

tracer := otel.Tracer("my-tracer")

2. С помощью tracer, вы теперь можете использовать конструктор интервалов для создания и запуска новых интервалов.

_, span := tracer.Start(r.Context(), "Call to /myendpoint")

defer span.End()

span.SetAttributes(attribute.String("http.method", "GET"), attribute.String("net.protocol.version", "1.1"))

// TODO your code goes here

В приведенном выше коде мы:

  • Создали новый диапазон и назвали его «Call to /myendpoint».
  • Запланировали отложенный вызов End(), чтобы гарантировать правильное закрытие диапазона при возврате функции.
  • Добавили два атрибута, следуя семантическому соглашению об именовании, специфичные для действия этого диапазона: информацию о методе HTTP и версии.
  • Добавьте TODO вместо конечной бизнес-логики.

Сбор метрик

1. Получите объект метрик.

meter := otel.Meter("my-meter")

2. С помощью meter мы теперь можем создавать отдельные инструменты, например, метрику.

requestCounter, _ := meter.Int64Counter("request_counter")

3. Теперь мы можем вызвать метод Add() для записи новых значений requestCounter с помощью счетчика.

requestCounter.Add(context.Background(), 1)

Подключение логов

После инициализации логов OpenTelemetry InitOpenTelemetry() и настройки его в качестве регистратора по умолчанию для slog мы теперь можем вызывать любую из функций логов slog (например, Info()) для отправки информации логов в Ключ-АСТРОМ.

slog.Info("an info message")

slog.Debug("a debug message")

slog.Error("an error")

Обеспечение распространения контекста (необязательно)

Распространение контекста особенно важно, когда задействованы сетевые вызовы (например, REST).

Извлечение контекста при получении запроса

В следующем примере мы предполагаем, что мы получили сетевой вызов через библиотеку net/http и его тип Request.

Чтобы получить дескриптор исходного контекста (предоставленного вызывающей службой), мы передаём объект HTTP-заголовка ( r.Header) функции Extract глобального propagator singleton, которая создаёт экземпляр этого контекста и возвращает результат в parentCtx. Это позволяет нам продолжить предыдущую трассировку с помощью наших собственных интервалов.

func httpHandler(w http.ResponseWriter, r *http.Request) {

  parentCtx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))

  tracer := otel.Tracer("my-tracer")

  ctx, span := tracer.Start(

    parentCtx,

    "manual-server", //TODO Replace with the name of your span

    trace.WithAttributes(

      attribute.String("my-key-1", "my-value-1"), //TODO Add attributes

    ),

  )

  defer span.End()

  //TODO your code goes here

}

Внедрение контекста при отправке запросов

В следующем примере мы создаём новый экземпляр Request и передаём объект вызову InjectDo глобального propagator singleton. Это добавляет необходимые HTTP-заголовки к объекту запроса, который мы в конечном итоге передаём для выполнения сетевого запроса.

client := http.Client{}

req, err := http.NewRequest("<method>", "<url>", <body>)

if err != nil {

  // TODO handle error

}

//Method to inject the current context in the request headers

otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))

client.Do(req) // Your call goes here

Настройте сбор данных в соответствии с требованиями конфиденциальности (необязательно)

Хотя Ключ-АСТРОМ автоматически собирает все атрибуты OpenTelemetry, в веб-интерфейсе Ключ-АСТРОМ сохраняются и отображаются только значения атрибутов, указанные в списке разрешенных. Это предотвращает случайное сохранение персональных данных, позволяя вам соблюдать требования к конфиденциальности и контролировать объем хранимых данных мониторинга.

Чтобы просматривать пользовательские атрибуты, необходимо сначала разрешить их использование в веб-интерфейсе Ключ-АСТРОМ.

Проверка загрузки данных в Ключ-АСТРОМ

После завершения инструментирования вашего приложения выполните несколько тестовых действий для создания и отправки демонстрационных трассировок, метрик и логов, а также проверьте, что они были правильно загружены в Ключ-АСТРОМ.

Чтобы сделать это для трассировок, перейдите в раздел Трассировки и выберите вкладку Распределенные трассировки. Если вы используете ЕдиныйАгент, выберите PurePaths .

Для просмотра метрик и логов перейдите в раздел Метрики или Логов или Логи и события.