Skip to content

Commit 8eed7d1

Browse files
authored
chore: bump otel deps + setup CI (unit + smoke tests) (#19)
* chore: bump deps * update: smoke tests * ci: run unit test * fix: ci * ci: bump checkout action * ci: run smoke tests * fix: setup BATS
1 parent 8f41d4b commit 8eed7d1

File tree

29 files changed

+878
-415
lines changed

29 files changed

+878
-415
lines changed

.github/workflows/smoke.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Smoke
2+
on:
3+
push:
4+
branches: [main]
5+
pull_request:
6+
branches: [main]
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.ref }}
9+
cancel-in-progress: true
10+
jobs:
11+
main:
12+
timeout-minutes: 8
13+
runs-on: ubuntu-20.04
14+
steps:
15+
- name: Setup BATS
16+
uses: mig4/setup-bats@v1
17+
with:
18+
bats-version: 1.10.0
19+
- name: Check out repository
20+
uses: actions/checkout@v4
21+
- name: Set up python
22+
id: setup-python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: '3.10'
26+
#----------------------------------------------
27+
# ----- install & configure poetry -----
28+
#----------------------------------------------
29+
- name: Install Poetry
30+
uses: snok/install-poetry@v1
31+
with:
32+
virtualenvs-create: true
33+
virtualenvs-in-project: true
34+
installer-parallel: true
35+
#----------------------------------------------
36+
# load cached venv if cache exists
37+
#----------------------------------------------
38+
- name: Load cached venv
39+
id: cached-poetry-dependencies
40+
uses: actions/cache@v3
41+
with:
42+
path: .venv
43+
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
44+
#----------------------------------------------
45+
# install dependencies if cache does not exist
46+
#----------------------------------------------
47+
- name: Install dependencies
48+
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
49+
run: poetry install --no-interaction --no-root
50+
#----------------------------------------------
51+
# install your root project, if required
52+
#----------------------------------------------
53+
- name: Install project
54+
run: poetry install --no-interaction
55+
#----------------------------------------------
56+
# run test suite
57+
#----------------------------------------------
58+
- name: Build
59+
run: make build
60+
- name: Run smoke tests
61+
run: make smoke-sdk

.github/workflows/unit.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Unit
2+
on:
3+
push:
4+
branches: [main]
5+
pull_request:
6+
branches: [main]
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.ref }}
9+
cancel-in-progress: true
10+
jobs:
11+
main:
12+
timeout-minutes: 8
13+
runs-on: ubuntu-20.04
14+
steps:
15+
- name: Check out repository
16+
uses: actions/checkout@v4
17+
- name: Set up python
18+
id: setup-python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: '3.10'
22+
#----------------------------------------------
23+
# ----- install & configure poetry -----
24+
#----------------------------------------------
25+
- name: Install Poetry
26+
uses: snok/install-poetry@v1
27+
with:
28+
virtualenvs-create: true
29+
virtualenvs-in-project: true
30+
installer-parallel: true
31+
#----------------------------------------------
32+
# load cached venv if cache exists
33+
#----------------------------------------------
34+
- name: Load cached venv
35+
id: cached-poetry-dependencies
36+
uses: actions/cache@v3
37+
with:
38+
path: .venv
39+
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
40+
#----------------------------------------------
41+
# install dependencies if cache does not exist
42+
#----------------------------------------------
43+
- name: Install dependencies
44+
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
45+
run: poetry install --no-interaction --no-root
46+
#----------------------------------------------
47+
# install your root project, if required
48+
#----------------------------------------------
49+
- name: Install project
50+
run: poetry install --no-interaction
51+
#----------------------------------------------
52+
# run test suite
53+
#----------------------------------------------
54+
- name: Build
55+
run: make build
56+
- name: Run unit tests
57+
run: make test

examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Check out the [Hello-World Readme](hello-world/README.md) for setting this up!
2727

2828
If you'd like to use Docker for running these examples, there is a `docker-compose.yml` we use for smoke-tests [that may be helpful.](../smoke-tests/docker-compose.yml)
2929

30-
We have the HYPERDX_API_ENDPOINT set to an OpenTelemetry Collector. This can be modified as needed or deleted entirely to use the default HyperDX API Endpoint.
30+
We have the HONEYCOMB_API_ENDPOINT set to an OpenTelemetry Collector. This can be modified as needed or deleted entirely to use the default Honeycomb API Endpoint.
3131

3232
Because each example uses the same port, either comment out the other apps in the docker-compose file, or specify the app and protocol to run:
3333

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# hello-world
2+
3+
This simple Django app returns "Hello World". This app uses the `configure_opentelemetry` method from `honeycomb.opentelemetry` to set up OpenTelemetry to export data to Honeycomb through configuration options set in the app's code. It is also possible to set configuration options through the `opentelemetry_instrument` command (see the instructions for automatic instrumenetation [here](https://docs.honeycomb.io/getting-data-in/opentelemetry/python-distro/#automatic-instrumentation)).
4+
5+
## Prerequisites
6+
7+
You'll need [Poetry](https://python-poetry.org/) installed to run the example. Poetry automatically creates a virtual environment to run the example in so you don't need to manage one yourself.
8+
9+
## Running the example
10+
11+
Install application dependencies:
12+
13+
```bash
14+
poetry install
15+
```
16+
17+
Run the application:
18+
19+
```bash
20+
poetry run python manage.py runserver
21+
```
22+
23+
Then navigate to http://127.0.0.1:8000 as shown in the command output and you should see `Hello, world`.
24+
25+
## Distro Instrumentation Example
26+
27+
This app uses configuration configures the OpenTelemetry SDK programmatically in [manage.py](./manage.py).
28+
Alternatively, you can use environment variables as parameters like below:
29+
30+
```python
31+
configure_opentelemetry(
32+
HoneycombOptions(
33+
debug=True,
34+
apikey=os.getenv("HYPERDX_API_KEY"),
35+
service_name="hello-world-django"
36+
)
37+
)
38+
```
39+
40+
Note: With `debug` set to `True`, spans will also be printed to stdout.
41+
42+
To send to Honeycomb, set your API Key:
43+
44+
```bash
45+
HYPERDX_API_KEY="your-api-key" poetry run python manage.py runserver
46+
```
47+
48+
You can configure exporter protocol with this flag:
49+
`OTEL_EXPORTER_OTLP_PROTOCOL=grpc` or `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`

