Известные ограничения для поддержки Go

Материал из Dynatrace
Версия от 10:11, 22 января 2023; Lobanov (обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)

Прежде чем начать использовать мониторинг приложений Go, убедитесь, что вы знаете об известных ограничениях.

Поддержка ограничена официальными стабильными выпусками Go

Поддержка Go ограничена официальными стабильными выпусками Go, скомпилированными с помощью инструментария Golang.

OneAgent не поддерживает двоичные файлы, скомпилированные с использованием набора инструментов gccgo.

Двоичные файлы приложения должны быть динамически связаны

Это ограничение применяется только к системам Linux и если статический мониторинг Go отключен.

Для полностью автоматического внедрения OneAgent требуются динамически связанные двоичные файлы приложений. Динамическое связывание применяется автоматически, когда приложение использует определенные стандартные пакеты библиотеки времени выполнения, например net / http.

Во всех остальных случаях вы можете принудительно установить динамическое связывание с помощью параметра командной строки -ldflags '-linkmode = external'. Обратите внимание, что отключение cgo, например, с использованием CGO_ENABLED = 0, не поддерживается, и OneAgent отклонит полученный двоичный файл приложения.

Поддержка статического мониторинга

Dynatrace OneAgent поддерживает статический мониторинг приложений Go, начиная с OneAgent версии 1.203. Инструкции по включению этой функции см. в разделе Включение статического мониторинга Go.

Ограничения

Полностью автоматическая статическая инъекция OneAgent поддерживается, если родительский процесс, например оболочка, такая как /bin/bash, которая запускает статически связанный двоичный файл Go, связан динамически. Однако после включения статического мониторинга Go перезапустите родительский процесс, чтобы включить автоматическое внедрение.

Статические приложения Go, использующие cgo, не поддерживаются.

OneAgent отклоняет мониторинг статических двоичных файлов Go, которые используют cgo и, следовательно, имеют статическую зависимость от системной библиотеки C libc. Эта версия статически связанной библиотеки libc может конфликтовать с версией, используемой OneAgent.

Обходной путь

Создайте приложение Go как динамически связанный исполняемый файл (который динамически связывается с libc). Это гарантирует, что и приложение Go, и OneAgent используют одну и ту же версию libc, доступную на хосте.

Для статического мониторинга Go требуется возможность SYS_PTRACE в контейнерах Docker.

Возможность SYS_PTRACE включена по умолчанию для Docker 19.03.0+ и ядра Linux 4.8+. Он разрешает системные вызовы между процессами, работающими в контейнере, что является требованием для статического мониторинга Go.

Обходной путь

Для версии Docker ниже 19.03.0 или версии ядра Linux ниже 4.8 запустите контейнер с возможностью SYS_PTRACE:

docker run --cap-add=SYS_PTRACE <container> ...

Образы Docker, которые не предоставляют системную библиотеку C, не поддерживаются.

OneAgent требует, чтобы системная библиотека C была доступна на отслеживаемом узле.

Пример и обходной путь

Примером может служить scratch image:

FROM scratch
COPY StaticGoMinimal /
CMD ["/StaticGoMinimal"]

Чтобы обойти это ограничение, измените базовый образ контейнера на тот, который предоставляет системную библиотеку C, например, образ alpine:

FROM alpine:3.11
COPY StaticGoMinimal /
CMD ["/StaticGoMinimal"]

Побочные эффекты

Файл proc/<pId>/exe относится к исполняемому файлу с именем oneagentdynamizer, а не к бинарному файлу приложения Go. Он содержится в псевдофайловой системе proc, которая предоставляет интерфейс к структурам данных ядра запущенных процессов. Это может привести к тому, что системные инструменты, такие как ps или top, будут отображать oneagentdynamizer вместо имени двоичного файла Go в своих выходных данных.

Приложения не могут быть созданы с параметром -linkshared

Go поддерживает динамическое связывание стандартной библиотеки Go. Этот режим сборки используется редко, и OneAgent не будет внедряться в приложения, созданные таким образом.

Пример

Рассмотрим следующее минималистичное приложение Go под названием GoMinimal.go:

go install -buildmode=shared -linkshared std
go build -linkshared GoMinimal.go

OneAgent отклонит полученный двоичный файл приложения.

Приложения, загружающие плагины Go, не поддерживаются

Плагин Go — это пакет, скомпилированный с использованием флага сборки -buildmode=plugin для создания общего объектного файла. Этот режим сборки редко используется, и OneAgent отключит глубокий мониторинг, когда приложение фактически загружает плагин Go.

Пакеты сторонних производителей не поддерживаются

