OpenTelemetry
OpenTelemetry 는 프로그램이 자기 상태를 밖으로 내보낼 때 그것을 어떤 이름으로 어떻게 내보낼지 문서로 정해 둔 합의입니다. 이름과 형식을 못 박아 두면 내보내는 쪽과 받는 쪽이 서로를 몰라도 맞물립니다. 정작 그 데이터를 저장하고 화면에 그려 주는 일은 이 합의가 하지 않습니다.
쉽고 빠른 이해
OpenTelemetry 는 프로그램이 자기 상태를 밖으로 내보낼 때 어떤 이름과 형식으로 담을지 미리 정해 둔 약속입니다. 예를 들어 요청 방식이 GET 이었는지를 나타내는 값에도 정해진 이름을 붙여 내보내게 합니다.
이런 약속이 없으면 프로그램마다 이름과 형식이 제각각이라, 데이터를 모아 보여주는 쪽이 프로그램마다 따로 맞춰야 합니다. 이름과 형식을 하나로 맞춰 두면 어떤 언어로 짠 프로그램이든 같은 모양으로 데이터를 내보냅니다.
이 약속이 정하는 것은 세 가지입니다.
- 어떤 데이터에 어떤 이름을 붙일지
- 그 데이터를 실제로 만드는 방법과, 언어마다 그 방법을 구현한 것
- 만든 데이터를 다른 프로그램으로 보내는 방법
대신 이 약속만으로는 데이터를 저장하고 화면에 그려 보여주는 일까지 되지 않습니다. 어떤 제품으로 저장하고 보여줄지는 따로 골라 붙여야 하는 부담이 남습니다.
상세
공식 문서는 OpenTelemetry 를 관측성(밖으로 나온 것만 보고 안을 얼마나 알아낼 수 있는가 하는 성질) 프레임워크이자 툴킷이라고 적습니다. 개요에서 말한 「프로그램이 자기 상태를 밖으로 내보내는 것」을 이 문서는 텔레메트리 데이터라고 부릅니다. 트레이스 · 메트릭 · 로그 가 그 텔레메트리 데이터의 종류입니다. 이 생성 · 내보내기 · 수집을 수월하게 하려고 설계됐다고 밝힙니다. 오픈소스이고, 특정 벤더나 특정 도구에 매이지 않습니다. 그래서 여러 관측성 백엔드(텔레메트리 데이터를 저장하는 쪽)와 함께 쓸 수 있습니다. 오픈소스 도구도 상용 제품도 그 대상에 들어갑니다.
무엇을 안 하는지가 같은 문단에 못 박혀 있습니다. OpenTelemetry 자신은 관측성 백엔드가 아닙니다. 이 프로젝트의 주요 목표 하나는 프로그래밍 언어 · 인프라 · 런타임 환경을 가리지 않고 애플리케이션과 시스템을 쉽게 계측(시스템이 자기 동작에 관한 신호를 밖으로 내보내도록 코드를 심는 일)할 수 있게 하는 것입니다. 텔레메트리 데이터의 백엔드, 곧 저장과 프런트엔드, 곧 시각화는 의도적으로 다른 도구들에 남겨 두었습니다.
그래서 「OpenTelemetry 를 쓴다」고 말할 때 실제로 딸려 오는 것은 하나가 아닙니다. 공식 문서가 주요 구성물로 아홉 가지를 듭니다.
| 구성물 | 문서가 적은 역할 |
|---|---|
| 명세 | 모든 구성물을 규정하는 문서 |
| 표준 프로토콜 | 텔레메트리 데이터의 모양을 정의합니다 |
| 시맨틱 컨벤션 | 흔한 텔레메트리 데이터 종류에 붙일 표준 이름 체계를 정의합니다 |
| API(Application Programming Interface, 응용 프로그래밍 인터페이스) | 텔레메트리 데이터를 어떻게 생성하는지 정의합니다 |
| 언어별 SDK(Software Development Kit, 소프트웨어 개발 키트) | 명세와 API, 그리고 텔레메트리 데이터의 내보내기를 구현합니다 |
| 라이브러리 생태계 | 흔히 쓰는 라이브러리와 프레임워크에 대한 계측을 구현합니다 |
| 자동 계측 구성물 | 코드를 고치지 않고도 텔레메트리 데이터를 생성합니다 |
| OpenTelemetry Collector | 텔레메트리 데이터를 받고 처리하고 내보내는 프록시입니다 |
| 그 밖의 도구 | 쿠버네티스용 OpenTelemetry Operator, OpenTelemetry Helm 차트, FaaS(Function as a Service, 서비스형 함수)용 커뮤니티 자산 등 |
문서가 정하는 것은 이름과 모양입니다. 명세가 이 아홉 구성물 전체를 규정하는 자리에 있습니다. 그 아래에서 표준 프로토콜이 텔레메트리 데이터의 모양을 정의하고, 시맨틱 컨벤션이 거기 붙일 표준 이름 체계를 정의합니다. 명세와 API 를 실제 코드로 구현하고, 텔레메트리 데이터의 내보내기까지 맡는 것이 언어별 SDK 입니다.
block-beta columns 3 spec["명세 · 모든 구성물을 규정"]:3 proto["표준 프로토콜 · 모양을 정의"] semconv["시맨틱 컨벤션 · 이름 체계를 정의"] api["API · 생성 방법을 정의"] space sdk["언어별 SDK"] space spec --> sdk api --> sdk
출처 문서
정본은 opentelemetry.io 가 내는 명세 묶음입니다. 색인 페이지의 상태 요약표에 판 번호가 나란히 적혀 있습니다.
| 명세 | 판 |
|---|---|
| OpenTelemetry Specification | 1.60.0 |
| OTLP(OpenTelemetry Protocol) Specification | 1.11.0 |
| OpenTelemetry Semantic Conventions | 1.44.0 |
OTLP 가 상세에서 말한 표준 프로토콜의 정식 명세 이름이고, OpenTelemetry Semantic Conventions 가 시맨틱 컨벤션의 정식 명세 이름입니다. 같은 표에 Open Agent Management Protocol(OpAMP) 도 이름이 올라 있습니다. 이 색인에는 그 판 번호가 붙어 있지 않습니다. 위 세 판 번호는 색인 페이지를 조회한 시점의 값입니다.
요구 강도의 근거
명세 저장소의 specification/README.md 에 표기 규약이 있습니다. 이 규약이 정하는 것이 요구
강도입니다 — must · should · may 같은 낱말이 규칙을 얼마나 반드시 지켜야 하는지 나타내는
세기입니다. must · must not · required · should · should not · recommended · not recommended ·
may · optional 이라는 낱말들은 BCP 14
(Best Current Practice 14), 곧 RFC(Request for Comments) 2119 와 RFC 8174 에 적힌 대로
해석합니다. 다만 그 낱말들이 전부 대문자로 적혀 있을 때, 그리고 그때만 그렇게 해석합니다.
준수 여부도 이 문단이 정의합니다. 명세에 정의된 MUST · MUST NOT · REQUIRED 요구사항 가운데 하나라도 못 지키면 그 구현은 명세를 준수하지 않는 것입니다. 반대로 그 요구사항을 모두 지키면 준수하는 것입니다. 이 판정에 SHOULD 는 들어가지 않습니다.
시그널 생애주기
버전과 안정성을 다루는 문서는 자신의 상태를 stable 로 적어 두고, OpenTelemetry 클라이언트가 제공하는 안정성 보증과 그 보증을 지키기 위한 규칙 · 절차를 정의한다고 밝힙니다. 설계 목표로는 이런 것들을 듭니다. 애플리케이션 소유자가 SDK 의 최신 릴리스를 계속 따라가게 합니다. 서로 다른 OpenTelemetry 판에 기대는 패키지들 사이에 의존성 충돌이 절대 생기지 않게 합니다. 안정된 모든 공개 API 를 깨는 일을 피합니다. 하위 호환성은 엄격한 요구사항입니다. 계측 API 는 버전 충돌을 절대로 만들 수 없습니다.
이 규칙이 적용되는 단위가 시그널입니다. 시그널은 트레이스 · 메트릭 · 로그처럼 이 표준이 이름 붙인 텔레메트리 데이터의 한 종류를 가리킵니다. 시그널 하나하나는 development · stable · deprecated · removed 라는 생애주기를 따릅니다.
시그널은 OTEP(OpenTelemetry Enhancement Proposal) 0232 가 정의한 development 상태에서 시작합니다. development 인 동안에는 깨는 변경과 성능 문제가 일어날 수 있습니다. 구성물이 기능 완성이라고 기대하지 않는 것이 좋습니다. development 인 시그널에는 장기 의존을 걸지 않는 것이 좋습니다.
development 인 시그널이 엄정한 테스트를 거치면 stable 로 넘어갈 수 있습니다(may). 이때부터는 그 시그널에 장기 의존을 걸어도 됩니다. 시그널 구성물이 stable 로 표시되고 나면, 그 시그널이 존재하는 동안 정해진 규칙들이 반드시 적용됩니다. API 안정성 규칙이 그 예입니다. 주 버전 번호를 올리지 않는 한 API 패키지에 하위 비호환 변경을 하면 안 됩니다(MUST NOT).
stateDiagram-v2
[*] --> development
development --> stable: 엄정한 테스트를 거치면(may)
stable --> deprecated
deprecated --> removed
note right of stable
하위 비호환 API 변경 금지(MUST NOT)
주 버전을 올릴 때만 예외
end note
문서 상태 일곱 단계
방금의 네 단계와 별개로, 명세 문서와 구성물에 붙는 상태 딱지가 따로 정의되어 있습니다. 문서 제목 바로 아래에 표시하는 그 값입니다. 상태 표시가 없으면 alpha 와 같다고 봅니다. 아래 표에서 Development 가 Alpha 보다 앞에 있지만 이는 나열 순서일 뿐입니다. 표시가 없을 때 명세가 기본으로 가정하는 단계는 더 이른 Development 가 아니라 Alpha 입니다.
| 상태 | 문서가 적은 뜻 |
|---|---|
| Development | 구성물의 모든 조각이 아직 자리를 잡지 않았고 사용자가 쓸 수 없을 수도 있습니다. 프로덕션에 쓰지 않는 것이 좋습니다. 예고 없이 제거될 수 있습니다 |
| Alpha | 중요하지 않은 제한된 프로덕션 작업부하에 쓸 준비가 됐습니다 |
| Beta | alpha 와 같되, 인터페이스는 가능한 한 안정된 것으로 취급합니다 |
| Release Candidate | 기능이 완성됐고 더 넓게 쓸 준비가 됐습니다 |
| Stable | 일반 사용을 할 준비가 됐습니다 |
| Deprecated | 개발이 멈췄습니다. 새 판 계획이 없고 배포판에서 제거될 수 있습니다 |
| Unmaintained | 활성 코드 오너가 없는 구성물입니다 |
같은 낱말이 두 자리에 쓰인다는 점을 눈여겨봐야 합니다. 시그널 생애주기의 development · stable 과 문서 상태표의 Development · Stable 은 다른 표가 정의합니다. 이 문서는 소문자 development · stable 이면 시그널의 생애주기를, 대문자로 시작하는 Development · Stable 이면 문서 · 구성물에 붙는 상태 딱지를 가리키도록 표기를 나눠 씁니다.
명세가 안 정한 자리
저장과 시각화가 그 자리입니다. 공식 문서는 백엔드와 프런트엔드를 의도적으로 다른 도구들에 남겨 두었다고 적습니다. 그래서 무엇을 어떤 이름으로 내보낼지까지가 이 문서들의 관할이고, 그 데이터를 어디에 얼마나 쌓고 어떻게 질의할지는 받는 쪽 제품마다 갈립니다.
예시
명세 본문에 실제로 적혀 있는 값들입니다. 성격이 다른 둘을 나란히 둡니다. 하나는 데이터에 붙일 이름과 값이고, 다른 하나는 그 데이터를 어디로 보낼지의 기본값입니다.
HTTP 스팬의 속성 한 벌
스팬은 트레이스를 이루는 낱개 기록입니다. HTTP(HyperText Transfer Protocol) 스팬은 그 낱개 기록 가운데 HTTP 요청 하나를 나타냅니다. 이 스팬의 시맨틱 컨벤션이 정하는 공통 속성입니다. 속성 이름 · 요구 수준 · 타입 · 예시 값이 표로 붙어 있습니다.
| 속성 | 요구 수준 | 타입 | 문서가 든 예시 값 |
|---|---|---|---|
http.request.method |
Required | string | GET · POST · HEAD |
server.address |
Required | string | example.com · 10.1.2.80 · /tmp/my.sock |
server.port |
Required | int | 80 · 8080 · 443 |
url.full |
Required | string | https://www.foo.bar/search?q=opentelemetry#semconv · //localhost |
error.type |
Conditionally Required — 요청이 오류로 끝났을 때 | string | timeout · java.net.UnknownHostException · SERVER_CERTIFICATE_INVALID · 500 |
http.request.method_original |
Conditionally Required — 조건은 각주로 넘어가 있습니다 | string | GET · ACL · foo |
http.response.status_code |
Conditionally Required — 받았거나 보냈을 때에 한해서 | int | 200 |
요구 수준이 Required 인 속성은 그 스팬을 만들 때 반드시 들어갑니다. Conditionally Required 는
조건이 따로 붙습니다. server.address 는
역방향 DNS(Domain Name System, 도메인 이름 시스템)
조회 없이 알 수 있으면 서버 도메인 이름, 아니면 IP(Internet Protocol, 인터넷 프로토콜) 주소나
유닉스 도메인 소켓 이름을 적습니다. url.full 은 RFC 3986 에 따라 네트워크 리소스를 서술하는
절대 URL(Uniform Resource Locator, 통합 자원 위치 지정자) 입니다. http.request.method_original 은 클라이언트가 요청 줄에
실제로 보낸 원래 메서드를 그대로 담는 자리라, foo 같은 값도 예시로 실려 있습니다. 다만 이
속성이 언제 필수가 되는지는 표에 안 적혀 있습니다. 표는 각주 번호만 달아 두고 조건을 각주로
넘깁니다. 조건을 알려면 그 각주를 따라가야 합니다.
OTLP 엔드포인트의 기본값
내보내기 설정은 환경변수로 받습니다. 같은 이름의 옵션이 전송 방식에 따라 다른 기본값을 가집니다.
OTLP/HTTP 기본값 http://localhost:4318
OTLP/gRPC 기본값 http://localhost:4317
OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
이 네 환경변수가 그 값을 받습니다. 타입은 문자열입니다. 앞서 상세가 말한 내보내기를 실제로 수행하는 구성 요소가 익스포터입니다. 익스포터가 스팬 · 메트릭 · 로그를 보낼 대상이 이 값입니다. OTLP/HTTP 쪽 명세는 이 대상을 URL 이라 부르고, OTLP/gRPC(gRPC Remote Procedure Calls) 쪽 명세는 그냥 대상이라고만 부릅니다. 포트 4318 과 4317 이 갈리는 것이 전송 방식이 갈린다는 표시입니다.
배경
트레이스 · 메트릭 · 로그를 코드에서 뽑아 관측성 백엔드로 보내는 일에는 표준이 없었습니다. 공식 문서는 그것을 「the lack of a standard」, 곧 코드를 어떻게 계측하고 텔레메트리 데이터를 어떻게 관측성 백엔드로 보낼지에 대한 표준의 부재라고 적습니다.
이 문제를 풀려고 만들어진 프로젝트가 둘 있었습니다. OpenTracing 과 OpenCensus 입니다. 둘 다 같은 문제를 풀려고 생겼습니다. 어느 쪽도 그 문제를 혼자서 온전히 풀어내지는 못했습니다. 그래서 둘은 합쳐져 OpenTelemetry 가 됐고, 각자의 강점을 합치면서 하나의 해법을 내놓게 됐습니다. 결과물은 CNCF(Cloud Native Computing Foundation) 프로젝트입니다. 표준이 없다는 문제에 이름을 붙여 문서로 굳힌 것이 이 표제어입니다.
합쳐진 쪽은 처음부터 앞의 둘의 다음 주 버전으로 여겨졌습니다. 그래서 두 프로젝트에 대한 하위 호환과 기존 사용자를 위한 이전 경로를 제공하는 것이 이 프로젝트의 핵심 목표 가운데 하나가 됐습니다. 이전 경로는 앞의 두 프로젝트 밖으로도 이어집니다. Jaeger 커뮤니티는 자기 클라이언트 라이브러리를 폐기하고 OpenTelemetry 의 API · SDK · 계측으로 옮길 것을 권고했습니다. Jaeger 백엔드는 v1.35 부터 OTLP 로 트레이스 데이터를 받습니다.
flowchart TD
ot["OpenTracing"] --> merge["병합"]
oc["OpenCensus"] --> merge
merge --> otel["OpenTelemetry"]
jc["Jaeger 클라이언트 라이브러리"] -- 폐기 · 이전 권고 --> otel_api["OpenTelemetry API · SDK · 계측"]
관련 항목
이 표준이 정하는 구성물
OTLP · OpenTelemetry Collector · 시맨틱 컨벤션 · 계측 · 자동 계측 · 언어별 SDK · OpenTelemetry Operator · OpAMP
내보내는 데이터에 붙는 이름
스팬 · 트레이스 · 메트릭 · 로그 · 프로파일 · 배기지 · 컨텍스트 전파 · W3C(World Wide Web Consortium, 월드 와이드 웹 컨소시엄) Trace Context
이 표준이 비롯된 배경
OpenTracing · OpenCensus · CNCF · OTEP
이 표준이 속하는 관측성 분야
Jaeger · Prometheus · 관측성 · 모니터링
다른 이름: OTel · 오픈텔레메트리