examples/hello-world-django/db.sqlite3

Whitespace-only changes.

examples/hello-world-django/hello_world/__init__.py

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
ASGI config for hello_world project.
3+
4+
It exposes the ASGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.asgi import get_asgi_application
13+
14+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_world.settings')
15+
16+
application = get_asgi_application()
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""
2+
Django settings for hello_world project.
3+
4+
Generated by 'django-admin startproject' using Django 5.0.1.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/5.0/topics/settings/
8+
9+
For the full list of settings and their values, see
10+
https://docs.djangoproject.com/en/5.0/ref/settings/
11+
"""
12+
13+
from pathlib import Path
14+
15+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
16+
BASE_DIR = Path(__file__).resolve().parent.parent
17+
18+
19+
# Quick-start development settings - unsuitable for production
20+
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
21+
22+
# SECURITY WARNING: keep the secret key used in production secret!
23+
SECRET_KEY = 'django-insecure-c8cw65!*ys%e%w*$ow-%fi3&0k-zt51+c25pv_c&9zk#ba3e^i'
24+
25+
# SECURITY WARNING: don't run with debug turned on in production!
26+
DEBUG = True
27+
28+
ALLOWED_HOSTS = []
29+
30+
31+
# Application definition
32+
33+
INSTALLED_APPS = [
34+
'django.contrib.admin',
35+
'django.contrib.auth',
36+
'django.contrib.contenttypes',
37+
'django.contrib.sessions',
38+
'django.contrib.messages',
39+
'django.contrib.staticfiles',
40+
]
41+
42+
MIDDLEWARE = [
43+
'django.middleware.security.SecurityMiddleware',
44+
'django.contrib.sessions.middleware.SessionMiddleware',
45+
'django.middleware.common.CommonMiddleware',
46+
'django.middleware.csrf.CsrfViewMiddleware',
47+
'django.contrib.auth.middleware.AuthenticationMiddleware',
48+
'django.contrib.messages.middleware.MessageMiddleware',
49+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
50+
]
51+
52+
ROOT_URLCONF = 'hello_world.urls'
53+
54+
TEMPLATES = [
55+
{
56+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
57+
'DIRS': [],
58+
'APP_DIRS': True,
59+
'OPTIONS': {
60+
'context_processors': [
61+
'django.template.context_processors.debug',
62+
'django.template.context_processors.request',
63+
'django.contrib.auth.context_processors.auth',
64+
'django.contrib.messages.context_processors.messages',
65+
],
66+
},
67+
},
68+
]
69+
70+
WSGI_APPLICATION = 'hello_world.wsgi.application'
71+
72+
73+
# Database
74+
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
75+
76+
DATABASES = {
77+
'default': {
78+
'ENGINE': 'django.db.backends.sqlite3',
79+
'NAME': BASE_DIR / 'db.sqlite3',
80+
}
81+
}
82+
83+
84+
# Password validation
85+
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
86+
87+
AUTH_PASSWORD_VALIDATORS = [
88+
{
89+
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
90+
},
91+
{
92+
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
93+
},
94+
{
95+
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
96+
},
97+
{
98+
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
99+
},
100+
]
101+
102+
103+
# Internationalization
104+
# https://docs.djangoproject.com/en/5.0/topics/i18n/
105+
106+
LANGUAGE_CODE = 'en-us'
107+
108+
TIME_ZONE = 'UTC'
109+
110+
USE_I18N = True
111+
112+
USE_TZ = True
113+
114+
115+
# Static files (CSS, JavaScript, Images)
116+
# https://docs.djangoproject.com/en/5.0/howto/static-files/
117+
118+
STATIC_URL = 'static/'
119+
120+
# Default primary key field type
121+
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
122+
123+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
URL configuration for hello_world project.
3+
4+
The `urlpatterns` list routes URLs to views. For more information please see:
5+
https://docs.djangoproject.com/en/5.0/topics/http/urls/
6+
Examples:
7+
Function views
8+
1. Add an import: from my_app import views
9+
2. Add a URL to urlpatterns: path('', views.home, name='home')
10+
Class-based views
11+
1. Add an import: from other_app.views import Home
12+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
13+
Including another URLconf
14+
1. Import the include() function: from django.urls import include, path
15+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
16+
"""
17+
from django.contrib import admin
18+
from django.urls import path, include
19+
20+
urlpatterns = [
21+
path('admin/', admin.site.urls),
22+
path("", include("pages.urls")),
23+
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
WSGI config for hello_world project.
3+
4+
It exposes the WSGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.wsgi import get_wsgi_application
13+
14+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_world.settings')
15+
16+
application = get_wsgi_application()

0 commit comments

Comments
 (0)