Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions pipeline/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
services:
# Video Voter Application
video-voter:
build: ../server
depends_on:
- otel-collector # Depends on otel-collector to be running first
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: otel-collector:4317
ports:
- "5000:5000"

# OpenTelemetry Collector
otel-collector:
image: otel/opentelemetry-collector:0.100.0 # Use `otel/opentelemetry-collector-contrib` to support more backends.
command:
- "--config=/conf/otel-collector-config.yaml" # Autodiscovery folder changes between versions. Better to provide explicitly.
volumes:
- ./conf/otel-collector-config.yaml:/conf/otel-collector-config.yaml
ports:
- 8888:8888 # Prometheus metrics exposed by the collector
- 8889:8889 # Prometheus exporter metrics
- 13133:13133 # health_check extension
- 4317:4317 # OTLP gRPC receiver
- 4318:4318 # OTLP http receiver
restart: unless-stopped

# Prometheus
prometheus:
image: prom/prometheus:latest
volumes:
- ./conf/prometheus-config.yaml:/etc/prometheus/prometheus.yml
depends_on:
- otel-collector
ports:
- "9090:9090"

# Grafana
grafana:
image: grafana/grafana:latest
volumes:
- ./conf/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
ports:
- "3000:3000"
10 changes: 10 additions & 0 deletions pipeline/conf/grafana-datasources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
datasources:
- name: Prometheus
type: prometheus
uid: prometheus-1
url: http://prometheus:9090
access: server

# deleteDatasources:
# - name: Prometheus
# uid: prometheus-1
27 changes: 27 additions & 0 deletions pipeline/conf/otel-collector-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317

processors:
batch:

exporters:
prometheus:
endpoint: 0.0.0.0:8889
namespace: default
debug:
verbosity: detailed

extensions:
health_check:

service:
extensions: [health_check]
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]

11 changes: 11 additions & 0 deletions pipeline/conf/prometheus-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
scrape_configs:
- job_name: "otel-collector-self-reporting"
scrape_interval: 15s
static_configs:
- targets:
- "otel-collector:8888"
- job_name: "otel-collector-exporter"
scrape_interval: 15s
static_configs:
- targets:
- "otel-collector:8889"
41 changes: 36 additions & 5 deletions server/app.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
from apps.videos import videos
from apps.instrumentation import instrumentation
from flask import Flask, request, render_template
from time import time

from opentelemetry.metrics import get_meter_provider

from apps.videos import videos

app = Flask(__name__)

default_meter = get_meter_provider().get_meter("default")
meter_likes = default_meter.create_counter("video_likes", description="Calls to the Like Endpoint")
meter_dislikes = default_meter.create_counter("video_dislikes", description="Calls to the Dislike Endpoint")
meter_latency_get = default_meter.create_histogram("get_video_latency_milliseconds", unit="ms", description="Latency of Video information retrieval")


@app.get("/api/v1/video")
def get_videos():
Expand All @@ -14,21 +23,43 @@ def get_videos():

@app.get("/api/v1/video/<id>")
def get_video_details(id):
return videos.get(id) # Unhandled exception on purpose
start = time()
video = videos.get(id)
end = time()
meter_latency_get.record(
(end - start) * 1000,
{
"id": id,
},
)

return video


@app.get("/api/v1/video/<id>/like")
def like_video(id):
meter_likes.add(
1,
{
"id": id,
},
)
videos.like(id)

return ("OK", 204)
return ("OK", 200)


@app.get("/api/v1/video/<id>/dislike")
def dislike_video(id):
meter_dislikes.add(
1,
{
"id": id,
},
)
videos.dislike(id)

return ("OK", 204)
return ("OK", 200)


@app.route("/")
Expand All @@ -47,5 +78,5 @@ def index():


if __name__ == "__main__":
# TODO: init Open Telemetry
instrumentation.init()
app.run(host="0.0.0.0")
Empty file.
23 changes: 23 additions & 0 deletions server/apps/instrumentation/instrumentation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from opentelemetry import metrics
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import (
ConsoleMetricExporter, # Useful for debugging - exports the metrics to console
PeriodicExportingMetricReader, # Reader that batches metrics in configurable time intervals before sending it to the exporter
)


def init():
# Configure the provider with the exporter and reader
exporter = OTLPMetricExporter(
insecure=True
) # Endpoint provided via Environment variable - OTEL_EXPORTER_OTLP_ENDPOINT
reader = PeriodicExportingMetricReader(
exporter, export_interval_millis=15000, export_timeout_millis=5000
)
provider = MeterProvider(metric_readers=[reader])

# Set the global meter provider, and create a Meter for usage
metrics.set_meter_provider(provider)

print("OTEL Metrics successfully initialised")
2 changes: 1 addition & 1 deletion server/apps/videos/videos.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def get(id):
with open(DATABASE_JSON_LOCATION) as db:
videos = json.load(db)

time.sleep(math.fabs(random.gauss(mu=0, sigma=0.5)))
for video in videos:
if video["id"] == id:
return video
Expand All @@ -42,7 +43,6 @@ def like(id):
if video["id"] == id:
video["likes"] += 1
continue
time.sleep(math.fabs(random.gauss(mu=1, sigma=0.5)))

with open(DATABASE_JSON_LOCATION, "w") as db:
json.dump(videos, db, indent=2)
Expand Down
20 changes: 16 additions & 4 deletions server/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
blinker==1.8.2
click==8.1.7
flask==3.0.3
importlib-metadata==7.1.0
Deprecated==1.2.14
Flask==3.0.3
googleapis-common-protos==1.63.0
grpcio==1.64.0
importlib-metadata==7.0.0
itsdangerous==2.2.0
jinja2==3.1.4
Jinja2==3.1.4
MarkupSafe==2.1.5
werkzeug==3.0.3
opentelemetry-api==1.24.0
opentelemetry-exporter-otlp-proto-common==1.24.0
opentelemetry-exporter-otlp-proto-grpc==1.24.0
opentelemetry-proto==1.24.0
opentelemetry-sdk==1.24.0
opentelemetry-semantic-conventions==0.45b0
protobuf==4.25.3
typing_extensions==4.11.0
Werkzeug==3.0.3
wrapt==1.16.0
zipp==3.18.2