Customize 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 certain 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 are 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 for EventLogEvents.LogEvent
only affect events logged into the project’s main database (specified in the CMSConnectionString
connection string in appsettings.json
). Events logged using custom event log writers are not affected.
- Open your solution in Visual Studio.
- Create a custom module class.
- Override the module’s
OnInit
method and assign a handler method toEventLogEvents.LogEvent.Before
. - Perform the required actions within the handler method.
- Access the data of the logged event through the
Event
property of the handler’sLogEventArgs
parameter. - To cancel the logging of an event, call the
Cancel
method of the handler’sLogEventArgs
parameter.
- Access the data of the logged event through the
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";
}
}
}
Implement 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 file located in the application’s root directory. It also sends an email to the address specified in NOTIFICATION_RECIPIENT
.
- Create a new
CsvErrorEventWriter
class.- See Integrate custom code for best practices about adding custom code to your project.
- Implement the
IEventLogWriter
interface. - Register the implementation using the
RegisterImplementation
assembly attribute.
using CMS;
using CMS.Base;
using CMS.Core;
using CMS.EmailEngine;
using System;
using System.IO;
using EventLogCustomizations;
[assembly: RegisterImplementation(typeof(IEventLogWriter), typeof(CsvErrorEventWriter))]
public class CsvErrorEventWriter : IEventLogWriter
{
private readonly IEmailService emailService;
private const string NOTIFICATION_RECIPIENT = "administrators@localhost.local";
private const string NOTIFICATION_SENDER = "automation@localhost.local";
public CsvErrorEventWriter(IEmailService emailService)
{
this.emailService = emailService;
}
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);
// Sends an email notifying about the error event
emailService.SendEmail(GetEmailMessage(eventLogData, eventData));
}
}
private EmailMessage GetEmailMessage(EventLogData data, string eventData)
{
return new EmailMessage()
{
From = NOTIFICATION_SENDER,
Recipients = NOTIFICATION_RECIPIENT,
Subject = $"Error {data.EventCode}",
Body = $"The following error occurred:{Environment.NewLine}{Environment.NewLine}{eventData}"
};
}
}
CsvErrorEventWriter
is now registered in the system. When logging an event, the system calls the writer’s WriteLog method, executing the code within.