6.4 o11y 레퍼런스 #7

많은 분들이 오픈텔레메트리 추적과 오픈텔레메트리 메트릭의 필요성에 대해서는 공감합니다. 하지만 오픈텔레메트리 로그의 적용여부에 대해서는 고민이 많은 것 같습니다.

오픈텔레메트리 로그의 장점을 몇 가지 설명하면,

  1. 오픈텔레메트리 로그는 기존 로깅 라이브러리에 추가되는 플러그인 개념입니다.
  2. 언어 별로 로깅 라이브러리(예를 들어 자바 log4j)가 있습니다. 오픈텔레메트리 로그는 다양한 언어 별 로깅 라이브러리를 지원합니다.
  3. 표준화된 로그 스키마(물론 구조적인 JSON 형식으로)를 제공하므로, 쉽고 복잡하지 않습니다.
  4. 오픈텔레메트리 로그는 소스 내 작은 수정이 필요하며, 간단하게 적용이 가능합니다.

관찰가능성을 구현하기 위해서, 오픈텔레메트리 로그는 필수가 아닙니다. 하지만 일반적인 구조적 로그보다, 오픈텔레메트리 로그를 사용해서 구조적인 로그를 만드는 것을 권장합니다.

예를 들어 이상탐지는 로그를 읽고, 수많은 로그에서 이상치를 찾습니다. 만약 이상탐지에 필요로 하는 변수(데이터가 아니라) 가 현재 로그에 없다면, 개발자와 상의해서 로그에 추가해야 합니다. 로그는 자주 변경이 발생하므로, 유연하게 설계되어야 합니다.

오픈텔레메트리 로그 예제

파이썬 라이브러리를 설치합니다.

pip install opentelemetry-api==1.9.0
pip install opentelemetry-sdk==1.9.0
pip install opentelemetry-propagator-b3==1.9.0
pip install opentelemetry-instrumentation==0.28b0
pip install opentelemetry-instrumentation-wsgi==0.28b0
pip install opentelemetry-semantic-conventions==0.28b0
pip install flask
pip install requests
pip install opentelemetry-exporter-otlp
pip install protobuf==3.20.*
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

에러가 발생하면, 재설치를 합니다.

pip uninstall opentelemetry-exporter-otlp-proto-http
pip uninstall opentelemetry-exporter-otlp-proto-grpc
pip install opentelemetry-sdk==1.9.0
pip install opentelemetry-exporter-otlp==1.9.0

프론트엔드를 시작합니다.

visiting the grocery store
{
"body": "add orange to cart",
"name": null,
"severity_number": "<SeverityNumber.INFO: 9>",
"severity_text": "INFO",
"attributes": {},
"timestamp": "2022-12-07T14:39:14.405979Z",
"trace_id": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0x8ac49c2e18b0e356",
"trace_flags": 1,
"resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.9.0', 'net.host.name': 'philip-virtual-machine', 'net.host.ip': '127.0.1.1', 'service.name': 'shopper', 'service.version': '0.1.2'}, maxlen=None)"
}
{
"name": "web request",
"context": {
"trace_id": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0xbeea05afe9906b44",
"trace_state": "[]"
},
"kind": "SpanKind.CLIENT",
"parent_id": "0xe88bc2da3004cff5",
"start_time": "2022-12-07T14:39:14.392935Z",
"end_time": "2022-12-07T14:39:14.405718Z",
"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:39:14.393007Z",
"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.9.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": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0x8ac49c2e18b0e356",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0xe88bc2da3004cff5",
"start_time": "2022-12-07T14:39:14.405909Z",
"end_time": "2022-12-07T14:39:14.406077Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"item": "orange",
"quantity": 5
},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.9.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": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0xe88bc2da3004cff5",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0xffe134bec06dce23",
"start_time": "2022-12-07T14:39:14.392799Z",
"end_time": "2022-12-07T14:39:14.406139Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.9.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": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0xffe134bec06dce23",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": null,
"start_time": "2022-12-07T14:39:14.392728Z",
"end_time": "2022-12-07T14:39:14.406158Z",
"status": {
"status_code": "UNSET"
},
"attributes": {},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.9.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "shopper",
"service.version": "0.1.2"
}
}
philip@philip-virtual-machine:~/Cloud-Native-Observability/chapter06$

