Sharepoint (WSS/MOSS) Auditing VIEW On List Items

Recently I had a request from a client to log/audit when a user clicks on anything on a Sharepoint site. At first I thought, this will be easy, I will just turn on Auditing and select to log all VIEWs on all Items and then produce a report based on the Audit log. Well, things were not that simple.

It appears that Sharepoint logs VIEWs for Document Libraries very well, but fails miserably for logging VIEWs on every other type of Item, including Picture Libraries (this is true for WSS and MOSS). Basically, Sharepoint logs the List that the Item is contained in, but there is no logging as to the actual Item that was clicked on. So after Googling around bit I found that there was very little information on how to get around this and wanted to post a solution that works for most Items, but still fails for certain ones, e.g. Discussion Items for one. Maybe someone else here can enhance this solution to grab the missing ones.

My solution involves a custom HttpModule (not an HttpHandler), that inspects the IIS requests and if can load the Sharepoint context, Site, List and Item, then it manually adds the Audit Entry via the Sharepoint Object Model. This approach is only needed for non Document Libraries, since the regular Sharepoint Auditing does a better job at logging these types of Items.

The code for the HttpModule is below. You will need to do a bit of research on how to deploy an HttpModule, but there is plenty of information on this on the web. Essentially, you will need to compile this, strong name it, deploy it to the GAC and add an entry to the web.config of the Sharepoint site you wish to Audit.

Enjoy!

Imports System.Web
Imports Microsoft.SharePoint

Public Class AuditViewHttpModule
    Implements IHttpModule

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

    End Sub

    Public Sub Init(ByVal context As System.Web.HttpApplication) _
    Implements System.Web.IHttpModule.Init

        AddHandler context.PreRequestHandlerExecute, _
        AddressOf Application_PreRequestHandlerExecute
    End Sub

    Private Sub Application_PreRequestHandlerExecute( _
        ByVal _source As Object, ByVal e As EventArgs)

        Dim _application As HttpApplication = Nothing
        Dim _context As HttpContext = Nothing

        Try

            _application = CType(_source, HttpApplication)
            _context = _application.Context

            Dim _site As SPSite = SPContext.Current.Site
            Dim _list As SPList = SPContext.Current.List
            Dim _item As SPListItem = SPContext.Current.ListItem

            If Not _site Is Nothing Then
                If Not _list Is Nothing Then
                    If Not _item Is Nothing Then
                        If _
                        _list.BaseTemplate <> _
                        SPListTemplateType.DocumentLibrary _
                        Then

                            _list.Audit.WriteAuditEvent( _
                            SPAuditEventType.View, "", "")
                        End If
                    End If
                End If
            End If

        Catch ex As Exception
            ' handle the error otherwise your
            ' sharepoint pages will crash!
        End Try
    End Sub

End Class


4 Comments

  1. This is exactly the same problem I have, Ive been asked to audit when a user downloads a file, and it only logs the list where this item is contained. Ive created the same handler, but the problem is that always, when i click the item (the file is downloaded) in the http handler SPContext is null, with every possible method from IHttpHanlder.

    Any ideas???

    Thanks!

  2. Samuel,

    Are you dealing with a Document Library or a custom list? If it’s a Document Library, you just need to turn on Auditing for it. It logs this information very well. In MOSS you have a UI to turn this on. For WSS you will have to write code to turn this auditing on for the library.

    If it’s a custom list, did you create an IHttpModule as I did in my example?

    1. Sorry for the long time of reply, im on Europe so the UTC problems hahaha,

      Yes im using a document library, and I have turn on Auditing,
      The problem is that (I’ll put and example),..

      I have my List “A” where I have 3 List Items “b”, “c”, “d”

      I can see these items in the allItems view, these items are .ppt/.zip/.doc/.img etc…
      on the TITLE column i enabled the hyperlink option, meaning that when the user clicks the title they begin downloading the file, at this point, an Audit Entry is made, but is on the list, not on the item:

      UserName site/subiste/A List Date

      So I did your code, but the problem is that in any of the methods of IHttpModule, at the moment of clicking the file, SPContext exists, but SPContext.Current is null.

  3. Samuel,

    On the project I worked on, I had no need to make the title hyper-linked as you described. I went with the standard functionality which gives you the dropdown box with options besides every document or, by default, if you click on the item it opens it within IE if it knows what type of document it is (typically Office docs). Also, by default if it does not know what type it is, it will start to download it. These two scenarios are logged appropriately with the standard auditing in WSS/MOSS to the Item level.

    First, can you verify this by not hyper-linking?

    If you have confirmed this, then it will be an issue I did not tackle myself. My only suggestion is to create an actual HttpHandler, since you have more granular control over the http requests, but it will also be more complex code.

    Can you get your users to comply with the standard WSS/MOSS functionality for document libraries? That would probably be the best solution.