avo icon indicating copy to clipboard operation
avo copied to clipboard

Audit logging

Open adrianthedev opened this issue 3 years ago • 14 comments

[!NOTE]
Enterprise feature - https://github.com/avo-hq/avo-audit_logging

Feature

Know who did what in Avo.

Approach

This feature should:

  • [x] record which user edited a record and which fields he updated
  • [x] record when a user runs an action on which record and with which field values
  • [x] display these changes in a separate view (maybe as associations?) (maybe a new timeline view?)
  • [x] enable the user to rollback the record changes (not action changes)
  • [ ] maybe custom implementation (last resort)
  • [ ] maybe custom audited model
### Related
- [ ] https://github.com/avo-hq/avo/issues/1322

Gems to test out:

  • https://github.com/collectiveidea/audited (preferred)
  • https://github.com/paper-trail-gem/paper_trail

Related

We could use the same thing in https://github.com/avo-hq/avo/issues/1322

"We’ve seen some particularities that make Audited mostly used to “Active Record User Stamping”, (checking the actions taken by a particular user), while Paper Trail is referenced as being in the “Active Record Versioning Area” (getting a timeline of changes in a record due to the larger set of options that Paper Trail offers in terms of functions and methods)."

https://revs.runtime-revolution.com/the-battle-for-auditing-and-versioning-in-rails-audited-vs-paper-trail-17ad0011ecd9

CleanShot 2024-04-16 at 16 25 31@2x

adrianthedev avatar Oct 18 '22 20:10 adrianthedev

I did some audit log work for the RubyGems.org admin site in https://github.com/rubygems/rubygems.org/pull/3426, if that helps at all with inspiration!

segiddins avatar Feb 13 '23 18:02 segiddins

That's interesting work you're doing there with the ActionHandler @segiddins. That will definitely come in handy when we'll implement our own logging feature. Thanks for sharing!

Was it difficult to navigate the codebase and understand how actions work?

adrianthedev avatar Feb 13 '23 18:02 adrianthedev

Not too difficult, though I did spend a bunch of time reading through the code (instead of being able to use the docs 100%). Overall I'd say it was easy to figure out what I needed in order to do my hackery :)

segiddins avatar Feb 13 '23 18:02 segiddins

Yeah, we don't have a lot of internals documented. I'd like to do that after we have the API more stable.

adrianthedev avatar Feb 13 '23 19:02 adrianthedev

Thanks for sharing!

adrianthedev avatar Feb 13 '23 19:02 adrianthedev

Just to inform your thinking on this a little bit: We're using PaperTrail, and heavily customizing how the whodunnit field is used. In our case, it can be a User (via the API), an Administrator (via Avo), a Ruby class (scheduled Sidekiq job), or a Unix username (via a Rails console). So, for us, the ability to customize how that information is presented would be pretty critical.

That said, anything you do here is in nice-to-have territory now that we've established a pattern of using a carefully tailored Resource, and a field declaration in a tab for showing versions associated with a record.

MrJoy avatar Jan 04 '24 22:01 MrJoy

Hey @MrJoy thanks for sharing! We are exploring an adapter pattern that could work with both gems, PaperTrail and Audited. Would be the preferred path to follow but we can't promise anything until we have a working POC

Paul-Bob avatar Jan 05 '24 14:01 Paul-Bob

We have also been using PaperTrail but have been having trouble tracking records' Action Text rich text attributes on the one hand and plain text Mobility-translated attributes on the other hand, which are stored in their own tables using polymorphic associations (we have actually been serving both needs with this gem I built).

PaperTrail indicates that it does not offer proper association tracking out of the box.

To track and reify associations, use paper_trail-association_tracking (PT-AT).

So I was going to try paper_trail-association_tracking but its own README recommends against its use, in favor of active_snapshot.

PT-AT README:

Alternative Solution

Model versioning and restoration require concious thought, design, and understanding. You should understand your versioning and restoration process completely. This gem paper_trail-association-tracking is mostly a blackbox solution which encourages you to set it up and then assume its Just WorkingTM. This can make for major data problems later.

