OpenTelemetry Go(otelc)¶
OpenTelemetry Go Compile-Time Instrumentation은 otelc를 사용하여 Go 컴파일 단계에서 OpenTelemetry SDK 초기화 및 컴포넌트 계측 로직을 자동으로 주입합니다. 애플리케이션은 비즈니스 코드를 수정할 필요 없이 기존 go build를 go tool otelc go build로 대체하기만 하면 OTLP를 통해 텔레메트리 데이터를 DataKit으로 전송하고 Guance로 전달할 수 있습니다.
이 문서에서는 otelc v1.1.0, 호스트에 설치된 DataKit, OTLP/gRPC를 예시로 Go HTTP 서비스의 Trace를 연결하는 방법을 설명합니다.
참고:
otelc의 "제로 코드"는 비즈니스 코드에서 OpenTelemetry SDK를 수동으로 가져오거나 초기화할 필요가 없다는 의미이며, 재빌드가 필요하지 않다는 의미는 아닙니다. 이미 생성된 일반 Go 바이너리에 계측을 직접 추가할 수 없으므로otelc를 사용하여 다시 컴파일하고 새 아티팩트를 배포해야 합니다.
전제 조건¶
- Go 1.25 이상
- Go Module을 사용하는 프로젝트이며 일반
go build로 정상 컴파일되어야 함 - DataKit이 설치되어 있고, DataKit이 대상 Guance 워크스페이스에 연결되어 있어야 함
- Go 애플리케이션에서 DataKit으로 네트워크 접근 가능: OTLP/gRPC는 기본적으로
4317포트를 사용하고, OTLP/HTTP는 DataKit HTTP 포트9529를 사용 - 애플리케이션에서 사용하는 프레임워크 또는 컴포넌트가
otelc v1.1.0에서 지원되어야 함 - 애플리케이션에서 OpenTelemetry SDK를 중복 초기화하지 않아야 함. SDK 수명 주기를 직접 제어해야 하는 프로젝트는 OpenTelemetry Go SDK 연결 방식을 사용해야 함
이 문서에서는 Linux 호스트와 net/http 서비스를 기준으로 설명하며, Kubernetes 배포는 포함하지 않습니다.
1. OpenTelemetry 수집기 활성화¶
DataKit의 OpenTelemetry 수집기 디렉토리로 이동합니다. 설정 파일이 아직 없으면 예제 설정을 복사합니다.
opentelemetry.conf에 최소한 다음 설정이 포함되어 있는지 확인합니다.
[[inputs.opentelemetry]]
# Guance 태그로 유지해야 하는 사용자 정의 속성 화이트리스트입니다.
customer_tags = ["team", "project"]
[inputs.opentelemetry.http]
http_status_ok = 200
trace_api = "/otel/v1/traces"
metric_api = "/otel/v1/metrics"
[inputs.opentelemetry.grpc]
addr = "127.0.0.1:4317"
위 설정은 다음 수신 주소에 해당합니다.
| 프로토콜 | 데이터 유형 | DataKit 수신 주소 |
|---|---|---|
| OTLP/gRPC | Trace, Metric | http://<DataKit-IP>:4317 |
| OTLP/HTTP + Protobuf | Trace | http://<DataKit-IP>:9529/otel/v1/traces |
| OTLP/HTTP + Protobuf | Metric | http://<DataKit-IP>:9529/otel/v1/metrics |
애플리케이션이 DataKit과 동일한 호스트에 있지 않은 경우, gRPC의 addr을 애플리케이션에서 접근 가능한 수신 주소(예: 0.0.0.0:4317)로 조정하고 방화벽 또는 기타 네트워크 액세스 제어를 함께 구성하십시오. OTLP 수신 포트를 공용 네트워크에 직접 노출하지 마십시오.
DataKit을 재시작하여 설정을 적용합니다.
DataKit 및 gRPC 포트를 확인합니다.
2. 애플리케이션 OpenTelemetry 연결¶
계측 전 확인¶
애플리케이션의 Go Module 루트 디렉토리로 이동하여 원본 프로젝트가 정상적으로 빌드될 수 있는지 확인합니다.
현재 디렉토리에 go.mod가 없으면 먼저 Module을 초기화합니다.
프로젝트가 OpenTelemetry SDK 또는 Contrib 계측 라이브러리에 이미 직접 의존하고 있는지 확인합니다.
otelc는 SDK 초기화 로직을 주입합니다. 프로젝트에 이미 다른 SDK 초기화 또는 중복된 HTTP instrumentation이 있는 경우 중복 Span, Provider 재정의 또는 의존성 버전 충돌이 발생할 수 있습니다. 이 문서에서는 비즈니스 코드에서 SDK에 직접 연결하지 않는 것을 권장합니다.
otelc 설치¶
Go tool 명령어를 사용하여 otelc v1.1.0을 설치하고 고정합니다.
도구 버전을 확인합니다.
예상 출력:
프로덕션 빌드에서는 go.mod와 go.sum에 버전을 고정하고, @latest를 사용하여 버전을 고정하지 않은 상태로 사용하지 마십시오.
otelc를 사용한 컴파일¶
기존 빌드 매개변수를 유지하고 go build 앞에 go tool otelc만 추가합니다.
일반적인 빌드 매개변수를 포함한 예시:
mkdir -p ./bin
go tool otelc go build \
-trimpath \
-ldflags="-s -w" \
-o ./bin/my-service \
./cmd/my-service
otelc go는 현재 go build, go install 및 go test를 지원합니다. 첫 번째 계측 빌드에서는 OpenTelemetry 의존성을 다운로드하고 컴파일해야 하므로 일반 go build보다 현저히 느릴 수 있습니다. 터미널에 명령 프롬프트가 다시 나타나면 빌드가 완료된 것입니다.
빌드가 완료되면 .otelc-build/matched.json에 일치하는 규칙이 기록됩니다. HTTP 서버 측 Hook을 확인합니다.
jq -e '[.. | objects | .name?] | index("server_hook") != null' \
.otelc-build/matched.json >/dev/null
주의: 릴리스 프로세스에서는
go tool otelc go build로 생성된 바이너리를 배포해야 합니다. 이후 일반go build로 아티팩트를 덮어쓰면 런타임에 자동 계측이 포함되지 않습니다.
OTLP/gRPC 구성 및 시작¶
다음 구성은 net/http Trace만 활성화하고 OTLP/gRPC를 통해 로컬 DataKit으로 전송합니다.
export OTEL_SERVICE_NAME="my-service"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=prod,service.version=1.0.0,team=backend"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="none"
export OTEL_LOGS_EXPORTER="none"
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4317"
export OTEL_EXPORTER_OTLP_INSECURE="true"
export OTEL_GO_ENABLED_INSTRUMENTATIONS="nethttp"
./my-service
실행 매개변수는 컴파일 호스트뿐만 아니라 계측된 바이너리의 실제 실행 환경에 구성되어야 합니다. 애플리케이션을 시작한 후 지원되는 구성 요소가 처리하는 엔드포인트를 요청하여 검증 가능한 Span을 생성합니다.
프로덕션 환경에서는 TLS 엔드포인트를 사용하고 Secret을 통해 인증서 및 인증 헤더를 관리해야 합니다. http://127.0.0.1:4317은 로컬 연결에만 적합합니다.
OTLP/HTTP 사용¶
OTLP/HTTP + Protobuf로 변경하려면 프로토콜과 엔드포인트를 교체합니다.
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:9529/otel"
export OTEL_EXPORTER_OTLP_INSECURE="true"
Exporter는 데이터 유형에 따라 /v1/traces 또는 /v1/metrics를 자동으로 추가합니다. Trace 엔드포인트만 설정하는 경우 다음을 직접 사용할 수도 있습니다.
3. 데이터 전송 매개변수¶
리소스 및 Exporter 매개변수¶
| 환경 변수 | 설명 | 권장 값 또는 예시 |
|---|---|---|
OTEL_SERVICE_NAME |
Guance에서 APM 서비스 귀속을 결정하는 핵심 필드 | my-service, 반드시 명시적으로 설정 |
OTEL_RESOURCE_ATTRIBUTES |
리소스 속성, 여러 개의 key=value는 쉼표로 구분 |
deployment.environment.name=prod,service.version=1.0.0 |
OTEL_TRACES_EXPORTER |
Trace Exporter | DataKit으로 전송 시 otlp로 설정 |
OTEL_METRICS_EXPORTER |
Metric Exporter | 수집하지 않을 경우 none으로 설정 |
OTEL_LOGS_EXPORTER |
Log Exporter | OTLP를 통해 애플리케이션 로그를 수집하지 않을 경우 none으로 설정 |
OTEL_EXPORTER_OTLP_PROTOCOL |
일반 OTLP 프로토콜 | grpc 또는 http/protobuf |
OTEL_EXPORTER_OTLP_ENDPOINT |
모든 OTLP 신호에 공통으로 사용되는 엔드포인트 | gRPC: http://datakit-host:4317 |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
Trace 전용 엔드포인트, 일반 값보다 우선 | HTTP: http://datakit-host:9529/otel/v1/traces |
OTEL_EXPORTER_OTLP_INSECURE |
비 TLS 연결 사용 여부 | 로컬 평문 연결 시 true로 설정 |
OTEL_EXPORTER_OTLP_HEADERS |
OTLP 요청 인증 헤더 | Secret을 통해 주입, 코드나 이미지에 포함하지 않음 |
계측, 샘플링 및 디버그 매개변수¶
| 환경 변수 | 설명 | 권장 값 또는 예시 |
|---|---|---|
OTEL_GO_ENABLED_INSTRUMENTATIONS |
런타임 계측 화이트리스트 | HTTP 서비스는 nethttp 사용 |
OTEL_GO_DISABLED_INSTRUMENTATIONS |
런타임 계측 블랙리스트 | 필요에 따라 비활성화, 예: redis |
OTEL_TRACES_SAMPLER |
Trace 샘플러 | 연결 확인 시 parentbased_always_on 사용 |
OTEL_TRACES_SAMPLER_ARG |
비율 샘플링 매개변수 | 예: 0.10, parentbased_traceidratio와 함께 사용 |
OTEL_PROPAGATORS |
Trace Context 전파 형식 | tracecontext,baggage |
OTEL_LOG_LEVEL |
otelc가 주입한 런타임의 로그 수준 |
기본값 info, 문제 해결 시 debug 사용 |
OTEL_GO_SIMPLE_SPAN_PROCESSOR |
Span을 개별적으로 즉시 내보낼지 여부 | 로컬 문제 해결 시에만 true로 설정 |
OTEL_SDK_DISABLED |
주입된 SDK 비활성화 여부 | true로 설정 시 수집 및 전송 중단 |
OTELC_DEBUG |
상세 빌드 로그 기록 여부 | 문제 해결 시 1로 설정 |
OTEL_GO_ENABLED_INSTRUMENTATIONS와 OTEL_GO_DISABLED_INSTRUMENTATIONS는 이미 바이너리에 컴파일된 계측만 제어합니다. 두 변수가 동시에 존재하는 경우 화이트리스트가 먼저 적용되고 블랙리스트 내용이 제외됩니다.
프로덕션 환경에서는 트래픽과 데이터 예산에 따라 샘플링 비율을 설정해야 합니다. 애플리케이션 측 샘플링과 DataKit 측 샘플링이 동시에 활성화되면 최종 유지율이 더 낮아지므로 샘플링 위치를 통합하여 계획해야 합니다.
지원되는 구성 요소¶
otelc v1.1.0에 내장된 규칙은 다음과 같은 일반적인 구성 요소를 지원합니다.
| 유형 | 구성 요소 |
|---|---|
| HTTP | net/http 클라이언트 및 서버, Gin |
| RPC | gRPC 클라이언트 및 서버 |
| 데이터베이스 | database/sql, Redis v9, MongoDB |
| 메시지 큐 | Kafka Go |
| 클라우드 및 인프라 | Kubernetes client-go, AWS SDK for Go v2, Linode Go v2 |
| GenAI | OpenAI Go v1/v2/v3, Anthropic Go SDK |
| 로그 연동 | 표준 라이브러리 log, log/slog, Logrus |
실제 지원 범위는 구성 요소 버전 및 빌드 방식에 따라 영향을 받을 수 있습니다. 애플리케이션 의존성 또는 otelc를 업그레이드한 후에는 .otelc-build/matched.json을 다시 확인하고 링크 회귀 테스트를 수행해야 합니다.
필드 매핑¶
DataKit OpenTelemetry 수집기는 일반적인 OpenTelemetry Span Attributes를 Guance 링크 필드로 변환합니다.
| OpenTelemetry 속성 | DataKit 필드 |
|---|---|
http.request.method |
http_method |
http.response.status_code |
http_status_code |
network.protocol.name |
net_protocol_name |
network.protocol.version |
net_protocol_version |
db.system.name |
db_system |
db.operation.name |
db_operation |
db.query.text |
db_statement |
rpc.system.name |
rpc_system |
rpc.method |
rpc_method |
다른 Attributes를 Guance 태그로 유지하려면 DataKit opentelemetry.conf에서 customer_tags를 구성할 수 있습니다. 사용자 ID, 주문 번호와 같은 높은 카디널리티 값을 일괄적으로 태그로 승격시키지 말고, 비밀번호, 토큰, 전체 데이터베이스 연결 문자열과 같은 민감한 정보를 전송하지 마십시오.
연결 확인¶
- 도구 버전과 계측 빌드가 모두 성공했는지 확인합니다.
- 애플리케이션을 시작하고 로그에 다음 내용이 나타나고 OTLP 내보내기 오류가 없는지 확인합니다.
trace provider initialized with auto-export
OpenTelemetry initialized
HTTP server instrumentation initialized
- 애플리케이션 엔드포인트를 요청하여 Trace를 생성합니다.
- 빌드 규칙에
server_hook가 포함되어 있는지 확인합니다.
- OTLP/gRPC를 사용하는 경우 DataKit 호스트에서 수신 카운트가 증가하는지 확인할 수 있습니다.
curl -fsS http://127.0.0.1:9529/metrics \
| grep 'opentelemetry.proto.collector.trace.v1.TraceService/Export'
- Guance의 '애플리케이션 성능 모니터링(APM) > 링크'로 이동하여
service:my-service로 검색하고 방금 요청으로 생성된 Trace를 확인할 수 있는지 확인합니다.
자주 묻는 질문¶
go.mod file not found¶
go get -tool은 Go Module 내에서 실행해야 합니다. 프로젝트 루트 디렉토리로 이동하거나 먼저 다음을 실행합니다.
컴파일이 WORK=/tmp/go-build...에서 멈춤¶
첫 번째 계측 빌드는 많은 의존성을 컴파일해야 합니다. go tool otelc go build 프로세스가 계속 실행 중이면 기다리십시오. 터미널에 명령 프롬프트가 다시 나타나면 빌드가 완료된 것입니다. 컴파일 중에 애플리케이션 바이너리를 미리 실행하지 마십시오.
요청 포트 연결 실패¶
컴파일이 완료되었는지 확인하고 계측된 바이너리를 시작한 후 수신 포트를 확인합니다.
애플리케이션은 정상이지만 Guance에 Trace가 없음¶
다음 항목을 순서대로 확인합니다.
- 배포된 바이너리가
go tool otelc go build로 생성된 것인지 확인 OTEL_SERVICE_NAME, Exporter, 프로토콜 및 엔드포인트가 실제 실행 중인 프로세스에 구성되어 있는지 확인.otelc-build/matched.json에 예상 규칙이 포함되어 있는지 확인OTEL_GO_ENABLED_INSTRUMENTATIONS에 대상 구성 요소가 포함되어 있는지 확인- DataKit OpenTelemetry 수집기가 활성화되어 있고 재시작되어 적용되었는지 확인
- 애플리케이션에서 DataKit까지의 네트워크 및
4317또는9529포트에 연결할 수 있는지 확인
빌드 문제는 임시로 상세 로그를 활성화할 수 있습니다.
상세 로그는 .otelc-build/debug.log에 위치합니다. 문제 해결이 완료되면 Debug를 비활성화하여 로그가 계속 증가하지 않도록 합니다.
첫 번째 Ctrl+C 후 애플리케이션이 종료되지 않음¶
otelc v1.1.0이 주입한 런타임은 SIGINT 및 SIGTERM을 수신합니다. 첫 번째 신호는 텔레메트리 데이터를 플러시하는 데 사용되지만, 애플리케이션은 자체 종료 프로세스를 담당합니다. 정상적인 종료를 구현하지 않은 간단한 애플리케이션의 경우 신호를 다시 보내야 할 수 있습니다. 프로덕션 서비스는 Go 표준 라이브러리를 사용하여 HTTP Server의 정상적인 종료를 구현하고 텔레메트리 플러시 시간을 확보해야 합니다.