The Logging Provider in DotNetNuke provides a very configurable and extensible set of logging services. It is designed to handle a wide array of logging needs including exception logging, event auditing, and security logging. As you may have gathered from its name, the Logging Provider uses the Provider Model design pattern. This allows the default DB Logging Provider to be replaced with another logging mechanism without having to make changes to the core code. This section covers the ways you can use the Logging Provider to log events in custom modules.
Before you dive into the details of how to use the Logging Provider API, it is important to understand some concepts and terminology that will be used in this section:
Log classification: There are two different types of log classifications in the Logging Provider. The first is the event log classification. This encapsulates all log entries related to some type of event within DotNetNuke. For example, you can configure the Logging Provider to write a log entry when a login attempt fails. This would be considered an event log entry. The second log classification is the exception log classification. You can configure the Logging Provider to log exceptions and stack traces when exceptions are thrown within DotNetNuke. These two classifications are distinct only because they have different needs in terms of what type of information they log.
Log type: A log type defines the type of event that creates the log entry. For example, an event log type is LOGIN_FAILURE. The Logging Provider can react differently for each log type. You can configure the Logging Provider to enable or disable logging for each of the log types. Depending on the Logging Provider, you can configure it to log each log type to a different file or to send e-mail notifications upon creating new log entries for that log type.
Log type configuration: The Logging Provider is configured via a module that is accessible from the Log Viewer screen (the Edit Log Configuration Module Action). This enables you to configure each log type to be handled differently by the Logging Provider.
The Logging Provider functionality lives in the DotNetNuke.Services.Log.EventLog namespace. In this namespace, you will find the classes that comprise the Logging Provider API. These are described in Table 8-1.
Class | Description |
---|---|
EventLogController | Provides the methods necessary to write log entries with the event log classification. It inherits from LogController. |
ExceptionLogController | Provides the methods necessary to write log entries with the exception log classification. It inherits from LogController. |
LogController | Provides the methods that interact with the Logging Provider—the basic methods for adding, deleting, and getting log entries. |
LogDetailInfo | Holds a single key/value pair of information from a log entry. |
LoggingProvider | Provides the bridge to the implementation of the Logging Provider. |
LogInfo | Container for the information that goes into a log entry. |
LogInfoArray | Holds an array of LogInfo objects. |
LogProperties | Holds an array of LogDetailInfo objects. |
LogTypeConfigInfo | Container for the configuration data relating to how logs of a specific log type are to be handled. |
LogTypeInfo | Container for the log type information. |
PurgeLogBuffer | Scheduler task that can be executed regularly if Log Buffering is enabled. |
SendLogNotifications | Scheduler task that can be executed regularly if any log type is configured to send e-mail notifications. |
The controller classes, EventLogController and ExceptionLogController, are the two that bring the most functionality to custom modules. Many of the other classes are used in concert with the controllers.
The EventLogController provides the methods necessary to log significant system events. This class is located in the DotNetNuke.Library in the Components/Providers/Logging/EventLogging/EventLogController.vb file. The class also defines the EventLogType enumeration that lists each log type that is handled by the EventLogController. The enumerations are shown in Listing 8-1.
Listing 8-1: EventLogController.EventLogType Enumeration
Public Enum EventLogType USER_CREATED USER_DELETED LOGIN_SUPERUSER LOGIN_SUCCESS LOGIN_FAILURE CACHE_REFRESHED PASSWORD_SENT_SUCCESS PASSWORD_SENT_FAILURE LOG_NOTIFICATION_FAILURE PORTAL_CREATED PORTAL_DELETED TAB_CREATED TAB_UPDATED TAB_DELETED TAB_SENT_TO_RECYCLE_BIN TAB_RESTORED USER_ROLE_CREATED USER_ROLE_DELETED ROLE_CREATED ROLE_UPDATED ROLE_DELETED MODULE_CREATED MODULE_UPDATED MODULE_DELETED MODULE_SENT_TO_RECYCLE_BIN MODULE_RESTORED SCHEDULER_EVENT_STARTED SCHEDULER_EVENT_PROGRESSING SCHEDULER_EVENT_COMPLETED APPLICATION_START APPLICATION_END APPLICATION_SHUTTING_DOWN SCHEDULER_STARTED SCHEDULER_SHUTTING_DOWN SCHEDULER_STOPPED ADMIN_ALERT HOST_ALERT End Enum
The EventLogController.AddLog() method has several method overloads that enable a developer to log just about any values derived from an object or its properties. Following are descriptions of these overloaded methods, along with brief explanations of their parameters:
The primary AddLog method is ultimately used by all of the other AddLog overloads and accepts a single LogInfo object. This method provides easy access to the base logging method in inherited LogController class:
Public Overloads Sub AddLog(ByVal objEventLogInfo As LogInfo)
To log the property names and values of a Custom Business Object, use the following method:
Public Overloads Sub AddLog(ByVal objCBO As Object, ByVal _PortalSettings As _ PortalSettings, ByVal UserID As Integer, ByVal UserName As String, ByVal _ objLogType As Services.Log.EventLog.EventLogController.EventLogType)
Parameter | Type | Description |
---|---|---|
objCBO | Object | Custom Business Object. |
_PortalSettings | PortalSettings | Current PortalSettings object. |
UserID | Integer | UserID of the authenticated user of the request. |
UserName | String | UserName of the authenticated user of the request. |
objLogType | EventLogType | Event log type. |
To add a log entry that has no custom properties, use the following method:
Public Overloads Sub AddLog(ByVal _PortalSettings As PortalSettings, ByVal UserID _ As Integer, ByVal objLogType As _ Services.Log.EventLog.EventLogController.EventLogType)
This is useful if you simply need to log that an event has occurred, but you have no requirement to log any further details about the event.
Parameter | Type | Description |
---|---|---|
_PortalSettings | PortalSettings | Current PortalSettings object. |
UserID | Integer | UserID of the authenticated user of the request. |
objLogType | EventLogType | Event log type. |
To add a log entry that has a single property name and value, use the following method:
Public Overloads Sub AddLog(ByVal PropertyName As String, ByVal PropertyValue As _ String, ByVal _PortalSettings As PortalSettings, ByVal UserID As Integer, ByVal _ objLogType As Services.Log.EventLog.EventLogController.EventLogType)
Parameter | Type | Description |
---|---|---|
PropertyName | String | Name of the property to log. |
PropertyValue | String | Value of the property to log. |
_PortalSettings | PortalSettings | Current PortalSettings object. |
UserID | Integer | UserID of the authenticated user of the request. |
objLogType | EventLogType | Event log type. |
To add a log entry that has a single property name and value and the LogType is not defined in a core enumeration, use the following method:
Public Overloads Sub AddLog(ByVal PropertyName As String, ByVal PropertyValue As _ String, ByVal _PortalSettings As PortalSettings, ByVal UserID As Integer, ByVal _ LogType As String)
This is useful for custom modules that define their own log types.
Parameter | Type | Description |
---|---|---|
PropertyName | String | Name of the property to log. |
PropertyValue | String | Value of the property to log. |
_PortalSettings | PortalSettings | Current PortalSettings object. |
UserID | Integer | UserID of the authenticated user of the request. |
LogType | String | Event log type string. |
To add a log entry that has multiple property names and values, use the following method. To use this method, you must send into it a LogProperties object that is comprised of a collection of LogDetailInfo objects:
Public Overloads Sub AddLog(ByVal objProperties As LogProperties, ByVal _ _PortalSettings As PortalSettings, ByVal UserID As Integer, ByVal LogTypeKey As _ String, ByVal BypassBuffering As Boolean)
Parameter | Type | Description |
---|---|---|
objProperties | LogProperties | A collection of LogDetailInfo objects. |
_PortalSettings | PortalSettings | Current PortalSettings object. |
UserID | Integer | UserID of the authenticated user of the request. |
LogTypeKey | String | Event log type. |
BypassBuffering | Boolean | Specifies whether to write directly to the log (true) or to use log buffering (false) if log buffering is enabled. |
Listings 8-2 through 8-6 show how to use the two most common overloaded methods for EventLogController.AddLog(). To exemplify the flexibility of this method, Listing 8-2 illustrates how you can send in a Custom Business Object and automatically log its property values.
Listing 8-2: EventLogController.AddLog Example
Private Sub TestUserInfoLog() Dim objUserInfo As New UserInfo objUserInfo.FirstName = "John" objUserInfo.LastName = "Doe" objUserInfo.UserID = 6 objUserInfo.Username = "jdoe" Dim objEventLog As New Services.Log.EventLog.EventLogController objEventLog.AddLog(objUserInfo, PortalSettings, UserID, UserInfo.Username, _ Services.Log.EventLog.EventLogController.EventLogType.USER_CREATED) End Sub
The resulting log entry written by the XML Logging Provider for this example includes each property name and value in the objUserInfo object as shown in the <properties/> XML element in Listing 8-3.
Listing 8-3: EventLogController.AddLog Log Entry for the XML Logging Provider
<logs> <log LogGUID="" LogFilebackground-color:d9d9d9">e984-4483-891b-26a2b95bf9bd" LogTypeKey="USER_CREATED" LogUser LogUserName="" LogPortal LogPortalName="DotNetNuke" LogCreateDate="2005-02-04T14:33:46.9318672-05:00" LogCreateDateNum="20050204143346931" LogServerName="DNNTEST"> <properties> <property> <name>UserID</name> <value>6</value> </property> <property> <name>FirstName</name> <value>John</value> </property> <property> <name>LastName</name> <value>Doe</value> </property> <property> <name>UserName</name> <value>jdoe</value> </property> </properties> </log> </logs>
If you are using the default DB LoggingProvider, this same information is stored in the EventLog table. The properties element is saved in the LogProperties column as an XML fragment as shown in Listing 8-4. This format is similar to the properties node for the corresponding XML log version.
Listing 8-4: EventLogController.AddLog LogProperties for the DB Logging Provider
<ArrayOfAnyType xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <anyType xsi:type="LogDetailInfo"> <name>UserID</name> <value>4</value> </anyType> <anyType xsi:type="LogDetailInfo"> <name>FirstName</name> <value>Joe</value> </anyType> <anyType xsi:type="LogDetailInfo"> <name>LastName</name> <value>Brinkman</value> </anyType> <anyType xsi:type="LogDetailInfo"> <name>UserName</name> <value>tuser2</value> </anyType> <anyType xsi:type="LogDetailInfo"> <name>Email</name> <value>joe.brinkman@tag-software.net</value> </anyType> </ArrayOfAnyType>
Important | Because the XML log format is a little easier to read, the XML Logging Provider is used for all additional examples in this chapter and will note any substantial differences with the DB Logging Provider. |
This example logs each of the properties of a Custom Business Object. There are other overloaded EventLogController.AddLog() methods available if you need to log less information or information that isn't stored in a Custom Business Object. The example in Listing 8-5 shows how you can use EventLogController.AddLog()to add a single key/value pair to the log.
Listing 8-5: EventLogController.AddLog Example
Private Sub TestCreateRole() Dim objRoleController As New RoleController Dim objRoleInfo As New RoleInfo 'create and add the new role objRoleInfo.RoleName = "Newsletter Subscribers" objRoleInfo.PortalID = 5 objRoleController.AddRole(objRoleInfo) 'log the event Dim objEventLog As New Services.Log.EventLog.EventLogController objEventLog.AddLog("Role", objRoleInfo.RoleName, PortalSettings, _ UserId, objEventLog.EventLogType.USER_ROLE_CREATED) End Sub
In this case, the key Role and the value Newsletter Subscribers will be logged. The resulting log entry written by the default XML Logging Provider for this example is shown in the <properties/> XML element in Listing 8-6.
Listing 8-6: EventLogController.AddLog Log Entry
<logs> <log LogGUID="" LogFilebackground-color:d9d9d9">e984-4483-891b-26a2b95bf9bd" LogTypeKey="ROLE_CREATED" LogUser LogUserName="host" LogPortal LogPortalName="DotNetNuke" LogCreateDate="2005-02-04T22:00:22.0413424-05:00" LogCreateDateNum="20050204220022041" LogServerName="DNNTEST"> <properties> <property> <name>RoleName</name> <value>Newsletter Subscribers</value> </property> </properties> </log> </logs>
The ExceptionLogController exposes the methods necessary for adding information about exceptions to the log. This controller class also defines four exception types in the ExceptionLogType enumeration: GENERAL_EXCEPTION, MODULE_LOAD_EXCEPTION, PAGE_LOAD_EXCEPTION, and SCHEDULER_EXCEPTION. By defining different log types for exceptions, the configuration of the Logging Provider can treat each exception log type differently regarding how and if the exceptions get logged.
The next section covers exceptions in more detail. For now, the focus is on how to log the exceptions. The ExceptionLogController.AddLog() method has three overloaded methods that enable you to pass in various types of exceptions. The first method enables you to send in a System.Exception or any exception that inherits System.Exception, as shown in Listing 8-7.
Listing 8-7: ExceptionLogController.AddLog Example
Public Sub test() Try If 1 = 1 Then Throw New Exception("Oh no, an exception!") End If Catch exc As Exception Dim objExceptionLog As New Services.Log.EventLog.ExceptionLogController objExceptionLog.AddLog(exc) 'a shortcut to this is simply "LogException(exc)" End Try End Sub
In this case, the properties of the System.Exception will be logged along with a collection of properties that are specific to the request. For instance, it will log the filename, line, and column number the exception occurred in if it is available. The resulting log entry written by the default XML Logging Provider for this example is shown in Listing 8-8.
Listing 8-8: ExceptionLogController.AddLog Log Entry
<logs> <log LogGUID="" LogFilebackground-color:d9d9d9">cf46-4588-8a76-75ae9c577277" LogTypeKey="GENERAL_EXCEPTION" LogUser LogUserName="" LogPortal LogPortalName="" LogCreateDate="2005-02-04T23:25:44.6873456-05:00" LogCreateDateNum="20050204232544687" LogServerName="DNNTEST"> <properties> <property> <name>AssemblyVersion</name> <value>03.00.10</value> </property> <property> <name>Method</name> <value>DotNetNuke.Framework.CDefault.test</value> </property> <property> <name>FileName</name> <value>c:\public\dotnetnuke\Default.aspx.vb</value> </property> <property> <name>FileLineNumber</name> <value>481</value> </property> <property> <name>FileColumnNumber</name> <value>21</value> </property> <property> <name>PortalID</name> <value>0</value> </property> <property> <name>PortalName</name> <value>DotNetNuke</value> </property> <property> <name>UserID</name> <value>-1</value> </property> <property> <name>UserName</name> <value /> </property> <property> <name>ActiveTabID</name> <value>36</value> </property> <property> <name>ActiveTabName</name> <value>Home</value> </property> <property> <name>AbsoluteURL</name> <value>/DotNetNuke/Default.aspx</value> </property> <property> <name>AbsoluteURLReferrer</name> <value /> </property> <property> <name>ExceptionGUID</name> <value></value> </property> <property> <name>DefaultDataProvider</name> <value>DotNetNuke.Data.SqlDataProvider, DotNetNuke.SqlDataProvider</value> </property> <property> <name>InnerException</name> <value>Oh no, an exception!</value> </property> <property> <name>Message</name> <value>Oh no, an exception!</value> </property> <property> <name>StackTrace</name> <value> at DotNetNuke.Framework.CDefault.test() in c:\public\dotnetnuke\Default.aspx.vb:line 481</value> </property> <property> <name>Source</name> <value>DotNetNuke</value> </property> </properties> </log> </logs>
Notice that Listing 8-8 does not tell you the portal module that the exception was thrown from. This is because a general exception was thrown (System.Exception). If a ModuleLoadException is thrown, more details about the portal module that throws the exception will be logged.