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

Проблемы, связанные с изменениями в системе, с изменением данных и с ошибками, приобретают особую остроту при выполнении операций по извлечению, преобразованию и загрузке данных (extraction, transformation and loading — ETL). Код ETL должен наводить мосты между двумя или большим числом систем. С течением времени эти системы меняются. Даже при отсутствии новых модификаций, обновлений и исправлений изменения могут приводить к проблемам. Кроме того, сообщество пользователей постоянно вносит в исходные системы новые данные.

Существует два закона разработки ETL, и они столь же незыблемы, как законы термодинамики. Вот они.

  • Исходные системы подвержены постоянным изменениям. Никто из причастных к этому никогда не сообщит разработчикам ETL о том, что предстоит некоторое изменение; до тех пор, пока оно не будет реализовано и операции по извлечению не закончатся сбоем. При этом сотрудник, в название должности которого входит слово «директор», например директор по информационным технологиям, как правило, теряет хорошее расположение духа в связи с тем, что в его компьютере нет нужной информации и различные дополнения подверглись бессистемному усечению.
  • Пользователи постоянно ошибаются в процессе ввода данных. Причем всякий раз они делают это по-новому, и в их действиях нет абсолютно никакой логики. Вам придется решать подобные проблемы под грозный рев начальника, которому нужны отчеты. Вы будете заниматься этой неблагодарной работой до тех пор, пока кто-нибудь не сжалится над вами и не отправит на пенсию.

