-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp_manual.py
More file actions
138 lines (112 loc) · 5.43 KB
/
app_manual.py
File metadata and controls
138 lines (112 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import time
import os
import random
import uuid
from flask import Flask, jsonify
from opentelemetry import trace
# Setup manual tracer for custom spans
tracer = trace.get_tracer(__name__)
app = Flask(__name__)
@app.route('/')
def hello_world():
"""Simple hello world endpoint."""
return jsonify({
'message': 'Hello, World! (Manual Instrumentation Demo)',
'status': 'success'
})
# --- K-Commerce Scenario (Manual Spans) ---
def check_inventory(item_ids):
with tracer.start_as_current_span("inventory.check") as span:
# Add Custom Attributes
span.set_attribute("inventory.items_count", len(item_ids))
span.set_attribute("inventory.warehouse", "US-East-1")
span.set_attribute("inventory.items", str(item_ids))
time.sleep(random.uniform(0.1, 0.3))
# 10% chance of out-of-stock/ generate these based on your custom business logic...
if random.random() < 0.1:
# Add Custom Span Events
span.add_event("inventory.out_of_stock", {"item.id": item_ids[0]})
span.set_status(trace.Status(trace.StatusCode.ERROR, f"Item {item_ids[0]} out of stock"))
raise ValueError(f"Item {item_ids[0]} is out of stock!")
span.set_attribute("inventory.status", "available")
return True
def process_payment(order_amount, user_id):
with tracer.start_as_current_span("payment.process") as span:
# User defined metrics and attributes
span.set_attribute("payment.amount", order_amount)
span.set_attribute("payment.currency", "USD")
span.set_attribute("payment.method", "credit_card")
span.set_attribute("payment.gateway", "stripe")
span.set_attribute("user.id", user_id)
span.add_event("payment.gateway.initiated")
time.sleep(random.uniform(0.3, 0.8))
# 5% chance of payment failure/ generate these based on your custom business logic...
if random.random() < 0.05:
span.add_event("payment.gateway.declined")
span.set_status(trace.Status(trace.StatusCode.ERROR, "Payment declined by gateway"))
raise RuntimeError("Payment declined by bank")
span.add_event("payment.gateway.success", {
"transaction.id": f"txn_{random.randint(10000, 99999)}"
})
return True
def schedule_shipping(order_id):
with tracer.start_as_current_span("logistics.schedule") as span:
span.set_attribute("order.id", order_id)
span.set_attribute("logistics.provider", "fedex")
span.set_attribute("logistics.shipping_method", "express")
time.sleep(random.uniform(0.1, 0.4))
tracking_number = f"1Z999{random.randint(1000000, 9999999)}"
span.set_attribute("logistics.tracking_number", tracking_number)
return tracking_number
from flask import request
@app.route('/checkout', methods=['POST', 'GET'])
def checkout():
"""
Complex Commerce checkout endpoint showing manual spans nested under a web trace.
"""
if request.method == 'POST':
order_data = request.json or {}
else:
# Mock data for quick GET testing
order_data = {
"order_id": f"ORD-{uuid.uuid4().hex[:6].upper()}",
"user_id": f"USR-{random.randint(100, 999)}",
"amount": round(random.uniform(10.0, 500.0), 2),
"items": [f"item_{random.randint(1, 100)}", f"item_{random.randint(1, 100)}"]
}
order_id = order_data.get("order_id", "UNKNOWN-ORDER")
# We wrap the business logic in an explicit custom span
with tracer.start_as_current_span("order.process") as span:
span.set_attribute("order.id", order_id)
span.set_attribute("user.id", order_data.get("user_id", "unknown"))
span.set_attribute("order.total_value", order_data.get("amount", 0.0))
span.add_event("order.started")
try:
check_inventory(order_data.get("items", []))
process_payment(order_data.get("amount", 0.0), order_data.get("user_id", "unknown"))
tracking = schedule_shipping(order_id)
span.set_attribute("order.status", "completed")
span.set_status(trace.Status(trace.StatusCode.OK))
span.add_event("order.completed", {"tracking.number": tracking})
return jsonify({
"status": "success",
"order_id": order_id,
"tracking_number": tracking,
"message": "Order processed successfully."
})
except ValueError as e:
span.record_exception(e)
span.set_attribute("order.status", "failed_inventory")
return jsonify({"status": "error", "error": str(e)}), 400
except RuntimeError as e:
span.record_exception(e)
span.set_attribute("order.status", "failed_payment")
return jsonify({"status": "error", "error": str(e)}), 402
except Exception as e:
span.record_exception(e)
span.set_status(trace.Status(trace.StatusCode.ERROR, str(e)))
span.set_attribute("order.status", "failed_unknown")
return jsonify({"status": "error", "error": "Internal server error"}), 500
if __name__ == '__main__':
debug_mode = os.getenv('FLASK_DEBUG', 'false').lower() in ('true', '1', 'yes')
app.run(host='0.0.0.0', port=5000, debug=debug_mode)