Instead I recommend a newer gem that I have created for handling snapshots of records and associations called active_snapshot. This gem does not utilize paper_trail at all. The focus of the active_snapshot gem is to have a simple and fully understandable design is easy to customize and know inside and out for your projects needs.

ActiveSnapshot README:

Why This Library:

Model Versioning and Restoration require concious thought, design, and understanding. You should understand your versioning and restoration process completely. This gem's small API and fully understandable design fully supports this.

I do not recommend using paper_trail-association_tracking because it is mostly a blackbox solution which encourages you to set it up and then assume its Just WorkingTM. This makes for major data problems later. Dont fall into this trap. Instead read this gems brief source code completely before use OR copy the code straight into your codebase. Once you know it, then you are free.

So basically PaperTrail declares that it is missing a feature, redirects to using an alternative gem, which itself redirects to yet another one, which presents itself as a solution completely replacing PaperTrail.

So what do you think of ActiveSnapshot? Might it offer a more durable solution when modifying attributes stored in associated tables?

sedubois avatar Jan 09 '24 16:01 sedubois

I did some tests of compatibility between 3 audit gems and translated and/or rich-text attributes.

These are my current conclusions:

  • I couldn't track attributes stored in polymorphic associations (incl. Action Text) with Paper Trail and Audited
  • Although Paper Trail and Audited seem more popular, active Snapshot seems more promising as far as these tests are concerned, with two caveats: still need to fix an error when restoring a snapshot, and also the callbacks need to be registered manually in the app (e.g. before_update { create_snapshot! }). For more details, see here.
Attribute type Sample code Paper Trail (1) Audited (1) Active Snapshot (2)
Action Text rich text has_rich_text :text
Mobility (key_value = default backend: separate table with polymorphic association) translates :title, backend: :key_value, type: :string
Mobility (container backend: JSONB column on model table) translates :description, backend: :container ✅(3) ✅(3)
Translated Action Text (4) translates :body, backend: :action_text

(1) These gems seem to only track changes to columns on the model's table. I also did not find an API to add attributes/associations to be tracked. For instance has_paper_trail has options only, skip to restrict attributes but not to specify additional ones.

(2) Active Snapshot needs to be configured with a has_snapshot_children block, see here.

(3) Stores the changes with the name of the underlying translations association. Paper Trail allows to successfully reify and restore the version (version.reify.save). NB: Whereas Paper Trail allows to restore (reify) versions, Audited does not seem to. I also encountered an error when trying to .restore! the Active Snapshot but might be due to the particular STI model I was testing with.

(4) Using Mobility Action Text.

sedubois avatar Jan 10 '24 12:01 sedubois

Also see the new Hoardable gem that looks interesting but Postgresql-only (didn't try it).

Hoardable is an ActiveRecord extension for Ruby 3+, Rails 7+, and PostgreSQL that allows for versioning and soft-deletion of records through the use of uni-temporal inherited tables.

It supports Action Text out of the box.

It also explains how it compares with other gems.

sedubois avatar Jan 10 '24 13:01 sedubois

The way this feature is evolving (still experimental) is to adapt to the gem (audited or paper_trail and maybe others on the future) that parent app already uses or wants to use. We'll consider your research and feedback! Thanks for sharing it!

We're also exploring the possibility to have a custom table where we store Avo related audits like actions (who run it, on what records, params, etc...) .

Paul-Bob avatar Jan 10 '24 15:01 Paul-Bob

Paper Trail seems to be the most popular so it makes sense for Avo to support it. At the same time, it would be great for Avo to support other more recent/modern solutions as they emerge. After some playing around, Hoardable and Active Snapshot look promising. Good luck!

sedubois avatar Jan 10 '24 16:01 sedubois

https://blog.bemi.io/audit-trail-in-ruby/

rafafloresta avatar May 04 '24 03:05 rafafloresta

What a great article @rafafloresta! Thank you for that!

We will use a combination of those. We add audited or papertrail to keep track of record changes and we add our own layer to keep track of changes and activity throughout Avo like who viewed records, ran actions, and more. A full tutorial is incoming when we launch the feature.

adrianthedev avatar May 04 '24 18:05 adrianthedev