Skip to content

Commit 82a4f08

Browse files
committed
PB-1954: improve OTEL instrumentation and add local testing env
1 parent 352c02e commit 82a4f08

File tree

9 files changed

+197
-133
lines changed

9 files changed

+197
-133
lines changed

.env.local

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
ALLOWED_DOMAINS=.*localhost,.*\.admin\.ch,.*\.bgdi\.ch
22

33
# OTEL
4-
OTEL_SDK_DISABLED=true
4+
OTEL_SDK_DISABLED=false
5+
OTEL_ENABLE_FLASK=true
6+
OTEL_ENABLE_LOGGING=true
7+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
8+
OTEL_EXPORTER_OTLP_INSECURE=true
9+
OTEL_RESOURCE_ATTRIBUTES=service.name=service-qrcode
10+
OTEL_PYTHON_EXCLUDED_URLS="checker"

.env.test

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
ALLOWED_DOMAINS=some_random_domain,.*\.geo\.admin\.ch,http://localhost
22

33
# OTEL
4-
OTEL_SDK_DISABLED=true
4+
OTEL_SDK_DISABLED=false
5+
OTEL_ENABLE_FLASK=true
6+
OTEL_ENABLE_LOGGING=true
7+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
8+
OTEL_EXPORTER_OTLP_INSECURE=true
9+
OTEL_RESOURCE_ATTRIBUTES=service.name=service-qrcode
10+
OTEL_PYTHON_EXCLUDED_URLS="checker"

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ serve: clean_logs $(LOGS_DIR)
148148

149149
.PHONY: gunicornserve
150150
gunicornserve: clean_logs $(LOGS_DIR)
151-
OTEL_SDK_DISABLED=true SCRIPT_NAME=$(ROUTE_PREFIX) ENV_FILE=$(ENV_FILE) LOGS_DIR=$(LOGS_DIR) $(PYTHON) wsgi.py
151+
SCRIPT_NAME=$(ROUTE_PREFIX) ENV_FILE=$(ENV_FILE) LOGS_DIR=$(LOGS_DIR) $(PYTHON) wsgi.py
152152

153153

154154
# Docker related functions.

Pipfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ gunicorn = "~=23.0.0"
1010
Flask = "~=3.0.3"
1111
Pillow = "~=10.4.0"
1212
qrcode = "~=7.4"
13-
logging-utilities = "~=4.4.1"
13+
logging-utilities = "~=5.3.0"
1414
python-dotenv = "~=1.0.1"
1515

1616
# OpenTelemetry packages
1717
opentelemetry-sdk = "*"
1818
opentelemetry-exporter-otlp = "*"
1919
opentelemetry-instrumentation-flask = "*"
20-
opentelemetry-instrumentation-requests = "*"
20+
opentelemetry-instrumentation-logging = "*"
2121

2222
[dev-packages]
2323
yapf = "*"

Pipfile.lock

Lines changed: 110 additions & 110 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/helpers/otel.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,41 @@
1-
import os
1+
from os import getenv
22

33
from opentelemetry import trace
44
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import \
55
OTLPSpanExporter
6+
from opentelemetry.instrumentation.flask import FlaskInstrumentor
7+
from opentelemetry.instrumentation.logging import LoggingInstrumentor
68
from opentelemetry.sdk.resources import Resource
79
from opentelemetry.sdk.trace import TracerProvider
810
from opentelemetry.sdk.trace.export import BatchSpanProcessor
911

1012
from app.helpers.utils import strtobool
1113

1214

13-
def setup_trace_provider(worker_pid):
14-
trace.set_tracer_provider(TracerProvider(resource=Resource.create()))
15+
def initialize() -> None:
16+
if not strtobool(getenv("OTEL_SDK_DISABLED", "false")):
17+
if strtobool(getenv("OTEL_ENABLE_LOGGING", "false")):
18+
LoggingInstrumentor().instrument()
1519

