Skip to content

Commit

Permalink
feat: make trace demo application use OpenTelemetry (#8428)
Browse files Browse the repository at this point in the history
removes trace demo application that using OpenCensus from the repo.
makes the removed demo's README file to reference to the active demo.
modifies the OpenTelemetry based demo so it has functional parity with the removed demo.
removes manual span creation that with OT leads to orphan span ingestion.
adds comment explaining needlessness of manual trace context creation.
updates README to refresh the instructions for OT version of the demo app.
refactors `setup.sh` to include building image into the script.
removes container building to improve deployment time and instead uses predeployed (in gcr.io/google_samples) image.
fixes distinct traces by adding request instrumentation.
  • Loading branch information
minherz authored Nov 2, 2022
1 parent b04113a commit 912ccc3
Show file tree
Hide file tree
Showing 21 changed files with 340 additions and 635 deletions.
165 changes: 106 additions & 59 deletions trace/cloud-trace-demo-app-opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,120 @@

Open this demo app in [Google Cloud Shell](https://cloud.google.com/shell/docs/). This includes necessary tools.


[![Open Cloud Trace Demo APP in Cloud Shell](http://gstatic.com/cloudssh/images/open-btn.svg)](https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=trace/cloud-trace-demo-app/README.md&cloudshell_tutorial=trace/cloud-trace-demo-app/README.md)

#### Demo Requirements
## Demo Requirements

If you are using Cloud Shell, skip to the next section.

1. Install gcloud <https://cloud.google.com/sdk/install>
2. Install kubectl <https://kubernetes.io/docs/tasks/tools/install-kubectl/>
3. Install docker <https://docs.docker.com/install/>


#### Create a GKE cluster

4. Enable Google Cloud and set up region and zone.

`gcloud init`
5. Enable the GKE API & billing:

`gcloud services enable container.googleapis.com`
6. Create a GKE cluster named "cloud-trace-demo", replacing `your-gcp-zone` below
with the
[GCP Zone](https://cloud.google.com/compute/docs/regions-zones) closest in proximity to you:

```
gcloud container clusters create cloud-trace-demo\`
--num-nodes 1 \
--enable-basic-auth \
--issue-client-certificate \
--zone your-gcp-zone
```
7. Verify that you have access to the cluster:

`kubectl get nodes`

#### Deploy The Cloud Trace Demo App

8. Build and tag the docker image for demo app:

`docker build -t gcr.io/${PROJECT_ID}/cloud-trace-demo:v1 .`
9. Deploy resource to the cluster:

`kubectl apply -f deployment.yaml`
10. Track the status of the deployment:

`kubectl get deployments`

Deployment is complete when all of the available deployments are ready.
11. Run the following command to see the pods the deployment created:

`kubectl get pods`

#### Deploy The Cloud Trace Demo Service

12. Create the cloud trace demo service:

`kubectl apply -f service.yaml`
13. Get the services IP address by running the following command:

`kubectl get services`
14. Send a curl request to the EXTERNAL_IP, replacing `EXTERNAL_IP` with the external IP address found
in step 13:

`curl EXTERNAL_IP`
15. Visit [Trace List](https://console.cloud.google.com/traces/list) to check traces generated.
## Deploy and run the demo application

1. Enable Google Cloud and set up region and zone.

```bash
gcloud init
```

1. Enable the GKE API:

```bash
gcloud services enable container.googleapis.com
```

1. Setup GCP project to `YOUR_PROJECT_ID`. Replace `YOUR_PROJECT_ID` with your GCP project id.

```bash
gcloud config set project YOUR_PROJECT_ID
```

1. Setup the location of GKE cluster and create a new cluster named
`cloud-trace-demo`.
The example below sets the cluster's location to the "us-central1-c" zone.
You can replace the zone with one which you like. See [zones][] for the full
list.
```bash
ZONE=us-central1-c
gcloud container clusters create cloud-trace-demo \
--zone $ZONE
```
1. Update GKE cluster credentials and verify the access to the cluster:
```bash
gcloud container clusters get-credentials cloud-trace-demo --zone $ZONE
kubectl get nodes
```
The output is similar to the following:
```bash
NAME STATUS ROLES AGE VERSION
gke-cloud-trace-demo-default-pool-43f3fe97-dnk1 Ready <none> 5m v1.23.8-gke.1900
gke-cloud-trace-demo-default-pool-43f3fe97-j2b8 Ready <none> 5m v1.23.8-gke.1900
gke-cloud-trace-demo-default-pool-43f3fe97-znvv Ready <none> 5m v1.23.8-gke.1900
```
1. Download the demo application:
```bash
git clone https://github.com/GoogleCloudPlatform/python-docs-samples
cd python-docs-samples/trace/cloud-trace-demo-app-opentelemetry/
```
1. Setup the application:
```bash
./setup.sh
```
The setup deployes 3 services of the demo application using a pre-built
image. If you like, you can build your own container image using
[`app/Dockerfile`][dockerfile].
1. Track the status of the deployment:
```bash
kubectl get deployments
```
The output is similar to the following:
```bash
NAME READY UP-TO-DATE AVAILABLE AGE
cloud-trace-demo-a 1/1 1 1 3m
cloud-trace-demo-b 1/1 1 1 3m
cloud-trace-demo-c 1/1 1 1 3m
```
1. Send a curl request to the cloud-trace-demo-a:
```bash
curl $(kubectl get svc -o=jsonpath='{.items[?(@.metadata.name=="cloud-trace-demo-a")].status.loadBalancer.ingress[0].ip}')
```
The output is similar to the following:
```bash
Hello, I am service A
And I am service B
Hello, I am service C
```
1. Visit [Trace List](https://console.cloud.google.com/traces/list) to check traces generated.
Click on any trace in the graph to see the Waterfall View.
![Screenshot](example-trace.png)
16. Clean up GKE cluster/pods/services:
`gcloud container clusters delete cloud-trace-demo`
1. To clean up the provisioned resources:
```bash
gcloud container clusters delete cloud-trace-demo --zone $ZONE
```
[zones]: https://cloud.google.com/compute/docs/regions-zones#zones_and_clusters
[dockerfile]: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/trace/cloud-trace-demo-app-opentelemetry/app/Dockerfile
10 changes: 6 additions & 4 deletions trace/cloud-trace-demo-app-opentelemetry/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
# https://hub.docker.com/_/python
FROM python:3.10-slim

# Copy local code to the container image.
RUN pip3 install --upgrade pip

ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
COPY requirements.txt /app/
RUN pip install Flask gunicorn

# Copy local code to the container image.
COPY *.py *.txt ./

RUN pip install -r requirements.txt

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app
56 changes: 39 additions & 17 deletions trace/cloud-trace-demo-app-opentelemetry/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,71 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
A sample app demonstrating CloudTraceSpanExporter
"""

import os
import random
import time

# [START trace_demo_imports]
import flask
from opentelemetry import propagate, trace
# [START trace_demo_imports]
from opentelemetry import trace
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor

from opentelemetry.sdk.trace.export import BatchSpanProcessor
# [END trace_demo_imports]

app = flask.Flask(__name__)
FlaskInstrumentor().instrument_app(app)
import requests


# [START trace_demo_create_exporter]
def configure_exporter(exporter):
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(exporter))
propagate.set_global_textmap(CloudTraceFormatPropagator())
set_global_textmap(CloudTraceFormatPropagator())
tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(tracer_provider)


configure_exporter(CloudTraceSpanExporter())
tracer = trace.get_tracer(__name__)
# [END trace_demo_create_exporter]


# [START trace_demo_middleware]
app = flask.Flask(__name__)
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()
# [END trace_demo_middleware]


@app.route("/")
def template_test():
# Sleep for a random time to imitate a random processing time
time.sleep(random.uniform(0, 0.5))

with tracer.start_as_current_span("span1"):
with tracer.start_as_current_span("span2"):
with tracer.start_as_current_span("span3"):
print("Hello world from Cloud Trace Exporter!")

return "Hello World"
# If there is an endpoint, send keyword to next service.
# Return received input with the keyword
keyword = os.getenv("KEYWORD")
endpoint = os.getenv("ENDPOINT")
# [START trace_context_header]
if endpoint is not None and endpoint != "":
data = {'body': keyword}
response = requests.get(
endpoint,
params=data,
)
return keyword + "\n" + response.text
else:
return keyword, 200
# [END trace_context_header]


if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=8080)
port = os.getenv("PORT")
app.run(debug=True, host="0.0.0.0", port=port)
6 changes: 6 additions & 0 deletions trace/cloud-trace-demo-app-opentelemetry/app/app_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@
"""
A sample app demonstrating Google Cloud Trace
"""
import os

import mock

import app


def test_traces():
expected = "Lorem ipsum dolor sit amet"
os.environ["KEYWORD"] = expected
app.app.testing = True
exporter = mock.Mock()
app.configure_exporter(exporter)
client = app.app.test_client()
resp = client.get("/")
assert resp.status_code == 200
assert expected in resp.data.decode('utf-8')
Loading

0 comments on commit 912ccc3

Please sign in to comment.