Skip to content

Commit

Permalink
Add grpc trace export sample (#316)
Browse files Browse the repository at this point in the history
* update python version

* Add sample that uses gRPC to export traces

* Fix grpc auto-refresh token

* Remove debug logging statements

* Revert python version to avoid failing CI lint checks

* Rename example-grpc.py → example_grpc.py

* Fix formatting using isort and black

* Fix formatting in http sample

* Simplify AuthMetadataPlugin implementation

The default implementation was not working earlier because the
x-goog-user-project was being set by the code as well as gRPC. Resulting in
duplicating the header. This caused value of the project name to be
repeated, resulting in a project ID that did not exist.
  • Loading branch information
psx95 authored May 2, 2024
1 parent f84ece2 commit cd0870a
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 3 deletions.
32 changes: 32 additions & 0 deletions samples/otlptrace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
### OTLP Export Sample with GCP Auth
This example shows how to send traces to an OTLP (OpenTelemetry Protocol) endpoint that is protected by GCP authentication. The sample showcases the trace export using:
- gRPC
- http with protobuf

#### Installation
Install the dependencies and libraries required to run the samples:

```sh
# Move to the sample repository
cd samples/otlptrace

pip install -r requirements.txt
```

#### Prerequisites
Get Google credentials on your machine:

```sh
gcloud auth application-default login
```

#### Run the Sample
```sh
# export necessary OTEL environment variables
export OTEL_RESOURCE_ATTRIBUTES="gcp.project_id=<project-id>"
export OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint>

cd samples/otlptrace && python3 example_grpc.py
```
Other variations of the sample:
- `python3 example_http.py` - will run a program that will export traces using http/protobuf.
74 changes: 74 additions & 0 deletions samples/otlptrace/example_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.

import time

import google.auth
import google.auth.transport.grpc
import google.auth.transport.requests
import grpc
from google.auth.transport.grpc import AuthMetadataPlugin
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
OTLPSpanExporter,
)
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

"""
This is a sample script that exports OTLP traces encoded as protobufs via gRPC.
"""


credentials, project_id = google.auth.default()
request = google.auth.transport.requests.Request()
credentials.refresh(request)
resource = Resource.create(attributes={SERVICE_NAME: "otlp-gcp-grpc-sample"})

auth_metadata_plugin = AuthMetadataPlugin(
credentials=credentials, request=request
)
channel_creds = grpc.composite_channel_credentials(
grpc.ssl_channel_credentials(),
grpc.metadata_call_credentials(auth_metadata_plugin),
)

trace_provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(
OTLPSpanExporter(credentials=channel_creds, insecure=False)
)
trace_provider.add_span_processor(processor)
trace.set_tracer_provider(trace_provider)
tracer = trace.get_tracer("my.tracer.name")


def do_work():
with tracer.start_as_current_span("span-grpc") as span:
# do some work that 'span' will track
print("doing some work...")
# When the 'with' block goes out of scope, 'span' is closed for you


def do_work_repeatedly():
try:
while True:
do_work()
time.sleep(10)
except KeyboardInterrupt:
print("\nKeyboard Interrupt: Stopping work.")


do_work_repeatedly()
4 changes: 1 addition & 3 deletions samples/otlptrace/example_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
"x-goog-user-project": credentials.quota_project_id,
"Authorization": "Bearer " + credentials.token,
}
resource = Resource.create(attributes={
SERVICE_NAME: "otlp-gcp-http-sample"
})
resource = Resource.create(attributes={SERVICE_NAME: "otlp-gcp-http-sample"})

trace_provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter(headers=req_headers))
Expand Down
7 changes: 7 additions & 0 deletions samples/otlptrace/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dependencies require for trace export samples
opentelemetry-api==1.24.0
opentelemetry-sdk==1.24.0
google-auth==2.18.1
opentelemetry-exporter-otlp-proto-http==1.24.0
opentelemetry-exporter-otlp-proto-grpc==1.24.0
grpcio==1.63.0

0 comments on commit cd0870a

Please sign in to comment.