Skip to content

Commit

Permalink
Copy the app from the previous tutorial
Browse files Browse the repository at this point in the history
Signed-off-by: Pavol Loffay <p.loffay@gmail.com>
  • Loading branch information
pavolloffay committed Oct 24, 2023
1 parent c3a841b commit 12ba4d9
Show file tree
Hide file tree
Showing 37 changed files with 6,521 additions and 0 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/build_and_push_images.yml
@@ -0,0 +1,53 @@
name: "Build and Push Images"

on:
push:
paths:
- "app/**"

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

strategy:
matrix:
app:
- frontend
- backend1
- backend2
- loadgen

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Log in to the Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
config-inline: |
[worker.oci]
max-parallelism = 2
- name: Build and push images
uses: docker/build-push-action@v3.3.0
with:
context: ./app/${{ matrix.app }}
file: ./app/${{ matrix.app }}/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository }}-${{ matrix.app }}
cache-from: type=gha
cache-to: type=gha
65 changes: 65 additions & 0 deletions app/README.md
@@ -0,0 +1,65 @@
# Sample Application

This is the source code of the sample application used in the tutorial step [Deploy the application](../03-app-instrumentation.md).

## Usage

### Docker Compose

The quickest way to try out the sample application is by using docker compose.
In the [app/](.) folder run:

```console
docker compose up
```

This will build the images for all services + the load generator and then run
them for you. You can test the frontend service yourself by calling it with
your browser or curl at <http://localhost:4000?player1=alice&player2=bob>

If you'd like to try out all services being instrumented with OpenTelemetry run

```console
docker compose --env-file=./otel-env up
```

### Kubernetes

To run the the sample application on your kubernetes cluster, run

```console
kubectl apply -f ./k8s.yaml
```

Note that this will pull images of the applications from ghcr.io.

If you'd like to access the frontend service, open a new terminal and run

```console
kubectl port-forward svc/frontend-service 4000:4000
```

### Development

If you'd like to change the code of any of the applications,
you need to install Node.JS, Java and python3 with flask first.

Then you can run them all standalone:

- frontend (in folder [./frontend](./frontend)):

```console
node index.js
```

- backend1 (in folder [./backend1](./backend1)):

```console
flask run
```

- backend2 (in folder [./backend2](./backend)):

```console
./gradlew bootRun
```
11 changes: 11 additions & 0 deletions app/backend1/Dockerfile
@@ -0,0 +1,11 @@
FROM python:3.11-slim-buster

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

COPY app.py .
COPY run.sh .

CMD [ "./run.sh" ]
37 changes: 37 additions & 0 deletions app/backend1/app.py
@@ -0,0 +1,37 @@
from prometheus_client import generate_latest, Counter
from hashlib import sha256
from time import sleep
from random import randint
from flask import Flask, Response, request
from logging.config import dictConfig

app = Flask(__name__)

ROLL_COUNTER = Counter(
'dice_roll_count', 'How often the dice was rolled'
)

NUMBERS_COUNTER = Counter(
'dice_numbers_count', 'How often each number of the dice was rolled',
['number']
)

@app.route("/rolldice")
def roll_dice():
player = request.args.get('player', default="Anonymous player")
max = 8 if sha256(bytes(player, 'utf-8')).hexdigest() == 'f4b7c19317c929d2a34297d6229defe5262fa556ef654b600fc98f02c6d87fdc' else 6
result = str(do_roll(max))
app.logger.info("%s is rolling the dice: %s", player, result);
ROLL_COUNTER.inc()
NUMBERS_COUNTER.labels(result).inc()
return result

def do_roll(max):
result = randint(1, max)
if result > 6:
sleep(0.1 * result)
return result

@app.route("/metrics/")
def metrics():
return Response(generate_latest(), mimetype=str('text/plain; version=0.0.4; charset=utf-8'))
13 changes: 13 additions & 0 deletions app/backend1/requirements.txt
@@ -0,0 +1,13 @@
Flask==2.0.2
opentelemetry-exporter-otlp==1.17.0
opentelemetry-exporter-otlp-proto-http==1.17.0
opentelemetry-instrumentation-flask==0.38b0
opentelemetry-instrumentation-logging==0.38b0
opentelemetry-instrumentation-wsgi==0.38b0
opentelemetry-api==1.17.0
opentelemetry-distro==0.38b0
opentelemetry-instrumentation==0.38b0
opentelemetry-sdk==1.17.0
opentelemetry-semantic-conventions==0.38b0
prometheus-client==0.16.0
Werkzeug==2.2.2
16 changes: 16 additions & 0 deletions app/backend1/run.sh
@@ -0,0 +1,16 @@
#!/bin/bash

PORT=${PORT:-5000}
HOST=${HOST:-"0.0.0.0"}

if [[ "${OTEL_INSTRUMENTATION_ENABLED}" == "true" ]] ; then
echo 'Run with instrumentation'
env OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-backend1} \
OTEL_TRACES_EXPORTER=${OTEL_TRACES_EXPORTER:-console} \
OTEL_METRICS_EXPORTER=${OTEL_METRICS_EXPORTER:-console} \
OTEL_LOGS_EXPORTER=${OTEL_LOGS_EXPORTER:-console} \
OTEL_PYTHON_LOG_CORRELATION=${OTEL_PYTHON_LOG_CORRELATION:-"true"} \
opentelemetry-instrument python3 -m flask run --host="${HOST}" --port="${PORT}"
else
python3 -m flask run --host="${HOST}" --port "${PORT}"
fi
37 changes: 37 additions & 0 deletions app/backend2/.gitignore
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
26 changes: 26 additions & 0 deletions app/backend2/Dockerfile
@@ -0,0 +1,26 @@
FROM gradle:7.6.1-jdk17 AS builder

WORKDIR /usr/src/app

COPY . .
RUN gradle bootJar

FROM eclipse-temurin:17-jre

WORKDIR /usr/src/app

COPY --from=builder /usr/src/app/ .

ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar javaagent.jar

COPY run.sh .

CMD ["./run.sh"]

# For debug purpose:
# Comment the CMD above and uncomment the lines below to add the OTel java agent
#
# ENV OTEL_TRACES_EXPORTER=logging
# ENV OTEL_METRICS_EXPORTER=logging
# ENV OTEL_LOGS_EXPORTER=logging
# CMD ["java", "-javaagent:/javaagent.jar", "-jar", "./build/libs/dice-0.0.1-SNAPSHOT.jar"]
22 changes: 22 additions & 0 deletions app/backend2/build.gradle
@@ -0,0 +1,22 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.5'
id 'io.spring.dependency-management' version '1.1.0'
}

group = 'io.opentelemetry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web',
'org.apache.logging.log4j:log4j-core:2.17.2'
}

tasks.named('test') {
useJUnitPlatform()
}
Binary file added app/backend2/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions app/backend2/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

0 comments on commit 12ba4d9

Please sign in to comment.