"http_path": "GET /product/:id"). Эту информацию можно привязывать к группам логов, метрик или трассировок.trace_id — идентификатор текущей операции и span_id — идентификатор подзапроса. При повторных попытках выполнения операции (например, при ошибках) каждый подзапрос должен иметь уникальный идентификатор span_id.Flask
requests 8000 замените на 8001, а в третьем — на 8002):DOCKER
FROM python:3.12
COPY app.py requirements.txt /
RUN apt-get update && apt-get install -y g++
RUN /usr/local/bin/python -m pip install --upgrade pip
RUN pip install -r requirements.txt
EXPOSE 800(0/1/2)
CMD ["flask", "run", "-h", "0.0.0.0", "-p", "800(0/1/2)"] PYTHON
from flask import Flask
import requests
app = Flask(__name__)
@app.route("/buy")
def buy():
res = requests.get("http://billing:8000")
return res.text PYTHON
from flask import Flask
import requests
app = Flask(__name__)
@app.route("/")
def pay():
res = requests.get("http://order:8002")
return "Payed"+res.text
PYTHON
from flask import Flask
import random
import time
app = Flask(__name__)
@app.route("/")
def order():
random_order_number = random.randint(1, 500)
time.sleep(random_order_number*0.001) #задержка
return str(random_order_number) PYTHON
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
#tracer
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create({SERVICE_NAME: "имя сервиса"})
)
)
jaeger_exporter = JaegerExporter( #jaeger
agent_host_name="jaeger",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter) #span creator
)
app = Flask(__name__)
FlaskInstrumentor().instrument_app(app) #flask instrumentation
RequestsInstrumentor().instrument() #request instrumentation PYTHON
with trace.get_tracer(__name__).start_as_current_span("pay"): Полный код cart/app.py
PYTHON
from flask import Flask
import requests
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create({SERVICE_NAME: "cart"})
)
)
jaeger_exporter = JaegerExporter(
agent_host_name="jaeger",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)
app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()
@app.route("/buy")
def buy():
with trace.get_tracer(__name__).start_as_current_span("buy"):
res = requests.get("http://billing:8000")
return res.text Полный код billing/app.py
PYTHON
from flask import Flask
import requests
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create({SERVICE_NAME: "billing"})
)
)
jaeger_exporter = JaegerExporter(
agent_host_name="jaeger",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)
app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()
@app.route("/")
def pay():
with trace.get_tracer(__name__).start_as_current_span("pay"):
res = requests.get("http://order:8002")
return "Payed"+" "+res.text Полный код order/app.py
PYTHON
from flask import Flask
import random
import time
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.flask import FlaskInstrumentor
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create({SERVICE_NAME: "order"})
)
)
jaeger_exporter = JaegerExporter(
agent_host_name="jaeger",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)
app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
@app.route("/")
def order():
with trace.get_tracer(__name__).start_as_current_span("order"):
random_order_number = random.randint(1, 500)
time.sleep(random_order_number*0.001) #задержка
return str(random_order_number) PYTHON
opentelemetry-api #api otel
opentelemetry-sdk #sdk otel
opentelemetry-instrumentation-flask #framework instrumentation
opentelemetry-instrumentation-requests #framework instrumentation
opentelemetry-exporter-jaeger YAML
version: "3"
services:
jaeger:
image: jaegertracing/all-in-one
hostname: jaeger
ports:
- 6831:6831/udp # accept jaeger.thrift in compact Thrift protocol used by most current Jaeger clients
- 6832:6832/udp # accept jaeger.thrift in binary Thrift protocol used by Node.js Jaeger client (because thriftrw npm package does not support compact protocol)
- 5775:5775/udp # accept zipkin.thrift in compact Thrift protocol (deprecated; only used by very old Jaeger clients, circa 2016)
- 5778:5778 # serve configs, sampling strategies
- 4317:4317 # OpenTelemetry Protocol (OTLP) over gRPC
- 4318:4318 # OpenTelemetry Protocol (OTLP) over HTTP
- 16686:16686 # UI port
- 14269:14269 # collector admin port: health check at / and metrics at /metrics
- 9411:9411 # Zipkin compatible endpoint
environment:
- COLLECTOR_ZIPKIN_HOST_PORT=:9411
cart:
image: cart
build:
context: cart
dockerfile: ./Dockerfile
ports:
- target: 8001
published: 8001
billing:
image: billing
build:
context: billing
dockerfile: ./Dockerfile
ports:
- target: 8000
published: 8080
order:
image: order
build:
context: order
dockerfile: ./Dockerfile
ports:
- target: 8002
published: 8002 build:PYTHON
docker-compose build PYTHON
docker-compose up -d http://localhost:16686/search. Jaeger UI будет собирать свои метрики и сохранять их по умолчанию в своей памяти. Или вы можете настроить базы данных Elasticsearch, Cassandra:PYTHON
curl -X GET localhost:8001/buy Сергей