Немного о Powershell
Powershell - расширяемое средство автоматизации от Microsoft, состоящее из оболочки с интерфейсом командной строки и сопутствующего языка сценариев.
PowerShell версии 2.0 - неотъемлемый компонент в составе Windows 7, Windows 8 и Windows Server 2008 R2 и др. Т.е. доустанавливать обычно ничего не надо - все уже есть в системе.
Требуемую функциональность для своих задач можно наращивать при помощи уже готовых скриптов-командлетов. Базовых операций очень много, изобретать велосипеды не обязательно. В открытом доступе можно найти множество готовых решений, созданных другими пользователями, не только Microsoft (кстати, тоже бесплатно).
Про журнал регистрации и его мониторинг
Зачем мониторить журнал регистрации?
Ну, например, можно делать выборку последних ошибок за час и отправлять их на рассмотрение службе поддержки. Или сигнализировать о частом появлении определенных типов ошибок. Или мониторить работоспособность регламентных заданий.
Одна из задач - получение оповещений о том, что конфигурация БД изменилась. На основе этого события можно запускать, например, сохранение конфигурации из SQL, можно отправлять уведомление разработчикам, чтобы они были в курсе и не теребили владельца продукта вопросами вида "а ты накатил мои изменения?". Давайте реализуем этот функционал.
Уже достаточно давно платформа 1С предоставляет возможность вести ЖР в формате SQLite. Одним из преимуществ формата является быстрый поиск по настраиваемым фильтрам. Сразу оговоримся, что далее мы работаем с ЖР именно с этим форматом. Как узнать, что у вас новая версия? Достаточно взглянуть на его начинку, файл журнала находится в 1Cv8.lgd. Уже в первых строках содержится ответ:
При обновлении конфигурации базы данных в ЖР попадает событие "Изменение конфигурации базы данных". Выглядит это примерно так:
Как же представлено это событие в самой базе SQLite? Откроем файл базы каким-нибудь средством просмотра. Воспользуемся DB Browser for SQLite (есть portable-версия)
Открываем базу (1Cv8.lgd) и находим в EventCodes "странное" событие "_$InfoBase$_.DBConfigUpdate". Именно оно отвечает за фразу "Изменение конфигурации базы данных". Учтем, что код события разнится от журнала к журналу для разных баз.
Теперь попробуем найти в основной таблице EventLog все события с таким кодом (в нашем примере 101) и заодно узнаем пользователя, который сделал изменения (данные в таблице UserCodes). Воспользуемся "консолью запросов" DB Browser:
Как видим нашлась всего 1 запись. Хотя могло быть сколько угодно. Запрос выполнен за 3.2 секунды для 200-мегового лог-файла, лежащего в локальной сети. Тот же запрос для файла на SSD-диске выполняется 1.7 секунды.
Для задачи уведомлений, нам не обязательно знать все моменты обновления, поэтому если ограничить выборку определенной датой, то запрос выполняется в разы быстрее: доли секунды.
Давайте попробуем сделать выборку при помощи скрипта на Powershell. Находим первый попавшийся PSSQLite PowerShell Module
для работы с SQLite. Пакет работает на Powershell 2.0, не требует инсталляции, достаточно просто скопировать его в папку и он готов к работе.
Тут же прекрасная документация по работе с методами, разобраться можно за считанные минуты.
Искомые события найдем при помощи метода Invoke-SqliteQuery:
##### подключить модуль
Import-Module .\PSSQLite
## ищем событие, отвечающее за обновление базы данных
$db_update_string = '"_$InfoBase$_.DBConfigUpdate"'
try {
$data_row = Invoke-SqliteQuery -DataSource $path_to_ZhR -as "DataRow" -Query "select code from EventCodes where name = '$db_update_string'"
}
catch {
show_message("Ошибки при получении данных из базы: $error")
exit 1
}
$db_update = $data_row.Code
if (!$db_update)
{
show_message("нет события обновления БД")
exit 0
}
show_message("Код события обновления БД: <$db_update>")
$query = "SELECT connectid,`
date as original_date,`
datetime(date/10000-$utc_seconds,'unixepoch') as date ,`
comment, `
UserCode, `
UserCodes.uuid, `
UserCodes.name as user `
FROM EventLog `
left join UserCodes on EventLog.userCode = UserCodes.code`
where eventcode=$db_update `
and date>$date_content `
ORDER BY date asc `
LIMIT 10"
try {
$data_row = Invoke-SqliteQuery -DataSource $path_to_ZhR -as "DataRow" -Query $query
}
catch {
show_message("Ошибки при получении данных из базы: $error")
exit 1
}
if (!$data_row)
{
show_message("Не найдено обновлений")
exit 0
}
Итак, мы нашли нужные события, теперь надо отправить их куда-то. Например, в slack
Отправка в Slack при помощи PowerShell
С отправкой в слак все еще проще с точки зрения реализации. Создана простейшая функция по отправке сообщения в канал. Нужно знать только token.
function SendToSlack {
param (
[Parameter(Mandatory=$true, Position=0)]$Text,
$token="xxxxx",
$Username,
$Proxy ,
$Channel
)
$max_dlina=500
if ($text.length -gt $max_dlina)
{
$Text = $Text.Substring(0,$max_dlina)+"..." # ограничим длину сообщения, чтобы слак смог принять
}
$postSlackMessage = @{token=$token;channel=$Channel;text=$Text;username=$username;as_user=$true}
$response = Invoke-RestMethod -Uri https://slack.com/api/chat.postMessage -Body $postSlackMessage -Proxy $Proxy
show_message "Результат отправки: $response"
}
Код прост, но есть ложка дегтя - для выполнения метода Invoke-RestMethod требуется powershell версии 3.0. Для Windows server 2012 это не проблема, он уже установлен, а вот обладателям более ранних версий операционной системы придется доставить соответствующие пакеты. В частности, на windows server 2008 r2 (sp1) надо поставить Windows Management Framework 3.0 (Windows6.1-KB2506143-x64.msu)
Не Slack-ом единым
Для тех, кто предпочитает уведомления просто в почту, достаточно воспользоваться командлетом Send-MailMessage. Он, кстати, работает и на версии 2.0.
Send-MailMessage -From "1C-reports@domain.ru" -To "1C-developers@domain.ru" -Subject "обновление базы" -Body "сообщение"
Правда, возможно, тут придется поколдовать с авторизацией для вашего домена.
Никто не запрещает придумать свои способы оповещения через другие мессенджеры или каналы связи.
Про права
Сам журнал регистрации не требует особых прав на доступ к нему - достаточно просто прав на чтение файла. А вот powershell-скрипты должны быть разрешены во избежание получения сообщения "...так как выполнение скриптов запрещено для данной системы".
Это делается один раз командой
## Restricted (Запрещено, по умолчанию) Сценарии не запускаются.
## Allsigned (Все подписанные) Запускаются только подписанные сценарии.
## RemoteSigned (Удаленные подписанные) Разрешен запуск локальных сценариев, прочие сценарии должны быть подписаны.
## Unrestricted (Без ограничений) Запускаются все сценарии.
set-executionpolicy remotesigned
Кстати, о доступе к файлу журналу. Наш скрипт не мешает штатной работе 1С. Можно подключаться к "боевому" файлу журнала. Проводили эксперимент, чтобы проверить влияние механизма на работу 1С. Запускали фоновое задание, строчащее в ЖР по сотне сообщений в секунду. Одновременно стартовали скрипт - все отрабатывается без ошибок. База клиент-серверная, скрипт стоит локально на сервере. Никто никому не мешает
Что в итоге
Сам powershell-скрипт можно запускать через планировщик windows от имени сервисной учетной записи, встраивать в сборочные линии и находить другие применения.
За рамками статьи остались нюансы превращения времени unix в нормальные человекопонятные даты и учет часовых поясов. Эти моменты можно посмотреть в самом скрипте, который прикладывается к статье. Также скрипт умеет "запоминать" последнее время работы, пишет в лог, что он делал и отправляет сообщения в Slack. В архиве приложена и сама библиотека для работы с SQLite.
Ссылки
- Документация по SQLite
- Библиотека PSSQLite PowerShell Module, кстати, там вообще, много полезных командлетов
- DB Browser for SQLite инструмент для просмотра
- Как начать работу с Powershell. Оказывается просто ))
- Про ошибку "mailformed": Ошибка формата файла журнала регистрации (Инфостарт)
- Мониторинг изменений рабочих конфигураций. Часть 1. Сохранение конфигураций из базы SQL без конфигуратора (Инфостарт)