Вендинг Go используется для включения локальных копий внешних зависимостей в репозиторий проекта. Этот подход использовался для закрепления версий сторонних пакетов до того, как была добавлена ​​поддержка модуля Go.

OneAgent не будет отслеживать пакеты поставщиков. Например, службы gRPC поддерживаются только при использовании модулей Go или при непосредственном импорте go-grpc без использования системы управления зависимостями.

Приложения должны содержать таблицу символов

OneAgent использует информацию, хранящуюся в таблице символов двоичного файла приложения. По умолчанию Go создает таблицу символов в двоичном файле приложения, но это можно подавить параметрами командной строки или внешними инструментами, такими как полоса.

Редко используемая команда go run <application> создает и запускает приложения на лету. Поскольку выходной файл приложения является временным (файл автоматически удаляется после закрытия приложения), двоичный файл приложения не содержит таблицы символов. Таким образом, OneAgent не может контролировать приложение, созданное с помощью команды go run <application>.

Приложения, созданные с включенным race detector, не поддерживаются

Приложение, созданное с флагом -race, содержит встроенный data race detector. Этот режим сборки в основном используется в среде разработки, и OneAgent не будет внедряться в приложения, созданные таким образом.

Профилирование стека создания потоков ОС отключено

OneAgent не поддерживает предопределенный профиль threadcreate. Результаты профилирования создания потоков для приложений Go, отслеживаемых OneAgent, будут содержать только пустые трассировки стека.

Поддержка musl libc

Библиотека musl libc является заменой библиотеки glibc. Dynatrace поддерживает приложения Go на основе musl, например, созданные на Alpine Linux.

Существует одно дополнительное требование для создания динамически подключаемого двоичного файла приложения. Вы должны использовать цепочку инструментов Go для alpine (golang:<версия>-alpine) и добавить -ldflags '-linkmode external' в командную строку сборки, чтобы принудительно использовать системный компоновщик. Это не требуется для статически связанных приложений Go, отслеживаемых статическим мониторингом Go.

Подробности

Хотя musl libc очень похожа на функциональность glibc, между ними есть тонкие поведенческие различия. Более того, Go официально не поддерживает набор инструментов Go на основе musl, а это означает, что бинарные файлы набора инструментов Go нельзя загрузить с веб-сайта golang.org.

Кроме того, существует серьезная проблема с тем, как Go использует musl libc. Это ограничивает степень, в которой Dynatrace может поддерживать приложения на основе musl. Цепочка инструментов Go включает внутренний компоновщик, который генерирует двоичные файлы приложений на основе musl, которые неправильно инициализируют musl libc при запуске приложения. Эта проблема не позволяет Dynatrace отслеживать эти приложения. В таком случае на соответствующей странице обработки заявки отображается следующее сообщение:

Активация глубокого мониторинга не удалась, мониторинг двоичных файлов Go musl, созданных с помощью внутреннего компоновщика Go, не поддерживается.

Если вы используете системный компоновщик для создания двоичного файла приложения, он добавляет код запуска, который правильно инициализирует общие объекты. Кроме того, добавление -ldflags 'linkmode external' в командную строку сборки обеспечивает использование системного компоновщика. Полученный двоичный файл будет выполняться с правильно инициализированной libc, что позволит Dynatrace контролировать такое приложение.

Пример

Рассмотрим следующее минималистичное приложение Go под названием GoMinimal.go:

package main
import "fmt"
func main() {
    fmt.Print("Enter text: ")
    var input string
    fmt.Scanln(&input)
    fmt.Print(input)
}

Следующий многоэтапный файл докера дает действительный динамически связанный двоичный файл Go musl на этапе 1 и запускает приложение на этапе 2.

# --- Stage 1:
# Use Golang toolchain for alpine to build the application.
FROM golang:1.13.5-alpine as builder
RUN apk update && apk add gcc libc-dev

# Copy local code, for example, GoMinimal.go, to the container image.
COPY ./GoMinimal.go ./GoMinimal.go

# Build dynamically linked Go binary.
RUN go build -ldflags '-linkmode=external' GoMinimal.go

# --- Stage 2:
# Use a Docker multi-stage build to create a lean production image.
FROM alpine:3.11
# Install ca-certificates and libc6-compat for Go programs to work properly.
RUN apk add --no-cache ca-certificates libc6-compat

# Copy the binary to the production image from the builder stage.
COPY --from=builder /go/GoMinimal /GoMinimal

# Run the application on container startup.
CMD ["/GoMinimal"]

Соберите контейнер и запустите приложение:

docker build -t gominimal-alpine .
docker run --interactive gominimal-alpine