Поэтому нам нужно проектировать системы, способные к восстановлению после таких ошибок. Кроме того, они должны предоставлять соответствующим сотрудникам сведения, достаточные для того, чтобы те могли устранять возникающие проблемы в рабочем порядке. В этой связи возникает вопрос о том, что именно необходимо регистрировать, а иногда — где размещать зарегистрированные данные. В целом регистрации подлежат события, относящиеся к трем категориям:

  • события ночные, странные и непонятные;
  • явления типа WTF (что означает «Where's this from?» — «Откуда это взялось?»);
  • регистрация на основе событий, или журналы аудита.

Рассмотрим все три категории более подробно.

События ночные, странные и непонятные

Странные и непонятные события могут происходить в любое время суток, но, как правило, задачи ETL выполняются поздно вечером или в утренние часы. Именно в это время данные извлекаются из транзакционной системы и загружаются в киоск данных либо в хранилище данных для анализа; в это же время осуществляется синхронизация различных систем в период обслуживания. Я имею в виду в первую очередь неустранимые ошибки. Раз уж мы толковые разработчики, то должны предоставлять сотрудникам достаточную информацию, чтобы они могли выявить и устранить проблему. Однако нам нужно представлять эти данные таким образом, чтобы рано утром или по выходным нас не вызывали на работу для починки вышедшей из строя системы.

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

Когда случаются такого рода события, оповещение об ошибке должно отображаться таким образом, чтобы его могли увидеть сотрудники, которые смогут приступить к решению проблемы. Поэтому прежде всего необходимо выбрать такой интерфейс для оповещения сотрудников, который даст им возможность получать представление о статусе каждого задания во время выполнения последнего. Позвольте мне написать следующее предложение прописными буквами, чтобы мысль моя была предельно ясной: НИКОГДА НЕ СООБЩАЙТЕ ОБ ОШИБКАХ ПО КАНАЛАМ ЭЛЕКТРОННОЙ ПОЧТЫ!

Почему? Во‑первых, потому что в списки сообщений электронной почты для целей оповещения редко включаются только что поступившие сообщения (если такие сообщения вообще включаются в них). Во‑вторых, все специалисты включают в свои учетные записи правила, в соответствии с которыми такие почтовые сообщения перенаправляются в ту или иную папку. И как бы ни называлась эта папка, ее имя на самом деле читается так: «Не заглядывать, пока не позвонит начальство». В результате ошибка игнорируется до тех пор, пока не начнут поступать жалобы от пользователей. Наконец, плохие новости поступают не по одной. Если первое плохое известие состоит в том, что приложение вышло из строя, то второе — в том, что человека, которому было направлено сообщение о сбое, нет на месте (он болен, в отпуске или уехал из зоны действия сотового оператора). Ну а третье плохое известие поступит к вам в два часа ночи в виде вызова на работу для устранения проблемы.

Кроме того, нередко такие почтовые сообщения направляются группам сотрудников. Между тем железный закон корпоративного поведения гласит: если ответственность возлагается на всех, спроса нет ни с кого. Поэтому до тех пор, пока сотрудника, в название должности которого входит слово «директор», не спросят по телефону: «А где же данные?», ничего происходить не будет. Наверняка желания попасть в такой переплет у вас нет.

Идеальным решением на случай возникновения подобных ошибок будет простой для понимания интерфейс «красный свет — зеленый свет». Это приложение приведет сотрудников к детальным сообщениям, которые помогут им разобраться с проблемой. К сожалению, обычно мы получаем от своих приложений весьма невразумительные сообщения об ошибках. Часто мы сталкиваемся с неполадками на этапе разработки или передачи изделия использующим его сотрудникам. Нам следует взять за правило расшифровку этих сообщений для ответственных лиц.

Поясню эту мысль на примере. Недавно я завершил работу над проектом, в котором источником информации для киоска данных является веб-служба. На заключительных этапах разработки мой код часто выдавал следующее: «Возникла неизвестная ошибка. Для получения более подробной информации свяжитесь с администратором приложения». Такое известие трудно назвать самым полезным сообщением об ошибке за всю историю программирования. Но мы заметили, что эта ошибка неизменно возникала после выхода из строя сервера веб-служб. Мне показалось, что простая вежливость, не говоря уже обо всем прочем, обязывает программиста поделиться этими знаниями с тем беднягой, которого вызовут на работу в два часа ночи — в то время, когда по плану должна осуществляться загрузка этих данных. С помощью простого кода дополнительные детали были вписаны в текстовый файл, а путь к этому текстовому файлу был указан в сообщении, зарегистрированном в журналах Windows Event, как показано в листинге 1.

Следует также отметить, что в данном приложении сообщения о внутреннем исключении содержат немало информации, которая могла бы помочь в решении проблемы. Это простой вызов метода, который можно абстрагировать в файл класса и вызывать тем способом, которым вы обычно вызываете какой-либо метод. В нашем случае, к примеру, мы просто вызвали этот метод из раздела catch блока try/catch сценария VB Script. Можно также включить этот метод в хранимую процедуру CLR и выполнить его из блока try/catch в инструкции SQL, а можно вызвать из обработчика ошибок.

А где же регистрировать подобные ошибки? Ответ на этот вопрос зависит от того, где именно выполняющая мониторинг система ищет информацию о состоянии приложения. Мне еще не попадалось инструментальное средство, которое не выполняло бы поиск ошибок в журнале событий Windows, поэтому для начала неплохо бы организовать регистрацию ошибок в журнале событий. Опять-таки код для выполнения этой задачи весьма прост: нужно использовать класс EventLog, как показано в листинге 2.

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

  • Обычным сотрудникам нужен простой пользовательский интер­фейс для отслеживания статуса ETL (ЭЛЕКТРОННУЮ ПОЧТУ НЕ ИСПОЛЬЗОВАТЬ!)
  • Где-нибудь сохраните подробные данные об ошибке. Не составляет труда просто записать все детали в текстовом файле и указать путь к нему в журнале событий Windows либо в средстве мониторинга.
  • Проявите уважение. Если вы можете привести более подробные данные, чем указаны в исключении, отображаемом приложением, сделайте это.

WTF-регистрация

В любом ETL-проекте обязательно попадаются данные в непредвиденных форматах или другие отклонения. Например, вы ожидаете увидеть целое число, но вместо цифры «2» получаете слово two. Такого рода проблемы никогда не выводятся на уровень, где приложение может или должно дать сбой. Напротив, здесь мы имеем дело с вопросами, связанными с бизнес-правилами или с качеством данных; о них следует сообщать пользователям, чтобы несообразности были устранены. Так, данные, полученные в исходной системе, могут нарушать бизнес-правила или ограничения, применяемые к целевой системе. Всякому профессионалу в области баз данных на том или ином этапе его карьеры попадались таблицы, созданные с нарушениями принципов проектирования или кодирования. В результате критически важные данные помещаются в поля, допускающие значения NULL. Если более добротно спроектированная система бизнес-аналитики попытается обеспечить выполнение бизнес-правила NOT NULL, в случае предпринятой кем-либо попытки включить в такое поле методом ввода либо обновления ошибочно полученное в исходной системе NULL-значение непременно будет зафиксирована ошибка. Эту ошибку не следует выводить на такой уровень, когда нарушается весь ETL-процесс. Вместо этого следует зафиксировать одну строку, вызывающую данную ошибку, и изящно устранить проблему с помощью процесса WTF-регистрации.

Данные, поступившие из исходной системы, могут быть получены с отступлениями от промышленных стандартов, и ошибка в коде исходной системы может привести к формированию противоречащих логике данных. Так, в одном приложении суммарная добыча нефтяной скважины время от времени обнуляется в исходной системе из-за ошибки в ней. Поэтому при расчете средней производительности скважины мы попытались использовать следующую простую формулу:

(Суммарный объем на настоящий момент — суммарный объем на предшествующий момент)/прошедшее время.

В случае обнуления суммарного объема мы получили в итоге отрицательное число, как если бы компания закачивала нефть обратно в скважину. С учетом тогдашней цены на нефть такая возможность представлялась маловероятной.

Приведенные примеры иллюстрируют различные типы вопросов, связанных с качеством данных, и каждый из них можно решить тем или иным способом с помощью служб интеграции SQL Server (SSIS). В первом приближении эти вопросы можно классифицировать следующим образом.

  1. Данные, полученные в исходной системе, не проходят вследствие ограничения или бизнес-правила, реализованного в целевой системе.
  2. Исходная система постоянно нарушает промышленный или корпоративный стандарт.
  3. Вследствие ошибки в исходной системе последняя выдает непредвиденные или нелогичные данные.

Существует несколько способов решать эти проблемы по мере возникновения. Первый и, на мой взгляд, наилучший состоит в том, чтобы устранять проблемы во взаимодействии с сотрудниками, обслуживающими исходные системы. Следующий этап — добиться соблюдения бизнес-правил и логических правил в целевой базе данных. Разумеется, это стандартная рекомендация для проектировщиков баз данных, но порой просто диву даешься, глядя на то, как часто разработчики от нее отступают. В службе SSIS реализованы простые механизмы регистрации нарушений данных правил или ограничений. Рассмотрим для примера тот случай, когда суммарный объем нефти, полученной из скважины, обнуляется. С помощью простого проверочного ограничения можно реализовать правило: суммарный объем по состоянию на сегодня должен быть больше или равен суммарному объему по состоянию на вчера. Если тест не пройден, введение сегодняшних данных считается недействительным. После этого службы SSIS могут выявить и зафиксировать этот отказ для одной строки данных, продолжая загружать данные, соответствующие настоящему бизнес-правилу.

Данные извлекаются из источника OLE DB для загрузки непосредственно в целевую систему OLE DB. Если операция вставки будет выполнена с ошибкой, данные будут записаны в файл с разделителями-запятыми вместе с кодом и столбцом ошибки.

На данном этапе бизнес-процесс чаще всего прерывается. Данные помещены в некоторый журнал, а что дальше? Лучший вариант — реализовать легко осваиваемый пользовательский интерфейс, который даст бизнес-пользователям возможность решать возникающие вопросы. В минимальной конфигурации этот графический интерфейс должен обеспечивать:

  • идентификацию информации, что позволит пользователю отследить сформированные с нарушениями данные непосредственно до их источника;
  • причину, по которой ввод или обновление данных завершились отказом. Здесь нужно будет перевести код ошибки. Коды ошибок SQL Server 2008 можно просмотреть по адресу msdn.microsoft.com/en-us/library/ms345164.aspx, а коды ошибок SQL Server 2005 — по адресу msdn.microsoft.com/en-us/library/ms345164 (SQL.90).aspx. Для добавления описания ошибки нужно ввести всего лишь одну строку сценария, как указывается в справочной теме SSIS Enhancing an Error Output with the Script Component;
  • дополнительную информацию, которая поможет пользователю идентифицировать ошибку. К примеру, если указать, что «это значение данных нарушает ограничение схемы», пользователю от этого будет мало проку. Вы должны пояснить ему, почему ограничение было нарушено, так, чтобы пользователь мог выполнить свою работу и устранить проблему.

Регистрация на основе аудита и на основе событий

Бывают случаи, когда требуется аудит пересылки данных. Почти все эти требования могут быть удовлетворены с помощью внутренних для SSIS механизмов регистрации на основе событий. Базовый экран регистрации довольно прост. Достаточно выбрать события для регистрации.

В окне дополнительных параметров пользователь имеет более широкие возможности контроля регистрируемых объектов.

К регистрации событий средствами SSIS следует прибегать с осторожностью. Она сопряжена с большими непроизводительными затратами при вводе/выводе и может привести к резкому снижению быстродействия приложений. При отсутствии абсолютной необходимости принять другое решение я бы ограничивал использование механизма SSIS для регистрации событий событиями OnError и OnTaskFail. Рекомендую вам ограничить подробности такими деталями для производственных целей, как компьютер, идентификатор источника и текст сообщения. В условиях повседневной эксплуатации этих данных будет достаточно для диагностики отказов и для того, чтобы регистрировать ошибки на уровне, где они будут видны и где их можно будет устранить.

Если же количество попадающихся вам типовых ошибок возрастает или если вы не получаете достаточной информации для корректной диагностики проблемы, целесообразно постепенно включать в журнал дополнительные события. Прежде всего, в процессе выявления причин неполадок старайтесь не перегружать себя слишком большими объемами данных. В конце концов кому-то придется «перелопатить» все эти сведения, чтобы выяснить, что именно вызывает проблему. Кроме того, сама процедура ведения журнала приводит к замедлению процесса SSIS в связи с появлением непроизводительных затрат — в некоторых случаях весьма существенных, — что, в свою очередь, может вызвать дополнительные проблемы. Я бы начал с добавления событий OnWarning и диагностических событий для выявления сбоев и ошибок. Для устранения таких проблем, как медленно выполняющаяся загрузка, можно подключить и OnProgress, OnPreExecute и OnPostExecute. Разумеется, можно использовать и другие события — это уже зависит от особенностей вашей среды.

Как вести журнал

Ответ на вопрос о том, как организовать ведение журнала, зависит от конкретных условий работы. В рамках данной статьи я ограничился регистрацией событий в простейшем текстовом файле. Вы можете также вести журнал в любом OLE DB-совместимом приложении (для этого нужно выбрать соответствующее инструментальное средство из панели инструментов SSIS или создать пользовательский сценарий либо класс). Никаких ограничений нет — можете поступать так, как подсказывает вам воображение.

Майк Секстон (m.sexton@avanade.com) — консультант в подразделении Information Management Services компании Avanade, специализируется на бизнес-аналитике, разработке и управлении метаданными 

Запись дополнительных деталей в текстовый файл, который будет добавлен в журналы событий Windows

Использование класса EventLog для регистрации ошибок в журналах событий