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.
Note
For working samples of custom log providers, see HtmlLogProvider Sample and EmailLogProvider Sample.
Configuring the Log Provider
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;
}
else
{
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;
}
Public Overrides Function Validate(ByVal infoEvents As IDTSInfoEvents) As DTSExecResult
If Me.ConfigString.Length = 0 Or connections.Contains(ConfigString) = False Then
infoEvents.FireError(0, "MyTextLogProvider", "The ConnectionManager " + ConfigString + " specified in the ConfigString property cannot be found in the collection.", "", 0)
Return DTSExecResult.Failure
Else
Dim fileName As String = connections(ConfigString).AcquireConnectionCType(as string, Nothing)
If fileName = Nothing Or fileName.Length = 0 Then
infoEvents.FireError(0, "MyTextLogProvider", "The ConnectionManager " + ConfigString + " specified in the ConfigString property cannot be found in the collection.", "", 0)
Return DTSExecResult.Failure
End If
End If
Return DTSExecResult.Success
End Function
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.
Logging with the Log Provider
There are three run-time methods that must be overridden by all log providers: OpenLog, Log, and CloseLog.
Important
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()
{
if(!this.connections.Contains(this.ConfigString))
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());
}
Public Overrides Sub OpenLog()
If Not Me.connections.Contains(Me.ConfigString) Then
Throw New Exception("The ConnectionManager " + Me.ConfigString + " does not exist in the Connections collection.")
End If
Me.connectionManager = connections(ConfigString)
Dim filePath As String = Me.connectionManager.AcquireConnectionCType(as string, Nothing)
If filePath = Nothing Or filePath.Length = 0 Then
Throw New Exception("The ConnectionManager " + Me.ConfigString + " is not a valid FILE ConnectionManager")
End If
' Create a StreamWriter to append to.
sw = New StreamWriter(filePath,True)
sw.WriteLine("Open log" + System.DateTime.Now.ToShortTimeString())
End Sub
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 + ",");
sw.WriteLine("");
}
Public Overrides Sub Log(ByVal logEnTryName As String, ByVal computerName As String, ByVal operatorName As String, ByVal sourceName As String, ByVal sourceID As String, ByVal executionID As String, ByVal messageText As String, ByVal startTime As DateTime, ByVal endTime As DateTime, ByVal dataCode As Integer, ByVal dataBytes() As Byte)
sw.Write(logEnTryName + ",")
sw.Write(computerName + ",")
sw.Write(operatorName + ",")
sw.Write(sourceName + ",")
sw.Write(sourceID + ",")
sw.Write(messageText + ",")
sw.Write(dataBytes + ",")
sw.WriteLine("")
End Sub
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());
sw.Close();
}
}
Public Overrides Sub CloseLog()
If Not sw Is Nothing Then
sw.WriteLine("Close log" + System.DateTime.Now.ToShortTimeString())
sw.Close()
End If
End Sub
See Also
Tasks
Creating a Custom Log Provider
Concepts
Developing a User Interface for a Custom Log Provider