Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Программное отслеживание событий в журнале Event Viewer

48K
13 ноября 2009 года
aviva
26 / / 28.10.2009
Всем добрый день! У меня есть вопрос к знающим людям.
Предистория: Есть файл, из которого на прибор идет подача команд. Когда прибор виснет или появляется ошибка, то в журнале ошибок Event Viewer появляется соответствующая запись. Мне нужно отследить момент появления этого сообщения и прекратить подачу команд в прибор. Но не просто прекратить, а и зафиксировать то, какая команда передалась последней, чтобы дальше прогонять предыдущие несколько команд, приближаясь к комбинации, вызвавшей вылет программы или ошибку. Таким образом, научившись программно реагировать на факт добавления сообщения о вылете основной программы в журнал событий, можно вовремя остановить ПО тестирование, и отметить в логе этого ПО, примерно после каких воздействий произошёл вылет.
А теперь сам вопрос: Как программно отслеживать факт добавления сообщения о вылете основной программы в журнал событий? Подскажите, пожалуйста! :confused::confused::confused:
1.9K
14 ноября 2009 года
andriano
474 / / 10.01.2008
Может, не стоит искать обходняе пути, а идти прямым - добавить обработку ошибки в саму основную программу?
241
14 ноября 2009 года
Sanila_san
1.6K / / 07.06.2005
То есть прибор виснет из-за неприемлемых команд?
241
14 ноября 2009 года
Sanila_san
1.6K / / 07.06.2005
[QUOTE=andriano]Может, не стоит искать обходняе пути, а идти прямым - добавить обработку ошибки в саму основную программу?[/QUOTE]Хороший вариант, если программа написана самостоятельно. А если исходники недоступны?;)
1.9K
14 ноября 2009 года
andriano
474 / / 10.01.2008
Цитата: Sanila_san
Хороший вариант, если программа написана самостоятельно. А если исходники недоступны?;)

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

7
14 ноября 2009 года
@pixo $oft
3.4K / / 20.09.2006
Дело в том,что туда может писать не сама программа,а,допустим,драйвер,посредством которого идёт обращение к прибору.Или система пишет.В крайнем случае,в программе может быть какой-нибудь SEH,который посмертно будет это делать
А перехват записи в журнал–интересная тема,на мой взгляд.Хотелось бы узнать,как это делается,причём желательно с помощью API
48K
16 ноября 2009 года
aviva
26 / / 28.10.2009
Цитата: Sanila_san
То есть прибор виснет из-за неприемлемых команд?


Не совсем. Просто иногда каждая команда в отдельности является правильной и приемлемой, а вот некоторая их комбмнация заводит прибор в тупик и он виснет.
Поэтому трудно отловить ошибки, тестируя и обрабатывая ошибки в самом коде (как предложил, например, andriano). Нужно работать с прибором и регистрировать его вылеты.

48K
16 ноября 2009 года
aviva
26 / / 28.10.2009
Цитата: Sanila_san
Хороший вариант, если программа написана самостоятельно. А если исходники недоступны?;)


Нет, как раз исходники мне доступны, только вот там 170 тыс. строк. Так что это даже не иголка в стоге сена!:)


Для чтения записей из журнала используеться функция ReadEventLog. Предварительно журнал открывается функцией OpenEventLog вот их описание:

 
Код:
The OpenEventLog function opens a handle to an event log.
HANDLE OpenEventLog(
  LPCTSTR  lpUNCServerName ,    // server name
  LPCTSTR lpSourceName      // file name
);


Цитата:
BOOL ReadEventLog (
HANDLE hEventLog , // handle to event log
DWORD dwReadFlags,, // how to read log
DWORD dwRecordOffset, // offset of first record
LPVOID lpBuffer, // buffer for read data
DWORD nNumberOfBytesToRead,// bytes to read
DWORD * pnBytesRead, // number of bytes read
DWORD * pnMinNumberOfBytesNeeded // bytes required
);


А еще я нашла интересную программу, осуществляющую т.н. мониторанг и слежение за журналом событий. Вот что о ней написано:

