Skip to content

Commit

Permalink
feat: add opt to track only specific models
Browse files Browse the repository at this point in the history
  • Loading branch information
mutantsan committed Nov 25, 2024
1 parent 2292af7 commit 5b36182
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 12 deletions.
11 changes: 9 additions & 2 deletions ckanext/event_audit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
CONF_IGNORED_ACTIONS = "ckanext.event_audit.ignore.actions"
CONF_IGNORED_MODELS = "ckanext.event_audit.ignore.models"

CONF_DATABASE_TRACK_ENABLED = "ckanext.event_audit.track.model"
CONF_API_TRACK_ENABLED = "ckanext.event_audit.track.api"
CONF_TRACK_MODELS = "ckanext.event_audit.track.models"

CONF_DATABASE_TRACK_ENABLED = "ckanext.event_audit.track_model"
CONF_API_TRACK_ENABLED = "ckanext.event_audit.track_api"

CONF_STORE_PAYLOAD_AND_RESULT = "ckanext.event_audit.store_payload_and_result"

Expand Down Expand Up @@ -62,6 +64,11 @@ def get_ignored_models() -> list[str]:
return tk.config[CONF_IGNORED_MODELS]


def get_tracked_models() -> list[str]:
"""A list of database models to track when logging events."""
return tk.config[CONF_TRACK_MODELS]


def is_database_log_enabled() -> bool:
"""Returns True if database logging is enabled."""
return tk.config[CONF_DATABASE_TRACK_ENABLED]
Expand Down
9 changes: 7 additions & 2 deletions ckanext/event_audit/config_declaration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,23 @@ groups:
editable: true
default: Option

- key: ckanext.event_audit.track.model
- key: ckanext.event_audit.track_model
description: Enable logging of database events
default: true
editable: true
type: bool

- key: ckanext.event_audit.track.api
- key: ckanext.event_audit.track_api
description: Enable logging of API events
default: true
editable: true
type: bool

- key: ckanext.event_audit.track.models
description: A list of models to track
type: list
editable: true

- key: ckanext.event_audit.store_payload_and_result
description: Store the payload and result of the event
default: false
Expand Down
4 changes: 2 additions & 2 deletions ckanext/event_audit/config_schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fields:
form_snippet: tom_tags.html
required: false

- field_name: ckanext.event_audit.track.model
- field_name: ckanext.event_audit.track_model
label: Track Model
help_text: Enable logging of database events
preset: select
Expand All @@ -60,7 +60,7 @@ fields:
- value: false
label: No

- field_name: ckanext.event_audit.track.api
- field_name: ckanext.event_audit.track_api
label: Track API
help_text: Enable logging of API events
preset: select
Expand Down
4 changes: 4 additions & 0 deletions ckanext/event_audit/listeners/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ def after_commit(session: SQLAlchemySession):

thread_mode_enabled = config.is_threaded_mode_enabled()
should_store_complex_data = config.should_store_payload_and_result()
tracked_models = config.get_tracked_models()

for action, instances in session._audit_cache.items(): # type: ignore
for instance in instances:
if isinstance(instance, EventModel):
continue

if tracked_models and instance.__class__.__name__ not in tracked_models:
continue

event = repo.build_event(
types.EventData(
category=const.Category.MODEL.value,
Expand Down
9 changes: 8 additions & 1 deletion ckanext/event_audit/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,14 @@ def skip_event(self, event: types.Event) -> bool:
if event.category in config.get_ignored_categories():
return True

return event.action_object in config.get_ignored_models()
# track specific models have priority over ignoring specific models
if (
not config.get_tracked_models()
and event.action_object in config.get_ignored_models()
):
return True

return False

# IConfigDeclaration

Expand Down
23 changes: 23 additions & 0 deletions ckanext/event_audit/tests/listeners/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,26 @@ def test_store_payload_and_result(
user_idx = 1

assert events[user_idx].payload["name"] == user["name"]

@pytest.mark.usefixtures("with_plugins", "clean_db")
@pytest.mark.ckan_config(config.CONF_ACTIVE_REPO, "postgres")
@pytest.mark.ckan_config(config.CONF_TRACK_MODELS, ["Dashboard"])
def test_track_only_specific_models(self, user: dict[str, Any], repo: repositories.AbstractRepository):
events = repo.filter_events(types.Filters())

assert len(events) == 1
assert events[0].action_object == "Dashboard"

@pytest.mark.usefixtures("with_plugins", "clean_db")
@pytest.mark.ckan_config(config.CONF_ACTIVE_REPO, "postgres")
@pytest.mark.ckan_config(config.CONF_TRACK_MODELS, ["Dashboard"])
@pytest.mark.ckan_config(config.CONF_IGNORED_MODELS, ["Dashboard"])
def test_track_have_priority_over_ignore(self, user: dict[str, Any], repo: repositories.AbstractRepository):
assert config.get_tracked_models() == ["Dashboard"]
assert config.get_ignored_models() == ["Dashboard"]

events = repo.filter_events(types.Filters())

assert len(events) == 1
assert events[0].action_object == "Dashboard"

16 changes: 14 additions & 2 deletions docs/configure/tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Captures all events that are triggered by the CKAN API. Everything that is calle
To disable the API tracker, specify this in the configuration file:

```ini
ckanext.event_audit.track.api = false
ckanext.event_audit.track_api = false
```

We can ignore specific actions from being tracked by setting the `ckanext.event_audit.ignore.actions` configuration option. See the [ignore](ignore.md) section for more details.
Expand All @@ -21,7 +21,7 @@ We're utilising the SQLAlchemy’s event system for tracking database interactio
To disable the Database tracker, specify this in the configuration file:

```ini
ckanext.event_audit.track.model = false
ckanext.event_audit.track_model = false
```

We can ignore specific models from being tracked by setting the `ckanext.event_audit.ignore.models` configuration option. See the [ignore](ignore.md) section for more details.
Expand All @@ -40,3 +40,15 @@ ckanext.event_audit.store_payload_and_result = true
## Custom trackers

You can create and write an event anywhere in your codebase. See the [usage](../usage.md) section for more details.

## Track only specific models

If you want to track only specific models, you can set the `ckanext.event_audit.track.models` configuration option. This will ignore all the models that are not specified in the list.

```ini
ckanext.event_audit.track.models = Package Resource User
```

???+ Warning
1. The model names are case-sensitive.
2. Tracking specific models have a priority over ignoring specific models. If you specify the models to track, the ignore list will be ignored.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "ckanext-event-audit"
version = "1.0.0"
version = "1.0.1"
description = ""
classifiers = [
"Development Status :: 4 - Beta",
Expand Down
4 changes: 2 additions & 2 deletions test.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ ckanext.event_audit.cloudwatch.region = ap-southeast-2

# disable tracking of model and api events for tests
# we're going to enable it only for specific tests
ckanext.event_audit.track.model = false
ckanext.event_audit.track.api = false
ckanext.event_audit.track_model = false
ckanext.event_audit.track_api = false

# disable threaded mode for tests, as it's requires timeout for the tests to pass
ckanext.event_audit.threaded_mode = false
Expand Down

0 comments on commit 5b36182

Please sign in to comment.