JustAnalytics for Flask
Step-by-step guide to add analytics, error tracking, and APM to your Flask app
JustAnalytics for Flask
Add distributed tracing, error tracking, structured logging, and infrastructure metrics to your Flask application.
Time to data: 3 minutesPrerequisites#
- Flask 2.0+
- Python 3.9+
- A JustAnalytics account with a Site ID and API key
Install the SDK
pip install justanalytics-python[flask]
Initialize and add middleware
# app.py
import os
import justanalytics
from flask import Flask
from justanalytics.integrations.flask import JustAnalyticsMiddleware
# Initialize the SDK BEFORE creating the Flask app
justanalytics.init(
site_id=os.environ.get("JA_SITE_ID"),
api_key=os.environ.get("JA_API_KEY"),
service_name="flask-api",
environment=os.environ.get("FLASK_ENV", "development"),
)
app = Flask(__name__)
# Add the middleware — traces all incoming requests automatically
JustAnalyticsMiddleware(app)
Add your routes
Routes are automatically traced. Each request creates a span named after the endpoint:
@app.route("/api/users/<int:user_id>")
def get_user(user_id):
# Automatically traced as "GET /api/users/<int:user_id>"
user = User.query.get_or_404(user_id)
return jsonify(user.to_dict())
@app.route("/api/orders", methods=["POST"])
def create_order():
data = request.get_json()
order = Order.create(**data)
return jsonify(order.to_dict()), 201
Add error handling
Unhandled exceptions are automatically captured. For explicit error reporting:
@app.errorhandler(500)
def handle_500(error):
justanalytics.capture_exception(error, tags={"handler": "500"})
return jsonify({"error": "Internal server error"}), 500
@app.route("/api/payments", methods=["POST"])
def process_payment():
try:
result = charge_card(request.json)
return jsonify(result)
except PaymentError as e:
justanalytics.capture_exception(e, tags={"module": "payments"})
return jsonify({"error": str(e)}), 400
Verify data is flowing
Start your Flask app and make a test request:
flask run
curl http://localhost:5000/api/users/1
Verify Your Setup
After sending a test request, check the Traces tab. You should see Flask request spans with route patterns.
Open DashboardAdvanced Features#
Custom spans#
@app.route("/api/reports/<report_id>")
def get_report(report_id):
with justanalytics.start_span("generate-report") as span:
span.set_attribute("report.id", report_id)
with justanalytics.start_span("query-database"):
data = Report.query.get(report_id)
with justanalytics.start_span("render-template"):
html = render_template("report.html", data=data)
return html
Decorator-based tracing#
@justanalytics.span(op="service.call")
def send_notification(user_id, message):
# Automatically creates a span named "send_notification"
return notification_service.send(user_id, message)
User identification#
@app.before_request
def identify_user():
if hasattr(g, "current_user") and g.current_user:
justanalytics.set_user(
id=str(g.current_user.id),
email=g.current_user.email,
)
Structured logging#
justanalytics.log("info", "User registered", {"user_id": "u123", "source": "google"})
justanalytics.log("warn", "Rate limit close", {"ip": request.remote_addr, "remaining": 5})
Outgoing HTTP tracing#
from justanalytics.integrations.requests import RequestsIntegration
RequestsIntegration(service_name="flask-api").enable()
# Now all requests.get/post calls propagate trace context
import requests
response = requests.get("https://api.stripe.com/v1/charges")
Custom metrics#
justanalytics.record_metric("custom.active_users", active_count)
justanalytics.record_metric("custom.response_time_ms", elapsed, {"endpoint": "/api/users"})
Graceful shutdown#
import atexit
atexit.register(justanalytics.flush)
atexit.register(justanalytics.close)
Environment variables#
| Variable | Description | Required |
|----------|-------------|----------|
| JA_SITE_ID | Your site ID from the dashboard | Yes |
| JA_API_KEY | API key (starts with ja_sk_) | Yes |
| FLASK_ENV | Used as the default environment tag | No |