"EventMeister - это средство для чтения журнала событий Windows с обширными возможностями мониторинга и формирования предупреждений. Установленный на одном компьютере EventMeister может собирать данные со всех компьютеров сети, не требуя большого количества лицензий. EventMeister может собирать информацию о журнале событий Windows на вашем компьютере и на любом компьютере внутри сети. Данные из всех журналов представляются для вас в последовательном формате. С помощью фильтров вы можете получить лишь интересующую вас информацию, а также, группировать данные из различных журналов для облегчения анализа. вы можете фильтровать, сортировать и реорганизовывать столбцы для упрощения анализа и представления, создавать различные проекции одних и тех же данных. Вы можете экспортировать журнал, переводит журналы в различные форматы, включая text, csv, xml, форматированный html и RSS. Это позволяет импортировать отфильтрованные данные в базы данных или приложения для анализа, такие как Excel. Вы можете даже опубликовать ваши данные в формате RSS. EventMeister размещается в system tray и выполняет мониторинг ваших журналов 24 часа в сутки 7 дней в неделю в соответствии с определенными шаблонами. При обнаружении интересующего события он реагирует формированием звукового или визуального предупреждения, посылает электронные письма, записывает в журнал и даже запускает ваши собственные скрипты."
Правда мне нужен *.log. Только как вот ее встроить в программу? Ведь как раз исходники EventMeister мне недоступны.

1.9K
16 ноября 2009 года
andriano
474 / / 10.01.2008
Цитата: aviva
Не совсем. Просто иногда каждая команда в отдельности является правильной и приемлемой, а вот некоторая их комбмнация заводит прибор в тупик и он виснет.
Поэтому трудно отловить ошибки, тестируя и обрабатывая ошибки в самом коде (как предложил, например, andriano). Нужно работать с прибором и регистрировать его вылеты.


Мне по-прежнему непонятно, почему это не делать в одной программе.
И я так и не получил ответа на вопрос: сколько программ взаимодействуют с прибором и какова логика распределения работы между ними?

48K
16 ноября 2009 года
aviva
26 / / 28.10.2009
Цитата: andriano
Мне по-прежнему непонятно, почему это не делать в одной программе.
И я так и не получил ответа на вопрос: сколько программ взаимодействуют с прибором и какова логика распределения работы между ними?



На первую часть вопроса я вроде бы уже ответила :) (см. выше). А насчет числа программ, то их очень и очень много (самыми большими являются те, которые обеспечивают работу самого прибора, база данных (архив) и многие-многие другие). Все они объединены в один большой Setup.
Кстати, некоторые ошибки, те, что можно предугадать, и так обрабатываются в самой программе. Когда они происходят, то прибор защищен от вылета и пользователь получает сообщение об ошибке. Но вот беда: не все можно предугадать. Поэтому прибор и вылетает, поэтому и создаются записи в журнале сообщений. И нужно дальше работать уже с ними, чтобы понять причину выдета. :confused:

14
16 ноября 2009 года
Phodopus
3.3K / / 19.06.2008
Все верно вы нашли, но почему то не посмотрели рядом:
OpenEventLog();
NotifyChangeEventLog();
48K
18 ноября 2009 года
aviva
26 / / 28.10.2009
Привет всем!
У меня к вам есть вопрос.
Как мне посоветовал Phodopus, я нашла информацию про NotifyChangeEventLog. Это действительно именно то, что мне нужно. Эта функция позволяет получать уведомления о событиях. Ее описание:

BOOL NotifyChangeEventLog(
HANDLE hEventLog, // описатель, полученный с помощью функции OpenEventLog
HANDLE hEvent // описатель ранее созданного объекта ядра события
);

