This post describes a simple pproach to recording login, logout, insert, update and delete operations that are carried out by a Python Flask application.
This is not the same as a table auditing function similar to Ruby’s Paperclip module.
https://github.com/slugbucket/crossword-hints/issues/9 is an example feature branch for a personal project implementing this.
The activity log will be stored in a database table with the following structure:
* rowid – auto-assigned unique id for the activity record
* actor – the name of the user performing the action
* action – one of login, insert, update, delete or logout,
* item_type -the table on which the operation has been performed.
* item_id – the numeric id of the item under operation
* act_action – details of the content that has been changed
This can be modeled in Flask using PeeWee
... from peewee import * from datetime import date, timedelta, datetime ... class BaseModel(Model): with application.app_context(): class Meta: database = database class activity_logs(BaseModel): rowid = AutoField() actor = CharField(max_length=32) action = CharField(max_length=32) item_type = CharField(max_length=32) item_id = IntegerField() act_action = TextField() created_at = CharField(max_length=32) updated_at = DateTimeField(default=datetime.now())
The application context is called application to work better when deployed to AWS.
Having used Flask-login to control the login process. we have a variable. current_user, that contains a numeric id of the user from their record in teh database.
The users model includes a method to return the name of the user and this can be used for the ‘actor’ value.
A simple function can create the activity log reord:
def add_log(actor, action, item_type, item_id, activity): log = activity_logs(actor=actor, action=action, item_type=item_type, item_id=item_id, act_action=activity, created_at=datetime.now(), updated_at=datetime.now()) log.save()
And activities to be logged can be logged with something like,
log = ("name: %s\ndescription: %s" % (name, description)) add_log(users.get_name(current_user), 'update', 'solution_types', id, log)
Where,
- name and description are variables containing form-submitted data
- activity_logs is the PeeWee model of the databse table
- users is a PeeWee ORM model of an application user that can be authenticated.
When used the (sqlite3) database records will look like,
sqlite> select * from activity_logs; crossy|login|user|1|Successful login for crossy|2019-02-15 18:44:38.257050|2019-02-15 18:44:38.257061 crossy|update|solution_types|12|name: Homophone description: Sounds like a word that has a different spelling|2019-02-15 18:45:03.227188|2019-02-15 18:45:03.227193 crossy|logout|user|1|Successful logout user for crossy|2019-02-15 18:48:11.043243|2019-02-15 18:48:11.043249
With these records it should be possible to display an activity report and perhaps even recover previous versions of particular database records.
Improvements
- Storing the full record on each update is inefficient; only differences should be recorded.
- The logging function should be able to determine what to include in the log message based on the