6.3 o11y 레퍼런스 #6

이번 데모는 오픈텔레메트리 메트릭입니다. 오픈텔레메트리는 Counter, Histogram, Gauge 등 다양한 유형의 메트릭을 제공합니다.

각 메트릭 유형에 대해서 이해하는 것도 중요하지만, 결과값을 이해하는 것도 중요합니다. 오픈텔레메트리는 단순히 개발로 완료되지 않으며, 결과를 보면서 개선하는 과정이 중요하기 때문이죠. 우리는 문맥이 풍부한 관찰가능성을 만들기 위해서 노력해야 합니다.

오픈텔레메트리 신호의 목적은 시스템에 대한 이해입니다. 신호의 세부 데이터를 이해하고, 부정확한지 판단할 수 있어야 됩니다. 멋지게 시각화 이전에, 엔지니어는 데이터 자체에 대해서 익숙해져야 합니다.

오픈텔레메트리 메트릭 외에도 프로메테우스 클라이언트 API도 중요합니다. 2가지를 모두 이해하고, 요구사항에 따라 적용하는 것을 추천합니다.

오픈텔레메트리 메트릭 예제

  1. 오픈텔레메트리 메트릭을 개발하는 소스입니다.
from typing import Iterable

from opentelemetry.metrics import (
CallbackOptions,
Observation,
get_meter_provider,
set_meter_provider,
)
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import (
ConsoleMetricExporter,
PeriodicExportingMetricReader,
)

exporter = ConsoleMetricExporter()
reader = PeriodicExportingMetricReader(exporter)
provider = MeterProvider(metric_readers=[reader])
set_meter_provider(provider)


def observable_counter_func(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(1, {})


def observable_up_down_counter_func(
options: CallbackOptions,
) -> Iterable[Observation]:
yield Observation(-10, {})


def observable_gauge_func(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(9, {})


meter = get_meter_provider().get_meter("getting-started", "0.1.2")

# Counter
counter = meter.create_counter("counter")
counter.add(1)

# Async Counter
observable_counter = meter.create_observable_counter(
"observable_counter", [observable_counter_func]
)

# UpDownCounter
updown_counter = meter.create_up_down_counter("updown_counter")
updown_counter.add(1)
updown_counter.add(-5)

# Async UpDownCounter
observable_updown_counter = meter.create_observable_up_down_counter(
"observable_updown_counter", [observable_up_down_counter_func]
)

# Histogram
histogram = meter.create_histogram("histogram")
histogram.record(99.9)

# Async Gauge
gauge = meter.create_observable_gauge("gauge", [observable_gauge_func])

2. 결과를 확인하세요.

{
"resource_metrics": [
{
"resource": {
"attributes": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.13.0",
"service.name": "unknown_service"
},
"schema_url": ""
},
"scope_metrics": [
{
"scope": {
"name": "getting-started",
"version": "0.1.2",
"schema_url": ""
},
"metrics": [
{
"name": "counter",
"description": "",
"unit": "",
"data": {
"data_points": [
{
"attributes": {},
"start_time_unix_nano": 1670508984365299000,
"time_unix_nano": 1670508984366005000,
"value": 1
}
],
"aggregation_temporality": 2,
"is_monotonic": true
}
},
{
"name": "updown_counter",
"description": "",
"unit": "",
"data": {
"data_points": [
{
"attributes": {},
"start_time_unix_nano": 1670508984365397800,
"time_unix_nano": 1670508984366005000,
"value": -4
}
],
"aggregation_temporality": 2,
"is_monotonic": false
}
},
{
"name": "histogram",
"description": "",
"unit": "",
"data": {
"data_points": [
{
"attributes": {},
"start_time_unix_nano": 1670508984365470700,
"time_unix_nano": 1670508984366005000,
"count": 1,
"sum": 99.9,
"bucket_counts": [
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0
],
"explicit_bounds": [
0,
5,
10,
25,
50,
75,
100,
250,
500,
1000
],
"min": 99.9,
"max": 99.9
}
],
"aggregation_temporality": 2
}
},
{
"name": "observable_counter",
"description": "",
"unit": "",
"data": {
"data_points": [
{
"attributes": {},
"start_time_unix_nano": 1670508984365780700,
"time_unix_nano": 1670508984366005000,
"value": 1
}
],
"aggregation_temporality": 2,
"is_monotonic": true
}
},
{
"name": "observable_updown_counter",
"description": "",
"unit": "",
"data": {
"data_points": [
{
"attributes": {},
"start_time_unix_nano": 1670508984365831400,
"time_unix_nano": 1670508984366005000,
"value": -10
}
],
"aggregation_temporality": 2,
"is_monotonic": false
}
},
{
"name": "gauge",
"description": "",
"unit": "",
"data": {
"data_points": [
{
"attributes": {},
"start_time_unix_nano": 0,
"time_unix_nano": 1670508984366005000,
"value": 9
}
]
}
}
],
"schema_url": ""
}
],
"schema_url": ""
}
]
}

오픈텔레메트리 메트릭 예제

조금 더 복잡한 예제를 설명합니다.

  1. 라이브러리를 설치합니다.
pip install flask requests
pip install opentelemetry-api==1.3.0
pip install opentelemetry-sdk==1.3.0
pip install opentelemetry-propagator-b3==1.3.0

2. 프론트엔드를 시작하고, 아래의 로그를 확인하세요.

(otel4) root@philip-virtual-machine:/home/philip/다운로드/Cloud-Native-Observability-main/chapter04# python ./shopper.py
visiting the grocery store
add orange to cart
{
"name": "web request",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0x7f1edd42815e5375",
"trace_state": "[]"
},
"kind": "SpanKind.CLIENT",
"parent_id": "0x526c1897b00a64d6",
"start_time": "2022-12-07T14:23:35.916018Z",
"end_time": "2022-12-07T14:23:35.929830Z",
"status": {
"status_code": "OK"
},
"attributes": {
"http.method": "GET",
"http.flavor": "1.1",
"http.url": "http://localhost:5000/products",
"net.peer.ip": "127.0.0.1",
"http.status_code": 200
},
"events": [
{
"name": "about to send a request",
"timestamp": "2022-12-07T14:23:35.916123Z",
"attributes": {}
},
{
"name": "request sent",
"timestamp": "1970-01-01T00:00:00.000000Z",
"attributes": {
"url": "http://localhost:5000/products"
}
}
],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "shopper",
"service.version": "0.1.2"
}
}
{
"name": "add item to cart",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0x42299891fae4e774",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x526c1897b00a64d6",
"start_time": "2022-12-07T14:23:35.929910Z",
"end_time": "2022-12-07T14:23:35.929977Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"item": "orange",
"quantity": 5
},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "shopper",
"service.version": "0.1.2"
}
}
{
"name": "browse",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0x526c1897b00a64d6",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0xaccaa48005856599",
"start_time": "2022-12-07T14:23:35.915826Z",
"end_time": "2022-12-07T14:23:35.930008Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "shopper",
"service.version": "0.1.2"
}
}
{
"name": "visit store",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0xaccaa48005856599",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-12-07T14:23:35.915773Z",
"end_time": "2022-12-07T14:23:35.930019Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "shopper",
"service.version": "0.1.2"
}
}
(otel4) root@philip-virtual-machine:/home/philip/다운로드/Cloud-Native-Observability-main/chapter04#