Определив, что регистрационный файл изменен, система автоматически генерирует объект ядра события. Поток приложения определяет это и запускает все необходимые ему обработчики.
Я нашла несколько примеров применения функции NotifyChangeEventLog, но все они "вырваны" из больших программ и очень громоздки. Может ли кто-нибудь привести т.н. "компактный"пример, чтобы было ясно просто как работает функция.
14
18 ноября 2009 года
Phodopus
3.3K / / 19.06.2008
А чего тут неясного? Открываем ивентлог - получаем хендл. Создаем ивент -получаем хендл. Создаем тред (как вариант) - усыпляем на ивенте. Даем оба хендла функции. Все, теперь как получен ивент проснется наш тред.
48K
18 ноября 2009 года
aviva
26 / / 28.10.2009
Цитата: Phodopus
А чего тут неясного? Открываем ивентлог - получаем хендл. Создаем ивент -получаем хендл. Создаем тред (как вариант) - усыпляем на ивенте. Даем оба хендла функции. Все, теперь как получен ивент проснется наш тред.



Спасибо Вам за ответ! Я только немного не ориентируюсь в сленге. Вы предложили:
"Открываем журнал событий - получаем HANDLE. Создаем событие - получаем HANDLE. Создаем поток команд (как вариант) - усыпляем на событии. Даем оба HANDLE-ла функции. Все, теперь как получено событие проснется наш поток команд."
Извините, что я заменила некоторые слова, просто пытаюсь осознать смысл написанного. И еще уточните, пожалуйста, что значит "усыпляем на событии"?
Т.е. функции NotijyChangeEventLog передается 2 HANDLE-ла: один - лога событий, другой - самого события? Когда событие происходит и записывается в лог, то начинает работать NotijyChangeEventLog. А как это выглядит на примере?

14
18 ноября 2009 года
Phodopus
3.3K / / 19.06.2008
Ладно, немного разжуем.
OpenEventLog() - получаем HANDLE.
CreateEvent() - получаем HANDLE.
Создаем поток (как вариант) CreateThread()
WaitForSingleObject() в функции потока - усыпляем на событии.
Даем оба HANDLE-ла функции.
Цитата:

Т.е. функции NotijyChangeEventLog передается 2 HANDLE-ла


Да.

Цитата:

один - лога событий, другой - самого события?


Объект сихронизации event не имеет ничего общего с событием в журнале, это разные вещи. Возникновение записи в журнале порождает установку объекта синхронизации, как-то так.

Цитата:

А как это выглядит на примере?


Извините, код писать нет никакого желания. Может кто-нибудь и..

48K
18 ноября 2009 года
aviva
26 / / 28.10.2009
Спасибо! Буду копать дальше. А насчет кода, то конечно, не нужно его писать специально. Думала есть пример чуть получше, чем понаходила я :):):)
48K
30 ноября 2009 года
aviva
26 / / 28.10.2009
Здравствуйте! Я снова решила вернуться к непонятному мне вопросу. Вот пример, который я нашла относительно работы с журналом событий и фиксации с помощью функции NotifyChangeEventLog() появления сообщения о событии:
Код:
#include <windows.h>
#include <stdio.h>

void __cdecl wmain(int argc, LPWSTR *argv)
{
  wchar_t *logName = L"Application";// Имя event log.
  wchar_t *sourceName = L"SampleEventSourceName"; // Event Source name.

  BOOL bSuccess;
  HANDLE hEventLog;
  HANDLE hEvent;
  DWORD dwWaitResult;
  hEventLog = OpenEventLogW( //открытие журнала событий
                           NULL, //server name
                           sourceName // Event log source name.
                           );
 


 if (hEventLog == NULL)
  {
    printf("Could not open event log."); //если не удалось открыть журнал
    return;
  }

     hEvent = CreateEvent //Создание объекта события
                       (NULL,  // атрибут защиты
                        FALSE, // тип сброса FALSE – автоматический
                        FALSE, // начальное состояние FALSE – не сигнальное
                        NULL); // без имени обьекта
 
  NotifyChangeEventLog(hEventLog, hEvent); //получение уведомления о событии

  dwWaitResult = WaitForSingleObject //ожидание события
                            (hEvent, //идентификатор объекта
                             INFINITE); // время ожидания в миллисекундах

  if (dwWaitResult == WAIT_FAILED)
    printf("Could not wait for an event to occur.");
    else
    printf("An event has been logged.\n");

    CloseHandle(hEvent);
    CloseEventLog(hEventLog);
    return;
}