백엔드를 시작합니다.

philip@philip-virtual-machine:~/Cloud-Native-Observability/chapter06$ python3 grocery_store.py
* Serving Flask app 'grocery_store' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
{
"body": " * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)",
"name": null,
"severity_number": "<SeverityNumber.INFO: 9>",
"severity_text": "INFO",
"attributes": {},
"timestamp": "2022-12-07T14:39:05.434688Z",
"trace_id": "0x00000000000000000000000000000000",
"span_id": "0x0000000000000000",
"trace_flags": 0,
"resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.9.0', 'net.host.name': 'philip-virtual-machine', 'net.host.ip': '127.0.1.1', 'service.name': 'grocery-store', 'service.version': '0.1.2'}, maxlen=None)"
}
{
"name": "inventory request",
"context": {
"trace_id": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0xb483d7c185c30bd8",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x1dc94b545ed64bd6",
"start_time": "2022-12-07T14:39:14.396996Z",
"end_time": "2022-12-07T14:39:14.403786Z",
"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.9.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": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0x1dc94b545ed64bd6",
"trace_state": "[]"
},
"kind": "SpanKind.SERVER",
"parent_id": "0xbeea05afe9906b44",
"start_time": "2022-12-07T14:39:14.396755Z",
"end_time": "2022-12-07T14:39:14.403889Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"http.flavor": "HTTP/1.1",
"http.method": "GET",
"http.user_agent": "python-requests/2.22.0",
"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.9.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "grocery-store",
"service.version": "0.1.2"
}
}
{
"name": "HTTP GET",
"context": {
"trace_id": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0x84317ed6a5ea3234",
"trace_state": "[]"
},
"kind": "SpanKind.SERVER",
"parent_id": "0xbeea05afe9906b44",
"start_time": "2022-12-07T14:39:14.396409Z",
"end_time": "2022-12-07T14:39:14.404993Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"http.method": "GET",
"http.server_name": "127.0.0.1",
"http.scheme": "http",
"net.host.port": 5000,
"http.host": "localhost:5000",
"http.target": "/products",
"net.peer.ip": "127.0.0.1",
"http.user_agent": "python-requests/2.22.0",
"net.peer.port": 48272,
"http.flavor": "1.1",
"http.status_code": 200
},
"events": [],
"links": [],
"resource": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.9.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "grocery-store",
"service.version": "0.1.2"
}
}
{
"body": "127.0.0.1 - - [07/Dec/2022 23:39:14] \"GET /products HTTP/1.1\" 200 -",
"name": null,
"severity_number": "<SeverityNumber.INFO: 9>",
"severity_text": "INFO",
"attributes": {},
"timestamp": "2022-12-07T14:39:14.404612Z",
"trace_id": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0x84317ed6a5ea3234",
"trace_flags": 1,
"resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.9.0', 'net.host.name': 'philip-virtual-machine', 'net.host.ip': '127.0.1.1', 'service.name': 'grocery-store', 'service.version': '0.1.2'}, maxlen=None)"
}

데이터 서비스를 시작합니다.

philip@philip-virtual-machine:~/Cloud-Native-Observability/chapter06$ python3 legacy_inventory.py
* Serving Flask app 'legacy_inventory' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5001 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 449-334-808
127.0.0.1 - - [07/Dec/2022 23:39:14] "GET /inventory HTTP/1.1" 200 -
{
"name": "/inventory",
"context": {
"trace_id": "0xf17f1fc3e5fe71925dedc05a4321a184",
"span_id": "0x12f2331548368c8f",
"trace_state": "[]"
},
"kind": "SpanKind.SERVER",
"parent_id": "0xb483d7c185c30bd8",
"start_time": "2022-12-07T14:39:14.402085Z",
"end_time": "2022-12-07T14:39:14.402282Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"http.flavor": "HTTP/1.1",
"http.method": "GET",
"http.user_agent": "python-requests/2.22.0",
"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.9.0",
"net.host.name": "philip-virtual-machine",
"net.host.ip": "127.0.1.1",
"service.name": "legacy-inventory",
"service.version": "0.9.1"
}
}



--

--

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

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