Package: django-insights
FeaturesCreate insights for your app, store them in a SQLite database for further processing, these insights are written right next to your application logic.Note:Still working on some small things, extending tests and improving the documentation.For now focus is on:Django 3.2 (LTS), 4.0,4.1 and 4.2;Python ≥ 3.8InstallationInstalling with:pipinstall'django-insights'UsageFirst create ainsights.pyfile in your app directory, for example:project
└──testapp└──insights.pyEach app can have it's owninsignts.pyfile, these files are auto-discovered by Django Insights, so at any given location it would pick up your metrics.In these insights files you write out any metric you would like to track. Each metric starts with a question and some values to store. Below is a example of the@metrics.counterfunction:# project/testapp/insights.pyfromdjango_insights.metricsimportmetricsfromproject.testapp.modelsimportAuthorlabel="Bookstore"@metrics.counter(question="How many authors are there?")defcount_authors()->int:returnAuthor.objects.count()Insight apps can have alabel, this is used in the dashboard or can be read frominsights_apptable later on.SettingsAdd django_insights package, insights database and router to your settingsINSTALLED_APPS=[..."django_insights",]DATABASES={..."insights":{"ENGINE":"django.db.backends.sqlite3","NAME":"db/insights.db"},...}DATABASE_ROUTERS=['django_insights.database.Router']Note: please make sure you exclude the database in your.gitignorefileMigrate insights database:workonmyapp
pythonmanage.pymigrateinsights--database=insightsNow collect your insightspythonmanage.pycollect_insightsYou now have a database containing all insights from your application.You can inspect this database yourself withsqlite3 db/insights.db- or - you can use the Django Insights dashboard.DashboardTo enable this dashboard, add the following settings:fromdjango.urlsimportinclude,pathurlpatterns=[path('/insights',include('django_insights.urls',namespace='insights'),),]Now you can visithttps://localhost:8000/insightsto inspect your Django Insights database.MetricsDjango insights contains 5 types of metrics it can collect:@metrics.counter@metrics.gauge@metrics.timeseries@metrics.scatterplot@metrics.barchartCounter:fromdjango_insights.metricsimportmetricsfromproject.testapp.modelsimportAuthor@metrics.counter(question="How many authors are there?")defcount_authors()->int:returnAuthor.objects.count()Gauge:fromdjango.db.modelsimportAvg,Countfromdjango_insights.metricsimportmetricsfromproject.testapp.modelsimportAuthor@metrics.gauge(question="Average book(s) per author?")defavg_books_per_author()->int:avg_total_books=(Author.objects.prefetch_related('books').annotate(total_books=Count('books')).aggregate(Avg('total_books')).get('total_books__avg'))returnavg_total_booksTimeseries:fromdatetimeimportdatetimefromdjango.db.modelsimportCountfromdjango.db.models.functionsimportTruncMonthfromdjango_insights.metricsimportmetricsfromproject.testapp.modelsimportBook@metrics.timeseries(question="Num of books created per month?",desc="How many books are added each month, since the opening of our store",xlabel="Month",xformat='%m',ylabel="Num of books",)defnum_of_books_per_month()->list[tuple[datetime,int]]:return(Book.objects.all().annotate(month=TruncMonth('created')).values('month').filter(month__isnull=False).annotate(total=Count('pk')).values_list('month','total').order_by('month'))Scatterplot:fromdatetimeimportdatetimefromdjango.db.modelsimportCount,Valuefromdjango_insights.metricsimportmetricsfromproject.testapp.modelsimportAuthor@metrics.scatterplot(question="Num of books by age of author?",xlabel="Age",ylabel="Num of books",)defauthor_age_vs_num_of_books()->list[tuple[float,float,Any]]:return(Author.objects.values('age').annotate(num_of_books=Count('books'),category=Value("author")).values_list('num_of_books','age','category'))Barchart:fromdatetimeimportdatetimefromdjango.db.modelsimportCase,Count,Value,Whenfromdjango_insights.metricsimportmetricsfromproject.testapp.modelsimportAuthor@metrics.barchart(question="Num of books by gender of author?",xlabel="Gender",ylabel="Num of books",)defauthor_gender_vs_num_of_books()->list[tuple[float,float,str]]:return(Author.objects.values('gender').annotate(num_of_books=Count('books'),gender_category=Case(When(gender=1,then=Value('Male')),When(gender=2,then=Value('Female')),),).values_list('num_of_books','gender','gender_category'))Settings# Custom app nameINSIGHTS_APP_NAME="Bezamon"# Quality of chart imagesINSIGHTS_CHART_DPI=180# Default theme for dashboardINSIGHTS_THEME="dark"# Change primary color of dashboardINSIGHTS_CHART_LIGHT_PRIMARY_COLOR="#2563EB"INSIGHTS_CHART_DARK_PRIMARY_COLOR="#BFDBFE"Use-casesInsights are gathered from your current application state, Django Insights is not intentend to be used as a realtime, incremementing data-source. You should be able to re-gather these insights from your actual data at any moment in time.Yes:How many users, how many users invited a yearHow many reports a day, how many messages send on Wednesday'sNo:How many GET request for url XXX a secondRealtime profit target percentageBackgroundI'm currently working at a small company that is in the process of renewing some parts of our product. To gain insight into the usage over different periods, we have tried a few solutions. We initially attempted to periodically generate CSV files from queries, as well as send data to a dashboard at regular intervals.We ended up with many exports that where spread out over multiple people. Additionally, exporting data directly from the database also posed a security risk, as it required constant movement of possible sensitive information. After several months of working with CSV files, which were often outdated and required conversion by other (paid) tools, we where looking for a better solution.I wanted an easy-to-configure file within our various apps that would allow me to create "insights" easily, so Django Insights was born. I decided to switch to a local SQLite database which could be share on request, as a plus these files can be tracked by a security officer.DocumentationWrite more about where to find documentationIdeasConnect to other datasources and export to different file-formats ( ArrowFile?, NDJSON )Is it any good?Yes.LicenseThe MIT License