This project is read-only.

how do you implement Auditing in custom module

Dec 7, 2011 at 4:21 PM

Hi,

Sorry I'm new to Orchard and am trying to build some auditing into my application, i have generated my own module which contains my own views and controllers (similar to Hello World module), so i am only using orchard as a landing cms to deal with the adminstration of the site, so sorry for not knowing it inside out currently.

My question is :- Is it possible to give me an example of how this product is implemented into a module i am building, i want to keep the auditing generic for the site but save my model per view into your data field (i was thinking of serializing it) so my auditing page could display whatever i wanted to specific to my model, is this something you have done, if so any advice would be great

Thanks

Coordinator
Dec 7, 2011 at 4:39 PM

Hi, yes the auditing module is set up to be completely generic, you can audit any type of events you like.

There are two ways to do it: You can either make a direct call to IAuditService, and add an audit by hand.

Or, you can hook into Orchard's Rules framework (in 1.3+) to have increased flexibility in what events you audit (and that means you can assign additional actions to perform on those events, and it lets you use the tokens system to record extra audit data).

By default, you can have events trigger for content events like view, edit, delete, etc. But if you're using MVC views, rather than Orchard's Content Management pipeline, then you'd need to fire your own events, but you can do so from anywhere.

To see how Audit hooks into Rules, first look at: Downplay.Audit\Rules\ContentEvents.cs

That's where the "View" event is defined (the publish/edit/delete events are already built into Orchard.Core.Content.Rules)

Now if you look at Downplay.Audit\Handlers\AuditHandler.cs, you can see where I raise that event. I call IRulesManager to trigger the event, and pass in a dictionary with the content and display type, so you can choose which DisplayTypes trigger the audit or any other action. I've done this because I use a lot of custom DisplayTypes in some other modules, and Detail isn't the only one I wanted (although normally that's the main one for viewing an item rather than just seeing a Summary etc.)

What you'll notice in the above code is there's a funny thing going on with the Orchard Event Bus. It's actually a form of "duck typing" if you've heard of that. An interface is defined locally to your module, and because it directly matches an interface in another module, they all get automagically wired to the same handlers. This avoids the need for a project dependency on the other module.

Dec 8, 2011 at 9:36 AM

Is it possible for you to give me an example of how you do it by hand within my module?

Do I specify it as an attribute on a view or do I need to initialize it in my controller before calling? Do I do it per view, and I don't think my module has a content item do you know how I can add it as a content item ?

Thanks for your help.

Coordinator
Dec 8, 2011 at 2:55 PM

Well I don't know what your module is so it's hard to give a specific example ;)

First you need to understand Orchard's dependency injection. This means that in the constructor of anything you implement, you can actually grab hold of anything you need, and Autofac will automatically pass you the right instance. More information here: http://docs.orchardproject.net/Documentation/How-Orchard-works

So your controller should look like this:

public class MyController: Controller {

  private readonly IAuditService _auditService;

  public MyController(IAuditService auditService) {
    _auditService = auditService;
  }

  public ActionResult DoSomeWork() {
    _auditService.CreateAudit("SomeWorkDone");
  }

}

There are other options on the audit service but this will create a simple task log.

"I don't think my module has a content item do you know how I can add it as a content item ?"

A content item is a set of data composed of many parts. It allows you to plug behaviour together from many components. It's up to you whether you use the system but it's very powerful. I refer you towards: http://docs.orchardproject.net/ (see all the topics under "Extending Orchard")

Dec 12, 2011 at 9:32 AM

thats great thanks Pete, I didn't realise how easy it was to tap into any service by referencing it in the initialization of the controller, so that was pretty straight forward, i've also extended your audit code to give me the ability to store serialized xml of the model and messages etc, so if your interested i can send it to you? Also did you ever create anything to display the auditing to the user?

thanks again for your help.

Coordinator
Dec 12, 2011 at 5:41 PM

Cool, sounds interesting - do you mean the serialized content item? The only thing there is that Orchard already has a versioning system for content items - although it could be really useful for auditing non-content events (which is also possible). Also, I'd want to avoid serializing anything for the "View" audit event; not really needed there, and it can run multiple times on page render. But yeah I'd like to have a look at the code.

Regarding reporting: When I made this module public, it was after a discussion on the Orchard forums with someone who was about to write something like this, but since I'd already done most of the work I said I'd release my code, and he said he'd do the admin interface for viewing the data. I haven't heard anything else about that, not even any feedback, so I don't know what's happening. It's something I might get around to eventually, but of course if anyone wanted to have a go at building something in the meantime that would be welcome :)  The other idea I had was aggregating the View events and creating a View Counter for content items off of this. But for now I'm fine pulling reports out of SQL server, and I have too many priorities to do anything in detail. But it wouldn't be too hard at least to get a link from content items to a page showing their audit history.