Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions samples/instrumentation-quickstart/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,54 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from random import randint, uniform
import time
import logging
import time
from random import randint, uniform

import requests
from flask import Flask, url_for
import setup_opentelemetry
import gcp_logging

from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor

from gcp_logging import setup_structured_logging
from setup_opentelemetry import setup_opentelemetry

# [START opentelemetry_instrumentation_main]
logger = logging.getLogger(__name__)

# Initialize OpenTelemetry Python SDK and structured logging
setup_opentelemetry()
setup_structured_logging()

app = Flask(__name__)

# Add instrumentation
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()
# [END opentelemetry_instrumentation_main]


# [START opentelemetry_instrumentation_handle_multi]
@app.route('/multi')
@app.route("/multi")
def multi():
"""Handle an http request by making 3-7 http requests to the /single endpoint."""
subRequests = randint(3, 7)
logger.info("handle /multi request", extra={'subRequests': subRequests})
for _ in range(subRequests):
requests.get(url_for('single', _external=True))
return 'ok'
sub_requests = randint(3, 7)
logger.info("handle /multi request", extra={"subRequests": sub_requests})
for _ in range(sub_requests):
requests.get(url_for("single", _external=True))
return "ok"


# [END opentelemetry_instrumentation_handle_multi]


# [START opentelemetry_instrumentation_handle_single]
@app.route('/single')
@app.route("/single")
def single():
"""Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
duration = uniform(0.1, 0.2)
time.sleep(duration)
return f'slept {duration} seconds'
return f"slept {duration} seconds"


# [END opentelemetry_instrumentation_handle_single]
41 changes: 23 additions & 18 deletions samples/instrumentation-quickstart/gcp_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,32 @@
# limitations under the License.

import logging
from pythonjsonlogger import jsonlogger

from opentelemetry.instrumentation.logging import LoggingInstrumentor
from pythonjsonlogger import jsonlogger


# [START opentelemetry_instrumentation_setup_logging]
LoggingInstrumentor().instrument()
def setup_structured_logging() -> None:
LoggingInstrumentor().instrument()

logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
"%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
rename_fields={
"levelname": "severity",
"asctime": "timestamp",
"otelTraceID": "logging.googleapis.com/trace",
"otelSpanID": "logging.googleapis.com/spanId",
"otelTraceSampled": "logging.googleapis.com/trace_sampled",
log_handler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
"%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
rename_fields={
"levelname": "severity",
"asctime": "timestamp",
"otelTraceID": "logging.googleapis.com/trace",
"otelSpanID": "logging.googleapis.com/spanId",
"otelTraceSampled": "logging.googleapis.com/trace_sampled",
},
datefmt="%Y-%m-%dT%H:%M:%SZ",
)
logHandler.setFormatter(formatter)
logging.basicConfig(
level=logging.INFO,
handlers=[logHandler],
)
datefmt="%Y-%m-%dT%H:%M:%SZ",
)
log_handler.setFormatter(formatter)
logging.basicConfig(
level=logging.INFO,
handlers=[log_handler],
)


# [END opentelemetry_instrumentation_setup_logging]
53 changes: 28 additions & 25 deletions samples/instrumentation-quickstart/setup_opentelemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

import os

from opentelemetry import _logs as logs
from opentelemetry import _events as events
from opentelemetry import _logs as logs
from opentelemetry import metrics, trace
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._events import EventLoggerProvider
from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
Expand All @@ -31,27 +31,30 @@


# [START opentelemetry_instrumentation_setup_opentelemetry]
resource = Resource.create(
attributes={
# Use the PID as the service.instance.id to avoid duplicate timeseries
# from different Gunicorn worker processes.
SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
}
)

# Set up OpenTelemetry Python SDK
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)

logger_provider = LoggerProvider(resource=resource)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
logs.set_logger_provider(logger_provider)

event_logger_provider = EventLoggerProvider(logger_provider)
events.set_event_logger_provider(event_logger_provider)

reader = PeriodicExportingMetricReader(OTLPMetricExporter())
meter_provider = MeterProvider(metric_readers=[reader], resource=resource)
metrics.set_meter_provider(meter_provider)
def setup_opentelemetry() -> None:
resource = Resource.create(
attributes={
# Use the PID as the service.instance.id to avoid duplicate timeseries
# from different Gunicorn worker processes.
SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
}
)

# Set up OpenTelemetry Python SDK
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)

logger_provider = LoggerProvider(resource=resource)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
logs.set_logger_provider(logger_provider)

event_logger_provider = EventLoggerProvider(logger_provider)
events.set_event_logger_provider(event_logger_provider)

reader = PeriodicExportingMetricReader(OTLPMetricExporter())
meter_provider = MeterProvider(metric_readers=[reader], resource=resource)
metrics.set_meter_provider(meter_provider)


# [END opentelemetry_instrumentation_setup_opentelemetry]