16-
# Since we created a new tracer, the default span processor is gone. We need to
17-
# create a new one using the default OTEL env variables and ad it to the tracer.
18-
span_processor = BatchSpanProcessor(
19-
OTLPSpanExporter(
20-
endpoint=os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT', "http://localhost:4317"),
21-
headers=os.getenv('OTEL_EXPORTER_OTLP_HEADERS'),
22-
insecure=strtobool(os.getenv('OTEL_EXPORTER_OTLP_INSECURE', "false"))
20+
21+
def initialize_flask(app):
22+
if not strtobool(getenv("OTEL_SDK_DISABLED", "false")):
23+
if strtobool(getenv("OTEL_ENABLE_FLASK", "false")):
24+
FlaskInstrumentor().instrument_app(app)
25+
26+
27+
def setup_trace_provider():
28+
if not strtobool(getenv("OTEL_SDK_DISABLED", "false")):
29+
# Since we created a new tracer, the default span processor is gone. We need to
30+
# create a new one using the default OTEL env variables and ad it to the tracer.
31+
span_processor = BatchSpanProcessor(
32+
OTLPSpanExporter(
33+
endpoint=getenv('OTEL_EXPORTER_OTLP_ENDPOINT', "http://localhost:4317"),
34+
headers=getenv('OTEL_EXPORTER_OTLP_HEADERS'),
35+
insecure=strtobool(getenv('OTEL_EXPORTER_OTLP_INSECURE', "false"))
36+
)
2337
)
24-
)
25-
trace.get_tracer_provider().add_span_processor(span_processor)
38+
39+
provider = TracerProvider(resource=Resource.create())
40+
provider.add_span_processor(span_processor)
41+
trace.set_tracer_provider(provider)

docker-compose-otel.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: "2"
2+
services:
3+
otel-collector:
4+
image: otel/opentelemetry-collector-contrib:latest
5+
command: --config otel-local-config.yaml
6+
volumes:
7+
- ./otel-local-config.yaml:/otel-local-config.yaml
8+
ports:
9+
- "4317:4317"
10+
11+
zipkin:
12+
image: openzipkin/zipkin:latest
13+
ports:
14+
- "9411:9411"

otel-local-config.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
receivers:
2+
otlp:
3+
protocols:
4+
grpc:
5+
endpoint: 0.0.0.0:4317
6+
7+
processors:
8+
batch:
9+
10+
exporters:
11+
debug:
12+
verbosity: detailed
13+
zipkin:
14+
endpoint: http://zipkin:9411/api/v2/spans
15+
16+
service:
17+
pipelines:
18+
traces:
19+
receivers: [otlp]
20+
processors: [batch]
21+
exporters: [debug, zipkin]

wsgi.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
load the ssl module.
99
"""
1010

11-
# pylint: disable=wrong-import-position,wrong-import-order
11+
# pylint: disable=wrong-import-position,wrong-import-order,ungrouped-imports
1212
import gevent.monkey
1313

1414
gevent.monkey.patch_all()
@@ -19,7 +19,9 @@
1919
# e.g. the flask instrumentation has no effect. See:
2020
# https://github.com/open-telemetry/opentelemetry.io/blob/main/content/en/docs/zero-code/python/troubleshooting.md#use-programmatic-auto-instrumentation
2121

22-
from opentelemetry.instrumentation.auto_instrumentation import initialize
22+
from app.helpers.otel import initialize
23+
from app.helpers.otel import initialize_flask
24+
from app.helpers.otel import setup_trace_provider
2325

2426
initialize()
2527

@@ -28,18 +30,17 @@
2830
from gunicorn.app.base import BaseApplication
2931

3032
from app.app import app as application
31-
from app.helpers import otel
3233
from app.helpers.utils import get_logging_cfg
33-
from app.helpers.utils import strtobool
3434
from app.settings import GUNICORN_KEEPALIVE
3535

36+
initialize_flask(application)
37+
3638

3739
def post_fork(server, worker):
3840
server.log.info("Worker spawned (pid: %s)", worker.pid)
3941

4042
# Setup OTEL providers for this worker
41-
if not strtobool(os.getenv("OTEL_SDK_DISABLED", "false")):
42-
otel.setup_trace_provider(worker.pid)
43+
setup_trace_provider()
4344

4445

4546
class StandaloneApplication(BaseApplication): # pylint: disable=abstract-method

0 commit comments

Comments
 (0)