Мониторинг Go приложений с помощью Proto Observability
На этой странице:
- Введение
- Автоматическая инструментация (рекомендуется)
- Ручная инструментация
- Конфигурация трейсера
- Метрики Go runtime
- Трейсер ProtoOBP – дополнительная документация
Введение
Общий процесс подключения Go приложения на мониторинг в Proto Observability Platform :
- Установка ProtoOBP Агента.
- Установка трейсера.
- Конфигурация трейсера (опционально).
После подключения будут доступны все возможности модуля Application Performance Monitoring Proto Observability Platform.
Инструментацию Go-приложения можно подключить двумя категориями способов: автоматической — без написания кода инструментации (рекомендуется), и ручной — через изменение кода. Внутри каждой категории есть несколько вариантов, отличающихся трейсером и механизмом сбора данных.
Автоматическая инструментация (рекомендуется)
| Способ | Плюсы | Минусы | Документация |
|---|---|---|---|
| Orchestrion — на этапе компиляции (Datadog-совместимая) | Самое полное покрытие библиотек; runtime-метрики Go из коробки; код менять не нужно | Требуется пересборка приложения с orchestrion | orchestrion |
| OpenTelemetry AutoSDK — eBPF | Не требует ни изменения кода, ни пересборки; прикрепляется к запущенному бинарю | Минимальный набор библиотек (net/http, gRPC, database/sql, kafka-go); нужен привилегированный агент рядом; runtime-метрики отдельно | opentelemetry-go-instrumentation |
| OpenTelemetry OBI — eBPF | Единый zero-code подход для любого языка, не только Go; код/сборку менять не нужно | Покрытие на уровне сетевых протоколов (HTTP/gRPC/SQL), без деталей внутри процесса; нужен привилегированный агент | opentelemetry-ebpf-instrumentation |
Ручная инструментация
| Способ | Плюсы | Минусы | Документация |
|---|---|---|---|
Datadog трейсер (dd-trace-go) | Зрелый трейсер, широкое покрытие через contrib-пакеты; runtime-метрики из коробки; полный контроль над спанами | Требует изменения кода | dd-trace-go |
| OpenTelemetry — ручная инструментация | Vendor-neutral (OpenTelemetry SDK); полный контроль; большой выбор инструментаций | Требует изменения кода и настройки SDK/экспортёра | OpenTelemetry Go: instrumentation |
Трейсер ProtoOBP (pobp-trace-go) ⚠️ устаревшее | Совместимость с уже подключёнными сервисами | Устаревший вариант; для новых проектов используйте Datadog-совместимый или OpenTelemetry | pobp-trace-go |
Как выбрать способ
- По умолчанию — Orchestrion (на этапе компиляции). Даёт самое полное покрытие и runtime-метрики Go без изменения кода. Подходит, если вы собираете приложение сами и можете добавить шаг сборки в CI/CD.
- Нельзя менять сборку или код (готовый бинарь, сторонний образ) — OpenTelemetry AutoSDK (eBPF): агент прикрепляется к запущенному процессу. Покрытие ограничено набором поддерживаемых библиотек.
- Полиглот-окружение (Go вместе с другими языками) и нужен единый zero-code подход — OpenTelemetry OBI (eBPF): один механизм на уровне ядра для всех сервисов.
- Нужен полный контроль над тем, что и как трейсится, или кастомные спаны на зрелом трейсере — ручная инструментация Datadog-трейсером.
- Стандартизируетесь на OpenTelemetry и готовы вести инструментацию в коде — ручная инструментация OpenTelemetry.
- Трейсер ProtoOBP устарел — для новых проектов не используйте.
Ниже — детали по каждому способу.
Автоматическая инструментация (рекомендуется)
Автоматические способы не требуют написания кода инструментации. Выберите один из трёх вариантов ниже.
Инструментация на этапе компиляции (Orchestrion)
Рекомендуемый способ по умолчанию.
Пакет Orchestrion автоматически добавляет инструментацию в приложения Go во время компиляции, устраняя необходимость в модификации кода. Пакет обеспечивает всестороннее покрытие трассировкой:
- Инструментирует ваш код и все зависимости, включая стандартную библиотеку Go.
- Инструментирует ваш код во время компиляции, предотвращая пробелы в покрытии трассировки из-за упущенной ручной инструментации.
Требования для инструментации на этапе компиляции:
- Поддерживает две последние версии среды выполнения Go (в соответствии с официальной политикой релизов Go).
- Приложения должны управляться с помощью модулей go.
Для добавления в Go приложение инструментации на этапе компиляции выполните:
Установите пакет
Orchestrion:go install github.com/DataDog/orchestrion@latestВыполните команду:
orchestrion pinДобавьте префикс
orchestrionк обычным командамgo:orchestrion go build . orchestrion go run . orchestrion go test ./...
Пример Dockerfile:
FROM golang:1.26
WORKDIR /home/apm-tutorial-golang
COPY go.mod ./
COPY go.sum ./
RUN go mod download
#Copy notes application
COPY notes notes/
COPY cmd/notes cmd/notes/
# добавление инструментации
RUN go install github.com/DataDog/orchestrion@latest
RUN orchestrion pin
RUN orchestrion go build -o cmd/notes/notes ./cmd/notes
# конфигурация трейсера
ENV DD_AGENT_HOST=protoobp-agent
ENV DD_TRACE_AGENT_PORT=8126
ENV DD_REMOTE_CONFIGURATION_ENABLED=false
ENV DD_TRACE_SAMPLE_RATE=1.0
#Run application
ENTRYPOINT ["./cmd/notes/notes"]
OpenTelemetry AutoSDK (eBPF)
zero-code инструментация с помощью eBPF, реализованная проектом opentelemetry-go-instrumentation (образ otel/autoinstrumentation-go, модуль go.opentelemetry.io/auto). Отдельный агент прикрепляется к уже запущенному бинарю Go через eBPF (uprobes) и формирует трейсы без изменения исходного кода и без пересборки приложения, отправляя их в OTLP-приёмник Агента ProtoOBP.
Какие библиотеки инструментируются автоматически:
| Библиотека | Что трейсится |
|---|---|
net/http | HTTP-сервер и HTTP-клиент |
google.golang.org/grpc | gRPC-сервер и клиент |
database/sql | запросы к базе данных |
github.com/segmentio/kafka-go | producer и consumer |
AutoSDK — ручные спаны без настройки SDK. Чтобы размечать бизнес-логику собственными спанами, используйте стандартный API OpenTelemetry (go.opentelemetry.io/otel) совместно с пакетом go.opentelemetry.io/auto/sdk. Настраивать собственный TracerProvider, экспортёр или OTLP-конвейер в коде не нужно: пока eBPF-агент не прикреплён, такие спаны являются дешёвыми no-op, а когда агент прикреплён — он сам превращает их в реальные спаны и связывает с автоматическими (net/http, gRPC, database/sql, kafka-go).
import "go.opentelemetry.io/otel"
// SDK НЕ инициализируется. Просто используем глобальный трейсер:
tr := otel.Tracer("my-service")
ctx, span := tr.Start(ctx, "validate-order")
defer span.End()
Важно
Не устанавливайте в коде собственный (реальный)TracerProvider через otel.SetTracerProvider(...) — это конфликтует с AutoSDK и ломает связывание ручных спанов с eBPF-спанами. Подробнее: opentelemetry.io/docs/zero-code/go/autosdk.Требования:
- Linux с поддержкой eBPF. Агент запускается привилегированно (
privileged,runAsUser: 0) и должен видеть процесс приложения (общий PID namespace). - Бинарь приложения собран без флагов
-ldflags "-s -w"— агенту нужна build-info/символьная информация Go. - Один агент инструментирует один бинарь; цель задаётся переменной
OTEL_GO_AUTO_TARGET_EXE(путь, по которому был запущен бинарь).
Перед началом включите OTLP-приёмник на Агенте ProtoOBP — см. Включение поддержки OpenTelemetry на агенте. Затем запустите агент инструментации рядом с приложением:
Добавьте контейнер-агент в docker-compose.yml. И контейнер приложения, и агент запускаются с pid: "host" и монтируют /proc, чтобы агент нашёл процесс по пути его бинаря:
services:
my-app:
image: my-app:latest
pid: "host"
volumes:
- /proc:/host/proc
go-auto:
image: otel/autoinstrumentation-go:v0.24.0
privileged: true
pid: "host"
environment:
- OTEL_GO_AUTO_TARGET_EXE=/app/my-app # путь, по которому запущен бинарь
- OTEL_SERVICE_NAME=my-app # имя сервиса в ProtoOBP
- OTEL_EXPORTER_OTLP_ENDPOINT=http://protoobp-agent:4318
- OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
- OTEL_PROPAGATORS=tracecontext,baggage
# опционально — захват SQL-запросов в спаны database/sql:
- OTEL_GO_AUTO_INCLUDE_DB_STATEMENT=true
volumes:
- /proc:/host/proc
Убедитесь, что контейнеры приложения, агента инструментации и Агента ProtoOBP находятся в одной Docker-сети.
Добавьте агент как sidecar в под приложения. Под помечается shareProcessNamespace: true (чтобы sidecar видел процесс приложения), а сам sidecar получает securityContext с privileged: true и runAsUser: 0. Эндпоинт берётся с host IP узла (как в настройке OpenTelemetry):
apiVersion: apps/v1
kind: Deployment
#(...)
spec:
shareProcessNamespace: true
containers:
- name: my-app
image: my-app:latest
command: ["/app/my-app"]
- name: go-auto
image: otel/autoinstrumentation-go:v0.24.0
securityContext:
runAsUser: 0
privileged: true
env:
- name: OTEL_GO_AUTO_TARGET_EXE
value: /app/my-app
- name: OTEL_SERVICE_NAME
value: my-app
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://$(HOST_IP):4318"
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: http/protobuf
- name: OTEL_GO_AUTO_INCLUDE_DB_STATEMENT
value: "true"
Поддерживаемые версии Go и библиотек см. в таблице совместимости.
OpenTelemetry OBI (eBPF)
OpenTelemetry eBPF Instrumentation (OBI) — zero-code инструментация на основе eBPF, работающая для любого языка, не только Go. OBI разворачивается как привилегированный агент (обычно DaemonSet в Kubernetes) и формирует трейсы и метрики на уровне сетевых протоколов (HTTP, gRPC, SQL и др.), не требуя ни изменения кода, ни пересборки.
В отличие от AutoSDK, OBI не привязан к Go и удобен в полиглот-окружениях, где нужно единообразно покрыть сервисы на разных языках. Покрытие при этом ограничено тем, что видно на уровне ядра (границы запросов между сервисами), без деталей внутри процесса.
Телеметрия отправляется в OTLP-приёмник Агента ProtoOBP (см. настройку OpenTelemetry).
Подробная инструкция по установке и настройке OBI — на странице Zero-code инструментация с OpenTelemetry eBPF (OBI).
Ручная инструментация
Ручная инструментация требует изменения кода: вы подключаете трейсер и пакеты-интеграции для нужных библиотек. Доступны три трейсера:
- Datadog (
dd-trace-go) — рекомендуемый вариант для ручной инструментации: зрелый трейсер с широким покрытием и runtime-метриками. - OpenTelemetry — vendor-neutral инструментация в коде с OpenTelemetry SDK; см. официальную документацию.
- Трейсер ProtoOBP (
pobp-trace-go) — ⚠️ устаревший, оставлен для обратной совместимости. Для новых проектов используйте Datadog-совместимую или OpenTelemetry инструментацию.
Добавьте библиотеку трейсера в свое приложение Сначала импортируйте и запустите трейсер в своем коде, следуя инструкциям в документации по настройке библиотеки. Инструкции по настройке и подробную информацию об использовании API см. ниже.
Добавление модуля pobptrace:
go get -u git.proto.group/protoobp/pobp-trace-go/pobptrace
или добавьте в main.go файл:
import(
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
Добавление модуля ddtrace:
go get -u github.com/DataDog/dd-trace-go/v2
или добавьте в main.go файл:
import(
"github.com/DataDog/dd-trace-go/v2/ddtrace/ext"
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
)
Используйте документацию трейсера:
https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2/ddtrace
Этот вариант предназначен для миграции приложений, уже инструментированных агентом New Relic: их распределённые трейсы направляются в Proto Observability Platform без изменения кода. Для новых приложений он не рекомендуется — используйте один из трейсеров, рекомендованных на этой странице.
Подробнее: Подключение приложений с трейсерами New Relic.
Выполните шаги, указанные на странице подключения инструментации OpenTelemetry для Go:
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform.
Активируйте интеграции Go для создания спанов Активируйте интеграции Go для генерации спанов. Предлагаются ряд подключаемых пакетов, которые обеспечивают готовую поддержку для инструментации ряда библиотек и фреймворков. Список этих пакетов можно найти на странице «Требования к совместимости». Импортируйте эти пакеты в свое приложение и следуйте инструкциям по настройке, указанным рядом с каждой интеграцией.
Дополнительные модули интеграции – пример добавления:
go get -u git.proto.group/protoobp/pobp-trace-go/contrib/net/http
Для автоматической инструментации вызововов поддерживаются следующие библиотеки и фреймворки (примеры доступны в документации по ссылкам):
Пакеты для интеграции должны быть импортированы следующим образом:
import "git.proto.group/protoobp/pobp-trace-go/contrib/<PACKAGE_DIR>/<PACKAGE_NAME>"
Пример использования пакета для инструментации стандартных net/http:
package main
import (
"fmt"
"net/http"
httptrace "git.proto.group/protoobp/pobp-trace-go/contrib/net/http" // дополнительный пакет
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func hello(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello My World!\n"))
}
func headers(w http.ResponseWriter, req *http.Request) {
for name, headers := range req.Header {
for _, h := range headers {
fmt.Fprintf(w, "%v: %v\n", name, h)
}
}
}
func main() {
tracer.Start(
tracer.WithService("test-server"),
tracer.WithRuntimeMetrics(),
tracer.WithAgentAddr("protoobp-agent:8126"),
tracer.WithDogstatsdAddress("protoobp-agent"),
)
mux := httptrace.NewServeMux()
defer tracer.Stop()
mux.HandleFunc("/hello", hello)
mux.HandleFunc("/headers", headers)
http.ListenAndServe(":8090", mux)
}
Пакеты интеграции импортируются следующим образом:
import "github.com/DataDog/dd-trace-go/contrib/<PACKAGE_DIR>/<PACKAGE_NAME>/v2"
Трейсер поддерживает следующие библиотеки и хранилища данных:
Этот вариант предназначен для миграции приложений, уже инструментированных агентом New Relic: их распределённые трейсы направляются в Proto Observability Platform без изменения кода. Для новых приложений он не рекомендуется — используйте один из трейсеров, рекомендованных на этой странице.
Подробнее: Подключение приложений с трейсерами New Relic.
Выполните шаги, указанные на странице подключения инструментации OpenTelemetry для Go:
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform.
Конфигурация трейсера
Трейсер поддерживает конфигурацию через переменные окружения или через параметры инициализации в коде вашего приложения.
Конфигурация трейсера через переменные окружения (рекомендуется)
POBP_AGENT_HOST – адрес Агента, на который будет отсылать данные трейсер:
- если Агент запущен в Docker контейнере, укажите имя Docker контейнера Агента:Убедитесь, что контейнер Агента и контейнер приложения находятся в одной Docker сети. Адрес агента должен быть доступен из Docker контейнера приложения.
ENV POBP_AGENT_HOST="protoobp-agent" - если Агент запущен на хосте как сервис (не в контейнере):Убедитесь что в конфигурации Агента разрешен прием APM данных от контейнеров:
ENV POBP_AGENT_HOST="host.docker.internal"apm_config: apm_non_local_traffic: true
POBP_SERVICE – имя сервиса, которое будет отображаться в интерфейсе Proto OBP:
ENV POBP_SERVICE="my_service_name"
POBP_ENV – окружение сервиса, которое будет отображаться в интерфейсе Proto OBP:
ENV POBP_ENV="prod" # prod/test/stage/dev и тд
POBP_RUNTIME_METRICS_ENABLED – обязательно установите в true для получения runtime метрик
ENV POBP_RUNTIME_METRICS_ENABLED="true"
POBP_TRACE_TELEMETRY_ENABLED – установите в false
ENV POBP_TRACE_TELEMETRY_ENABLED="false"
DD_AGENT_HOST – адрес Агента, на который будет отсылать данные трейсер:
- если Агент запущен в Docker контейнере, укажите имя Docker контейнера Агента:Убедитесь, что контейнер Агента и контейнер приложения находятся в одной Docker сети. Адрес агента должен быть доступен из Docker контейнера приложения.
ENV DD_AGENT_HOST="protoobp-agent" - если Агент запущен на хосте как сервис (не в контейнере):Убедитесь что в конфигурации Агента разрешен прием APM данных от контейнеров:
ENV DD_AGENT_HOST="host.docker.internal"apm_config: apm_non_local_traffic: true
DD_SERVICE – имя сервиса, которое будет отображаться в интерфейсе Proto OBP:
ENV DD_SERVICE="my_service_name"
DD_ENV – окружение сервиса, которое будет отображаться в интерфейсе Proto OBP:
ENV DD_ENV="prod" # prod/test/stage/dev и тд
DD_RUNTIME_METRICS_ENABLED – обязательно установите в true для получения runtime метрик
ENV DD_RUNTIME_METRICS_ENABLED="true"
DD_TRACE_TELEMETRY_ENABLED – установите в false
ENV DD_TRACE_TELEMETRY_ENABLED="false"
Этот вариант предназначен для миграции приложений, уже инструментированных агентом New Relic: их распределённые трейсы направляются в Proto Observability Platform без изменения кода. Для новых приложений он не рекомендуется — используйте один из трейсеров, рекомендованных на этой странице.
Подробнее: Подключение приложений с трейсерами New Relic.
Если приложение запускается в Docker контейнере
Пример готового Dockerfile:
ENV POBP_SERVICE=dispatch
ENV POBP_DOGSTATSD_NON_LOCAL_TRAFFIC=true
# следующие переменные лучше задавать в среде выполнения, а не в Dockerfile
ENV POBP_ENV=prod
ENV POBP_AGENT_HOST=protoobp-agent
ENV DD_SERVICE=dispatch
ENV DD_DOGSTATSD_NON_LOCAL_TRAFFIC=true
# следующие переменные лучше задавать в среде выполнения, а не в Dockerfile
ENV DD_ENV=prod
ENV DD_AGENT_HOST=protoobp-agent
Этот вариант предназначен для миграции приложений, уже инструментированных агентом New Relic: их распределённые трейсы направляются в Proto Observability Platform без изменения кода. Для новых приложений он не рекомендуется — используйте один из трейсеров, рекомендованных на этой странице.
Подробнее: Подключение приложений с трейсерами New Relic.
Выполните шаги, указанные на странице подключения инструментации OpenTelemetry для Go:
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform.
Если приложение работает в Kubernetes
Убедитесь, что у вас успешно установлен и настроен ProtoOBP Агент для Kubernetes.
Дополнительно необходимо передать поду переменную окружения POBP_AGENT_HOST со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную).
apiVersion: apps/v1
kind: Deployment
#(...)
spec:
containers:
- name: "<CONTAINER_NAME>"
image: "<CONTAINER_IMAGE>/<TAG>"
env:
- name: POBP_SERVICE
value: dispatch
- name: POBP_AGENT_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POBP_TAGS
value: "pod_name:$(POD_NAME),node:$(NODE_NAME),kube_namespace:$(POD_NAMESPACE),kube_cluster_name:<my_cluster_name>"
Дополнительно необходимо передать поду переменную окружения DD_AGENT_HOST со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную).
apiVersion: apps/v1
kind: Deployment
#(...)
spec:
containers:
- name: "<CONTAINER_NAME>"
image: "<CONTAINER_IMAGE>/<TAG>"
env:
- name: DD_SERVICE
value: dispatch
- name: DD_AGENT_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: DD_TAGS
value: "pod_name:$(POD_NAME),node:$(NODE_NAME),kube_namespace:$(POD_NAMESPACE),kube_cluster_name:<my_cluster_name>"
Этот вариант предназначен для миграции приложений, уже инструментированных агентом New Relic: их распределённые трейсы направляются в Proto Observability Platform без изменения кода. Для новых приложений он не рекомендуется — используйте один из трейсеров, рекомендованных на этой странице.
Подробнее: Подключение приложений с трейсерами New Relic.
Выполните шаги, указанные на странице подключения инструментации OpenTelemetry для Go:
Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform.
Метрики Go runtime
Помимо трейсов, ошибок и метрик по трейсам, Proto OBP также собирает runtime метрики Go приложений. Runtime метрики отображаются на дашборде конкретного инстанса сервиса.
Включение метрик Go runtime
Убедитесь, что у Агента установлена переменная окружения:
POBP_DOGSTATSD_NON_LOCAL_TRAFFIC=true
Добавьте переменную окружения к приложению:
POBP_RUNTIME_METRICS_ENABLED=true
Добавьте переменную окружения к приложению:
DD_RUNTIME_METRICS_ENABLED=true
Список метрик Go runtime, собираемых Proto OBP
runtime_go_num_cpu(gauge) | Процессоры, обнаруженные средой выполнения. |
runtime_go_num_goroutine(gauge) | Созданные goroutines. |
runtime_go_num_cgo_call(gauge) | Выполненные вызовы CGO. |
runtime_go_mem_stats_alloc(gauge) | Alloc — это байты выделенных объектов кучи. |
runtime_go_mem_stats_total_alloc(gauge) | TotalAlloc — это совокупный объем выделенной памяти для объектов кучи. |
runtime_go_mem_stats_sys(gauge) | Sys — это общий объем памяти, полученной от ОС. Отображается в байтах |
runtime_go_mem_stats_lookups(gauge) | Lookups — количество поисков указателей, выполненных. |
runtime_go_mem_stats_mallocs(gauge) | Mallocs — совокупное количество выделенных объектов кучи. |
runtime_go_mem_stats_frees(gauge) | Frees — это совокупное количество освобожденных объектов кучи. |
runtime_go_mem_stats_heap_alloc(gauge) | HeapAlloc — это байты выделенных объектов кучи. |
runtime_go_mem_stats_heap_sys(gauge) | HeapSys — это количество байтов кучи памяти, полученных от ОС. |
runtime_go_mem_stats_heap_idle(gauge) | HeapIdle — это количество байтов в неиспользуемых (незанятых) интервалах. |
runtime_go_mem_stats_heap_inuse(gauge) | HeapInuse — это байты в используемых диапазонах. |
runtime_go_mem_stats_heap_released(gauge) | HeapReleased — это количество байтов физической памяти, возвращенных ОС. |
runtime_go_mem_stats_heap_objects(gauge) | HeapObjects — это количество выделенных объектов кучи. |
runtime_go_mem_stats_stack_inuse(gauge) | StackInuse — это количество байтов в стеке. |
runtime_go_mem_stats_stack_sys(gauge) | StackSys — это количество байтов памяти стека, полученных от ОС. |
runtime_go_mem_stats_m_span_inuse(gauge) | MSpanInuse — это количество байтов выделенных структур mspan. |
runtime_go_mem_stats_m_span_sys(gauge) | MSpanSys — это количество байтов памяти, полученных от ОС для структур mspan. |
runtime_go_mem_stats_m_cache_inuse(gauge) | MCacheInuse — это количество байтов выделенных структур mcache. |
runtime_go_mem_stats_m_cache_sys(gauge) | MCacheSys — это количество байтов памяти, полученных от ОС |
runtime_go_mem_stats_buck_hash_sys(gauge) | BuckHashSys — это байты памяти в хэш-таблицах профилирования. |
runtime_go_mem_stats_gc_sys(gauge) | GCSys — это байты памяти в метаданных сборки мусора. |
runtime_go_mem_stats_other_sys(gauge) | OtherSys — это байты памяти в различных внекупочных областях. |
runtime_go_mem_stats_next_gc(gauge) | NextGC — это целевой размер кучи для следующего цикла GC. |
runtime_go_mem_stats_last_gc(gauge) | LastGC — время завершения последней сборки мусора в наносекундах с 1970 года (эпоха UNIX). |
runtime_go_mem_stats_pause_total_ns(gauge) | PauseTotalNs — это совокупное количество наносекунд в GC. |
runtime_go_mem_stats_num_gc(gauge) | NumGC — количество завершенных циклов GC. |
runtime_go_mem_stats_num_forced_gc(gauge) | NumForcedGC — количество циклов GC, которые были принудительно запущены приложением, вызвавшим функцию GC. |
runtime_go_mem_stats_gc_cpu_fraction(gauge) | GCCPUFraction — доля доступного времени ЦП данной программы, использованного GC с момента запуска программы. |
runtime_go_gc_stats_pause_quantiles_min(gauge) | Распределение времени пауз GC: минимальные значения. Отображается в наносекундах |
runtime_go_gc_stats_pause_quantiles_25p(gauge) | Распределение времени пауз GC: 25-й процентиль. Отображается в наносекундах |
runtime_go_gc_stats_pause_quantiles_75p(gauge) | Распределение времени пауз GC: 50-й процентиль. Отображается в наносекундах |
runtime_go_gc_stats_pause_quantiles_95p(gauge) | Распределение времени паузы GC: 75-й процентиль. Отображается в наносекундах |
runtime_go_gc_stats_pause_quantiles_max(gauge) | Распределение времени паузы GC: максимальные значения. Отображается в наносекундах |
Отображение метрик Go runtime
Для отображения метрик Go runtime выберите сервис, перейдите на вкладки Инстансы и откройте дашборд интересующего инстанса:

