Alibaba Cloud Observability와 Datadog, OpenTelemetry Go 자동 계측 도구 출시
Source: Dev.to
Source: …
작동 방식
자동 계측 도구는 Go 컴파일러의 -toolexec 매개변수를 활용합니다. -toolexec는 go 명령을 가로채어 우리의 계측 도구로 대체함으로써, 컴파일 전에 소스를 분석하고 수정할 수 있는 기회를 제공합니다. 이 과정은 두 단계로 구성됩니다:
1. 의존성 분석
- 컴파일이 시작되기 전에 도구는
go build -n을 실행해 빌드 흐름을 분석하고 프로젝트에서 사용되는 서드‑파티 라이브러리(예:net/http,grpc,redis)를 탐지합니다. - 그런 다음 자동으로
otel.runtime.go라는 파일을 생성하고, 해당 Hook 코드(모니터링 로직)를 빌드 의존성에 import합니다.
2. 코드 삽입
- 컴파일러가 대상 함수를 처리할 때, 도구는 다시
-toolexec를 사용해 컴파일을 가로채고 함수 코드를 수정합니다. - 함수 진입점에 Trampoline 스니펫을 삽입하여 미리 작성된 Hook 함수로 점프하도록 합니다.
Hook은 세 가지 작업을 수행합니다:
| 단계 | Hook이 수행하는 작업 |
|---|---|
| Before (함수 진입) | 시작 시간을 기록하고, 컨텍스트 정보(예: HTTP 헤더)를 추출한 뒤, 스팬을 시작합니다. |
| During (원래 비즈니스 로직) | 원본 함수 본문을 그대로 실행합니다. |
| After (함수 종료) | 반환값 또는 panic을 포착하고, 스팬을 종료하며, 소요 시간을 기록합니다. |
계측이 바이너리에 직접 컴파일되기 때문에 런타임 오버헤드가 0에 가깝습니다(모니터링 로직 자체의 실행 시간은 제외). eBPF와 달리 커널‑스페이스 ↔ 유저‑스페이스 전환이 필요 없으며, Java 에이전트와 달리 런타임 로딩 단계도 필요하지 않습니다.
HTTP Instrumentation Example
Simple HTTP Server (no instrumentation)
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/greet", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("Hello, OpenTelemetry!"))
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
Manual Instrumentation
package main
import (
"context"
"log"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/trace"
)
func initTracer() func(context.Context) error {
// ... dozens of lines of initialization code ...
return func(ctx context.Context) error { return nil }
}
func main() {
// 1️⃣ Initialize the tracer.
shutdown := initTracer()
defer shutdown(context.Background())
// 2️⃣ Wrap the handler.
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 3️⃣ Manually extract the context and start the span.
tracer := otel.Tracer("demo-server")
ctx, span := tracer.Start(r.Context(), "GET /greet")
defer span.End()
// 4️⃣ Record attributes if needed.
span.SetAttributes(attribute.String("http.method", "GET"))
// 5️⃣ Business logic.
_, _ = w.Write([]byte("Hello, OpenTelemetry!"))
// 6️⃣ (Optional) Use the derived context for downstream calls.
_ = ctx
})
// 7️⃣ Start the server.
log.Fatal(http.ListenAndServe(":8080", handler))
}
수백 개 또는 수천 개의 API를 가진 마이크로서비스에서는 이러한 코드를 수동으로 추가하는 것이 노력과 유지보수 측면에서 재앙이 됩니다.
Automatic Instrumentation
-
도구 다운로드 – Release Page1에서 바이너리를 받아옵니다.
-
애플리케이션 컴파일
./otel-linux-amd64 go build -o myapp -
설정 및 실행
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" export OTEL_SERVICE_NAME="my-app" ./myapp
컴파일러는 바이너리에 HTTP 요청 모니터링 로직을 조용히 “삽입”합니다. OpenTelemetry 익스포터(예: Jaeger, 콘솔)를 설정한 뒤 서버를 실행하면 /greet 엔드포인트에 대한 URI, 소요 시간, 상태 코드 등 추적 데이터가 코드 변경 없이 자동으로 생성·보고됩니다.
상용에서 오픈‑소스로
광범위한 eBPF 실습을 진행하면서 우리는 그 강력함을 인식했지만, 애플리케이션 레이어 컨텍스트를 완벽하게 처리하는 데 어려움이 있다는 점도 알게 되었습니다. 더 중요한 것은 사용자 피드백에서 반복적으로 지적된 번거로운 수동 추적과 높은 유지보수 비용이라는 고통이었습니다.
이 문제를 해결하기 위해 Go 컴파일‑타임 자동 계측 솔루션을 탐색했으며, 처음에는 Alibaba Cloud Observability의 Application Real‑Time Monitoring Service (ARMS)2에 공개했습니다. 이 엄격한 “실험 현장”에서 지속적인 반복을 거치면서 접근 방식은 코드 없이 추적을 제공하는 견고한 오픈‑소스 솔루션으로 성숙했습니다.
참고 문헌
향상된 가시성 기능
이 솔루션은 다음과 같은 풍부하고 고급 기능을 지원하도록 확장되었습니다:
- 메트릭 통계
- 런타임 모니터링
- 지속적인 프로파일링
또한 맞춤형 확장 기능을 통해 기업 내부 SDK의 이벤트‑추적까지 완전하게 수행할 수 있습니다 [4].
추적 분석

연속 프로파일링
이 솔루션은 전자상거래, 짧은 형식 비디오, AI 비디오, 자동차 등 다양한 분야의 고객에게 성공적으로 검증되었습니다. 사용자에게 제공하는 막대한 가치와 안정성·실현 가능성을 확인한 후, 우리는 핵심 기능을 OpenTelemetry 커뮤니티에 기여하기로 결정했으며, 이를 통해 포괄적인 기술이 되기를 기대합니다.
또한 관측성 분야의 선도 벤더인 Datadog과 협업하여 이 공식 프로젝트 [1]의 홍보와 탄생을 공동으로 촉진했습니다.
프로젝트는 현재 활발히 개발 중이며, 모든 분들이 직접 사용해 보고 피드백을 제공하며 더 나은 클라우드‑네이티브 관측성 생태계 구축에 기여해 주시길 환영합니다.
References
- OpenTelemetry Go compile‑instrumentation project –
- Release link –
- Alibaba Cloud ARMS Go Agent (Commercial Edition) –
- Custom extension –
Footnotes
-
Release page – https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/releases ↩
-
Alibaba Cloud Observability – ARMS 문서 (내부 링크) ↩