Coding a Custom Log Provider

New: 14 April 2006

After you have created a class that inherits from the LogProviderBase base class, and applied the DtsLogProviderAttribute attribute to the class, you must override the implementation of the properties and methods of the base class to provide your custom functionality.

For working samples of custom log providers, see HtmlLogProvider Sample and EmailLogProvider Sample.

Initializing the Log Provider

Override the InitializeLogProvider method to cache references to the connections collection and the events interface for later use in other methods of the log provider.

Using the ConfigString Property

At design time, a log provider receives configuration information from the Configuration column, which corresponds to the ConfigString property of the log provider. By default, this column contains a text box from which you can retrieve any string information. Most of the log providers included with Integration Services use this property to store the name of the connection manager that is used by the provider to connect to an external data source. If used, this property should be validated in the Validate method to make sure that it is set correctly.

Validating the Log Provider

Override the Validate method to ensure that the provider has been correctly configured and is ready for execution. Typically, a minimum level of validation would be to ensure that the ConfigString is set correctly. Execution cannot continue until the log provider returns Success from the Validate method.

The following code example shows an implementation of Validate that ensures that the name of a connection manager name is specified, that the connection manager exists in the package, and that the connection manager returns a file name in the ConfigString property.

public override DTSExecResult Validate(IDTSInfoEvents infoEvents)
    if (this.ConfigString.Length == 0 || connections.Contains(ConfigString) == false)
        infoEvents.FireError(0, "MyTextLogProvider", "The ConnectionManager " + ConfigString + " specified in the ConfigString property cannot be found in the collection.", "", 0);
        return DTSExecResult.Failure;
        string fileName = connections[ConfigString].AcquireConnection(null) as string;

        if (fileName == null || fileName.Length == 0)
            infoEvents.FireError(0, "MyTextLogProvider", "The ConnectionManager " + ConfigString + " specified in the ConfigString property cannot be found in the collection.", "", 0);
            return DTSExecResult.Failure;
    return DTSExecResult.Success;

Persisting the Log Provider

Ordinarily you do not have to implement custom persistence for a connection manager. Custom persistence is required only when the properties of an object use complex data types. For more information, see Developing Custom Objects for Integration Services.

There are three run-time methods that must be overridden by all log providers: OpenLog, Log, and CloseLog.

During the validation and execution of a single package, the OpenLog and CloseLog methods are called more than one time. Make sure that your custom code does not cause earlier log entries to be overwritten by the next opening and closing of the log. If you have selected to log validation events in your test package, the first logged event that you should see is OnPreValidate; if instead the first logged event that you see is PackageStart, the initial validation events have been overwritten.

Opening the Log

Most log providers connect to an external data source, such as a file or database, to store the event information that is collected during package execution. As with any other object in the runtime, connecting to the external data source is typically accomplished by using connection manager objects.

The OpenLog method is called at the start of package execution.Override this method to establish a connection to the external data source.

The following sample code shows a log provider that opens a text file for writing during OpenLog. It opens the file by calling the AcquireConnection method of the connection manager that was specified in the ConfigString property.

public override void OpenLog()
        throw new Exception("The ConnectionManager " + this.ConfigString + " does not exist in the Connections collection.");

    this.connectionManager = connections[ConfigString];
    string filePath = this.connectionManager.AcquireConnection(null) as string;

    if(filePath == null || filePath.Length == 0)
        throw new Exception("The ConnectionManager " + this.ConfigString + " is not a valid FILE ConnectionManager");

    //  Create a StreamWriter to append to.
    sw = new StreamWriter(filePath,true);

    sw.WriteLine("Open log" + System.DateTime.Now.ToShortTimeString());

Writing Log Entries

The Log method is called every time that an object in the package raises an event by calling a Fire<event> method on one of the event interfaces. Each event is raised with information about its context and usually an explanatory message. However, not every call to the Log method includes information for every method parameter. For example, some standard events whose names are self-explanatory do not provide MessageText, and DataCode and DataBytes are intended for optional supplemental information.

The following code example implements the Log method, and writes the events to the stream that was opened in the previous section.

public override void Log(string logEntryName, string computerName, string operatorName, string sourceName, string sourceID, string executionID, string messageText, DateTime startTime, DateTime endTime, int dataCode, byte[] dataBytes)
    sw.Write(logEntryName + ",");
    sw.Write(computerName + ",");
    sw.Write(operatorName + ",");
    sw.Write(sourceName + ",");
    sw.Write(sourceID + ",");
    sw.Write(messageText + ",");
    sw.Write(dataBytes + ",");

Closing the Log

The CloseLog method is called at the end of package execution, after all the objects in the package have completed execution, or, when the package stops because of errors.

The following code example demonstrates an implementation of the CloseLog method that closes the file stream that was opened during the OpenLog method.

public override void CloseLog()
    if (sw != null)
        sw.WriteLine("Close log" + System.DateTime.Now.ToShortTimeString());

Community Additions