Audit Log issues

125 views
Skip to first unread message

Randall Borck

unread,
Apr 22, 2014, 9:07:05 AM4/22/14
to rav...@googlegroups.com
I am trying to add a supplemental audit log information to my application, but I am having some difficulties. First off, all my difficulties would be solvable if I had public access to entitiesAndMetadata from the document session (even if it was a read only copy).

We use an command/event model in our application, so all changes to the database (that I care about) happen via a command. I know I can get document versioning with a bundle, but I'd like to have a separate document that keeps track of when a document is updated, what command updated it, what entities were updated by this unit of work, and the user session and person information to be able to correlate those changes if I need to at a later time. I only care about tenant document sessions, I do not have a need to record changes with the suite document session. The IDocumentStoreListener attaches to the document store and acts on all document sessions, not just the tenant sessions I'm interested in. We've wrapped up the document session and exposed a CompleteUnitOfWork that is called, which calls DocumentSession.SaveChanges(), so I have a great place to tie in the desired logging and it is simple to add my audit info if my DocumentSession.HasChanges > 0. Lastly, I'd like to have my audit info stick around, even if the entity document is deleted, which won't happen if I add this information to the metadata.

I have read through several forums and done several searches, but I still don't see a way to what I need without reflecting access to entitiesAndMetadata. Does anyone have some other recommendations for me? Is there a reason that you didn't expose InMemoryDocumentSessionOperations.entitiesAndMetadata publicly or can I do a pull request to make that happen in a future version of RavenDb?

Thanks!

Oren Eini (Ayende Rahien)

unread,
Apr 23, 2014, 2:35:32 AM4/23/14
to ravendb
entitiesAndMetadata is an implementation details.


It seems like that would be enough for what you need to do.



Oren Eini

CEO

Mobile: + 972-52-548-6969

Office:  + 972-4-674-7811

Fax:      + 972-153-4622-7811





--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Randall Borck

unread,
Apr 25, 2014, 2:11:38 PM4/25/14
to rav...@googlegroups.com
Is there a chance that in a future version of Raven you could expose a method that returns the all the changed entities? You already have HasChanges() and HasChanged(...), it is not much of a stretch return an enumeration of entities that have changed from a similarly named method, and this would solve my problem the most cleanly. If it is helpful, I could even volunteer a pull request.

Although the contextual listeners library will not work for me (because it requires a context to be supplied before I can know anything has changed), the concept it is built on can work for me, but it does seem a little messy. The issue here is that I have to modify the audit document in the BeforeStore(...) event of all the other changed entities. This means that I rely on the audit document calling the listener last (which in practice does seem to be working), and then I have to return true if the entity is my audit entity, even though the listener didn't change the audit entity in that BeforeStore(...) call.

```
Listener Pseudo Code:
public class AuditListener : IDocumentStoreListener {
  public bool BeforeStore(...) {
    if (entityInstance is Audit) return true; // <-- return true even though I didn't change Audit in this scope seems bad, it relies on an implicit order of operations that has happened in previous BeforeStore(...) calls
    if (AuditExists) UpdateAuditModifiedEntry(entityInstance); //Audit is already in the document session
    return false;
  }
  ...
}
```

Oren Eini (Ayende Rahien)

unread,
Apr 25, 2014, 9:17:47 PM4/25/14
to ravendb
It is already there in 3.0

session.Advacned.WhatChanged()

Chris Marisic

unread,
Apr 28, 2014, 9:20:07 AM4/28/14
to rav...@googlegroups.com
Can you give some example output?

Randall Borck

unread,
Apr 28, 2014, 11:39:06 AM4/28/14
to rav...@googlegroups.com

Chris Marisic

unread,
Apr 29, 2014, 3:02:43 PM4/29/14
to rav...@googlegroups.com
I see it uses

  public string FieldOldValue { get; set; }
        public string FieldNewValue { get; set; }

which makes sense

however what happens for rich object graphs? For example

Car { Renter { HomeAddress { Street, City, State } } }

What is the field for the street address changing? Car_Renter_HomeAddress_Street?

What if instead its this type?

Person { Cars[]{ Honda-Accord } }

And Honda-Accord has it's mileage updated?


Oren Eini (Ayende Rahien)

unread,
May 1, 2014, 4:07:32 AM5/1/14
to ravendb
You would get "Renter.HomeAddress.Street"

Chris Marisic

unread,
May 1, 2014, 9:35:59 AM5/1/14
to rav...@googlegroups.com
What about 2nd scenario that's an item being modified inside an array? 

Oren Eini (Ayende Rahien)

unread,
May 2, 2014, 1:34:33 AM5/2/14
to ravendb
You'll get a notice that you have a modification somewhere there, I don't think we track the actual positions there.
Reply all
Reply to author
Forward
0 new messages