Audit Logs
Contents
Audit Logs#
This article explains how the audit modules work in OpenSPP and how to customize them, using a practical example and a working sample module. The audit stack consists of spp_audit_log (core models and UI), spp_audit_post (optional chatter posting), and spp_audit_config (preconfigured rules).
Core Models
The audit stack provides core logging and optional posting with the following key components:
spp.audit.rule
: Configures what to log per model. Fields includemodel_id
,field_to_log_ids
, and toggles forlog_create
,log_write
,log_unlink
, plusview_logs
to add a context action.spp.audit.log
: Stores individual change entries includingaudit_rule_id
,user_id
,model_id
,res_id
,method
, and formatteddata_html
.(From
spp_audit_post
)spp.audit.rule
adds parent linking (parent_id
,child_ids
,field_id
) andspp.audit.log
addsparent_model_id
,parent_res_ids_str
, andparent_data_html
for posting to parent records.
Key Features
Dynamic method decoration on target models (
create
,write
,_write
,unlink
) when a rule is created or updatedField-level selection via
field_to_log_ids
and automatic formatting for selections, relational fields, and datetime valuesOptional action menu "View logs" bound to the target model when
view_logs
is enabledOptional posting of audit messages to the target record or its parent model chatter (
spp_audit_post
)Preconfigured default rules installed via
spp_audit_config
(data/audit_rule_data.xml
)
Prerequisites#
Solid understanding of Odoo 17 module development, including Python, XML, and XPath.
Ensure the following modules are installed: SPP Audit Config, SPP Audit Log, SPP Audit Post (optional).
To set up OpenSPP for development, please refer to the Development Setup Guide.
Module Structure#
A typical audit customization module follows the standard Odoo module structure. Here’s the structure for the example module, spp_audit_log_custom
:
spp_audit_log_custom/
├── __init__.py
├── __manifest__.py
├── models/
│ ├── __init__.py
│ └── spp_audit_rule.py
├── views/
│ └── spp_audit_rule_views.xml
├── security/
│ └── ir.model.access.csv
└── data/
└── audit_rule_data.xml
Step-by-Step Guide#
In this example, we customize the audit rule to include an active
flag, allowing rules to be enabled or disabled without deletion.
A working sample module is available at this link.
Create the Module Scaffold#
Start by creating a new directory for your module (e.g., spp_audit_log_custom
) and populate it
with the basic Odoo module files (__init__.py
, __manifest__.py
) and the directory structure shown above.
Define Module Manifest#
Create a manifest file with the correct dependencies and data files:
{
"name": "OpenSPP Audit Customizations",
"summary": "Custom extensions for OpenSPP Audit",
"category": "OpenSPP",
"version": "17.0.1.0.0",
"author": "Your Organization",
"website": "https://your-website.com",
"license": "LGPL-3",
"depends": [
"spp_audit_log",
# "spp_audit_post", # include if you extend or rely on chatter posting
],
"data": [
"views/spp_audit_rule_views.xml",
# "security/ir.model.access.csv", # not needed if you do not add new models
# "data/audit_rule_data.xml", # optional preconfigured rules
],
"application": False,
"installable": True,
"auto_install": False,
}
Extend the Audit Rule Model#
Create models/spp_audit_rule.py
and update models/__init__.py
:
from odoo import fields, models
class CustomAuditRule(models.Model):
_inherit = "spp.audit.rule"
active = fields.Boolean(
default=True,
help="If unchecked, the rule can be treated as inactive in your custom logic",
)
Create View Extensions#
Create views/spp_audit_rule_views.xml
and add it to the manifest:
<odoo>
<record id="view_custom_audit_log_form" model="ir.ui.view">
<field name="name">view_custom_audit_log_form</field>
<field name="model">spp.audit.rule</field>
<field name="inherit_id" ref="spp_audit_log.spp_audit_rule_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="before">
<field name="active" />
</xpath>
</field>
</record>
</odoo>
Add Security Access (Optional)#
If you introduce new models, add access rights. For simple field additions, this is not required. Example:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_custom_spp_audit_rule,custom.spp.audit.rule,spp_audit_log.model_spp_audit_rule,base.group_system,1,1,1,0
Group ID:
g2p_registry_base.group_g2p_registrar
for Registrar AccessGroup ID:
g2p_registry_base.group_g2p_admin
for Admin Access.
Add Preconfigured Rules (Optional)#
Seed rules using data/audit_rule_data.xml
and the spp.audit.rule.create_rules
helper:
<odoo>
<data noupdate="1">
<function model="spp.audit.rule" name="create_rules">
<value name="rule_name">My Registry Rule</value>
<value name="model">res.partner</value>
<value name="fields_to_log" eval="['name', 'gender', 'birthdate']" />
<value name="view_logs" eval="True" />
</function>
</data>
</odoo>
For parent/child rules (requires spp_audit_post
), also pass parent_rule_name
and connecting_field_name
.
Install and Test#
Install or upgrade the module through the Apps menu.
Create or update records in the configured models (e.g., Individual or Group Registry).
Open Audit Log → Audit → Log to review entries.
On a specific record, use Action → View logs (if enabled) to see related entries.
Best Practices#
Use Targeted Field Lists: Keep field_to_log_ids
focused on business-critical fields.
References#
For more information on extending OpenSPP modules, refer to:
Audit module sources: