- Notifications
You must be signed in to change notification settings - Fork 0
feat : Show Github Integration Demo on a Python Codebase #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Sky Singh <akashsingh2210670@gmail.com>
| I've analyzed the Python codebase and identified opportunities to add observability instrumentation. Here are my recommendations, sorted by priority: High Priority:
Medium Priority:
Low Priority:
Here are my specific recommendations: |
| # app.py | ||
| from flask import Flask | ||
| from routes import user_routes, product_routes, order_routes | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import logging | |
| from opentelemetry import trace | |
| from opentelemetry.instrumentation.flask import FlaskInstrumentor | |
| from opentelemetry.sdk.trace import TracerProvider | |
| from opentelemetry.sdk.resources import SERVICE_NAME, Resource | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
| # Configure OpenTelemetry | |
| trace.set_tracer_provider(TracerProvider(resource=Resource.create({SERVICE_NAME: "test-app"}))) | |
| FlaskInstrumentor().instrument_app(app) | |
| # Register error handlers | |
| @app.errorhandler(500) | |
| def server_error(e): | |
| logging.error(f"Server error: {str(e)}") | |
| return {"error": "Internal server error"}, 500 |
| @@ -0,0 +1,31 @@ | |||
| # routes/order_routes.py | |||
| from flask import Blueprint, jsonify, request | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from flask import Blueprint, jsonify, request | |
| import logging | |
| from opentelemetry import trace | |
| import amplitude | |
| tracer = trace.get_tracer(__name__) | |
| logger = logging.getLogger(__name__) | |
| with tracer.start_as_current_span("create_order") as span: | |
| logger.info("Processing order creation request") | |
| span.set_attribute("http.method", "POST") | |
| span.set_attribute("endpoint", "/orders/create") | |
| try: | |
| data = request.json | |
| span.set_attribute("order.data", str(data)) | |
| result = create_order(data) | |
| # Track order creation event | |
| amplitude.track({ | |
| "event_type": "order_created", | |
| "user_id": data.get("user_id", "unknown"), | |
| "event_properties": { | |
| "order_id": result.get("order", {}).get("id", "unknown"), | |
| "total_amount": data.get("amount", 0) | |
| } | |
| }) | |
| logger.info(f"Order created successfully: {result}") | |
| return jsonify(result) | |
| except Exception as e: | |
| logger.error(f"Error creating order: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to create order"}), 500 |
| return jsonify(create_order(data)) | ||
| | ||
| @bp.route('/<id>', methods=['GET']) | ||
| def get_order(id): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def get_order(id): | |
| with tracer.start_as_current_span("get_order") as span: | |
| logger.info(f"Retrieving order with ID: {id}") | |
| span.set_attribute("http.method", "GET") | |
| span.set_attribute("endpoint", f"/orders/{id}") | |
| span.set_attribute("order.id", id) | |
| try: | |
| order = get_order_by_id(id) | |
| if order: | |
| logger.info(f"Order found: {order}") | |
| return jsonify(order) | |
| logger.warning(f"Order not found with ID: {id}") | |
| span.set_attribute("order.found", False) | |
| return jsonify({"message": "Order not found"}), 404 | |
| except Exception as e: | |
| logger.error(f"Error retrieving order {id}: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to retrieve order"}), 500 |
| return jsonify({"message": "Order not found"}), 404 | ||
| | ||
| @bp.route('/<id>', methods=['PUT']) | ||
| def update_order(id): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def update_order(id): | |
| with tracer.start_as_current_span("update_order") as span: | |
| logger.info(f"Updating order with ID: {id}") | |
| span.set_attribute("http.method", "PUT") | |
| span.set_attribute("endpoint", f"/orders/{id}") | |
| span.set_attribute("order.id", id) | |
| try: | |
| data = request.json | |
| span.set_attribute("order.update_data", str(data)) | |
| updated_order = update_order_by_id(id, data) | |
| if updated_order: | |
| logger.info(f"Order updated successfully: {updated_order}") | |
| # Track order update event | |
| amplitude.track({ | |
| "event_type": "order_updated", | |
| "user_id": data.get("user_id", "unknown"), | |
| "event_properties": { | |
| "order_id": id, | |
| "update_fields": list(data.keys()) | |
| } | |
| }) | |
| return jsonify(updated_order) | |
| logger.warning(f"Order not found for update with ID: {id}") | |
| span.set_attribute("order.found", False) | |
| return jsonify({"message": "Order not found"}), 404 | |
| except Exception as e: | |
| logger.error(f"Error updating order {id}: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to update order"}), 500 |
| return jsonify(updated_order) | ||
| return jsonify({"message": "Order not found"}), 404 | ||
| | ||
| @bp.route('/<id>', methods=['DELETE']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| @bp.route('/<id>', methods=['DELETE']) | |
| with tracer.start_as_current_span("delete_order") as span: | |
| logger.info(f"Deleting order with ID: {id}") | |
| span.set_attribute("http.method", "DELETE") | |
| span.set_attribute("endpoint", f"/orders/{id}") | |
| span.set_attribute("order.id", id) | |
| try: | |
| result = delete_order_by_id(id) | |
| if result: | |
| logger.info(f"Order deleted successfully: {id}") | |
| # Track order deletion event | |
| amplitude.track({ | |
| "event_type": "order_deleted", | |
| "event_properties": { | |
| "order_id": id | |
| } | |
| }) | |
| return jsonify({"message": "Order deleted"}) | |
| logger.warning(f"Order not found for deletion with ID: {id}") | |
| span.set_attribute("order.found", False) | |
| return jsonify({"message": "Order not found"}), 404 | |
| except Exception as e: | |
| logger.error(f"Error deleting order {id}: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to delete order"}), 500 |
| @@ -0,0 +1,44 @@ | |||
| # routes/product_routes.py | |||
| from flask import Blueprint, jsonify, request | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from flask import Blueprint, jsonify, request | |
| import logging | |
| from opentelemetry import trace | |
| import amplitude | |
| tracer = trace.get_tracer(__name__) | |
| logger = logging.getLogger(__name__) |
| bp = Blueprint('product', __name__, url_prefix='/products') | ||
| | ||
| @bp.route('/', methods=['GET']) | ||
| def list_products(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def list_products(): | |
| with tracer.start_as_current_span("list_products") as span: | |
| logger.info("Retrieving product list") | |
| span.set_attribute("http.method", "GET") | |
| span.set_attribute("endpoint", "/products/") | |
| try: | |
| products = get_products() | |
| span.set_attribute("products.count", len(products)) | |
| logger.info(f"Retrieved {len(products)} products") | |
| return jsonify(products) | |
| except Exception as e: | |
| logger.error(f"Error retrieving products: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to retrieve products"}), 500 |
| return jsonify(get_products()) | ||
| | ||
| @bp.route('/<id>', methods=['GET']) | ||
| def get_product_by_id(id): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def get_product_by_id(id): | |
| with tracer.start_as_current_span("get_product") as span: | |
| logger.info(f"Retrieving product with ID: {id}") | |
| span.set_attribute("http.method", "GET") | |
| span.set_attribute("endpoint", f"/products/{id}") | |
| span.set_attribute("product.id", id) | |
| try: | |
| product = get_product(id) | |
| if product: | |
| logger.info(f"Product found: {product}") | |
| return jsonify(product) | |
| logger.warning(f"Product not found with ID: {id}") | |
| span.set_attribute("product.found", False) | |
| return jsonify({'message': 'Product not found'}), 404 | |
| except Exception as e: | |
| logger.error(f"Error retrieving product {id}: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to retrieve product"}), 500 |
| return jsonify({'message': 'Product not found'}), 404 | ||
| | ||
| @bp.route('/', methods=['POST']) | ||
| def add_product(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def add_product(): | |
| with tracer.start_as_current_span("create_product") as span: | |
| logger.info("Processing product creation request") | |
| span.set_attribute("http.method", "POST") | |
| span.set_attribute("endpoint", "/products/") | |
| try: | |
| data = request.get_json() | |
| span.set_attribute("product.data", str(data)) | |
| product = create_product(data) | |
| # Track product creation event | |
| amplitude.track({ | |
| "event_type": "product_created", | |
| "event_properties": { | |
| "product_id": product.get("id", "unknown"), | |
| "product_name": data.get("name", "unknown") | |
| } | |
| }) | |
| logger.info(f"Product created successfully: {product}") | |
| return jsonify(product), 201 | |
| except Exception as e: | |
| logger.error(f"Error creating product: {str(e)}") | |
| span.set_status(trace.StatusCode.ERROR, str(e)) | |
| return jsonify({"error": "Failed to create product"}), 500 |
| @@ -0,0 +1,38 @@ | |||
| from flask import Blueprint, request, jsonify | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from flask import Blueprint, request, jsonify | |
| import logging | |
| from opentelemetry import trace | |
| import amplitude | |
| tracer = trace.get_tracer(__name__) | |
| logger = logging.getLogger(__name__) |
Dashboard Suggestion: Flask API Service OverviewType: grafana Queries[ { "refId": "A", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\"}[5m])) by (route)", "legendFormat": "{{route}}", "interval": "30s" }, { "refId": "B", "datasource": "Prometheus", "expr": "histogram_quantile(0.95, sum(rate(http_server_duration_seconds_bucket{service_name=\"flask-app\"}[5m])) by (route, le))", "legendFormat": "p95 {{route}}", "interval": "30s" }, { "refId": "C", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", status_code=~\"5..\"}[5m])) by (route) / sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\"}[5m])) by (route)", "legendFormat": "Error % {{route}}", "interval": "30s" } ] Panels[ { "title": "Request Rate by Endpoint", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "targets": ["A"] }, { "title": "p95 Latency by Endpoint", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, "targets": ["B"] }, { "title": "Error Rate by Endpoint", "type": "timeseries", "gridPos": { "h": 8, "w": 24, "x": 0, "y": 8 }, "targets": ["C"] } ] Alerts[ { "name": "High Error Rate", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", status_code=~\"5..\"}[5m])) / sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\"}[5m])) > 0.05", "for": "5m", "severity": "warning" }, { "name": "High Latency", "expr": "histogram_quantile(0.95, sum(rate(http_server_duration_seconds_bucket{service_name=\"flask-app\"}[5m])) by (le)) > 1", "for": "5m", "severity": "warning" } ] Click to create this dashboardTo create this dashboard, comment with:
|
Dashboard Suggestion: E-commerce Business MetricsType: grafana Queries[ { "refId": "A", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=\"/orders/create\", status_code=~\"2..\"}[5m]))", "legendFormat": "Order Creation Rate", "interval": "30s" }, { "refId": "B", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=\"/refund\", http_method=\"POST\", status_code=~\"2..\"}[5m]))", "legendFormat": "Refund Rate", "interval": "30s" }, { "refId": "C", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=\"/products/search\", status_code=~\"2..\"}[5m]))", "legendFormat": "Product Search Rate", "interval": "30s" } ] Panels[ { "title": "Order Creation Rate", "type": "timeseries", "gridPos": { "h": 8, "w": 8, "x": 0, "y": 0 }, "targets": ["A"] }, { "title": "Refund Rate", "type": "timeseries", "gridPos": { "h": 8, "w": 8, "x": 8, "y": 0 }, "targets": ["B"] }, { "title": "Product Search Rate", "type": "timeseries", "gridPos": { "h": 8, "w": 8, "x": 16, "y": 0 }, "targets": ["C"] } ] Alerts[ { "name": "Order Creation Drop", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=\"/orders/create\", status_code=~\"2..\"}[30m])) < sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=\"/orders/create\", status_code=~\"2..\"}[30m] offset 1d)) * 0.5", "for": "15m", "severity": "warning" } ] Click to create this dashboardTo create this dashboard, comment with:
|
Dashboard Suggestion: Payment Services PerformanceType: grafana Queries[ { "refId": "A", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=~\"/remittance/.*\"}[5m])) by (route)", "legendFormat": "{{route}}", "interval": "30s" }, { "refId": "B", "datasource": "Prometheus", "expr": "histogram_quantile(0.95, sum(rate(http_server_duration_seconds_bucket{service_name=\"flask-app\", route=~\"/remittance/.*\"}[5m])) by (route, le))", "legendFormat": "p95 {{route}}", "interval": "30s" }, { "refId": "C", "datasource": "Prometheus", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=~\"/refund/.*\"}[5m])) by (route)", "legendFormat": "{{route}}", "interval": "30s" }, { "refId": "D", "datasource": "Prometheus", "expr": "histogram_quantile(0.95, sum(rate(http_server_duration_seconds_bucket{service_name=\"flask-app\", route=~\"/refund/.*\"}[5m])) by (route, le))", "legendFormat": "p95 {{route}}", "interval": "30s" } ] Panels[ { "title": "Remittance Request Rate", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "targets": ["A"] }, { "title": "Remittance Latency (p95)", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, "targets": ["B"] }, { "title": "Refund Request Rate", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 }, "targets": ["C"] }, { "title": "Refund Latency (p95)", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 }, "targets": ["D"] } ] Alerts[ { "name": "Slow Remittance Processing", "expr": "histogram_quantile(0.95, sum(rate(http_server_duration_seconds_bucket{service_name=\"flask-app\", route=\"/remittance/send\"}[5m])) by (le)) > 2", "for": "5m", "severity": "warning" }, { "name": "Refund Service Errors", "expr": "sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=~\"/refund/.*\", status_code=~\"5..\"}[5m])) / sum(rate(http_server_duration_seconds_count{service_name=\"flask-app\", route=~\"/refund/.*\"}[5m])) > 0.05", "for": "5m", "severity": "warning" } ] Click to create this dashboardTo create this dashboard, comment with:
|
Dashboard Suggestion: Flask Application OverviewType: datadog Queries[ { "refId": "A", "datasource": "Datadog", "query": "sum:trace.http.server.duration.by.resource_name{service:flask-app}.as_count().rollup(sum, 60)", "aggregator": "sum", "alias": "Request Count by Endpoint" }, { "refId": "B", "datasource": "Datadog", "query": "p95:trace.http.server.duration{service:flask-app} by {resource_name}", "aggregator": "avg", "alias": "p95 Latency by Endpoint" }, { "refId": "C", "datasource": "Datadog", "query": "sum:trace.http.server.duration.by.resource_name{service:flask-app,http.status_code:5xx}.as_count().rollup(sum, 60) / sum:trace.http.server.duration.by.resource_name{service:flask-app}.as_count().rollup(sum, 60) * 100", "aggregator": "avg", "alias": "Error Rate %" } ] Panels[ { "title": "Request Volume by Endpoint", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "targets": ["A"] }, { "title": "p95 Latency by Endpoint", "type": "timeseries", "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, "targets": ["B"] }, { "title": "Error Rate %", "type": "timeseries", "gridPos": { "h": 8, "w": 24, "x": 0, "y": 8 }, "targets": ["C"] } ] Alerts[ { "name": "High API Error Rate", "query": "sum:trace.http.server.duration.by.resource_name{service:flask-app,http.status_code:5xx}.as_count().rollup(sum, 300) / sum:trace.http.server.duration.by.resource_name{service:flask-app}.as_count().rollup(sum, 300) * 100 > 5", "warning_threshold": 3, "critical_threshold": 5, "notify_no_data": false, "require_full_window": false }, { "name": "High API Latency", "query": "avg:trace.http.server.duration{service:flask-app} by {resource_name} > 1", "warning_threshold": 0.5, "critical_threshold": 1, "notify_no_data": false, "require_full_window": false } ] Click to create this dashboardTo create this dashboard, comment with:
|
Create All DashboardsTo create all suggested dashboards, comment with:
|
Alert Suggestion: HighErrorRateAcrossAPIsType: metric Querysum(rate(http_server_duration_count{status_code=~"5.."}[5m])) / sum(rate(http_server_duration_count[5m])) > 0.05DescriptionHigh rate of 5xx errors across all API endpoints Threshold5% Duration5m Notificationslack-sre-channel RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: APILatencySpikeType: metric Queryhistogram_quantile(0.95, sum by(le, route) (rate(http_server_duration_bucket[5m]))) > 1.0Description95th percentile latency for API endpoints is above 1 second Threshold1.0 seconds Duration5m Notificationslack-sre-channel RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: HighNotFoundRateType: metric Querysum(rate(http_server_duration_count{status_code="404"}[5m])) / sum(rate(http_server_duration_count[5m])) > 0.10DescriptionUnusually high rate of 404 responses, may indicate client issues or missing resources Threshold10% Duration5m Notificationslack-sre-channel RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: RefundAPIErrorRateType: metric Querysum(rate(http_server_duration_count{route=~"/refund.*", status_code=~"5.."}[5m])) / sum(rate(http_server_duration_count{route=~"/refund.*"}[5m])) > 0.03DescriptionRefund API is experiencing a high error rate Threshold3% Duration5m Notificationslack-payments-team RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: RemittanceProcessingLatencyType: metric Queryhistogram_quantile(0.95, sum by(le) (rate(http_server_duration_bucket{route="/remittance/send"}[5m]))) > 2.0DescriptionRemittance processing is taking longer than expected Threshold2.0 seconds Duration5m Notificationslack-payments-team RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: CriticalApplicationErrorsType: log Query{app="flask-app"} |= "ERROR" | json | level="error" | count() > 10DescriptionHigh number of error-level log entries Threshold10 errors Duration5m Notificationslack-sre-channel RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: PaymentProcessingFailuresType: log Query{app="flask-app"} |= "ERROR" |= "payment" | json | count() > 5DescriptionMultiple payment processing failures detected Threshold5 errors Duration5m Notificationslack-payments-team RunbookClick to create this alertTo create this alert, comment with:
|
Alert Suggestion: BadRequestSpikeType: log Query{app="flask-app"} |= "400 Bad Request" | json | count() > 50DescriptionUnusual spike in bad requests, may indicate client integration issues Threshold50 bad requests Duration5m Notificationslack-api-team RunbookClick to create this alertTo create this alert, comment with:
|
Create All AlertsTo create all suggested alerts, comment with:
|
| prism check |
| The PR introduces a new Python Flask application with multiple endpoints but lacks proper observability. My recommendations focus on:
These changes will provide visibility into application performance, error conditions, and user behavior, replacing the alerting rules that were removed in the PR. |
| @@ -0,0 +1,16 @@ | |||
| # app.py | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # app.py | |
| import logging | |
| from flask import Flask, request | |
| from opentelemetry import trace | |
| from opentelemetry.instrumentation.flask import FlaskInstrumentor | |
| from opentelemetry.sdk.trace import TracerProvider | |
| from opentelemetry.sdk.trace.export import BatchSpanProcessor | |
| from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter | |
| # Configure logging | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| logger = logging.getLogger(__name__) | |
| # Configure OpenTelemetry | |
| trace.set_tracer_provider(TracerProvider()) | |
| tracer = trace.get_tracer(__name__) | |
| span_processor = BatchSpanProcessor(OTLPSpanExporter()) | |
| trace.get_tracer_provider().add_span_processor(span_processor) | |
| # Initialize Flask instrumentation | |
| FlaskInstrumentor().instrument_app(app) | |
| logger.info("Initializing Flask application") | |
| @app.before_request | |
| def before_request(): | |
| request_id = request.headers.get('X-Request-ID') | |
| if request_id: | |
| trace.get_current_span().set_attribute("request_id", request_id) | |
| logger.debug(f"Processing request: {request.method} {request.path}") | |
| @app.after_request | |
| def after_request(response): | |
| logger.debug(f"Request completed with status: {response.status_code}") | |
| return response | |
| logger.info("Starting Flask application") |
| @@ -0,0 +1,31 @@ | |||
| # routes/order_routes.py | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # routes/order_routes.py | |
| import logging | |
| import time | |
| import json | |
| from opentelemetry import trace | |
| logger = logging.getLogger(__name__) | |
| tracer = trace.get_tracer(__name__) | |
| with tracer.start_as_current_span("create_order") as span: | |
| start_time = time.time() | |
| logger.info("Processing order creation request") | |
| span.set_attribute("http.method", "POST") | |
| span.set_attribute("endpoint", "/orders/create") | |
| try: | |
| data = request.json | |
| span.set_attribute("order.data", json.dumps(data)) | |
| result = create_order(data) | |
| # Track order creation event | |
| # amplitude.track( | |
| # event_type="Order Created", | |
| # event_properties={ | |
| # "order_data": data, | |
| # "processing_time": time.time() - start_time | |
| # } | |
| # ) | |
| logger.info(f"Order created successfully: {result}") | |
| return jsonify(result) | |
| except Exception as e: | |
| span.record_exception(e) | |
| span.set_status(trace.Status(trace.StatusCode.ERROR)) | |
| logger.error(f"Error creating order: {str(e)}", exc_info=True) | |
| return jsonify({"error": "Failed to create order"}), 500 | |
| with tracer.start_as_current_span("get_order") as span: | |
| span.set_attribute("http.method", "GET") | |
| span.set_attribute("endpoint", f"/orders/{id}") | |
| span.set_attribute("order.id", id) | |
| logger.info(f"Retrieving order with ID: {id}") | |
| try: | |
| order = get_order_by_id(id) | |
| if order: | |
| logger.info(f"Order found: {id}") | |
| return jsonify(order) | |
| logger.warning(f"Order not found: {id}") | |
| span.set_attribute("order.found", False) | |
| return jsonify({"message": "Order not found"}), 404 | |
| except Exception as e: | |
| span.record_exception(e) | |
| span.set_status(trace.Status(trace.StatusCode.ERROR)) | |
| logger.error(f"Error retrieving order {id}: {str(e)}", exc_info=True) | |
| return jsonify({"error": "Failed to retrieve order"}), 500 | |
| with tracer.start_as_current_span("update_order") as span: | |
| start_time = time.time() | |
| span.set_attribute("http.method", "PUT") | |
| span.set_attribute("endpoint", f"/orders/{id}") | |
| span.set_attribute("order.id", id) | |
| logger.info(f"Updating order with ID: {id}") | |
| try: | |
| data = request.json | |
| span.set_attribute("order.update_data", json.dumps(data)) | |
| updated_order = update_order_by_id(id, data) | |
| if updated_order: | |
| # Track order update event | |
| # amplitude.track( | |
| # event_type="Order Updated", | |
| # event_properties={ | |
| # "order_id": id, | |
| # "update_data": data, | |
| # "processing_time": time.time() - start_time | |
| # } | |
| # ) | |
| logger.info(f"Order updated successfully: {id}") | |
| return jsonify(updated_order) | |
| logger.warning(f"Order not found for update: {id}") | |
| span.set_attribute("order.found", False) | |
| return jsonify({"message": "Order not found"}), 404 | |
| except Exception as e: | |
| span.record_exception(e) | |
| span.set_status(trace.Status(trace.StatusCode.ERROR)) | |
| logger.error(f"Error updating order {id}: {str(e)}", exc_info=True) | |
| return jsonify({"error": "Failed to update order"}), 500 | |
| with tracer.start_as_current_span("delete_order") as span: | |
| span.set_attribute("http.method", "DELETE") | |
| span.set_attribute("endpoint", f"/orders/{id}") | |
| span.set_attribute("order.id", id) | |
| logger.info(f"Deleting order with ID: {id}") | |
| try: | |
| result = delete_order_by_id(id) | |
| if result: | |
| # Track order deletion event | |
| # amplitude.track( | |
| # event_type="Order Deleted", | |
| # event_properties={"order_id": id} | |
| # ) | |
| logger.info(f"Order deleted successfully: {id}") | |
| return jsonify({"message": "Order deleted"}) | |
| logger.warning(f"Order not found for deletion: {id}") | |
| span.set_attribute("order.found", False) | |
| return jsonify({"message": "Order not found"}), 404 | |
| except Exception as e: | |
| span.record_exception(e) | |
| span.set_status(trace.Status(trace.StatusCode.ERROR)) | |
| logger.error(f"Error deleting order {id}: {str(e)}", exc_info=True) | |
| return jsonify({"error": "Failed to delete order"}), 500 |
| prism alert --create RefundAPIErrorRate |
| ✅ Successfully created alert! |
| prism dashboard --create Payment Services Performance |
| ✅ Successfully created dashboard! |
No description provided.