Monitoring your applications¶
Warning
This page describes an ad hoc solution to a problem to which better solutions certainly exist, like the famous Prometheus/Grafana stack.
It presumably reflects our limited knowledge (and if you do know of a better way to do it, do not hesitate to reach to us!! 😊).
TL DR: If your app sees a huge traffic, go with existing tools. If nevertheless you want to finely track a small number of users that connect from time to time, continue reading.
In our experience (we setup the Prometheus/Grafana stack for both dash and fastapi applications), tracking users proves cumbersome (Prometheus metrics were not meant to do that).
We provide a very crude user monitoring system in ecodev_core.
App Activity¶
A code snippet is hopefully worth a thousand words here
from typing import Optional
from datetime import datetime
from sqlmodel import Field
from sqlmodel import SQLModel
class AppActivityBase(SQLModel):
    """
    Simple monitoring class
    Attributes are:
        - user: the name of the user that triggered the monitoring log
        - application: the application in which the user triggered the monitoring log
        - method: the method called by the user  that triggered the monitoring log
        - relevant_option: if filled, complementary information on method (num of treated lines...)
    """
    user: str = Field(index=True)
    application: str = Field(index=True)
    method: str = Field(index=True)
    relevant_option: Optional[str] = Field(index=True, default=None)
class AppActivity(AppActivityBase, table=True):  # type: ignore
    """
    The table version of the AppActivityBase monitoring class
    """
    __tablename__ = 'app_activity'
    id: Optional[int] = Field(default=None, primary_key=True)
    created_at: datetime = Field(default_factory=datetime.utcnow)
To store in this monitoring table, we have two methods depending whether we are monitoring a dash or a fastapi endpoint.
Dash monitoring¶
dash_monitor(method: str, token: Dict, application: str,  relevant_option: Optional[str] = None)
Here we use the token that we usually have in a Dash store
You can see a use example in the test suite
FastAPI monitoring¶
fastapi_monitor(method: str, user: AppUser, application: str, session: Session, relevant_option: Optional[str] = None)
Here we usually directly have access to the user thanks to fastapi Depends class that acts as a middleware to perform certain operations (fetch a user and check if its valid, fetch a db session...)
You can see a use example in the test suite
How to use it in real life?¶
In the application we want to monitor, we usually put calls to these methods in Dash callbacks/FastAPI routes.
Then the application to monitor usually has a route of the sort
from typing import List
from ecodev_core import AppActivity
from ecodev_core import AppUser
from ecodev_core import get_recent_activities
from ecodev_core import get_session
from ecodev_core import is_monitoring_user
from fastapi import Depends
from fastapi import FastAPI
from fastapi import status
from sqlmodel import Session
app = FastAPI()
@app.get('/get-activities', status_code=status.HTTP_201_CREATED,
         response_model=List[AppActivity])
async def get_activities(*, last_date: str,
                         user: AppUser = Depends(is_monitoring_user),
                         session: Session = Depends(get_session),
                         ) -> List[AppActivity]:
    """
    Retrieve recent activities from the app
    """
    return get_recent_activities(last_date, session)
Where get_recent_activities is a ecodev_core helper method fetching all AppActivity more recent than a passed datetime.
Then another central monitoring web app is responsible for calling all get_activities from all registered applicaions to monitor. 
With dash you can then constructs a simple dashboard that looks like so in our case
Our EcoAct monitoring web application in all its splendor 😆
Where we can then easily track a user (hello me! 😆)
How one user uses a specific application
Tip
If enough interest is shown for the details of this monitoring app, we could consider releasing it as open source as well 😎