Но это только самое начало. Дело в том, что мне нужно фиксировать не просто наличие добавления новой записи в журнад событий, а и отмечать в др. месте (некотором log-файле) список последних, например, 10-ти отосланных кодов нажатия пульта. Это поможет выявить комбинацию, привеждую к вылету прибора. Но тут море вопросов.
Например, получили мы сообщение "An event has been logged". И что с этим делать? Ведь мне нужно понять не то, что был сбой, а какие отсылаемые коды команд к этому сбою привели. Если я беру пересылаемые коды из какого-то файла, то может нужно писать какой-то счетчик, который будет фиксировать порядковый номер кодов?В том смысле, чтобы по вылету можно было в огромном массиве данных файла и кодами выделить именно ту команду, после которой произошел вылет. И как это организовать? Есть ли идеи?
14
01 декабря 2009 года
Phodopus
3.3K / / 19.06.2008
Из того как я понял задачу, могу предложить отдельно в программе логгировать нажатия там всякие вместе со временем их возникновения. В журнале событий время, соответственно, тоже есть. Путем нехирых манипуляций со значениями получим события предшествующие возникновению записи в журнале.
48K
02 декабря 2009 года
aviva
26 / / 28.10.2009
Цитата: Phodopus
отдельно в программе логгировать нажатия там всякие вместе со временем их возникновения. В журнале событий время, соответственно, тоже есть. Путем нехирых манипуляций со значениями получим события предшествующие возникновению записи в журнале.


Т.е. я беру из файла массив с кодами команд, передаю их прибору, параллельно (или после передачи, но тогда время уже будет искажено) фиксируя отосланные команды в некотором log-файле c указанием времени их отправления. Потом сравниваю времена из журнала ошибок и из log-файла, определяя код "ошибочной" команды.
В принципе конечно это было бы неплохо, но вот только скорость передачи данных, установленная для пульта прибора составляет 38400 bps, т.е. я наверно буду проганять свой массив с такой же скоростью, чтобы максимально приблизить условия тестирования к реальным. Можно ли в случае таких времен адакватно следить за временем вылета, ведь наверняка время отправления кода, время записи в журнал, и время добавления кода отправленной команды в log-файл не будут идентичными. Или будут?

14
02 декабря 2009 года
Phodopus
3.3K / / 19.06.2008
Это было просто предложение, никто ж не знал как оно там в действительности. Может подойдет, может и нет. Программа сама в ивентлог пишет?
Чаще всего "вылет" происходит на неверной команде, то есть - последней в логах.
48K
02 декабря 2009 года
aviva
26 / / 28.10.2009
Спасибо Вам за помощь! Я просто не очень пока разбираюсь в подобных вопросах и многое додумываю. Может и можно сделать так, как Вы предложили, т.е. использовать время, если предел дискретности по времени это позволяет. Тогда вместо анализа 10-ти последних команд я посмотрела бы на время записи в журнале и в log-файле и четко выделила место сбоя.

Цитата:
Программа сама в ивентлог пишет?


Нет. ПО прибора работает само по себе. Дополнительная программа, которую я надеюсь все-таки написать, будет работать уже с фактическими имеющимися вылетами. Т.е.
1. передавать коды из одного файла в прибор;
2. записывать переданные коды в log-файл;
3. регистрировать появление записи в Event Viewer;
Прекращение передачи кодов будет происходить (наверно) автоматически после вылета ПО (опять же с такими временами посылки может быть компьютер еще будет "жить" и пересылать данные, а программа прибора уже вылетит). Тогда уже я вручную буду смотреть на файл с переданными кодами и вычислять ошибку.
А действительно, не получится ли так, что ПО прибора (являющееся частью общего ПО компьютера) вылетело, а вцелом компьютер работает и пересылает все коды команд вплоть до последнего. Ведь Setup прибора - это одна программа, и если она дала сбой, то почему не должен тут же работать и выполнять другие программы сам компьютер? Так может быть? Просто тогда в моей программе сработает функция NotifyChangeEventLog() и нужно будет по флагу ее срабатывания тут же прекращать посылку команд.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог