Skip to content

App Stats — Overview

ecodev_core ships a lightweight statistics layer (app_stats) that lets any app expose its usage data over HTTP and lets any central dashboard ingest that data on a schedule.

The two roles are deliberately separated:

Role Name What it does
Producer any ecodev_core app Serves aggregated activity & project data via /stats/* FastAPI routes
Consumer a central monitoring app Polls producers on a schedule, stores results locally, and renders dashboards

How they fit together

  ┌─────────────────────┐        /stats/activities     ┌──────────────────────────┐
  │   Producer app A    │ ◄─────────────────────────── │                          │
  │  (e.g. cf-tool)     │                              │   Consumer / monitoring  │
  └─────────────────────┘                              │          app             │
                                                       │                          │
  ┌─────────────────────┐        /stats/projects        │  • polls on a schedule   │
  │   Producer app B    │ ◄─────────────────────────── │  • stores locally        │
  │  (e.g. myecoapps)   │                              │  • renders dashboards    │
  └─────────────────────┘                              └──────────────────────────┘

The consumer never queries the producers at render time — network calls happen during the scheduled ingest only, keeping dashboards fast and resilient to producer downtime.


Producer in a nutshell

Wire get_stats_router() into an existing FastAPI app:

from ecodev_core import get_stats_router

app.include_router(get_stats_router())

This registers /stats/activities. Optionally pass a ProjectStatsAdapter to also expose /stats/projects. Authentication is handled via a per-environment api_key — no JWT needed.

→ See the Producer guide for the full setup.


Consumer in a nutshell

Import the consumer submodule, store producer configs (URLs + API keys), and run the ingest command on a schedule:

from ecodev_core.app_stats.consumer import StatsApiClient, upsert_remote_activities

# nightly via Ofelia / Typer command
run_ingest(granularity=HOUR_GRAIN)

Ingested rows land in local RemoteActivity and RemoteProject tables and are read back with get_remote_activities / get_remote_projects.

→ See the Consumer guide for the full setup.


Tip

Both guides share the same ecodev_core.app_stats.constants module for grain constants (HOUR_GRAIN, MONTH_GRAIN). Import them from there to avoid typos.