Поделиться через


Создание кода пользовательского регистратора

После создания класса, наследующего базовый класс LogProviderBase, и применения к нему атрибута DtsLogProviderAttribute необходимо переопределить реализацию свойств и методов базового класса, чтобы обеспечить пользовательские функциональные возможности.

Рабочие образцы пользовательских регистраторов см. в образцах служб Integration Services в разделе Codeplex.

Настройка регистратора

Инициализация регистратора

Необходимо переопределить метод InitializeLogProvider для кэширования ссылок на коллекцию соединений и интерфейс событий. В дальнейшем можно использовать эти кэшированные ссылки в других методах регистратора.

Использование свойства ConfigString

Во время разработки регистратор получает данные конфигурации из столбца Конфигурация. Эти данные конфигурации соответствуют свойству ConfigString регистратора. По умолчанию этот столбец содержит текстовое поле, из которого можно получить любые строковые данные. Большинство регистраторов, включенных в службы Integration Services, используют это свойство для хранения имени диспетчера соединений, которое регистратор применяет для соединения с внешним источником данных. Если выбранный регистратор использует свойство ConfigString, используйте метод Validate, чтобы проверить это свойство и убедиться, что оно имеет правильное значение.

Проверка регистратора

Необходимо переопределить метод Validate, чтобы убедиться в правильности настройки регистратора и его готовности к выполнению. Обычно, чтобы убедиться в правильности настройки ConfigString, требуется минимальный уровень проверки. Выполнение не может продолжиться, пока регистратор не возвратит значение Success из метода Validate.

В следующем примере кода демонстрируется реализация метода Validate, которая проверяет, что имя диспетчера соединений указано, что диспетчер соединений существует в пакете и что диспетчер соединений возвращает имя файла в свойстве ConfigString.

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

Сохраняемость регистратора

Как правило, нет необходимости реализовывать пользовательский механизм сохраняемости для диспетчера соединений. Нестандартный механизм сохраняемости необходим только в случае, когда свойства объекта используют сложные типы данных. Дополнительные сведения см. в разделе Разработка пользовательских объектов для служб Integration Services.

Ведение журнала с помощью регистратора

Существуют три метода времени выполнения, которые должны быть переопределены всеми регистраторами: OpenLog, Log и CloseLog.

Важное примечаниеВажно!

Во время проверки и выполнения одного пакета методы OpenLog и CloseLog вызываются более одного раза. Убедитесь, что пользовательский код не приведет к перезаписи более ранних записей журнала при следующем открытии и закрытии журнала. Если была выбрана регистрация событий проверки в тестовом пакете, первым зарегистрированным событием должно быть событие OnPreValidate. Если вместо него первым событием в журнале отображается PackageStart, начальные события проверки были перезаписаны.

Открытие журнала

Большинство регистраторов соединяются с внешним источником данных, например с файлом или базой данных, чтобы сохранять данные событий, которые собираются в ходе выполнения пакета. Как и в случае с любым другим объектом в среде выполнения, соединение с внешним источником данных обычно устанавливается с помощью объектов диспетчера соединений.

Метод OpenLog вызывается в начале выполнения пакета. Переопределите этот метод, чтобы установить соединение с внешним источником данных.

В следующем образце кода демонстрируется регистратор, который открывает текстовый файл для записи во время выполнения метода OpenLog. Файл открывается путем вызова метода AcquireConnection диспетчера соединений, который был указан в свойстве ConfigString.

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

Создание записей журнала

Метод Log вызывается каждый раз, когда объект в пакете инициирует событие путем вызова метода Fire<событие> для одного из интерфейсов события. Каждое событие инициируется со сведениями о его контексте и обычно дополняется поясняющим сообщением. Однако не каждый вызов метода Log включает сведения о каждом параметре метода. Например, некоторые стандартные события, имена которых очевидны без пояснений, не предоставляют параметров MessageText, а параметры DataCode и DataBytes предназначены для необязательных вспомогательных сведений.

В следующем примере кода реализуется метод Log и события записываются в поток, открытый в предыдущем разделе.

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

Закрытие журнала

Метод CloseLog вызывается в конце выполнения пакета, после того как все объекты в пакете завершили выполнение (либо если выполнение пакета остановлено в связи с ошибками).

В следующем примере кода демонстрируется реализация метода CloseLog, которая закрывает файловый поток, открытый при выполнении метода OpenLog.

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
Значок служб Integration Services (маленький) Будьте в курсе новых возможностей служб Integration Services

Чтобы загружать новейшую документацию, статьи, образцы и видеоматериалы от корпорации Майкрософт, а также лучшие решения от участников сообщества, посетите страницу служб Integration Services на сайтах MSDN или TechNet:

Чтобы получать автоматические уведомления об этих обновлениях, подпишитесь на RSS-каналы, предлагаемые на этой странице.