Skip to content

Manual span instrumentation for key business operations #8

@ncolesummers

Description

@ncolesummers

Context

Auto-instrumentation (issues #2 and #5) captures HTTP requests and DB queries, but business-level operations need manual spans with domain-specific attributes. This makes traces tell a meaningful story when debugging — you see "auth.login" and "items.create" instead of just "POST /api/v1/login/access-token".

Scope

Backend Manual Spans

  • backend/app/api/routes/login.py
    • Span auth.login around authentication logic with attributes: user.email, auth.result
    • Span auth.password_recovery around password recovery with attribute: recovery.email
  • backend/app/api/routes/items.py
    • Span items.create with attributes: item.title, item.owner_id
    • Span items.update with attributes: item.id, item.owner_id
    • Span items.delete with attributes: item.id
  • backend/app/utils.py
    • Span email.send around email sending with attributes: email.recipient, email.subject
  • backend/app/crud.py
    • Spans for CRUD operations with attributes: db.operation, db.entity_type

Frontend Manual Spans (optional, lower priority)

  • Page navigation events via TanStack Router lifecycle hooks
  • Form submission flows (login, create item, update user settings)

Span Events

Add span events for significant state transitions:

  • Login success/failure
  • Item created/updated/deleted
  • Validation errors
  • Email sent/failed

Example

from opentelemetry import trace

tracer = trace.get_tracer(__name__)

@tracer.start_as_current_span("auth.login")
def login_access_token(session, form_data):
    span = trace.get_current_span()
    span.set_attribute("user.email", form_data.username)
    
    user = crud.authenticate(session, email=form_data.username, password=form_data.password)
    if not user:
        span.set_attribute("auth.result", "failure")
        span.add_event("login_failed", {"reason": "invalid_credentials"})
        raise HTTPException(...)
    
    span.set_attribute("auth.result", "success")
    span.add_event("login_succeeded", {"user.id": str(user.id)})
    # ...

Acceptance Criteria

  • Business operations have descriptive span names (e.g., auth.login, items.create)
  • Span attributes provide domain context (user_id, item_id, operation type)
  • Span events capture state transitions (success/failure)
  • Traces in Jaeger tell a clear story of each user operation
  • No sensitive data (passwords, tokens) in span attributes

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendFastAPI backend changesfrontendReact frontend changesobservabilityObservability, tracing, metrics, loggingtracesDistributed tracing

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions