Customizing event logging

You can customize event logging by:

  • Handling system events – customize event information, limit which types of events the system logs, or execute any custom logic when an event gets logged.
  • Implementing classes of the IEventLogWriter type – specify additional logging destinations for events (e.g., another database, dedicated file, external system, etc.).

Handling event log events

By handling events, you can customize how the system logs records into its Event log.

The system raises the following types of logging events:

  • EventLogEvents.LogEvent.Before – allows you to customize the data logged for events or cancel logging for certain types of events.
  • EventLogEvents.LogEvent.After – allows you to perform custom actions after events are successfully logged.

Note: Performing demanding operations during event logging can negatively impact the performance of the website (particularly on sites under heavy load where a large number of events is logged).

Example

The following example demonstrates how to disable logging for events of a specific type and modify the Description text for certain events.

Note: Custom event handlers of EventLogEvents.LogEvent only affect events logged into the project’s main database (specified in the CMSConnectionString connection string). Events written using custom event log writers are not affected.

  1. Open your solution in Visual Studio.
  2. Create a custom module class.
  3. Override the module’s OnInit method and assign a handler method to the EventLogEvents.LogEvent.Before event.
  4. Perform the required actions within the handler method.
    • Access the data of the logged event through the Event property of the handler’s LogEventArgs parameter.
    • To cancel the logging of an event, call the Cancel method of the handler’s LogEventArgs parameter.



using CMS;

using CMS.DataEngine;
using CMS.EventLog;
using CMS.Base;

// Registers the custom module into the system
[assembly: RegisterModule(typeof(EventLogCustomization ))]

public class EventLogCustomization : Module
{
    // Module class constructor, the system registers the module under the name "EventLogCustomization"
    public EventLogCustomization()
        : base("EventLogCustomization")
    {
    }

    // Contains initialization code that is executed when the application starts
    protected override void OnInit()
    {
        base.OnInit();

        // Assigns a handler to the LogEvent.Before event
        EventLogEvents.LogEvent.Before += LogEvent_Before;
    }

    private void LogEvent_Before(object sender, LogEventArgs e)
    {
        // Gets an object representing the event that is being logged
        EventLogInfo eventLogRecord = e.Event;

        // Cancels logging for events with the "CREATEOBJ" or "UPDATEOBJ" event codes.
        // Disables event log records notifying about the creation or update of objects in the system,
        // but still allows events related to object deletion.
        string eventCode = eventLogRecord.EventCode;
        if (String.Equals(eventLogRecord.EventCode, "CREATEOBJ", StringComparison.OrdinalIgnoreCase || String.Equals(eventLogData.EventCode, "UPDATEOBJ", StringComparison.OrdinalIgnoreCase)
        {
            e.Cancel();
        }

        // Adds a custom message to the Description field for events of the Information type
        if (String.Equals(eventLogRecord.EventType, EventType.INFORMATION, StringComparison.OrdinalIgnoreCase))
        {
            eventLogRecord.EventDescription += " Custom message";
        }
    }
}


Implementing event log writers

Whenever the system logs an event to the database, you may want to persist the information in additional locations (external system, static file, etc.). For this purpose, the system allows you to specify additional logging destinations via event log writers.

An event log writer is a class that implements the IEventLogWriter interface. When the system logs an event, it iterates over all registered event log writers and calls their WriteLog(EventLogData eventLogData) method (given by the interface). The EventLogData parameter contains all data associated with the event being logged. This information can be used to direct the logging logic, for example, based on event severity.

The following example shows the implementation of an event log writer that writes all events of the ERROR type to a static file located in the application’s root directory.

  1. Create a new CsvErrorEventWriter class in an assembly shared by both the MVC and Xperience administration projects. See Applying customizations in the Xperience environment for more information.
  2. Implement the IEventLogWriter interface.
  3. Register the implementation using the RegisterImplementation assembly attribute.



using CMS;
using CMS.Base;
using CMS.Core;

using System;
using System.IO;

using EventLogCustomizations;

[assembly: RegisterImplementation(typeof(IEventLogWriter), typeof(CsvErrorEventWriter))]
namespace EventLogCustomizations
{   
    public class CsvErrorEventWriter : IEventLogWriter
    {
        public void WriteLog(EventLogData eventLogData)
        {
            if (eventLogData.EventType == EventTypeEnum.Error)
            {
                // Checks if the error event contains an exception
                string exception = eventLogData.Exception != null ? eventLogData.Exception.ToString() : "No exception logged.";

                string eventData = $"Error, {eventLogData.EventCode}, {DateTime.Now}, {eventLogData.EventDescription}, {exception}{Environment.NewLine}";

                // Writes logged error events into a 'errors.csv' file in the application's root directory
                File.AppendAllText(SystemContext.WebApplicationPhysicalPath + "\\errors.csv", eventData);
            }
        }
    }
}


The CsvErrorEventWriter event log writer is now registered in the system. When logging an event, the system calls the writer’s WriteLog method, executing the code within.