3. 백엔드를 시작하고, 아래의 로그를 확인하세요.

127.0.0.1 - - [07/Dec/2022 23:23:35] "GET /products HTTP/1.1" 200 -
{
"name": "inventory request",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0xdf53b0d4f3ae0439",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x41d8b60498cecc71",
"start_time": "2022-12-07T14:23:35.920963Z",
"end_time": "2022-12-07T14:23:35.928221Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"http.method": "GET",
"http.flavor": "HttpFlavorValues.HTTP_1_1",
"http.url": "http://localhost:5001/inventory",
"net.peer.ip": "127.0.0.1"
},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "grocery-store",
"service.version": "0.1.2"
}
}
{
"name": "/products",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0x41d8b60498cecc71",
"trace_state": "[]"
},
"kind": "SpanKind.SERVER",
"parent_id": "0x7f1edd42815e5375",
"start_time": "2022-12-07T14:23:35.920799Z",
"end_time": "2022-12-07T14:23:35.928272Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"http.flavor": "HTTP/1.1",
"http.method": "GET",
"http.user_agent": "python-requests/2.28.1",
"http.host": "localhost:5000",
"http.scheme": "http",
"http.target": "/products",
"http.client_ip": "127.0.0.1"
},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "grocery-store",
"service.version": "0.1.2"
}
}

4. 데이터 서비스를 시작하고, 아래의 로그를 확인하세요.

127.0.0.1 - - [07/Dec/2022 23:23:35] "GET /inventory HTTP/1.1" 200 -
{
"name": "/inventory",
"context": {
"trace_id": "0x2d4d5bf209e032647fef0cdd427f1f3a",
"span_id": "0x7b9b81160afe426d",
"trace_state": "[]"
},
"kind": "SpanKind.SERVER",
"parent_id": "0xdf53b0d4f3ae0439",
"start_time": "2022-12-07T14:23:35.925815Z",
"end_time": "2022-12-07T14:23:35.926343Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"http.flavor": "HTTP/1.1",
"http.method": "GET",
"http.user_agent": "python-requests/2.28.1",
"http.host": "localhost:5001",
"http.scheme": "http",
"http.target": "/inventory",
"http.client_ip": "127.0.0.1"
},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.3.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "legacy-inventory",
"service.version": "0.9.1"
}
}

--

--

모니터링의 새로운 미래 관측 가능성

모니터링의 새로운 미래 관측 가능성의 소스를 설명합니다.