Skip to content

Commit

Permalink
Tempo tracing (#20)
Browse files Browse the repository at this point in the history
* feat(tracing): Init gunicorn tracing

* chore(example): Change paas-charm branch in example flask

* chore(example): Fix missing import and libraries

* chore(): Fix wrong function

* feat(tracing): Remove unused topology, bring order to code

* feat(tracing): Implemented environmental approach

* chore(): Remove unnecessary log

* chore(): Write interface

* chore(): Cleaning

* chore(): More cleaning

* chore(): Remove empty line

* chore(): Add unit test for env variables.

* chore(): Addressed comment

* chore(): Modify examples to test out tracing.

* chore(lint): Format code

* chore(tracing): Update examples.

* chore(examples): Fix naming issues with tracing apps examples.

* chore(lint): Lint

* chore(fix): Fix gunicorn fork tracer

* chore(test): Add tracing image options

* chore(test): Fix test tracing image option name

* chore(test): Fix options

* chore(test): Add integration test for flask tracing

* chore: Format

* chore(test): Add tracing test to workflow

* chore(): Licence update

* chore(test): Fix test

* chore(test): Fix tracing integration test

* chore(test): Merge

* chore(lint): Format code

* chore(Format): Remove unnecessary files and format code

* Chore(test): Fix unit test

* Chore(test): Fix false positive

* chore(format):format

* Chore(test): Skip if juju <=3.4

* Chore(format): Format

* Chore(test): juju version skip fixed.

* chore(): Skip test at model level

* Chore(): Change matrix to not include workload stuff for juju 3.3

* chore(test): Move all tracing tests into one module and parametrize frameworks.

* Chore(): Cleanup the code and update docstrings.

* chore(): Update app.py

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore():Address comments

* Chore(): Fix

* chore(test): Improve tests

* chore(trivy): Add back Go stdlib ignore

* chore(trivy): Add back

* chore(test): Remove extra examples. Integrate tracing into default example

* Chore(example): Fix go example

* Chore(example): Remove commented out line

* Chore(test): Fix

* Chore(lint): Lint

* Chore(template): turned gunicorn conf into jinja template

* Chore(test): Updates app fixtures in integrations tests

* chore(): Initial

* chore(): Needs fixing in unit tests

* chore(test): Test

* Chore(test): Fixed unit tests.

* Chore(): Address comments.

* fix(): Fix '

* Fix(config): config error fixed when tracing relation is not there

* Chore(): Revert minor changes.

* Un-Merge branch 'smtp-integration' into tempo-tracing

* Chore(): Add example lib folders to lint ignore

* Revert "Merge branch 'smtp-integration' into tempo-tracing"

This reverts commit a2b439b, reversing
changes made to 8eeb7a3.

* Revert "Merge branch 'smtp-integration' into tempo-tracing"

This reverts commit a2b439b, reversing
changes made to 8eeb7a3.

* Chore(reqs): Pinned Jinja2 version.

* Chore(state): Addressed comment about Tempo state and how it is initialized.

* Chore(tracing): Fix string format

* Chore(): FIx generative functions.

* Cleanup

* Chore(): Cleanup

* Chore(): Fix test

* Chore(): Format

* Chore(test): Remove tempo rev

* Chore(example): Cleanup

* Chore(tempo): Update integration parameter

* Chore(): Update dosctring

* Chore(): update tempo parameter generation.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
alithethird and github-actions[bot] authored Feb 6, 2025
1 parent 872cac0 commit 5aeb322
Show file tree
Hide file tree
Showing 44 changed files with 928 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
extra-arguments: -x --localstack-address 172.17.0.1
pre-run-script: localstack-installation.sh
charmcraft-channel: latest/edge
modules: '["test_charm.py", "test_cos.py", "test_database.py", "test_db_migration.py", "test_django.py", "test_django_integrations.py", "test_fastapi.py", "test_go.py", "test_integrations.py", "test_proxy.py", "test_workers.py"]'
modules: '["test_charm.py", "test_cos.py", "test_database.py", "test_db_migration.py", "test_django.py", "test_django_integrations.py", "test_fastapi.py", "test_go.py", "test_integrations.py", "test_proxy.py", "test_workers.py", "test_tracing.py"]'
rockcraft-channel: latest/edge
juju-channel: ${{ matrix.juju-version }}
channel: 1.29-strict/stable
Expand Down
2 changes: 1 addition & 1 deletion .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ CVE-2024-34156
# pebble: Go stdlib
CVE-2024-45338
# go-app: Go crypto lib
CVE-2024-45337
CVE-2024-45337
4 changes: 4 additions & 0 deletions examples/django/charm/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ requires:
interface: postgresql_client
optional: False
limit: 1
tracing:
interface: tracing
optional: True
limit: 1
resources:
django-app-image:
description: django application image.
Expand Down
3 changes: 2 additions & 1 deletion examples/django/django_app/django_app/django_app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@

from django.contrib import admin
from django.urls import path
from testing.views import environ, get_settings, login, sleep, user_count
from testing.views import environ, get_settings, hello_world, login, sleep, user_count

urlpatterns = [
path("admin/", admin.site.urls),
path("settings/<str:name>", get_settings, name="get_settings"),
path("len/users", user_count, name="user_count"),
path("environ", environ, name="environ"),
path("", hello_world, name="hello_world"),
path("sleep", sleep, name="sleep"),
path("login", login, name="login"),
]
10 changes: 10 additions & 0 deletions examples/django/django_app/django_app/testing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse
from opentelemetry import trace

tracer = trace.get_tracer(__name__)


def environ(request):
Expand All @@ -25,6 +28,13 @@ def get_settings(request, name):
return JsonResponse({"error": f"settings {name!r} not found"}, status=404)


def hello_world(request):
# Create a custom span
with tracer.start_as_current_span("custom-span"):
print("Hello, World!!!")
return HttpResponse("Hello, World!")


def sleep(request):
duration = request.GET.get("duration")
time.sleep(int(duration))
Expand Down
6 changes: 6 additions & 0 deletions examples/django/django_app/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Django
tzdata
psycopg2-binary
opentelemetry-api
opentelemetry-exporter-otlp
opentelemetry-exporter-otlp-proto-http
opentelemetry-instrumentation
opentelemetry-instrumentation-wsgi
opentelemetry-sdk
10 changes: 7 additions & 3 deletions examples/fastapi/charm/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ config:
app-secret-key-id:
type: secret
description: >-
This configuration is similar to `app-secret-key`, but instead accepts a Juju user secret ID.
The secret should contain a single key, "value", which maps to the actual secret key.
To create the secret, run the following command:
This configuration is similar to `app-secret-key`, but instead accepts a Juju user secret ID.
The secret should contain a single key, "value", which maps to the actual secret key.
To create the secret, run the following command:
`juju add-secret my-secret-key value=<secret-string> && juju grant-secret my-secret-key fastapi-k8s`,
and use the outputted secret ID to configure this option.
user-defined-config:
Expand All @@ -79,6 +79,10 @@ requires:
interface: postgresql_client
optional: True
limit: 1
tracing:
interface: tracing
optional: True
limit: 1
resources:
app-image:
description: FastAPI application image.
Expand Down
File renamed without changes.
File renamed without changes.
14 changes: 13 additions & 1 deletion examples/fastapi/app.py → examples/fastapi/fastapi_app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
import os

from fastapi import FastAPI, HTTPException
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.trace import get_tracer_provider, set_tracer_provider
from sqlalchemy import Column, Integer, String, create_engine, inspect
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker

app = FastAPI()

set_tracer_provider(TracerProvider())
get_tracer_provider().add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
FastAPIInstrumentor.instrument_app(app)
tracer = trace.get_tracer(__name__)

engine = create_engine(os.environ["POSTGRESQL_DB_CONNECT_STRING"], echo=True)

Session = scoped_session(sessionmaker(bind=engine))
Expand All @@ -26,7 +37,8 @@ class User(Base):

@app.get("/")
async def root():
return "Hello, World!"
with tracer.start_as_current_span("custom-span"):
return "Hello, World!"


@app.get("/env/user-defined-config")
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions examples/fastapi/fastapi_app/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fastapi
SQLAlchemy
alembic
psycopg2-binary
opentelemetry-api
opentelemetry-sdk
opentelemetry-instrumentation-fastapi
opentelemetry-exporter-otlp
opentelemetry-exporter-otlp-proto-http
File renamed without changes.
4 changes: 0 additions & 4 deletions examples/fastapi/requirements.txt

This file was deleted.

5 changes: 4 additions & 1 deletion examples/flask/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ requires:
interface: rabbitmq
optional: True
limit: 1

tracing:
interface: tracing
optional: True
limit: 1
resources:
flask-app-image:
description: flask application image.
Expand Down
35 changes: 35 additions & 0 deletions examples/flask/test_rock/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import redis
from celery import Celery, Task
from flask import Flask, g, jsonify, request
from opentelemetry import trace
from opentelemetry.instrumentation.flask import FlaskInstrumentor


def hostname():
Expand Down Expand Up @@ -60,6 +62,39 @@ def __call__(self, *args: object, **kwargs: object) -> object:
celery_app = celery_init_app(app, broker_url)
redis_client = redis.Redis.from_url(broker_url) if broker_url else None

FlaskInstrumentor().instrument_app(app)
tracer = trace.get_tracer(__name__)


def fib_slow(n):
if n <= 1:
return n
return fib_slow(n - 1) + fib_fast(n - 2)


def fib_fast(n):
nth_fib = [0] * (n + 2)
nth_fib[1] = 1
for i in range(2, n + 1):
nth_fib[i] = nth_fib[i - 1] + nth_fib[i - 2]
return nth_fib[n]


@app.route("/fibonacci")
def fibonacci():
n = int(request.args.get("n", 1))
with tracer.start_as_current_span("root"):
with tracer.start_as_current_span("fib_slow") as slow_span:
answer = fib_slow(n)
slow_span.set_attribute("n", n)
slow_span.set_attribute("nth_fibonacci", answer)
with tracer.start_as_current_span("fib_fast") as fast_span:
answer = fib_fast(n)
fast_span.set_attribute("n", n)
fast_span.set_attribute("nth_fibonacci", answer)

return f"F({n}) is: ({answer})"


@celery_app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
Expand Down
4 changes: 4 additions & 0 deletions examples/flask/test_rock/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ redis[hiredis]
boto3
pika
celery
opentelemetry-api
opentelemetry-exporter-otlp-proto-http
opentelemetry-instrumentation-flask
opentelemetry-sdk
10 changes: 7 additions & 3 deletions examples/go/charm/charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ config:
app-secret-key-id:
type: secret
description: >-
This configuration is similar to `app-secret-key`, but instead accepts a Juju user secret ID.
The secret should contain a single key, "value", which maps to the actual secret key.
To create the secret, run the following command:
This configuration is similar to `app-secret-key`, but instead accepts a Juju user secret ID.
The secret should contain a single key, "value", which maps to the actual secret key.
To create the secret, run the following command:
`juju add-secret my-secret-key value=<secret-string> && juju grant-secret my-secret-key go-k8s`,
and use the outputted secret ID to configure this option.
user-defined-config:
Expand All @@ -70,6 +70,10 @@ requires:
interface: postgresql_client
optional: True
limit: 1
tracing:
interface: tracing
optional: True
limit: 1
resources:
app-image:
description: go application image.
Expand Down
26 changes: 0 additions & 26 deletions examples/go/go.mod

This file was deleted.

46 changes: 0 additions & 46 deletions examples/go/go.sum

This file was deleted.

46 changes: 46 additions & 0 deletions examples/go/go_app/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2025 Canonical Ltd.
// See LICENSE file for licensing details.
module go-app

go 1.22.7

toolchain go1.22.10

require (
github.com/jackc/pgx/v5 v5.6.0
github.com/prometheus/client_golang v1.19.1
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
golang.org/x/crypto v0.30.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/protobuf v1.35.2 // indirect
)
Loading

0 comments on commit 5aeb322

Please sign in to comment.