Трейсер ProtoOBP – дополнительная документация
Устаревшее
Трейсер ProtoOBP (pobp-trace-go) — устаревший вариант, оставлен для обратной совместимости. Для новых проектов используйте инструментацию на этапе компиляции (Orchestrion) или OpenTelemetry.Конфигурация трейсера при инициализации в коде
Параметры можно задать явным образом при инициализаци трейсера. В случае добавления ранее переменных окружения, достаточно указать только tracer.WithRuntimeMetrics() для отдачи метрик.
package main
import (
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func main() {
tracer.Start(
tracer.WithService("test-server"), // имя сервиса
tracer.WithRuntimeMetrics(), // включение передачи Go метрик
tracer.WithAgentAddr("protoobp-agent"), // адрес по которому доступен ProtoOBP агент
tracer.WithDogstatsdAddress("protoobp-agent"), // адрес по которому доступен ProtoOBP агент
)
defer tracer.Stop()
}
Использование трейсера
Создание трейсера
package main
import (
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func main() {
tracer.Start(
tracer.WithService("test-server"), // имя сервиса
tracer.WithRuntimeMetrics(), // включение передачи Go метрик
)
defer tracer.Stop()
}
Ручное добавление спанов
Если автоматической инструментации библиотек и фреймворков недостаточно, вы можете вручную добавить спаны. Для добавления спанов доступно две функции - StartSpan и StartSpanFromContext
//Создание спана с эндпонитом /user, который дочерный к родительскому спану.
span := tracer.StartSpan("mainOp", tracer.ResourceName("/user"), tracer.ChildOf(parentSpan))
// Создание спана, который будет дочерним к спану в контексте ctx, если в контексте есть спан.
// Возвращает новый спан, и новый контекст, содержащий спан.
span, ctx := tracer.StartSpanFromContext(ctx, "mainOp", tracer.ResourceName("/user"))
Пример ручного создания спанов
package main
import (
"io/ioutil"
"log"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/ext"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func main() {
// Запускаем трейсер и не забывает про Stop.
tracer.Start(tracer.WithAgentAddr("host:port"))
defer tracer.Stop()
// Начинаем корневой спан.
span := tracer.StartSpan("get.data")
defer span.Finish()
// Создаем дочерный спан, вычисляем время, необходимое для открытия файла.
child := tracer.StartSpan("read.file", tracer.ChildOf(span.Context()))
child.SetTag(ext.ResourceName, "test.json")
// Выполняем операцию.
_, err := ioutil.ReadFile("~/test.json")
// Мы можем завершить дочерный спан используя возвращаемую ошибку. Если это
// nil, будет отброшено.
child.Finish(tracer.WithError(err))
if err != nil {
log.Fatal(err)
}
}
Добавление тегов к спану
package main
import (
"log"
"net/http"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
// Создание спана для web request для запросов к /posts.
// ResourceName - имя эндпоинта в Proto OBP
span := tracer.StartSpan("web.request", tracer.ResourceName("/posts"))
defer span.Finish()
// Добавляем тег
span.SetTag("http.url", r.URL.Path)
span.SetTag("<TAG_KEY>", "<TAG_VALUE>")
}
func main() {
tracer.Start(tracer.WithService("<SERVICE_NAME>"))
defer tracer.Stop()
http.HandleFunc("/posts", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Пример добавления тэга к спану со значением кастомного HTTP заголовка
Используйте функцию span.SetTag("<KEY>", "<VALUE>") для добавления HTTP заголовка в тэг трейса, где:
KEY - должен начинаться с http.request.headers.<ИМЯ_HTTP_ЗАГОЛОВКА>
VALUE - значение заголовка
Пример:
package main
import (
"log"
"net/http"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
// Создание спана для web request для запросов к /posts.
// ResourceName - имя эндпоинта в Proto OBP
span := tracer.StartSpan("web.request", tracer.ResourceName("/posts"))
defer span.Finish()
// Добавляем тег
span.SetTag("http.url", r.URL.Path)
//Добавляем HTTP заголовк в тэг трейса
span.SetTag("http.request.headers.x-request-id", "<VALUE>")
}
func main() {
tracer.Start(tracer.WithService("<SERVICE_NAME>"))
defer tracer.Stop()
http.HandleFunc("/posts", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Распределенный трейсинг и обработка контекста
Мы используем тип Context для связи спанов. Если нужно добавить теги связанные с Context, вызывайте SpanFromContext:
package main
import (
"net/http"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
// Спан для веб запроса связанный с Go Context.
if span, ok := tracer.SpanFromContext(r.Context()); ok {
// добавляем тег.
span.SetTag("http.url", r.URL.Path)
}
}
Создание распределенного трейса путем ручного внедрения контекста:
package main
import (
"net/http"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
span, ctx := tracer.StartSpanFromContext(r.Context(), "post.process")
defer span.Finish()
req, err := http.NewRequest("GET", "http://example.com", nil)
req = req.WithContext(ctx)
// Внедрение Context хедеры Request
err = tracer.Inject(span.Context(), tracer.HTTPHeadersCarrier(req.Header))
if err != nil {
// Обработка или логгирование ошибки внедрения контекста
}
http.DefaultClient.Do(req)
}
Далее на серверной стороне для продолжения трейса создайте новый спан из извлеченного контекста:
package main
import (
"net/http"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
// Извлекаем контекст спана и продолжаем трейс в этом сервисе
sctx, err := tracer.Extract(tracer.HTTPHeadersCarrier(r.Header))
if err != nil {
// Обработка или логгирование ошибки извлечения контекста
}
span := tracer.StartSpan("post.filter", tracer.ChildOf(sctx))
defer span.Finish()
}
Ошибочный спан
Для добавления признака ошибки, используйте tracer.WithError:
err := someOperation()
span.Finish(tracer.WithError(err))
Трейсинг асинхронных запросов
func main() {
span, ctx := tracer.StartSpanFromContext(context.Background(), "mainOp")
defer span.Finish()
go func() {
asyncSpan := tracer.StartSpanFromContext(ctx, "asyncOp")
defer asyncSpan.Finish()
performOp()
}()
}
Использование трейсера вместе с OpenTracing
package main
import (
opentracing "github.com/opentracing/opentracing-go"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/opentracer"
"git.proto.group/protoobp/pobp-trace-go/pobptrace/tracer"
)
func main() {
//Запускаем POBP tracer, опционально передаем опции (лучше все определить через переменные окружения),
// возвращем opentracing.Tracer который оборачивает его.
t := opentracer.New(tracer.WithAgentAddr("host:port"))
defer tracer.Stop() // не забываем останавливать, иначе трейсы не придут
// Используем с Opentracing API. Уже запущенный POBP tracer
// может быть использован параллельно с Opentracing API если нужно.
opentracing.SetGlobalTracer(t)
}