Collecting usage statistics in Saas application

Collecting information on how users use Saas is crucial for its scaling up.

When implementing the solution for collecting stats you have to take into account:

Implemention in Flask

This example shows how to collect stats in the Flask Saas application and save them in an external database.

First, create extensions for handling database connections for the stats database. Remember about thread safety and fast connection handling. For that purpose it is recommended to use the: - SqlAlchemy for thread safe and optimal connection pooling, - turn on the AUTOCOMMIT mode for the performance reason, - use only raw SQL (instead ORM) for performance.

from sqlalchemy import create_engine  
from sqlalchemy.engine import Engine  


class Stats:  
    engine: Engine = None  

    def init_app(self, app):  
        eng = create_engine(  
            app.config['STATS_DATABASE_URI'])  
        self.engine = eng.execution_options(isolation_level="AUTOCOMMIT")  
        # app.extensions['pl.sszz.stats'] = self  

    def get_conn(self):  
        # print(self.engine.pool.status())  
        return self.engine.connect()  

    def register(self, sql):  
        try:  
            conn = self.get_conn()  
            conn.execute(sql)  
            conn.close()  
        except Exception as e:  # Collecting stats cannot break the app  
            print('Stats error: {}'.format(str(e)))

In the next step register the extension in the flask app to have only one engine running and optimal connections handling for the running app.


db = SQLAlchemy()  
migrate = Migrate(compare_type=True)  
stats = Stats()  


def create_app(config_class):  
    app = Flask(__name__)  
    app.config.from_object(config_class)  

    stats.init_app(app)

Then just create database and start collecting facts.

def new_anonymous_appuser(self, appuser):  
    sql = "INSERT INTO new_anonymous_appuser(id_appuser, id_device) values ({}, '{}')".format(  
        appuser.id, appuser.devices[0].id)  
    self.register(sql)